アクセスポイント化(Dumb AP)したOpenWRTデバイスで接続中クライアント名を表示するには

公開

OpenWrt ルータを アクセスポイント 化(Dumb AP)すると、接続中の WiFi クライアントの ホスト名 が解決されず、 ? マークで 表示されない ことがよくあります。そこで、DHCPサーバであるルータ機がホスト名リストを生成し、アクセスポイントへ配布する仕組みを構築しました。

誰がWiFi接続中なのか分からない

通常、OpenWrt無線ルータでは、接続中のWiFiクライアントのホスト名やIPアドレスをLuCI上で確認することができます。

図1.ルータ機のDHCPリース一覧

図1.ルータ機のDHCPリース一覧

図2.ルータ機のWiFiクライアント一覧

図2.ルータ機のWiFiクライアント一覧

ところが、DHCPサーバを廃してアクセスポイント化した場合、自身でIPアドレス配っていないデバイスのことはわからないので、MACアドレスからホスト名を得られず ? マークになってしまいます(ちなみに一部のIPアドレスは、おそらく arp で得られたのでしょう)。

図3.Dumb AP機のWiFiクライアント一覧

図3.Dumb AP機のWiFiクライアント一覧

/etc/ethersに書けばよい、が

同じことを指摘するユーザは多く、さまざまな対処法が提示されていました。

要は /etc/ethers にMACアドレスとホスト名(もしくはIPアドレス)のペアを列記しておけば、一覧ページに反映されるとのこと。

デフォルトではコメント文だけのファイルに、ひとまず手打ちでMACアドレスとホスト名を追加します。

ファイルを保存してしばらくすると、 ? マークだったホスト名が表示されました。

図4.ethersファイルが反映される

図4.ethersファイルが反映される

ちなみに、リースファイル /tmp/dhcp.leases に記述する対処法もありましたが、そもそもDumb APではDHCPサーバ機能を無効にしているので、このファイルは存在しないはず。

にも関わらず、例えばルータ機のリースファイルを安易にコピー配置してくると、LuCI上ではActive DHCP一覧に現れてしまい、これはこれで逆にトラブルのもとになりそう。

図5.dhcpリースファイル移植すると

図5.dhcpリースファイル移植すると

 

また、 arpwatch (OpenWrtでは addwatch )を利用して、この /etc/ethers を自動生成しようとする取り組みも見つけるも、生成されるのはMACアドレスとIPアドレスのペア。

 

リースファイルからethersのリストを更新

結局、全てを知っているルータ機が、DHCPリースファイルからMACアドレスとホスト名のペアを抜き出し、 /etc/ethers を更新して、ネットワーク上の他のOpenWrt機へ配布するような仕組みを考えてみます。

 

まずは、OpenWrtのDHCPサーバのリースファイル /tmp/dhcp.leases 。その中身はこのようになっています。

このリースファイルから /etc/ethers の形のリストを得るのは次の要領で。

後はこのリストをループで回して、 /etc/ethers とのクロスマッチングを行い、新しい情報であれば /etc/ethers に追記すればよし。

 

while文へパイプ渡しすると変数が外で正しく読めない

上述の、リストのような改行区切りの文字列を、 while ループで1行ずつ処理を進める次のようなスクリプトを組んでみたのですが、 while ループ内で更新された変数 $n の値が、その外では全く反映されていない事象に遭遇。

調べてみるとそれは別プロセスになってしまうためらしく、パイプで渡してはいけないようです。以下の記事が勉強になりました。

BashならProcess Substitutionを使うところですが、OpenWrtのデフォルトはAshなので、互換性を鑑みてレガシーにヒアドキュメントを使うことにします。使い方はこんな感じで、 done の後方にくっつけます。

 

whileループの回し方を会得したので、早速スクリプトを組んでみました。

実行時の標準出力は以下の通りで、一行ずつ /etc/ethers へ追記されます。

 

排他的論理和(XOR)を利用した更新法

上述のように、新しいホスト情報を一つ一つファイルに追記するのは少し忍びないので、以前にサイトへのスパムバックリンクを否認する際に学んだ「集合」の考え方を応用して、 /etc/ethers ファイルへまとめて追記するような手法を探ります。

 

まず、DHCPリースファイル、 ethers ファイルそれぞれのMACアドレスリストを連結(一旦全て小文字に変換)、

そのどちらかにしかない(重複していない)MACアドレスを抽出、

そのMACアドレス群をDHCPリースファイルへまとめて grep 検索すれば、それが ethers ファイルへ追記すべきリストに。

以上の流れでスクリプトを組んでみました。

実行結果は以下の通り、最後にまとめて追記するので生理的にも安心です。

 

ルータからアクセスポイントへ転送

次にルータ機で生成した /etc/ethers ファイルをネットワーク上の他のOpenWrt機器へ配布する仕組みを構築します。

まず配布元のルータ機の公開鍵を、配布先のOpenWrt機器の authorized_keys へ登録して、シームレスなアクセスができるようにしておきます。

図6.ssh公開鍵の登録

図6.ssh公開鍵の登録

計3機ある配布先の情報を配列に格納して、 scp によるファイル転送をループで回して、と思い付くも、配列が使えるのはBashだけ。

仕方ないのでAshではまた、改行区切りのリストのような文字列で格納してループを回すことにしました。

 

完成したスクリプトをスケジュールタスクに登録

ようやく完成したスクリプトの全体像は次の通りです。

これをルータ機のスケジュールタスク cron へ登録、取り敢えず1日1回の頻度で様子を見ます。

直近の実行結果は /tmp へ出力されたテキストファイルで確認。公衆ネットワークではないので、新しいデバイス情報の追加はそうは発生しません。

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA