hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

iptables-extensionsの使い方



1 iptables-extensionsとは?

拡張パケットマッチングモジュールのことです。iptables-extensionsを使うと、マッチする条件を詳細に指定することができます。

INPUTチェインでマッチングモジュールを指定する場合、以下のように使います。モジュール名には、mac,icmp等を指定します。ターゲットについては、iptablesコマンドの使い方(ターゲットの使い方) - hana_shinのLinux技術ブログを参照してください。

iptables -A INPUT -m <モジュール名> <モジュールのオプション> <ターゲット>

manは以下のようにして参照します。

[root@server ~]# man iptables-extensions

なお、iptablesコマンドの使い方は、iptablesコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

2 検証環境

2.1 ネットワーク構成

サーバとクライアントの2台構成です。図中のeth0はNICの名前です。

                          192.168.122.0/24
client(eth0) -------------------------------------------(eth0) server
            .153                                    .128
            52:54:00:8c:76:20                       52:54:00:78:10:73

2.2 版数

サーバとクライアントのCentOS の版数は以下のとおりです。

[root@client ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@client ~]# uname -r
3.10.0-1160.el7.x86_64

3 事前準備

firewall-cmdコマンドとiptablesコマンドは一緒に使うことはできないので、firewalldサービスを停止します。

[root@server ~]# systemctl stop firewalld.service

firewalldサービスの状態を確認します。firewalldサービスが停止したことがわかります。

[root@server ~]# systemctl is-active firewalld.service
inactive

4 macモジュールの使い方

macモジュールは、送信元MACアドレスを指定するモジュールです。REROUTING,FORWARD,INPUTの3つのチェインで使うことができます。

ここでは、INPUTチェインでmacモジュールを使ってみます。macモジュールで、送信元MACアドレスとして52:54:00:8C:76:20を指定します。LOGターゲットを使って、送信元MACアドレスが52:54:00:8C:76:20のパケットを受信したら、ログを出力するルールを作成してみます。

[root@server ~]# iptables -A INPUT -m mac --mac-source 52:54:00:8c:76:20 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 11 packets, 816 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            MAC 52:54:00:8C:76:20 LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。なお、journalctlコマンドの使い方は、https://hana-shin.hatenablog.com/entry/2022/02/28/203433を参照してください。

[root@server ~]# journalctl -f

クライアントでpingコマンドを実行します。-cオプションは、ICMP echoパケットの送信回数を指定するオプションです。以下の実行例では、pingコマンドを実行すると、ICMP echoパケットを1つ送信します。なお、pingコマンドの使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@client ~]# ping -c 1 192.168.122.128

ログを確認すると、送信元MACアドレスが52:54:00:8C:76:20のパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 20 20:00:30 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=8685 DF PROTO=ICMP TYPE=8 CODE=0 ID=1515 SEQ=1

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

5 icmpモジュールの使い方

icmpモジュールは、ICMPパケットのタイプ/コードを指定するモジュールです。

5.1 ICMP echoパケットの指定方法(type=8)

ICMP echoパケットを受信したらログを出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 9 packets, 660 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 LOG flags 0 level 4

クライアントでpingコマンドを実行します。

[root@client ~]# ping -c 1 192.168.122.128

ログを確認すると、ICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 21 20:48:35 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=63523 DF PROTO=ICMP TYPE=8 CODE=0 ID=1487 SEQ=1

またルールを確認すると、受信したICMPパケット数が1つ増加したことがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 18 packets, 1300 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    84 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 8 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

5.2 ICMP network unreachableパケットの指定方法(type=3,code=0)

ここではルールの作成だけをします。 ICMP network unreachableパケットを受信して、動作確認をしてみたい場合は、hping3コマンドの使い方 - hana_shinのLinux技術ブログを参照して実験してみてください。

ICMP network unreachableパケットを受信したらログを出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -m icmp --icmp-type 3/0 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 11 packets, 816 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 3 code 0 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

6 lengthモジュールの使い方

lengthモジュールは、IPパケット長を指定するモジュールです。IPパケット長は、IPヘッダ(20byte)にIPペイロードを加えた長さになります。

6.1 パケット長を指定する方法

28バイトのIPパケットを受信したらログを出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -m length --length 28 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 13 packets, 972 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 28 LOG flags 0 level 4

