続、自分でDDNSを実現化(ルータログ)

過去に「自分でDDNSを実現化(サブドメインの活用)」という内容を書いていましたが、今回は別のアプローチで書いてみます。

●事前準備
当サイトの「ルータのログを取得」を設定しておく必要があります。

●最初に
ルータからログを得る事により、割り当てられている hostname もしくは IPアドレスがわかります。
それを利用してわかりやすい名前を付けて、安定したサービスを実現しようと考えています。
自宅VPNやデータ収集先としても、自分でつけた名前なら扱いやすいでしょう。

★ちなみにこの方法を取ると正引きは対応できますが、逆引きは対応できないので注意してください★

●使用プログラム
OS:AlmaLinux 9.3
bind 9.16.23
PHP  8.2.14.1

●ネームサーバの設定
DDNSを実現する為には、動的IPアドレスを変更するたびにゾーンファイルに書き込む必要があります。
しかし、そのためにファイルを開いたり更新したりすることは手順が多すぎて実用的ではありません。
そこで、『 nsupdate 』というコマンドを使います。

nsupdate が受け付けられるように、ネームサーバを設定します。

	named.conf の編集
		# cd /etc
		# vi named.conf
		
		正引き部分に設定を追加します。
		
		【変更前】
		zone "usi.nu" {
		   type master;
		   file "seibiki.zone";
		};

		【変更後】
		zone "usi.nu" {
		   type master;
		   file "seibiki.zone";
		   allow-update { 133.18.168.21; 127.0.0.1; };     <-- 追加
		};
		
		再起動します
		# systemctl restart named
		
	これでネームサーバの方は準備完了です。

