なぜネットワークを切り替えるたびにコマンドを打つ必要があるのか?
おなじみの光景:ノートパソコンを自宅からオフィスに持ち込みます。自宅ではシンプルな192.168.1.xのIP範囲を使用していますが、会社に着いた途端、WireGuard VPNを起動し、内部サーバーにアクセスするためにルーティングテーブルを再構成し、セキュリティのために不要なサービスを停止しなければなりません。そして夕方帰宅すると、また同じ退屈な手順を繰り返すことになります。
手動で行うこともできますが、ミスが発生しがちです。NetworkManager Dispatcherスクリプトは、この問題に対する究極の解決策です。これはフックシステムのように動作し、ネットワークの状態が変化するたびに、あらかじめ設定しておいたスクリプトを自動的に実行します。
私はかつて、5分おきにインターフェースをリセットする古いバックグラウンドスクリプトのせいで、パケットロス(packet loss)のデバッグに丸一週間を費やしたことがあります。そこから学んだ教訓は「自動化は透明であるべきだ」ということです。NetworkManager Dispatcherはイベント駆動型(event-driven)であるため、この点において非常に優れており、システムをより厳密に制御できます。
ネットワーク自動化手法の比較
コードを書き始める前に、なぜDispatcherスクリプトが従来の手法よりも優れているのかを確認しましょう。
- Cron Job: かなり強引な方法です。1〜5分ごとにネットワークをチェックします。これは遅延(delay)を発生させるだけでなく、不要なCPUリソースを浪費します。
- Systemd Service: よりプロフェッショナルですが、設定が非常に複雑です。初心者にとって、インターフェースが「UP」になった正確なタイミングを捉えてコマンドを実行するのは簡単ではありません。
- NetworkManager Dispatcher: これはネイティブ機能です。バックグラウンドで待機し、LANケーブルの接続やWi-Fi接続が成功した瞬間にのみ実行されます。高速で、スマート、そして極めて正確です。
注意すべきメリットとデメリット
メリット
- 即座の反応:ネットワークの状態が変化した瞬間に実行されます(ミリ秒単位)。
- 明確なコンテキスト:スクリプトは、どのインターフェースが動作しており、具体的なアクション(up/down/vpn-up)が何であるかを正確に把握します。
- リソースの節約:常駐して動くわけではないため、RAMを消費しません。
デメリット
- セキュリティリスク:スクリプトは
root権限で実行されます。コード内の小さなミスがシステムの脆弱性につながる可能性があります。 - 監視の難しさ:スクリプトがエラーになっても、静かに「死ぬ」だけです。原因を特定するにはシステムログを確認する必要があります。
Dispatcherスクリプトの動作メカニズム
NetworkManager は/etc/NetworkManager/dispatcher.d/ディレクトリをスキャンします。接続に変動があるたびに、その中のスクリプトをアルファベット順に実行します。
実行時、NetworkManagerは2つの入力引数を渡します:
- $1: インターフェース名(例:eth0, wlan0, tun0)。
- $2: アクションの状態(例:up, down, vpn-up, vpn-down)。
実践的な導入ガイド
ステップ1:基本的な監視スクリプトの作成
まずは、ログを記録するスクリプトを作成しましょう。これにより、システムがイベントを正しく認識しているかを確認できます。
sudo nano /etc/NetworkManager/dispatcher.d/99-network-log.sh
スクリプトの内容:
#!/bin/bash
INTERFACE=$1
ACTION=$2
case "$ACTION" in
up)
echo "$(date): インターフェース $INTERFACE が接続されました" >> /var/log/network-events.log
;;
down)
echo "$(date): インターフェース $INTERFACE が切断されました" >> /var/log/network-events.log
;;
esac
ステップ2:実行権限の設定
NetworkManagerは権限設定に非常に厳格です。権限が緩すぎると、安全性のためにスクリプトが無視されます。
sudo chmod 755 /etc/NetworkManager/dispatcher.d/99-network-log.sh
sudo chown root:root /etc/NetworkManager/dispatcher.d/99-network-log.sh
ステップ3:SSIDに応じたルートとファイアウォールの自動設定
例えば、オフィスのWi-Fi(SSIDが「Office-Guest」)に接続したときに、10.10.x.xのIP範囲へのルートを追加し、ポート8080を開く必要があるとします。
環境変数 $CONNECTION_ID を活用します:
#!/bin/bash
if [ "$CONNECTION_ID" == "Office-Guest" ]; then
case "$2" in
up)
# ゲートウェイ 192.168.10.1 経由のスタティックルートを追加
ip route add 10.10.0.0/16 via 192.168.10.1 dev $1
# ファイアウォールのポートを開放
ufw allow from 10.10.0.0/16 to any port 8080 proto tcp
;;
down)
ip route del 10.10.0.0/16 dev $1
ufw delete allow from 10.10.0.0/16 to any port 8080 proto tcp
;;
esac
fi
スクリプトが動作しない時のデバッグのコツ
スクリプトはバックグラウンドで実行されるため、ターミナルにエラーは表示されません。リアルタイムでログを確認するには、次のコマンドを使用してください:
journalctl -u NetworkManager -f
さらに詳しく調べたい場合は、スクリプトの2行目に set -x を追加してください。これにより、実行されるすべてのコマンド行がログに表示され、どこでスクリプトが止まっているかを確認できます。
まとめ
NetworkManager Dispatcherスクリプトは、システム管理者やLinux愛好家にとって非常に強力なツールです。ネットワークを切り替えるたびに手動で2〜3分かけて設定する代わりに、コンピューターに1秒で処理させましょう。ネットワークドライブ(NFS)の自動マウントや、サーバーのIPが変わった際のTelegram通知など、小さなことから始めてみてください。成功を祈ります!

