iptablesの設定

[サーバの実験室 Redhat/Fedora]

作成 : 2005/01/27
修正 : 2011/05/05

"サーバの実験室"の検索


iptables

パケットフィルタリング、NA(P)Tを設定するためのパッケージ。 環境によってはカーネルの再構築が必要になるが、Fedora Core 3では不要。

参考になる文書

netfilter.orgのチュートリアル。 あと、manpage。

インストール

FTPサイトまたはFedoraCore3 CD Disk1からRPMパッケージをもらってきて、インストール。

# rpm -Uvh iptables-1.2.11-3.1.i386.rpm

yumを使ってもよい。

# yum install iptables

chkconfigユーティリティで、サーバ起動時にサービスが開始するよう設定する。

# chkconfig iptables on

iptablesのルールセットファイル

iptablesのルールセットは、/etc/sysconfig/iptablesに記述する。 起動スクリプト/etc/init.d/iptablesを実行すると、iptables-restoreユーティリティを使ってルールセットファイルを読み込む。

サービスの開始/停止/再起動

iptablesサービスの開始。

# /etc/init.d/iptables start

iptablesサービスの停止。

# /etc/init.d/iptables stop

iptablesサービスの再起動。 ルールセットファイルを修正したとき、再起動が必要。

# /etc/init.d/iptables restart

設定の確認

設定の確認。

# iptables -L

ルールセットファイルと同じ形式で設定を確認。

# iptables-save

パケットフィルタリング

パケットフィルタリングの例。

# /etc/sysconfig/iptables

### テーブル
### *テーブル名
# パケットフィルタリングでは、filterテーブルを使用
*filter
    # filterテーブル、パケットのフィルタリングを実施

### チェーンの定義
### :チェーン名 デフォルトポリシー [パケットカウント:バイトカウント]
# INPUT/FORWARD/OUTPUチェーンのいずれかひとつのみ使用する
# デフォルトポリシーをACCEPTにすると明示されないパケットは通過され、DROPにすると明示されないパケットは破棄される
:INPUT ACCEPT [0:0]
    # INPUTチェーン、送信先がローカルホストのパケットに適用される
:FORWARD ACCEPT [0:0]
    # FORWARDチェーン、ローカルホストを経由するパケットに適用される
:OUTPUT ACCEPT [0:0]
    # OUTPUTチェーン、送信元がローカルホストのパケットに適用
:RH-Firewall-1-INPUT - [0:0]
    # ユーザ定義チェーン

### ルール
# 基本は、-A チェーン名 マッチング条件 -j ターゲット
#    -A チェーン名 : チェーンに新たなルールを追加
#    -j(--jump) ターゲット : 条件したパケットをどうするか指定
#                              ターゲットには、ACCEPT(許可)/DROP(破棄)/REJECT(拒否)ユーザ定義チェーンなどなどを指定
#
# マッチング条件の一部
# 頭に"!"をつけると、notという意味
#    -i(--in-interface) 受信インタフェース : filterテーブルでは、INPUT/FORWARDチェーンで使用可能
#    -o(--out-interface) 送信インタフェース : filterテーブルでは、OUTPUT/FORWARDチェーンで使用可能
#    -p(--protocol) プロトコルまたはプロトコル番号 : 指定できるプロトコルは、tcp/udp/icmp/all
#    -s(--source、--src) 送信元アドレス : "192.168.0.1"、"192.168.0.0/24"、"192.168.0.0/255.255.255.0"のように指定
#    -d(--destination、--dst) 送信先アドレス : "192.168.0.1"、"192.168.0.0/24"、"192.168.0.0/255.255.255.0"のように指定
#
# 以下は拡張されたマッチングの一部
# 頭に"!"をつけると、notという意味
#    -m tcp --sport(--source-port) TCP送信元ポート :  "-p tcp"のとき使用可能、ポート範囲は"0:1023"のように指定
#    -m tcp --dport(--destination-port) TCP送信先ポート :  "-p tcp"のとき使用可能、ポート範囲は"0:1023"のように指定
#    -m udp --sport(--source-port) UDP送信元ポート :  "-p udp"のとき使用可能、ポート範囲は"0:1023"のように指定
#    -m udp --dport(--destination-port) UDP送信先ポート :  "-p udp"のとき使用可能、ポート範囲は"0:1023"のように指定
#    -m state --state 接続状態 : 接続状態には、NEW(新規)/ESTABLISHED(接続中)/RELATED(既存の接続に関係?)/INVALID(その他)を指定
#    --icmp-type ICMPタイプ : "-p icmp"のとき使用可能、指定できるICMPタイプは"iptables -p icmp -h"で確認
-A INPUT -j RH-Firewall-1-INPUT
    # ローカルホスト宛のパケットは、ユーザ定義チェーン"RH-Firewall-1-INPUT"でチェック
