iptables ( 1 ) ~ パケットフィルタリング ~

September 02, 2017

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] のような数字は該当の「テーブル/チェーン」を通過したパケット数とバイト数のカウンタであり、設定時は特に気にする必要はない。


 © 2023, Dealing with Ambiguity