Linuxでiptablesとかフォワーディングとか色々いじってたのでメモ。
※ ここで実行するコマンドは全てroot権限が必要。
複数のポートをまとめて指定
INPUTチェインで複数ポートへのアクセスをまとめて許可したいときとか、-m multiportモジュールをロードすると、複数ポートをまとめて登録することが出来る。
# iptables -I INPUT 8 -p tcp -j ACCEPT -m multiport --dports 53,80,8080
上記は送信先ポートに53,80,8080を指定する例。送信元のポート番号を指定するオプションとして--sportsもある。
なおmultiportモジュール使用時は-p で、tcp、udp、udplite、sctp、dccpのいずれか指定が必須。なので、TCPとUDP両方まとめて指定とかはできない。
(udplite、sctp、dccpについてはmanには記載なかったけど、-pを省略してコマンド実行したら以下のようなエラーになったので、指定出来るのだろうと判断)
# iptables -A INPUT -m multiport --dport 10000,20000 iptables v1.4.7: multiport needs `-p tcp', `-p udp', `-p udplite', `-p sctp' or `-p dccp' Try `iptables -h' or 'iptables --help' for more information.
フォワード設定
フォワーディングの有効化
以下コマンドを実行する。
# sysctl -w net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1
フォワーディングが有効になっているか確認。
# sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1
1であれば有効。0だと無効。
上記だけだとOS再起動後は反映されないので、OS再起動後もフォワーディングを有効にするためには、以下ファイルの設定を更新する必要がある。
- /etc/sysctl.conf
変更前 | net.ipv4.ip_forward = 0 |
---|---|
変更後 | net.ipv4.ip_forward = 1 |
ルーティング設定の変更
フォワードするパケットの宛先、応答がある場合はその応答パケットに対するルーティングをルーティングテーブルに設定する。
設定方法はCentOS スタティックルートの追加とかを参考に。
フォワードするパケットの限定
上記設定だけだと、どんなパケットもフォワードしてしまう。
フォワードするパケットを限定するためには、iptablesでFORWARDのデフォルトポリシーをDROPにした上で、フォワードを許可するパケットのみを通すルールを追加する。
# iptables -P FORWARD -j DROP # iptables -I FORWARD -p udp -i eth1 -s 10.1.1.0/24 -d 100.40.1.0/24 --dport 11111 -j ACCEPT
DNAT(送信先IPアドレス、ポート番号の変換)
natテーブルのPREROUTINGチェインに設定する。
# iptables -t nat -A PREROUTING -i eth1 -d 10.1.1.10 -p udp --dport 1000 \ -j DNAT --to-destination 192.168.10.120:2000
DNAT先は 「--to-destination ipaddr[-ipaddr][:port-port]」 のオプションで指定。
ポート番号省略時はポート番号の変換はなし。IPアドレス、ポート番号は範囲指定可能。
複数の --to-destination オプション指定で、それらのアドレスを使用したラウンドロビンも可能。
SNAT(送信元IPアドレス、ポート番号の変換)
natテーブルのPOSTROUTINGチェインに設定する。
インタフェースはパケットを送信するインタフェースを-oで指定する。
# iptables -I POSTROUTING -t nat -o eth2 -p udp -s 10.1.1.0/24 -m multiport \ --dports 1111,1112,1113 -d 100.200.1.0/24 -j SNAT --to-source 10.4.1.240:10000
SNATするアドレス、ポート番号は 「--to-source ipaddr[-ipaddr][:port-port]」で指定。
IP、ポート番号の範囲指定や複数指定についてはDNATと同様に可能。
コネクションのトラッキングを止める
iptablesでは、ある要求に対する応答を追跡してルールを適用する機能がある模様。例えば、natテーブルにDNAT設定したら、その設定によりDNATされた要求に対する応答にはDNATの逆の変換(SNAT)が行われる。
これを止めさせたいような場合、rawテーブルにNOTRACKターゲットを設定する。(やりたい人居るかは知らん)
# iptables -I PREROUTING -t raw -p udp -i eth1 -s 10.4.1.0/24 -d 10.1.1.0/24 -j NOTRACK
なお、CentOS6では、rawテーブルの内容は、日本語のiptablesのmanにはなく、英語版のmanにしか記載がない。(2013/11/27時点での確認)
TRACE
パケットがiptablesの、どのテーブルの、どのチェインの、どのポリシーやルールを通っているのか確認したいとき、rawテーブルにTRACEターゲットを設定すると、カーネルログにTRACEの内容を出力することが出来る。
# iptables -I OUTPUT -t raw -p udp -o eth2 -j TRACE # iptables -I PREROUTING -t raw -p udp -i eth1 -j TRACE
OUTPUTチェインに設定したTRACEは、自マシンから送信するパケットのトレース、PREROUTINGチェインに設定したTRACEは、自マシンが受信したパケットのトレースを取得する。
ログはカーネルログに出力されるが、CentOS6では、デフォルトのrsyslog設定ではカーネルログは出力しないようになっていたので、ログ出力時は、合わせてrsyslogの設定も変更する必要がある。
以下は、デフォルトの/etc/rsyslog.confのカーネルログの設定。
#kern.* /dev/console
なお、幾つかのパターンについてTRACEを取ってみた結果、以下の順番でチェインを通過していることが分かる。
- 自サーバで受信するパケットが通るチェイン
raw:PREROUTING→mangle:PREROUTING→filter:INPUT
- 自サーバより送信するパケットが通るチェイン
raw:OUTPUT→mangle:OUTPUT→nat:OUTPUT→filter:OUTPUT→mangle:POSTROUTING→nat:POSTROUTING
- 自サーバが転送(FORWARD)するパケットが通るチェイン
raw:PREROUTING→mangle:PREROUTING→nat:PREROUTING→mangle:FORWARD→filter:FORWARD→mangle:POSTROUTING→nat:POSTROUTING
参考:
ルーティング
http://redhatlinux.kt.fc2.com/cont/router.htm
NAPT
http://saoshi.gooside.com/
iptables
http://ft-lab.ne.jp/cgi-bin/wiki.cgi?page=iptables
http://alpha-netzilla.blogspot.jp/2012/08/napt.html