-A FORWARD -j RH-Firewall-1-INPUT
    # ローカルホスト経由のパケットは、ユーザ定義チェーン"RH-Firewall-1-INPUT"でチェック
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
    # 受信インタフェースが"lo"(ループバック)ならば、通信を許可
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
    # プロトコルが"icmp"ならば、通信を許可
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
    # プロトコル番号が"50"(ESP)ならば、通信を許可
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
    # プロトコル番号が"51"(AH)ならば、通信を許可
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
    # プロトコルが"udp"かつ送信先ポートが"5353"(Multicast DNS)かつ送信先アドレスが"224.0.0.251"ならば、通信を許可
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
    # プロトコルが"udp"かつ送信先ポートが"631"(Internet Printing Protocol)ならば、通信を許可
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    # 接続状態が"ESTABLISHED"または"RELATED"ならば、通信を許可
    # これがないと通信ができない!
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    # 接続状態が"NEW"かつプロトコルが"tcp"かつ送信先ポートが"22"ならば、通信を許可
    # SSHサーバへの接続要求パケット
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
    # 接続状態が"NEW"かつプロトコルが"tcp"かつ送信先ポートが"80"ならば、通信を許可
    # HTTPサーバへの接続要求パケット
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
    # 接続状態が"NEW"かつプロトコルが"tcp"かつ送信先ポートが"21"ならば、通信を許可
    # FTPサーバへの接続要求パケット
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
    # 接続状態が"NEW"かつプロトコルが"tcp"かつ送信先ポートが"25"ならば、通信を許可
    # SMTPサーバへの接続要求パケット
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
    # ここまでのチェックでひっかからなかったパケットは、ICMPパケット"host-prohibited"を返して接続拒否

### COMMIT
COMMIT
    # 以上を登録

パケットは、INPUT/FORWARD/OUTPUTいずれかのチェーンのルールしかチェックしない。 ローカルホストを経由して転送されるパケットは、単にFORWARDチェーンのルールだけチェックする。 (INPUTはローカルホスト宛、OUTPUTはローカルホストで生成されたパケットのとき、チェックされる)

同じチェーンなら、上の行に記述されているルールから順番にチェックされる。 ターゲットにACCEPT/DROP/REJECTを指定した場合、条件にマッチするとそのチェーンのルールチェックは終了するので、記述の順番は重要。

ログを記録する

ログを記録するには、ターゲットに"LOG"を指定する。 ターゲットに"LOG"を指定した場合、条件にマッチしても次のルールをチェックする。 ターゲット"LOG"は、ACCEPT/DROP/REJECTより前に記述する。

# /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]

-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
....
-A RH-Firewall-1-INPUT -j LOG --log-level info --log-prefix "[iptables] "
    # レベル"info"でログを記録(FC3だと/var/log/messages)、先頭に"[iptables] "を付加して見やすくする
    #    -j LOG : ログを記録
    #    --log-level ログレベル : ログレベルを名前か番号で指定
    #    --log-prefix プリフィックス: ログに付加するプリフィックスを指定
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

COMMIT

記録されたログはこんな感じ。

Jan 26 20:34:15 linux kernel: [iptables] IN=eth1 OUT=eth0 SRC=192.168.0.100 DST=
192.168.1.10 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=1598 DF PROTO=TCP SPT=2000 DPT
=900 WINDOW=64240 RES=0x00 SYN URGP=0

NAPT

                   ------ NAPT ------>
+----+             +------------------+             +------------+
| PC |-------------| Linux (iptables) |-------------| WEB Server |
+----+        eth1 +------------------+ eth0        +------------+
192.168.1.10    192.168.1.1    192.168.0.1    192.168.0.10

インタフェース間のパケット転送を有効にするよう、net.ipv4.ip_forwardを「1」にするのを忘ないこと。

# /etc/sysctl
...
net.ipv4.ip_forward = 1
...
# sysctl -p

NAPTを設定するには、natテーブルのPOSTROUTINGチェーンにルールを記述する。 下の例は、パケットフィルタリングをしていないNAPTのみの設定。

# /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# デフォルトで記述されている以下のエントリは転送パケットをすべてリジェクトする
# -A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

### テーブル
### *テーブル名
# filter/nat/mangleテーブルがある
*nat

