自宅ゲートウェイで敢えて今 UPnP を正しく有効にした件
こう書くと非常に大仰だが、MiniUPnPd を起動しているにもかかわらず、MiniUPnPd が動的にルールを追加するチェインに飛ばないように設定しているのに気付かなかったので色々と見直してみた。
Table of Contents
そもそもUPnPとは
UPnP は Universal Plug and Play の略で、ネットワーク上のデバイスを検知したりデバイスをコントロールしたりするプロトコルになる。DLNA が UPnP で実装されているらしいが、一般家庭で UPnP を意識するのは、自動でポート開放してくれる位のレベル感でだろう。
ただ、今時は UPnP なんてほぼ意識する必要はないし、パッシブに通信を確立する必要はほぼないので、UPnP が有効化されていなくてもほぼ問題はない。
敢えて意識する必要があるとしたら、ごく一部のオンライン対戦のときくらいだろう。実際、スプラトゥーン 2 などは UPnP が有効化されていなくても問題なくオンライン対戦ができる。
セキュリティ上のリスク
一方、UPnP を通じてルータのポート開放を動的に行える。仕様上は認証も可能だが、認証まで含めた実装はそこまで多くなく、かつては Flash を利用した UPnP exploit なども存在した。そのため、UPnP は無効にすべきという議論も存在する。
実際、UPnP を WAN に解放すると実質的にファイアウォールが存在しないに等しい状態になる。そのため、UPnP を有効にする場合は諸々気をつける必要がある。
MiniUPnPd とは
MiniUPnPd は、Linux や FreeBSD といった OS でルータを実装する際に UPnP を実現するための実装の一つになる。
かつては Linux-IGD が使われていたがメンテされなくなったこともあって、ここ 15 年ほどは MiniUPnPd が Linux や FreeBSD でルータを実装する際の UPnP の定番ではないだろうか。
今回気付いた問題
これまでずっと自宅ゲートウェイでは MiniUPnPd も起動していたし、UPnP が動作していると思い込んでいた。
が、しばらく前に “Call of Duty: Modern Warfare” を購入したのに、起動時に “Server Disconnected” となってタイトル画面しか表示されない問題が発生した。
ググると色々出てはくるが、大体はインターネット側の問題のパターンだった。そこで iptables -L
で UPnP が使われているかを確認したが、
Chain MINIUPNPD (1 references)
target prot opt source destination
ACCEPT udp -- anywhere 192.168.2.141 udp dpt:xbox
見た感じ、特に問題はないように見える。UPnPCJ でもテストをしてみたが、ポートは開放できているように見えた。
が、実際のところは……
しかし、実際のところは「ポートが開放されているように見えていた」だけだった。
確かに MINIUPNPD チェインにルールは動的に追加・削除されるのだが、iptables -L
の結果を全部確認したところ、そもそもFORWARD
チェインから MINIUPNPD
にジャンプするルールが存在していないので MINIUPNPD
チェインが存在しないに等しい状態だった。
Chain FORWARD (policy ACCEPT)
target prot opt source destination
TCPMSS tcp -- anywhere anywhere tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
なので、FORWARD
チェインから MINIUPNPD
チェインに飛ぶルールを追加すればよい。
なぜこうなっていたのか
そもそも余計なことをしていなければ、この辺のルールは自動的に設定される。Gentoo Portage の実装の場合、 /etc/miniupnpd/iptables_init.sh
でチェインの初期化を行っており、その中で FORWARD
チェインから MINIUPNPD
チェインに飛ぶルールも追加している。
# MINIUPNPD chain for filter
if [ "$FDIRTY" = "${CHAIN}Chain" ]; then
echo "Filter table dirty; Cleaning..."
elif [ "$FDIRTY" = "Chain" ]; then
echo "Dirty filter chain but no reference..? Fixing..."
$IPTABLES -t filter $ADDCMD FORWARD -i $EXTIF ! -o $EXTIF -j $CHAIN
else
echo "Filter table clean..initalizing.."
$IPTABLES -t filter -N MINIUPNPD
$IPTABLES -t filter $ADDCMD FORWARD -i $EXTIF ! -o $EXTIF -j $CHAIN
fi
にもかかわらずうちで有効になっていなかったのは、
- 起動ごとに明示的にスクリプトで
iptables
を再設定していた。 /etc/miniupnpd/iptables_init.sh
の呼び出しをそのスクリプトの先頭でやっていて、呼び出し後にFORWARD
チェインをフラッシュしていた。
という凡ミスだった。
これを修正して再度 Call of Duty を起動したところ、無事にタイトル画面まで遷移できた。
他の workaround; UPnP を無効にする
なお、その他の解消方法として UPnP を無効にするというのもある。Call of Duty もそうだが、UPnP が有効になっているからこそ UPnP を利用するのであって、UPnP が無効であればそれ前提にサーバに接続にいく。
実際、Call of Duty も MiniUPnPd を落とせば問題なくタイトル画面まで遷移する。セキュリティという観点でも実は UPnP を無効にするのが正しい選択かも知れない。
最後に MiniUPnPd の設定を確認しておく
最後に、改めて MiniUPnPd の設定に問題がないかを確認しておいた。確認ポイントは以下となる。
- LAN 側と WAN 側のインターフェイスが正しく指定されているか (今回は LAN 側が eth1、WAN 側が ppp0)
/etc/miniupnpd/miniupnpd.conf
でsecure_mode=yes
になっているかどうか- インターネット側に MiniUPnPd がオープンになっていないか (nmap でスキャンすると分かりやすい)
あまりにも初歩的なミスではあったが、UPnP などそうそう確認する箇所でもないのでいい機会になったと思う。
もちろん既製のルータを買うと諸々楽ではあるが、エンジニアとしてはこの辺はまず自分でまかなうところから始めると色々と理解が捗ると思っている。