インターネットから内部LAN上の一部のコンピュータを起動する必要があります。
設定方法がほとんどない、やや閉鎖的なルータがあります。
デーモンや同様のものは含まれていないので、netfilter(iptables)を使ってこれをやりたいのですが、他の解決策も動作します。
私の意見は次のとおりです。
- 外部コンピュータは、内部的に正しいMACを含むパブリックIPアドレスにWOL(Wake on LAN)パケットを送信します。
- データをLinuxボックスにリダイレクトするために、ルーター(たとえば1234)で正しいポートが開きます。
- LinuxボックスはUDPユニキャストパケットをブロードキャストパケットに変換します(宛先アドレスが255.255.255.255または192.168.0.255に変更されることを除いて、内容はまったく同じです)。
- マルチキャストパケットが各ネットワークカードに到着し、必要なコンピュータが目覚めます。
これに対する非常に単純なnetfilterルールは次のとおりです。
iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.255
残念ながら、netfilterはブロードキャスト変換を無視しているようです。 192.168.0.255 および 255.255.255.255 は情報を提供しません。また、192.168.0.0と0.0.0.0でテストし、
tcpdumpを使用して何が起こるかを確認しました
tcpdump -n dst port 1234
13:54:28.583556 IP www.xxx.yyy.zzz.43852 > 192.168.0.100.1234: UDP, length 102
。次の2行目が必要です。
13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > 192.168.0.255.1234: UDP, length 102
マルチキャスト以外のアドレスにリダイレクトすると、すべてがうまく機能します。 2つの予想される行があります。しかし、明らかにこれはWOLでは機能しません。
netfilterにブロードキャストパケットを送信するように指示する方法はありますか?
私が考えた他の方法:
- iptablesを使用して必要なパケットを一致させて記録し、デーモンを使用してログファイルを監視し、ブロードキャストパケットをトリガーします。
- iptablesを使用して、必要なパケットをブロードキャストパケットをトリガーするローカルデーモンにリダイレクトします(簡単)。
- socatを使う(どう?)
答え1
socat
キラーユーティリティです。初期化スクリプトのどこかにこれを置きなさい:
socat -u -T1 UDP-LISTEN:1234,fork,range=<ip address of source>/32 UDP-DATAGRAM:255.255.255.255:5678,broadcast
一部のユーザーはUDP-LISTENに問題があるため、UDP-RECVを使用する方が良いようです(警告:無限ループでブロードキャストパケットを送信できる)。
socat -u UDP-RECV:1234 UDP-DATAGRAM:255.255.255.255:5678,broadcast
fork
socat
次のパケットを聴き続けることができます。T1
分岐したサブプロセスの寿命を1秒に制限します。range
socat
このソースからのパケットのみを受信します。これが実行中のコンピュータ以外のコンピュータであると仮定すると、無限ループが発生する独自のブロードキャストパケットを受信しないことが役立ちsocat
ます。socat
255.255.255.255
。192.168.0.255
現在のネットワーク構造について考える必要なくコピーして貼り付けるだけです。注:これにより、すべてのインターフェイスにブロードキャストパケットが送信される可能性があります。
あなたと同じように、私はWOLがすべてのポートで動作することを知っていました。これが信頼できるものかどうかはわかりません。多くのドキュメントでは、ポート0、7、9についてのみ説明しています。
これにより、権限のないポートを使用できるため、socat
ユーザーとして実行できますnobody
。
この答えに貢献してくれた@lgeorget @Hauke Lagingと@Gregory MOUSSATに感謝します。
答え2
定義によると、ブロードキャストトラフィックの宛先はローカルコンピュータです。これは、パケットが192.168.0.255にDNATedされたことを意味し、カーネルはパケットを見て、宛先がルータ自体であると判断するため、INPUTチェーンでパケットを見ることができます。ルーター(および他のデバイス)は、192.168.0.255パケットが自分のためのものであると見なし、それ以上転送しません。ブロードキャストパケットは、設計どおりにルーティング/配信されません。
上記のARPトリックには良い解決策があります。 IPアドレスを「失う」。この例では仮想デバイスを使用します。ネットワーク上のどのデバイスにも192.168.0.254
割り当てないでください。192.168.0.254
コンピュータに絶対に使用しないIPアドレスのLANインターフェイスに固定ARPエントリを作成します。
arp -i ethLAN --set 192.168.0.254 FF:FF:FF:FF:FF:FF
この仮想IPアドレスへのWANインターフェイスのDNAT Wake-on-LAN UDPトラフィック:
iptables --table nat --append PREROUTING --in-interface ethWAN --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.254
これは WOL パケットに適しています。この回避策は、MikrotikデバイスやopenwrtデバイスなどのLinuxカーネルベースの製品にも適用されます。私はMikrotikデバイスでこのトリックを使って電話を使って自分のコンピュータをリモートで目覚めさせることができます。
答え3
私が見つけたServerfaultに関するこの質問について。
しかし、私は私のルーターを通してそのようなブロードキャストトラフィックを得ることができませんでした。 DNATted パケットは FORWARD チェーンにも到達しません。おそらくこれを許可しない奇妙なカーネルオプションがあるかもしれません。
しかし、ARPのアイデアは興味深いです。私は、これが転送されたトラフィックだけに到達できるように、パケットがそのアドレスに送信されるのを禁止するOUTPUTの規則を伴う必要があると思います。
答え4
実際、netfilterはブロードキャストを実行できませんが、ルーティングメカニズムはこれを行います。
ただし、デフォルトでは配信されたすべてのブロードキャストを削除します。
最近、Linuxカーネル(バージョン5.0頃)では直接UDPブロードキャスト配信が可能になりました。
bc_forwarding
ブロードキャストネットワークインタフェースパラメータを変更する必要があります。
sudo sysctl -w net.ipv4.conf.eth1.bc_forwarding=1
(注:net.ipv4.confオプションのようです。みんな.bc_forwardingは機能しません)
したがって、今は5.0 + iptables程度のカーネルで十分です。