2013/02/02(Sat)iptablesで特定のポートを別のホストへ転送する方法
2013/02/02 17:04
ルールの書き方はiptables本来のfilterとは少し違うのと、他のサイトでは解説が不足している点があるな、と思ったのでしっかり書き留めておく。
やろうとしていること
この図の通り。
今回、iptablesを使ってNATさせる箱は、192.168.1.30と10.0.2.40と二つのサブネットのIPを持っていなければならない。
しかしクライアント(192.168.1.20)とサーバ(10.0.2.50)となる2ホストに、スタティックルートを書く必要はない所がポイント。
なぜならNAT箱でアドレスを変換するので、クライアントは192.168.1.30さえ到達可能であればよい。同様にサーバも10.0.2.40には到達可能なので、実現できる。
サンプル構成
今回ルータは関係無いので図から削除。
クライアントはサーバのTCP80番ポートを開きたいのだが、直接到達できないので、代わりにNAT箱の192.168.1.30:1234を叩くことによって開く。
ip_forward
まずは、NAT箱にパケットのルーティングをさせるように設定。どうせなので、設定ファイルにも書き込んでおく。# sysctl -w net.ipv4.ip_forward=1 # echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
NATテーブル
まずは、アドレスを変換するルール。ちなみに以下で出てくるPREROUTINGとPOSTROUTINGというチェインの間に、FORWARDチェインが処理されると考えると良い。参考
NAT箱の192.168.1.30:1234宛に届いたパケットを、10.0.2.50:80へ投げるというNATを書く。
# iptables -t nat -A PREROUTING -m tcp -p tcp --dst 192.168.1.30 --dport 1234 -j DNAT --to-destination 10.0.2.50:80しかし、このままだと宛先アドレスを書き換えるだけなので、サーバ(10.0.2.50)は192.168.1.20という知らないサブネットから受信することになり、戻りのパケットは自分のデフォルトゲートウェイ10.0.2.1へ送りつける。
これではマズいので、NATしたパケットの送信元アドレスを10.0.2.40に変更するのがミソ。
"10.0.2.50:80宛のパケットは、NAT箱の10.0.2.40というアドレスに付け替えてから送信する"というルールを書く。
# iptables -t nat -A POSTROUTING -m tcp -p tcp --dst 10.0.2.50 --dport 80 -j SNAT --to-source 10.0.2.40逆方向に関しては、このルールだけで自動的に処理されるため心配しなくて良い。
クライアントの送信元ポート番号をきちんと覚えていて、そこに向かって戻りパケットを変換してくれる。
Filterテーブル
前述のルーティングだけ紹介しているサイトが多かったのだが、本来はここからきちんとパケット転送させるためのフィルタも書かなくてはならない。用心深い設定をしている人なら、チェインのデフォルトポリシーがDROPだろうから、上の設定だけではパケットは飛ばないはず。
# iptables -nL FORWARD
Chain FORWARD (policy DROP)
target prot opt source destination
というわけで、こんな感じで転送するパケットを許可。NATのPREROUTINGを通って変換されたアドレスに対して許可ルールを書いておく。
# iptables -A FORWARD -m tcp -p tcp --dst 10.0.2.50 --dport 80 -j ACCEPT忘れちゃいけないのが、戻りのパケットも許可するということ。これはTCPのフラグを見て通すようにするおなじみのやり方で。
# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
追記
今回は、MTUが揃っているので特にPath MTU周りの心配をすることはないのだけど、MTUが違うサブネット同士を結ぶ場合には以下の設定も入れておくと吉。# iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
参考文献
- 雑記 - iptablesによるNAT
- Tips/Linux/iptables - 福岡大学奥村研究室 - okkun-lab Pukiwiki!
- iptables ポートフォワーディング ≪ Demence/Cup
- iptablesでポートフォワーディング | Mazn.net
- iptablesでポート転送 - かえでのWebログ
DNATの説明があってもSNATの説明がないサイトが多かったり、FORWARDチェインをデフォルトをDROPにしてたり、戻りのFORWARDが落ちていることに気づかず、結構手間取った。