iptables の機能
- パケットフィルタリング: 特定の条件を満たす IP パケットだけ送受信を許可
- NAT: DNAT、SNAT、MASQUERADE 等、ルーターとしての機能
パケットフィルタリング
設定:
server 1 ( 10.1.51.165 ) と server 2 ( 10.1.77.146 ) が同一 VPC 内に存在。
VPC 内にはサブネットが以下の二つのサブネットが存在。
- Subnet 1 ( 10.1.51.0/24 ): パブリックサブネット
- Subnet 2 ( 10.1.77.0/24 ): プライベートサブネット
Server 1 内で新規の /etc/sysconfig/iptables を作成。
$ sudo yum install iptables-services -y
$ sudo systemctl enable iptables
$ sudo systemctl start iptables
$ sudo systemctl status iptables
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
Active: active (exited) since Sat 2017-09-02 08:51:48 UTC; 6s ago
Process: 1895 ExecStart=/usr/libexec/iptables/iptables.init start (code=exited, status=0/SUCCESS)
Main PID: 1895 (code=exited, status=0/SUCCESS)
$ sudo systemctl stop iptables
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
$ sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
$ sudo systemctl start iptables
Server 2 から受信した ICMP パケットをロギングする設定を以下のように追加。
$ sudo iptables -A INPUT -s 10.1.77.146 -p icmp -j LOG --log-prefix "[INPUT]"
Server 2 から Server 1 に ping リクエストを送ると Server 1 の /var/log/messages に以下のようなログが残る。
Sep 2 08:58:57 localhost kernel: [INPUT]IN=eth0 OUT= MAC=0a:11:d1:09:77:ce:0a:a2:e8:49:27:a3:08:00 SRC=10.1.77.146 DST=10.1.51.165 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10084 DF PROTO=ICMP TYPE=8 CODE=0 ID=1496 SEQ=1
Sep 2 08:58:58 localhost kernel: [INPUT]IN=eth0 OUT= MAC=0a:11:d1:09:77:ce:0a:a2:e8:49:27:a3:08:00 SRC=10.1.77.146 DST=10.1.51.165 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10928 DF PROTO=ICMP TYPE=8 CODE=0 ID=1496 SEQ=2
Sep 2 08:58:59 localhost kernel: [INPUT]IN=eth0 OUT= MAC=0a:11:d1:09:77:ce:0a:a2:e8:49:27:a3:08:00 SRC=10.1.77.146 DST=10.1.51.165 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=11195 DF PROTO=ICMP TYPE=8 CODE=0 ID=1496 SEQ=3
上記から、PROTO=ICMP TYPE=8 からタイプ 8 の ICMP パケットである Echo Request が送信されたことがわかる。
次に、ICMP パケットの受信を拒否する設定を追加。
$ sudo iptables -A INPUT -s 10.1.77.146 -p icmp -j DROP
Server 2 から Server 1 に ping リクエストを送っても Server 1 からの応答はない
$ ping 10.1.51.165
PING 10.1.51.165 (10.1.51.165) 56(84) bytes of data.
以下のコマンドで Server 1 で iptables におけるアクティブな設定の確認ができる。
$ sudo iptables -L -v
Chain INPUT (policy ACCEPT 343 packets, 26508 bytes)
pkts bytes target prot opt in out source destination
307 25788 LOG icmp -- any any server2 anywhere LOG level warning prefix "[INPUT]"
298 25032 DROP icmp -- any any server2 anywhere
server2 の ICMP パケットが DROP ターゲットに指定されていることがわかる。
DROP ターゲットに指定された場合、ロギング前にパケットが破棄され、ログファイルには記録が残らなくなる。
続いて、Server 2 からの SSH 接続を拒否する設定を行う。
$ sudo iptables -A INPUT -s 10.1.77.146 -p tcp --dport 22 -j REJECT
$ sudo iptables -A OUTPUT -p icmp -j LOG --log-prefix "[OUTPUT] "
1 行目で Server 2 からの 22 番ポートに対するアクセスを REJECT ターゲットに指定している。
REJECT ターゲットは DROP 同様その場でパケットを破棄するが、同時にタイプ 3 の ICMP パケット「 Destination Unreachable 」を返信する。
そのため、2 行目で Server 1 から送信する ICMP パケットをロギングする設定を行なっている。
この状態で Server 2 から Server 1 へ SSH 接続を試みると以下のように「 Connection refused 」メッセージが返信される。
$ ssh -i .ssh/key.pem user@server2
ssh: connect to host server1 port 22: Connection refused
ここで、Server 1 の /var/log/message を確認すると、以下のメッセージが記録されている。
Sep 2 09:31:43 localhost kernel: [OUTPUT] IN= OUT=eth0 SRC=10.1.51.165 DST=10.1.77.146 LEN=88 TOS=0x00 PREC=0xC0 TTL=64 ID=41414 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.1.77.146 DST=10.1.51.165 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=40037 DF PROTO=TCP SPT=55724 DPT=22 WINDOW=26883 RES=0x00 SYN URGP=0 ]
確かにタイプ 3 の ICMP パケットが Server 2 に送信されている。
ここで一度、以下のコマンドでこれまでの設定内容を /etc/sysconfig/iptables
に保存する。
$ sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
$ sudo cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Sat Sep 2 09:38:33 2017
*filter
:INPUT ACCEPT [589:130328]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [413:279548]
-A INPUT -s 10.1.77.146/32 -p icmp -j LOG --log-prefix "[INPUT]"
-A INPUT -s 10.1.77.146/32 -p icmp -j DROP
-A INPUT -s 10.1.77.146/32 -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -p icmp -j LOG --log-prefix "[OUTPUT] "
COMMIT
# Completed on Sat Sep 2 09:38:33 2017
なお、上記の :INPUT ACCEPT [589:130328]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [413:279548]
はデフォルトターゲットを表しており、これは該当のテーブルの各チェーンを通過したパケットがどの条件にもマッチしなかった場合に適用されるターゲット。
ちなみに、[589:130328] のような数字は該当の「テーブル/チェーン」を通過したパケット数とバイト数のカウンタであり、設定時は特に気にする必要はない。