NAT越しのWake On Lan
長らく実家にて運用しているVPNクライアントルーターについて、一部改善した。
Linux の NAT 環境では、デフォルト設定のままではマジックパケットなどの ブロードキャストパケットが転送されない。
そのため、VPN+NAT を介した Wake on LAN(WoL)は通常そのままでは利用できない。
これは iptables の NAT 機能そのものというより、Linux の IPv4 スタックがブロードキャストパケットのフォワーディングを抑制している仕様によるものだ。
●bc_forwarding によるブロードキャスト転送の有効化
Linux では /proc/sys/net/ipv4/conf/ 配下に、ネットワークデバイスごとの IPv4 動作を制御するパラメータが用意されている。
この中にある bc_forwarding を 1 に設定することで、ブロードキャストパケットの転送を許可できる。
これを利用して、NAT 越しの WoL を可能にする。
マジックパケット(ブロードキャスト)の転送を有効化
sysctl -w net.ipv4.conf.all.bc_forwarding=1
sysctl -w net.ipv4.conf.wlan0.bc_forwarding=1
sysctl -w net.ipv4.conf.vpn_vpn.bc_forwarding=1
all
→ 今後生成されるインタフェースに対してもデフォルト値として適用
wlan0
→ 無線 LAN 側
vpn_vpn
→ VPN トンネルインタフェース
関連するすべてのインタフェースについて bc_forwarding=1 を設定する必要がある。
●VPN デバイスは動的生成される点に注意
注意すべき点として、vpn_vpn デバイスは VPN クライアント起動時に動的に生成される。
そのため、起動直後に sysctl を実行すると、デバイスが存在せず設定に失敗する。
この問題を回避するため、起動プロセスの最終段階(default.target 到達後)で設定を行う仕組みを用意した。
●起動完了後に実行する systemd サービス
サービスファイル
/lib/systemd/system/rc-latest.service
[Unit]
After=default.target
[Install]
WantedBy=default.target
[Service]
Type=oneshot
ExecStart=/etc/rc.latest
RemainAfterExit=yes
※ 単発で実行するだけなので、Type=oneshot が適切。
●自動起動を有効化
systemctl --system enable rc-latest
●実行スクリプトの作成
/etc/rc.latest を作成し、実行権限を付与する。
chmod +x /etc/rc.latest
/etc/rc.latest
#!/bin/sh
ブロードキャスト(マジックパケット)転送を有効化
sysctl -w net.ipv4.conf.all.bc_forwarding=1
sysctl -w net.ipv4.conf.wlan0.bc_forwarding=1
sysctl -w net.ipv4.conf.vpn_vpn.bc_forwarding=1
●効果と注意点
この設定により、ルーターへ SSH ログインして手動でコマンドを実行しなくても、Wolwin などの Windows アプリケーションから VPN 経由でリモート PC を起動できるようになった。
なお、bc_forwarding を有効にすると、VPN を越えてブロードキャストパケットが流れるようになるため、
・信頼できる VPN 環境内でのみ使用すること
・不要なインタフェースでは有効化しないこと
といった点には注意が必要である。
●まとめ
・NAT 越し WoL が動かない原因は Linux のブロードキャスト抑制仕様
・bc_forwarding を有効化することで解決可能
・VPN デバイスの動的生成に注意し、起動完了後に設定するのがポイント
「実用的だが情報が少ない」領域なので、同じところでハマる人の助けになれば幸いです。