クライアントでpingコマンドを実行します。-sは、ICMPパケットのペイロード長を指定するオプションです。以下の実行例は、ペイロード長に0を指定しています。したがって、サーバに送信するICMP echoパケットは、20バイトのIPヘッダ、8バイトのICMPヘッダから構成されています。

[root@client ~]# ping -c 1 -s 0 192.168.122.128

ルールを確認すると、28バイトのICMP echoパケットを受信したので、パケット数が1増加したことがわかります(期待値)。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 123 packets, 8844 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    28 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 28 LOG flags 0 level 4

次は、29バイトのICMP echoパケットを送信してみます。

[root@client ~]# ping -c 1 -s 1 192.168.122.128

ルールを確認すると、29バイトのICMP echoパケットを受信しても、パケット数が増加しないことがわかります(期待値)。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 74 packets, 5370 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    28 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 28 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

6.2 パケット長の範囲を指定する方法

ICMPパケット長が30バイト~31バイトのICMPパケットを受信したらログを出力するルールを作成します。また、他のパケット長のICMPパケットを受信してもログが出力されないことを確認します。パケット長の範囲はコロンで指定します。

[root@server ~]# iptables -A INPUT -p icmp -m length --length 30:31 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 87 packets, 6264 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 30:31 LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

クライアントでpingを実行して、30バイトのICMP echoパケットを送信してみます。

[root@client ~]# ping -c 1 -s 2 192.168.122.128

ログを確認すると、ICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 22 19:56:26 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=30 TOS=0x00 PREC=0x00 TTL=64 ID=38722 DF PROTO=ICMP TYPE=8 CODE=0 ID=1456 SEQ=1

またルールを確認すると、30バイトのICMP echoパケットを受信したので、パケット数が1増加したことがわかります(期待値)。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 186 packets, 13306 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    30 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 30:31 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

6.3 パケット長の範囲(以上、以下)を指定する方法

ICMPのパケット長が31バイト以下のICMPパケットを受信したらログを出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -m length --length :31 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 7 packets, 504 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 0:31 LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

31バイトのICMP echoパケットを送信してみます。

[root@client ~]# ping -c 1 -s 3 192.168.122.128

ログを確認すると、ICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 22 20:31:12 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=31 TOS=0x00 PREC=0x00 TTL=64 ID=55728 DF PROTO=ICMP TYPE=8 CODE=0 ID=1547 SEQ=1

またルールを確認すると、31バイトのICMP echoパケットを受信していることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 73 packets, 5255 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    31 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            length 0:31 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

7 multiportモジュールの使い方

multiportモジュールは、複数のポート番号を指定するモジュールです。

7.1 ポート番号を複数指定する方法

宛先ポート番号が11111または11113のパケットを受信したらログに出力するルールを作成します。指定する複数のポート番号はカンマで指定します。

[root@server ~]# iptables -A INPUT -p tcp -m multiport --dports 11111,11113 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 7 packets, 504 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 11111,11113 LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

サーバでncコマンドを実行します。ターミナルを3つ開いて、それぞれで下記コマンドを実行します。

[root@server ~]# nc -kl 11111
[root@server ~]# nc -kl 11112
[root@server ~]# nc -kl 11113

クライアントでncコマンドを実行します。クライアントでも、ターミナルを3つ開いて、それぞれで下記コマンドを実行します。

[root@client ~]# nc 192.168.122.128 11111
[root@client ~]# nc 192.168.122.128 11112
[root@client ~]# nc 192.168.122.128 11113

ログを確認すると、宛先ポート番号が11111,11113を受信したログが記録されていることがわかります。宛先ポート番号が11112を受信したログは記録されていません(期待値)。

[root@server ~]# journalctl -f
12月 26 21:36:31 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=36855 DF PROTO=TCP SPT=41724 DPT=11111 WINDOW=29200 RES=0x00 SYN URGP=0
12月 26 21:36:31 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=36856 DF PROTO=TCP SPT=41724 DPT=11111 WINDOW=229 RES=0x00 ACK URGP=0
12月 26 21:36:35 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=14842 DF PROTO=TCP SPT=36130 DPT=11113 WINDOW=29200 RES=0x00 SYN URGP=0
12月 26 21:36:35 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=14843 DF PROTO=TCP SPT=36130 DPT=11113 WINDOW=229 RES=0x00 ACK URGP=0