### チェーンの定義
### :チェーン名 [パケットカウント:バイトカウント]
# filterテーブルと異なり、複数のチェーンを使用する
:PREROUTING ACCEPT [0:0]
    # PREROUTINGチェーン、送信先アドレス変換(ポートフォワーディング、DNAT)で使用
:POSTROUTING ACCEPT [0:0]
    # POSTROUTINGチェーン、送信元アドレス変換(NAPT、SNAT)で使用
:OUTPUT ACCEPT [0:0]
    # OUTPUTチェーン、なにに使うんだろう?

### ルール
# NAPTでは、-A POSTROUTING -o 送信インタフェース -j MASQUERADE -s NAPT対象の送信元アドレス
# -dオプションで、NAPT対象の送信先アドレスを指定することも可能
-A POSTROUTING -o eth0 -j MASQUERADE -s 192.168.0.0/24
    # 送信元が192.168.0.0/24のパケットをNAPTして送出

### COMMIT
COMMIT
    # 以上を登録

どのような順番でルールがチェックされるか検証するため、次のような/etc/sysconfig/iptablesを作成する。 NAPTの機能だけ持たせて、80番ポート/TCPの通信をログに記録する。

# /etc/sysconfig/iptables
# ルールチェックの順番検証用

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_IN] "
-A INPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_IN] "
-A FORWARD -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_FOR] "
-A FORWARD -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_FOR] "
-A OUTPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_OUT] "
-A OUTPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_OUT] "
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_PRE]"
-A PREROUTING -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_PRE]"
-A POSTROUTING -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_POST]"
-A POSTROUTING -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_POST]"
-A OUTPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_OUT]"
-A OUTPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_OUT]"
-A POSTROUTING -o eth0 -j MASQUERADE -s 192.168.0.0/24
COMMIT

eth1側のPC(192.168.1.10)からeth0側のWEBサーバ(192.168.0.10)にアクセスしたときのログは、次のようになる。

### 通信の1番目のパケット(PC ---> WEBサーバ)
# natテーブルのPREROUTINGチェーンのルールがチェックされる
#    SRC:192.168.1.10/DST:192.168.0.10
Jan 26 22:42:46 linux kernel: [N_PRE] IN=eth1 OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:X
X:XX:XX:XX:XX:XX SRC=192.168.1.10 DST=192.168.0.10 LEN=48 TOS=0x00 PREC=0x00 TTL
=128 ID=7808 DF PROTO=TCP SPT=2528 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
### 通信の1番目のパケット(PC ---> WEBサーバ)
# filterテーブルのFORWARDチェーンのルールがチェックされる
#    SRC:192.168.1.10/DST:192.168.0.10
Jan 26 22:42:46 linux kernel: [F_FOR] IN=eth1 OUT=eth0 SRC=192.168.1.10 DST=192.
168.0.10 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=7808 DF PROTO=TCP SPT=2528 DPT=80
WINDOW=64240 RES=0x00 SYN URGP=0
### 通信の1番目のパケット(PC ---> WEBサーバ)
# natテーブルのPOSTROUTINGチェーンのルールがチェックされる
# ここで送信元アドレスを変換する
#    SRC:192.168.1.10/DST:192.168.0.10 ---> SRC:192.168.0.1/DST:192.168.0.10
Jan 26 22:42:46 linux kernel: [N_POST] IN= OUT=eth0 SRC=192.168.1.10 DST=192.168
.0.10 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=7808 DF PROTO=TCP SPT=2528 DPT=80 WIN
DOW=64240 RES=0x00 SYN URGP=0

### 通信の2番目のパケット(WEBサーバ ---> PC)
# filterテーブルのFORWARDチェーンのルールがチェックされる
# FORWARDチェーンを評価する前にアドレスは変換されている
#    SRC:192.168.0.10/DST:192.168.1.10
Jan 26 22:42:46 linux kernel: [F_FOR] IN=eth0 OUT=eth1 SRC=192.168.0.10 DST=192.
168.1.10 LEN=48 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=80 DPT=2528 WIND
OW=5840 RES=0x00 ACK SYN URGP=0

### 通信の3番目のパケット(PC ---> WEBサーバ)
# filterテーブルのFORWARDチェーンのルールがチェックされる
# FORWARDチェーンを評価する前にアドレスは変換されている
#    SRC:192.168.0.1/DST:192.168.0.10
Jan 26 22:42:46 linux kernel: [F_FOR] IN=eth1 OUT=eth0 SRC=192.168.1.10 DST=192.
168.0.10 LEN=40 TOS=0x00 PREC=0x00 TTL=127 ID=7809 DF PROTO=TCP SPT=2528 DPT=80
WINDOW=64240 RES=0x00 ACK URGP=0

