読者です 読者をやめる 読者になる 読者になる

mokky14's IT diary

IT関係の仕事メモ、勉強会の感想など書いてます。

Linuxでiptablesとかフォワーディングとか

Linux

Linuxiptablesとかフォワーディングとか色々いじってたのでメモ。

※ ここで実行するコマンドは全てroot権限が必要。

複数のポートをまとめて指定

INPUTチェインで複数ポートへのアクセスをまとめて許可したいときとか、-m multiportモジュールをロードすると、複数ポートをまとめて登録することが出来る。

# iptables -I INPUT 8 -p tcp -j ACCEPT -m multiport --dports 53,80,8080

上記は送信先ポートに53,80,8080を指定する例。送信元のポート番号を指定するオプションとして--sportsもある。
なおmultiportモジュール使用時は-p で、tcpudp、udplite、sctp、dccpのいずれか指定が必須。なので、TCPUDP両方まとめて指定とかはできない。
(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

rawテーブル
http://d.hatena.ne.jp/elf/20090310/1236615360