dhcpリレーで社内の移動PCの場所を把握
ネットワークを複数持った会社でIT管理を任されている人で、貸与しているノートPCが今どの場所にあるか知りたいと思った事はありませんか。緊急のアップデートファイルを配布したかったり、IPアドレスの調べ方がわからない人が持つPCを遠隔操作する必要に迫られたりと。
今回はそのような悩みを無料のDHCPサーバーとDHCPリレーエージェントを使って解決したいと思います。
煩雑になりがちなDHCPサーバーの管理が一元化できたり、個人所有のPCを不正に社内に接続された場合(DHCPを使った接続をした場合に限ります)の検知などもできるようになります。
DHCPサーバーには古くなって不要になったXP世代のPCや、ラズベリーパイにDebian系のフリーOSをインストールして使います。また、DHCPリレーエージェントという機能が各場所のルーターに必要になります。もし存在しない場合はこちらもDebian系のPCサーバーで代替できます。
DHCPサーバーの設定
アドレスを管理するDHCPサーバーには、isc-dhcp-serverを使います。APTを使ってインストールします。
$su ... #apt update ... #apt install isc-dhcp-server ...
筆者がサンプルとして使用したDebian Blusterのisc-dhcp-serverの設定ファイルは次のようになっていました。
- /etc/default/isc-dhcp-server
ここに待ち受けるNIC名称を設定します。(enp1s0等)名称を確認するには、ip aコマンドで確認できます。デフォルトでは中身は
INTERFACESv4="" INTERFACESv6=""
という風に空白になっています。この状態で稼働させるとIPv6、IPv4の両方のDHCPサーバーが起動されます。今回はIPv4だけ動かしたいので、INTERFACESv4の方だけにNIC名称を設定し、INTERFACESv6の方は空白のままにしておきます。
INTERFACESv4="enp1s1" INTERFACESv6=""
- /etc/dhcp/dhcpd.conf
こちらにIPv4のDHCPサーバーの設定を入力していきます。
まず、次の項目を修正します。存在しないときは、domain-nameは存在しない場合は(myoffice.jp)など適当に、DNSサーバーには8.8.8.8(GoogleのPublic DNS)とでも入れておけばいいと思います。
option domain-name "ドメイン名"; option domein-name-servers DNSサーバー;
数行下にある、authoritativeのコメントアウトを外します。
そのあとはすべてコメント状態になっていると思います。自身の環境に合わせてDHCPのリースにまつわる設定を記載する箇所になっていて、subnetという単位でネットワークを設定します。基本の書式は次のようになっています。
subnet [ネットワークアドレス] netmask [ネットマスク] { [指定したネットワーク内でのDHCPの挙動の設定]; }
例として次のような構成で設定してみます。
- ネットワーク
192.168.1.0/24
/24はサブネット255.255.255.0という意味になります。
- デフォルトゲートウェイ(ルーター)
192.168.1.1
- 貸与するアドレス
192.168.1.100~192.168.1.115
subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.115; option routers 192.168.1.1; }
このsubnet単位の設定を管理するネットワークの数だけ入力します。
- ネットワーク
- /etc/dhcp/dhcpd6.conf
IPv6ネットワークの設定を入力するファイルです。今回は使用しません。
他にも/etc/dhcp/デイレクトリにファイルが存在しますが、ここでは省略します。ここまで設定すればDHCPサーバーとして稼働させることができます。
各場所のルーターの設定
DHCPサーバーがあるネットワーク以外のネットワークではそれぞれ「DHCPリレーエージェント」を設定しなければいけません。ヤマハNVR510や、アライドテレシスAR415S等、業務用のルーターには機能として備わっていることも多いですが、家庭用のルーターにその機能が備わっているのは見かけません。
なのでこちらもDebianに頼ります。サーバーとは別にDebianPCを用意し、固定IPアドレスを割り振って、各場所のネットワークに配置します。既存のDHCPサーバーがあった場合はそれを停止してください。
$su ... #apt update ... #apt install isc-dhcp-relay ...
isc-dhcp-relayの設定は、インストール時に聞かれるリレー先のDHCPサーバーのアドレスだけで完了です。他に受け付けるNICや起動時オプションも聞かれますが空白で問題ないと思います。
この設定を変更したい場合は/etc/default/isc-dhcp-relayに記述されている内容を修正します。アプリの実体は/sbin/dhcrelayとなります。
端末制限
ここで行う制限はあくまでもDHCPリースに対しての制限です。IPアドレスは各PCで自由に変更できますし、MACアドレスの盗聴や偽装は簡単ですので、以降で書かれている内容は少なくとも単独ではセキュリティの用途には使えないことをあらかじめ承知おきください。
ここまででDHCPサーバー、リレーエージェントの基本設定は終わりました。DHCPサーバーとしては役目を果たすようになりましたので、ふたたび親のDHCPサーバーに戻って、ここから手を加えて目的の情報を拾えるようにしていきます。
まず許可しない端末にはIPアドレスを払い出さない設定をします。制限なしの運用を考えている方は読み飛ばしてください。
/etc/dhcp/dhcpd.confの最後に次の行を加えます。
deny unknown-clients;
この記述で、登録されていない端末からのDHCP要求はすべて拒否されるようになります。
許可する端末の登録も同じファイルに記述します。書式は host [端末名] { hardware ethernet [MACアドレス]; }となります。固定IPアドレスを割り振りたい場合は、fixed-address [IPアドレス];のエントリーも加えます。固定IPアドレスを設定する場合、rangeで指定した範囲内のアドレスを使うとIPアドレスが重複して割り当てられる可能性がありますので範囲外のアドレスを指定するようにしてください。複数のネットワークにまたがって固定IPアドレスを設定する場合は,(カンマ)で区切ります。ネットワークに応じた固定アドレスがリストの中から払い出されます。
host user1 { hardware ethernet aa:bb:cc:dd:ee:ff; fixed-address 192.168.1.100,192.168.2.100; }
ユーザーによって接続可能なネットワークを切り分けたい場合はclassとsubclassを利用する方法をとります。/etc/dhcp/dhcpd.confのsubnetからの記述を次のように書き換えます。
classの設定は利用する前(subnetの前)に記述しなければいけません。
class "class1" { match hardware; } class "class2" { match hardware; } subclass "class1" 1:[class1に所属させたい機器のMACアドレス]; subclass "class1" 1:[複数記入が可能です]; subclass "class2" 1:[class2に所属させたい機器のMACアドレス]; ... subnet 192.168.1.0 netmask 255.255.255.0 { #アドレスプールの設定 pool { #class1のメンバーのみ許可 allow members of "class1"; range 192.168.1.100 192.168.1.109; } pool { #class1のメンバー以外 deny members of "class1"; range 192.168.1.200 192.168.1.209; } ... } subnet 192.168.2.0 netmask 255.255.255.0 { #アドレスプールの設定 pool { #class2のメンバーのみ許可 allow members of "class2"; range 192.168.2.100 192.168.2.109; } ... }
subclassの設定時に先頭につく「1:」はhardwareに設定される接頭で、ethernetを表します。ですので常に固定で「1:」を付けてください。
192.168.2.0のネットワークではclass2のメンバー以外のpoolエントリーがないため、class2以外のメンバーにはIPアドレスは割り当てられません。
ログの取得
次にログを取得します。通常DHCPサーバーのログはSyslogに保存されますが、それだと後からログを解析する場合に関係ないデータまで含まれていて処理が難しいので、個別に出力するようにします。
/etc/dhcp/dhcpd.confファイルの中盤に、独自にログを出すための設定がコメントアウトされて入っていますので、コメントアウトを除去します。
log-facility local7;
もし同じサーバー内でファシリティlocal7で出力されているものがあったら別の番号にします。ログに関してはDebian(Linux)のログについての記事に書いてありますので、よろしければそちらもご覧ください。
/etc/rsyslog.confに「local7.* /var/log/dhcp.log」というエントリーを追加してdhcp単独のログを出します。また後からウェブブラウザ経由でログを拾うための設定として新規作成時のログファイルの権限を変更して、読み取り権限のある状態で作成させます。そのあと読み取り権限の設定が他のログファイルに及ばないように元に戻します。
$FileCreateMode 0644 local7.* /var/log/dhcp.log $FileCreateMode 0640
合わせてlogrotateの設定もしておきます。/etc/logrotate.d/isc-dhcp-serverというファイルを作成し次のように記述します。
/var/log/dhcp.log { rotate 14 daily missingok ifempty postrotate pkill -1 rsyslog 2>/dev/null || true endscript }
記述内容を説明していきます。まず対象となるログファイルの後で{}を付けて設定をしています。中カッコの中身は次のようになっています。
- rotate 14
14世代分のログを残す設定です。
- daily
日毎のローテーションとする。先の設定と合わせて14日分のログを残す設定となります。weeklyとすると週、monthlyとすると月毎のローテーションになります。保存の期間は好みで調整してください。
- missingok
ログファイルがなくてもエラーにしない設定です。
- iempty
空のログファイルでもローテーションします。
- postrotate~endscript
ローテーション処理後に実行するスクリプトを記載します。ここではrsyslogにHUP(=1)シグナルを送っています。理由はrsyslogを再起動させたいからで、そうしないと以降のdhcp.logへのログ出力がなくなってしまいます。なぜHUPシグナルで再起動するかとう理由は「@IT:【 kill 】コマンド...」によると、そういう暗黙の了解でプログラムが構築されているからだそうです。(ちゃんとサービスをリブートした方がいいのかもしれません)
他には、圧縮をかけるcompressや、prerotate~endscriptの間で処理前に実行するスクリプトを記述したり、olddir ディレクトリパスで、過去ログの保存先を指定できたりします。
「logrotate -f 設定ファイル名」で強制的に処理を実行することができます。テストだけなら-dオプションでも可能です。
PHPでステータス把握
ログファイルの解析の方法や表示のさせ方はいろいろあると思いますが、ここではapacheサーバー上のPHPで表示してみたいと思います。特定のアドレスにアクセスすると当日のログを読み込んで端末がどのネットワークで利用されている(されていた)かを表示します。またユーザー名やネットワークを保持・管理してdhcpd.confの作成を自動化します。
先にclassでの管理の紹介もしましたが、PHPではdeny unknown-clientsの方式で管理するようにします。
まず、apacheサーバーとPHP、PHPのmbstringをイストール、設定をします。
$ su ... # apt update ... # apt install apache2 php7.3 php-mbstring ... # nano /etc/php/7.3/apache2/php.ini ...(次で説明するように編集してください) # touch /var/www/html/userlist # chmod 666 /var/www/html/userlist # touch /var/www/html/networklist # chmod 666 /var/www/html/networklist
PHPの/etc/php/7.3/apache2/php.iniのmbstringに関連する項目を次のように設定してください。
- default_charset="UTF-8" となっているかを確認
- mbstring.language = Japanese のコメントを外す
- mbstring.detect_order = auto のコメントを外す
touchとchmodコマンドでnetworklistとuserlistを誰でも読み書き可能なテキストファイルとして作成しています。
DHCPからログからリリース情報を取得したり、ユーザーやネットワークを管理してdhcpd.confを作成するPHPファイルはこちらで配布しています。ファイルをダウンロードしたのち、展開してapacheが管理するWebディレクトリに配置してください。ここでは/var/www/htmlディレクトリとなります。
中身は単一のPHPファイルです。テキストエディタで開くと中に設定項目を設けてありますので、環境に応じて編集してください。保存の際は文字コードUTF-8、改行コードはLFにするとトラブルが少ないと思います。
編集が終わったら、配置したPHPページにアクセスすると管理画面が表示されます。設定したパスワードでログインし、ユーザーやネットワークを登録してお使いください。