natテーブルのルールがチェックされるのは、その通信の1番目のパケットだけ。 2番目以降のパケットでは、単に(アドレス変換が終わった)転送パケットとしてFORWARDチェーンでルールチェックされる。 したがって、フィルタリングをするときは、NAPTは考慮に入れずにEnd-to-Endでルール考えればよい。

また、その通信の2番目以降のパケットはnatテーブルではチェックされないので、フィルタリングのルールはnatテーブルに記述してはいけないらしい。

Port Forwarding/DMZ

                      <--- Port Forwarding/DMZ ---
+------------+             +------------------+             +----+
| WEB Server |-------------| Linux (iptables) |-------------| PC |
+------------+        eth1 +------------------+ eth0        +----+
        192.168.1.10    192.168.1.1    192.168.0.1    192.168.0.10

インタフェース間のパケット転送を有効にするよう、net.ipv4.ip_forwardを「1」にするのを忘ないこと。

# /etc/sysctl
...
net.ipv4.ip_forward = 1
...
# sysctl -p

PortForwarding/DMZを設定するには、natテーブルのPREROUTINGチェーンにルールを記述する。 下の例は、パケットフィルタリングをしていないPortForwardingのみの設定。

# /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# デフォルトで記述されている以下のエントリは転送パケットをすべてリジェクトする
# -A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

### テーブル
### *テーブル名
# filter/nat/mangleテーブルがある
*nat

### チェーンの定義
### :チェーン名 [パケットカウント:バイトカウント]
# filterテーブルと異なり、複数のチェーンを使用する
:PREROUTING ACCEPT [0:0]
    # PREROUTINGチェーン、送信先アドレス変換(ポートフォワーディング、DNAT)で使用
:POSTROUTING ACCEPT [0:0]
    # POSTROUTINGチェーン、送信元アドレス変換(NAPT、SNAT)で使用
:OUTPUT ACCEPT [0:0]
    # OUTPUTチェーン、なにに使うんだろう?

### ルール
# DMZでは、-A PREROUTING -i 受信インタフェース -j DNAT
# TCP PortForwardingでは、-A PREROUTING -i 受信インタフェース -p tcp --dport 送信先ポート番号 -j DNAT --to-destination 変換後の送信先アドレス
# UDP PortForwardingでは、-A PREROUTING -i 受信インタフェース -p udp --dport 送信先ポート番号 -j DNAT --to-destination 変換後の送信先アドレス
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10
    # インタフェースeth0で受信した送信先ポート"80"番のTCPパケットは、送信先アドレスを"192.168.1.10"に変換
    # INPUT/FORWARDのパケットがチェックされる

### COMMIT
COMMIT
    # 以上を登録

どのような順番でルールがチェックされるか検証するため、次のような/etc/sysconfig/iptablesを作成する。 PortForwardingの機能だけ持たせて、80番ポート/TCPの通信をログに記録する。

# /etc/sysconfig/iptables
# ルールチェックの順番検証用

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_IN] "
-A INPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_IN] "
-A FORWARD -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_FOR] "
-A FORWARD -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_FOR] "
-A OUTPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[F_OUT] "
-A OUTPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[F_OUT] "
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_PRE]"
-A PREROUTING -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_PRE]"
-A POSTROUTING -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_POST]"
-A POSTROUTING -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_POST]"
-A OUTPUT -p tcp --sport 80 -j LOG --log-level info --log-prefix "[N_OUT]"
-A OUTPUT -p tcp --dport 80 -j LOG --log-level info --log-prefix "[N_OUT]"
-A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10
COMMIT

eth0側のPC(192.168.0.10)からLinuxルータ(192.168.0.1)の80番ポートにアクセスしたときのログは、次のようになる。

### 通信の1番目のパケット(PC ---> Linuxルータ)
# natテーブルのPREROUTINGチェーンのルールがチェックされる
# ここで送信先アドレスを変換する
#    SRC:192.168.0.10/DST:192.168.0.1 ---> SRC:192.168.0.10/DST:192.168.1.10
Jan 27 18:56:04 linux kernel: [N_PRE] IN=eth0 OUT= MAC=XX:XX:XX:XX:XX:XX:XX:XX:XX
:XX:XX:XX:XX:XX SRC=192.168.0.10 DST=192.168.0.1 LEN=48 TOS=0x00 PREC=0x00 TTL=1
28 ID=16738 DF PROTO=TCP SPT=2307 DPT=80 WINDOW=16384 RES=0x00 SYN URGP=0
### 通信の1番目のパケット(PC ---> Linuxルータ)
# filterテーブルのFORWARDチェーンのルールがチェックされる
#    SRC:192.168.0.10/DST:192.168.1.10
Jan 27 18:56:04 linux kernel: [F_FOR] IN=eth0 OUT=eth1 SRC=192.168.0.10 DST=192.
168.1.10 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=16738 DF PROTO=TCP SPT=2307 DPT=80
 WINDOW=16384 RES=0x00 SYN URGP=0