ルールを確認すると、受信パケット数が4つであることがわかります。これら4つのパケットは、クライアントからサーバへのSYN,SYN+ACKパケットです。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 140 packets, 11574 bytes)
 pkts bytes target     prot opt in     out     source               destination
    4   224 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 11111,11113 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

7.2 ポート番号の範囲を指定する方法

宛先ポート番号が11111から11113のパケットを受信したらログに出力するルールを作成します。指定する範囲はコロンで指定します。

[root@server ~]# iptables -A INPUT -p tcp -m multiport --dports 11111:11113 -j LOG

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 7 packets, 504 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 11111:11113 LOG flags 0 level 4

サーバでncコマンドを実行します。ターミナルを3つ開いて、それぞれで下記コマンドを実行します。

[root@server ~]# nc -kl 11111
[root@server ~]# nc -kl 11112
[root@server ~]# nc -kl 11113

クライアントでncコマンドを実行します。クライアントでも、ターミナルを3つ開いて、それぞれで下記コマンドを実行します。

[root@client ~]# nc 192.168.122.128 11111
[root@client ~]# nc 192.168.122.128 11112
[root@client ~]# nc 192.168.122.128 11113

ログを確認すると、宛先ポート番号が11111,11112,11113を受信したログが記録されていることがわかります。

[root@server ~]# journalctl -f
12月 27 19:50:22 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=28814 DF PROTO=TCP SPT=41188 DPT=11111 WINDOW=29200 RES=0x00 SYN URGP=0
12月 27 19:50:22 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=28815 DF PROTO=TCP SPT=41188 DPT=11111 WINDOW=229 RES=0x00 ACK URGP=0
12月 27 19:50:29 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=23525 DF PROTO=TCP SPT=60718 DPT=11112 WINDOW=29200 RES=0x00 SYN URGP=0
12月 27 19:50:29 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=23526 DF PROTO=TCP SPT=60718 DPT=11112 WINDOW=229 RES=0x00 ACK URGP=0
12月 27 19:50:31 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=42542 DF PROTO=TCP SPT=49124 DPT=11113 WINDOW=29200 RES=0x00 SYN URGP=0
12月 27 19:50:31 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=42543 DF PROTO=TCP SPT=49124 DPT=11113 WINDOW=229 RES=0x00 ACK URGP=0

ルールを確認すると、受信パケット数が6つであることがわかります。これら6つのパケットは、クライアントからサーバへのSYN,SYN+ACKパケットです。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 78 packets, 7006 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        6   336 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 11111:11113 LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

8 timeモジュールの使い方

timeモジュールは、日時を指定するモジュールです。なお、timeモジュールはUTCしか使えないようです。UTCは以下のようにして確認できます。

[root@server ~]# date -u
2022年 12月 23日 金曜日 10:44:35 UTC

8.1 日時を指定する方法(--datestart,--datestop)

下記日時にパケットを受信したらログを出力するルールを作成します。
2022年12月23日 10時40分~2022年12月23日 10時55分

[root@server ~]# iptables -A INPUT -p icmp -m time --datestart 2022-12-23T10:40:00 --datestop 2022-12-23T10:55:00 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 19 packets, 1440 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            TIME starting from 2022-12-23 10:40:00 until date 2022-12-23 10:55:00 UTC LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

クライアントでpingコマンドを実行します。

[root@client ~]# ping -c 1 192.168.122.128

ログを確認すると、ICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 23 19:51:38 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=6284 DF PROTO=ICMP TYPE=8 CODE=0 ID=1455 SEQ=1

またルールを確認すると、31バイトのICMP echoパケットを受信していることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 105 packets, 7648 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    84 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            TIME starting from 2022-12-23 10:40:00 until date 2022-12-23 10:55:00 UTC LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

8.2 時刻を指定する方法(--timestart,--timestop)

[root@server ~]# date -u
2022年 12月 23日 金曜日 11:01:11 UTC

下記時間帯にパケットを受信したらログに出力するルールを作成します。
11時10分~11時20分

[root@server ~]# iptables -A INPUT -p icmp -m time --timestart 11:10:00 --timestop 11:20:00 -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 11 packets, 816 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            TIME from 11:10:00 to 11:20:00 UTC LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

クライアントでpingコマンドを実行します。

[root@client ~]# ping -c 1 192.168.122.128