●データファイルの保存
nsupdate を利用するのですが、コマンドをいちいち送らなくてもファイル化しておけば一挙に登録できます。
今回は、ファイルを利用する方法で行います。

	・保存場所
		保存場所は、「 /usr/local/share/ddns 」という場所を作成します。
		
		# cd /usr/local/share
		# mkdir ddns
		drwxr-xr-x 1 root root 43 1月 10 ddns
		
	
	・チェックプログラムを作成
		作成プログラムのフローチャート
		 1:URLをつけるフルドメイン名の設定
		 2:ログファイル名(router)を指定
		 3:今日の日付を確認(hi)
		 4:9日より以前か以後かを確認。スペースの個数を調整
		 5:URLの現在の IPアドレスを取得(ipnow)
		 6:ログファイルの最終行を取得(endline)
		 7:endlineをスペースで区切る
		 8:ログファイルからの IPアドレスを取得(iplog)
		 9:ipnow と iplog を比べて一致するかどうか確認する
		10:不一致の場合は更新用ファイルを作成する
		11:nsupdate を実行する
		12:格納用ファイルを作成
		13:9行目で一致した場合は何もせず終了する。
		
		change_ddns.php の編集
		# cd /root
		# vi change_ddns.php
		
			<?php
			/*
			Make DDNS ipaddres to URL.

			sins 2024-01-10 Ver1.0  Make by usi.
			*/
			$url='ddns.usi.nu';
			$dnsserver='dns.usi.nu';
			$logf='router';
			
			$putlog='/var/log/' . $logf;

			// 日付の桁数確認
			date_default_timezone_set('Asia/Tokyo');
			$date = new DateTime();
			$hi=$date->format('d');
			if ($hi>9) {
			        $sp=3;
			} else {
			        $sp=4;
			}
			//echo "sp=" . $sp . "\n";
			// 現在のURLのIP addressを確認
			$ipnow_o=gethostbynamel($url);
			$ipnow=$ipnow_o[0];
			//echo "ipnow=" . $ipnow . "\n";
			// log最終行のURLを取得し、IP addressを確認
			$logdata = file($putlog, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
			$endline=array_pop($logdata);
			//echo $endline . "\n";
			$iplog_g=explode(' ',$endline);
			
			$iplog_o=gethostbynamel($iplog_g[$sp]);
			$iplog=$iplog_o[0];
			//echo $iplog . "\n";
			
			//IPアドレス一致判定
			if ($ipnow!=$iplog) {
					//IPアドレス更新用ファイル
					$file = '/usr/local/share/ddns/dns2rev.txt';
					
					//IPアドレス格納用
					$ipfile = '/usr/local/share/ddns/ipaddr.txt';
					
					// アドレス不一致
						//書き込むファイルの文字列とIPアドレス
						$str = "server " . $dnsserver . "\n";
						$str = $str."update delete " . $url . ". IN A\n\n";
						$str = $str."update add " . $url . ". 10080 IN A ".$iplog."\n\n";
					
					//ファイルを書き込む
						file_put_contents($file, $str, LOCK_EX);
					
					//nsupdateの実行
						$ex="nsupdate ".$file;
						exec($ex);
					
					//IP格納用更新
						file_put_contents($ipfile, $iplog, LOCK_EX);
					
			} else {
			//      echo "IPアドレスは一致しました。\n";
			}
			?>
		
	「//」を外すと途中経過の値を表示します。見たい値がある場合は、外して確認してください。


●動作確認
	php で動きますので、動作確認をしてみます。
	
	# php change_ddns.php
	
	#
	
	一行空けて終了します。
	
	実際に動作したかどうか確認してみましょう。
	
	# ls -l /usr/local/share/ddns
	合計 8
	-rw-r--r-- 1 root root  15  1月 10 09:48 ipaddr.txt
	-rw-r--r-- 1 root root 139  1月 10 09:48 dns2rev.txt
	
	ファイルが2つできています。
	
ipaddr.txt最新のIPアドレス
dns2rev.txtnsupdateで使うファイルです
中身を見てみます。 # cat ipaddr.txt aaa.bbb.ccc.ddd # cat dns2rev.txt server dns.usi.nu update delete router.usi.nu. IN A update add router.usi.nu. 10080 IN A aaa.bbb.ccc.ddd dns2rev.txt の中身は nsupdate を実行時に手動でやる手順が入っています。 1.サーバを指定 2.古いIPアドレスの設定を削除 3.新しいIPアドレスの設定 本当は、一番最後に「send」を入れると更新されるのですが、ファイルを使うとこれが省略できるようなので割愛しています。 更新データは、実行後徐々に広がっていきますので、検索したDNSサーバによっては時差が発生します。 すぐに恩恵を受けたければ、変更したDNSサーバ(今回は、dns.usi.nu)をクライアントのネームサーバに設定することをお勧めします。 設定できなければ、GoogleのDNSサーバ(8.8.8.8)をお勧めします。調査したところ、割と反応が早かったです。 ●継続設定 ルータの設定が変更されるたびに、手動でプログラムを実行していては間に合わない場合があります。 特に、電気が瞬停等をしてIPアドレスが不意に変更されている時などはわからないケースがほとんどです。 そこで、自動化する事にします。 【ポリシー】 朝7時から21時までは5分おきにIPアドレスのチェックを行い、変更されていれば更新する。 21時から翌朝7時までは1時間おきにIPアドレスのチェックを行う。 cronを使って実現してみましょう。 php実行ファイルの場所確認 # which php /usr/bin/php cronを編集 # crontab -e 17 0-6 * * * /usr/bin/php /root/change_ddns.php > /dev/null */5 7-21 * * * /usr/bin/php /root/change_ddns.php > /dev/null 17 22-23 * * * /usr/bin/php /root/change_ddns.php > /dev/null 分について 「*/5」は5分おきになります。「17」は毎時17分に処理です。21時から翌6時までの各17分に実行します。 時について 「0-6」「7-21」「22-23」はそれぞれの指示された時間です。 月・日・曜日について 全ての月・日・曜日で実施するので「*」になります。 以上で設定は終了です。 ログファイルはプッシュでサーバに届くため、変更があればすぐに情報が集まります。 ログ本来の使い方とは異なりますが、ログの情報をもとに設定を変更するという行為は、SEならよくある話ではないでしょうか。 遠隔地のルータ管理なども使えると思いますので、良ければ便利に使ってくださいませ。

Let's PC の Topに戻る
ホームページのTopに戻る