### 通信の1番目のパケット(PC ---> Linuxルータ)
# natテーブルのPOSTROUTINGチェーンのルールがチェックされる
#    SRC:192.168.0.10/DST:192.168.1.10
Jan 27 18:56:04 linux kernel: [N_POST] IN= OUT=eth1 SRC=192.168.0.10 DST=192.168.
1.10 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=16738 DF PROTO=TCP SPT=2307 DPT=80 WIN
DOW=16384 RES=0x00 SYN URGP=0

### 通信の2番目のパケット(WEBサーバ ---> PC)
# filterテーブルのFORWARDチェーンのルールがチェックされる
# FORWARDチェーンを評価する前にアドレスは変換されている
#    SRC:192.168.1.10/DST:192.168.0.10
Jan 27 18:56:04 linux kernel: [F_FOR] IN=eth1 OUT=eth0 SRC=192.168.1.10 DST=192.
168.0.10 LEN=48 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=80 DPT=2307 WIND
OW=5840 RES=0x00 ACK SYN URGP=0

### 通信の3番目のパケット(PC ---> WEBサーバ)
# filterテーブルのFORWARDチェーンのルールがチェックされる
# FORWARDチェーンを評価する前にアドレスは変換されている
#    SRC:192.168.0.10/DST:192.168.1.10
Jan 27 18:56:04 linux kernel: [F_FOR] IN=eth0 OUT=eth1 SRC=192.168.0.10 DST=192.
168.1.10 LEN=40 TOS=0x00 PREC=0x00 TTL=127 ID=16739 DF PROTO=TCP SPT=2307 DPT=80
 WINDOW=17520 RES=0x00 ACK URGP=0

NAPTのときと同様に、natテーブルのルールがチェックされるのは、その通信の1番目のパケットだけ。 2番目以降のパケットでは、単に(アドレス変換が終わった)転送パケットとしてFORWARDチェーンでルールチェックされる。 したがって、フィルタリングをするときは、PortForwarding/DMZは考慮に入れずにEnd-to-Endでルール考えればよい。

また、その通信の2番目以降のパケットはnatテーブルではチェックされないので、フィルタリングのルールはnatテーブルに記述してはいけないらしい。

同一セグメントでのNAT

            192.168.0.20
+------------------+
|    WEB Server    |-----+
+------------------+     |
+------------------+     |       +----+
| Linux (iptables) |-----+-------| PC |
+------------------+ eth0        +----+
            192.168.0.1    192.168.0.10

同じセグメントのホストへパケットを転送してみる。 PCからみるとLinuxルータとしか通信をしないが、実際はLinuxルータは80番ポート宛のパケットをWEBサーバへ転送している。

# /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

### テーブル
### *テーブル名
# filter/nat/mangleテーブルがある
*nat

### チェーンの定義
### :チェーン名 [パケットカウント:バイトカウント]
# filterテーブルと異なり、複数のチェーンを使用する
:PREROUTING ACCEPT [0:0]
    # PREROUTINGチェーン、送信先アドレス変換(ポートフォワーディング、DNAT)で使用
:POSTROUTING ACCEPT [0:0]
    # POSTROUTINGチェーン、送信元アドレス変換(NAPT、SNAT)で使用
:OUTPUT ACCEPT [0:0]
    # OUTPUTチェーン、なにに使うんだろう?

### ルール
-A PREROUTING -i eth0 -p tcp -d 192.168.0.1 --dport 80 -j DNAT --to-destination 192.168.0.20
    # インタフェースeth0で受信したホスト"192.168.0.1"のポート"80"番宛のTCPパケットは、送信先アドレスを"192.168.0.20"に変換
    # この変換の後、FORWARDチェインがチェックされ、さらにPOSTROUTINGチェインがチェックされる
-A POSTROUTING -o eth0 -p tcp -d 192.168.0.20 --dport 80 -j SNAT --to-source 192.168.0.1
    # インタフェースeth0からホスト"192.168.0.20"のポート"80"番へ転送されるTCPパケットは、送信元アドレスを"192.168.0.1"に変換

### COMMIT
COMMIT
    # 以上を登録

[サーバの実験室 Redhat/Fedora]