ログを確認すると、ICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 23 20:16:29 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=60099 DF PROTO=ICMP TYPE=8 CODE=0 ID=1520 SEQ=1

またルールを確認すると、31バイトのICMP echoパケットを受信していることがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 78 packets, 5872 bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    84 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            TIME from 11:10:00 to 11:20:00 UTC LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

9 setモジュールの使い方

setモジュールは、ipsetコマンドで作成したセットを使用するモジュールです。

ok_hostという名前のセットを作成します。

[root@server ~]# ipset n ok_host hash:ip

作成したセットにクライアントのIPアドレス(192.168.122.153)を追加します。

[root@server ~]# ipset a ok_host 192.168.122.153

セットを確認すると、ok_hostという名前のセットが作成されたことがわかります。

[root@server ~]# ipset l
Name: ok_host
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 168
References: 0
Number of entries: 1
Members:
192.168.122.153

作成したセットをINPUTチェインに登録します。ここでは、セットに登録するIPアドレスは1つだけですが、複数のIPアドレスを登録する場合、セットを使うと以下のように簡潔にルールを作成することができます。

[root@server ~]# iptables -A INPUT -m set --match-set ok_host src -j LOG

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 75 packets, 5232 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set ok_host src LOG flags 0 level 4

ログを確認するため、journalctlコマンドを実行します。

[root@server ~]# journalctl -f

クライアントでpingコマンドを実行します。

[root@client ~]# ping -c 1 192.168.122.128

ログを確認すると、クライアントのIPアドレスを送信元とするICMPパケットを受信していることがわかります。

[root@server ~]# journalctl -f
-snip-
12月 23 20:44:12 server kernel: IN=eth0 OUT= MAC=52:54:00:78:10:73:52:54:00:8c:76:20:08:00 SRC=192.168.122.153 DST=192.168.122.128 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=177 DF PROTO=ICMP TYPE=8 CODE=0 ID=1573 SEQ=1

またルールを確認すると、31バイトのICMP echoパケットを受信していることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 37 packets, 2592 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    84 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set ok_host src LOG flags 0 level 4

あと始末をします。まずルールを削除します。

[root@server ~]# iptables -D INPUT 1

ルールに登録したセットを削除します。

[root@server ~]# ipset x ok_host

10 connlimitモジュールの使い方

connlimitモジュールは、最大同時接続数を指定するモジュールです。

宛先ポート番号が11111番のTCPコネクションの最大同時接続数を1つにするルールを作成します。

[root@server ~]# iptables -A INPUT -p tcp --dport 11111 -m connlimit --connlimit-above 1 -j REJECT

作成したルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 9 packets, 660 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 #conn src/32 > 1 reject-with icmp-port-unreachable

サーバでncコマンドを実行します。なお、ncコマンドの使い方は、ncコマンドの使い方(ネットワーク実験の幅が広がるなぁ~) - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# nc -kl 11111

lsofコマンドを実行すると、ncプロセスがTCPの11111番ポートでListenしていることがわかります。なお、lsofコマンドの使い方は、lsofコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# lsof -c nc -a -i -a -nP
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      1909 root    3u  IPv6  27620      0t0  TCP *:11111 (LISTEN)
nc      1909 root    4u  IPv4  27621      0t0  TCP *:11111 (LISTEN)

クライアントでncコマンドを実行します。

[root@client ~]# nc 192.168.122.128 11111

もう1つターミナルをひらいて、ncコマンドを実行します。2つ目を実行すると、サーバとTCPコネクション確立ができないため、プロンプトがすぐに復帰します。

[root@client ~]# nc 192.168.122.128 11111
[root@client ~]#

ルールを確認します。2つ目のTCPコネクションが確立できなかったため、廃棄(REJECT)したパケットが1つであることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 58 packets, 3980 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    60 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 #conn src/32 > 1 reject-with icmp-port-unreachable

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

11 commentモジュールの使い方

commentモジュールは、iptablesのルールにコメントをつけるモジュールです。

ICMPパケットを受信したらログを出力するルールにコメントを付けてみます。

[root@server ~]# iptables -A INPUT -p icmp -m comment --comment "This is test comment" -j LOG

作成したルールを確認すると、ルールにコメントが付けられたことがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 53 packets, 3692 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            /* This is test comment */ LOG flags 0 level 4

後始末をします(作成したルールの削除)。

[root@server ~]# iptables -D INPUT 1

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