hana_shinのLinux技術ブログ

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

iptablesコマンドの使い方



1 iptablesコマンドとは

iptablesコマンドは、送受信パケットの廃棄/許可等のルールをnetfilterに設定/削除するコマンドです。なお、iptablesコマンドの位置づけは以下になります。

     CentOS          Ubuntu20.04         openSUSE(Leap42.3)
+--------------+    +------------+    +---------------------+   -*-
| firewall-cmd |    |     ufw    |    |    SUSEfirewall2    |    |
+--------------+    +------------+    +---------------------+    |
                                                               ユーザ空間
+-----------------------------------------------------------+    |
|                     iptables  command                     |    |
+-----------------------------------------------------------+   -*-

+-----------------------------------------------------------+   -*-
|                                                           |    |
|                    OS(netfilter)                          |  カーネル空間
|                                                           |    |
+-----------------------------------------------------------+   -*-

firewall-cmdコマンド、ufwコマンドの使い方は以下を参照してください。
firewall-cmdの使い方 - hana_shinのLinux技術ブログ
ufwコマンドの使い方 - hana_shinのLinux技術ブログ

2 検証環境

2.1 ネットワーク構成

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

                          192.168.122.0/24
client(eth0) -------------------------------------------(eth0) server
            .153                                    .128

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 チェインとは?

チェインとは、ルールの集合です。ルールはある条件にマッチしたらパケットの廃棄/通過といった規則のことです。チェインはOS内に5つあります。5つのチェインは、組み込みチェインと呼ばれています。なお、チェインはiptables利用者がユーザ定義チェインとして独自に定義することも可能です。

チェイン 意味
PREROUTING 受信パケットに対してルーティング処理を行う前のパケットに対して実行するチェインです
INPUT 受信パケットのルーティング処理を実行した結果、自分宛てのパケットに対して実行するチェインです
FORWARD 受信パケットのルーティング処理を実行した結果、他サーバ宛てに送信するパケットに対して実行するチェインです
OUTPUT 送信パケットに対してルーティング処理を行う前のパケットに対して実行するチェインです
POSTROUTING 送信パケットに対してルーティング処理を実行した後のパケットに対して実行するチェインです

5 ルールの表示方法(-L)

5.1 INPUTチェインのルールの表示方法

INPUTチェインのルールを表示します。何もルールが登録されていないことがわかります。

[root@server ~]# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

5.2 OUTPUTチェインのルールの表示方法

OUTPUTチェインのルールを表示します。何もルールが登録されていないことがわかります。

[root@server ~]# iptables -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

5.3 FORWARDチェインのルールの表示方法

FORWARDチェインのルールを表示します。何もルールが登録されていないことがわかります。

[root@server ~]# iptables -L FORWARD
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

5.4 PREROUTINGチェインのルールの表示方法

PREROUTINGチェインは、-t natオプションを付けてルールを表示します。PREROUTINGチェインには、何もルールが登録されていないことがわかります。

[root@server ~]# iptables -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

5.5 POSTROUTINGチェインのルールの表示方法

POSTROUTINGチェインは、-t natオプションを付けてルールを表示します。POSTROUTINGチェインには、何もルールが登録されていないことがわかります。

[root@server ~]# iptables -t nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

6 ルールの詳細を表示する方法

6.1 数値で表示する方法(-n)

-nは、IPアドレスやポート番号を数値で表示するオプションです。-nを指定しないと、以下のようIPアドレス(source,destination)が文字列で表示されます。

[root@server ~]# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
LOG        icmp --  anywhere             anywhere             LOG level warning

-nを指定すると、IPアドレスがanywhereではなく0.0.0.0と表示されていることがわかります。

[root@server ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
LOG        icmp --  0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4

6.2 パケット数やバイト数を表示する方法(-v)

-vは、パケット数(pkts)やバイト数(bytes)を表示するオプションです。-vオプションを付けてiptablesを実行すると、1列目にパケット数(pkts)、2列目にバイト数(bytes)が表示されていることがわかります。

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

クライアントでpingコマンドを1回実行します。宛先はサーバです。pingコマンドを実行すると、クライアントからサーバにICMP echoパケットが1つ送信されます。なお、pingコマンドの使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

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

iptablesコマンドの実行結果を確認すると、ICMPパケットを1つ受信していることがわかります。また、受信パケット数が84bytesであることがわかります。なお、84bytesは、IPヘッダを含めたサイズになります。詳細は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

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

6.3 ルールの番号を表示する方法(--line-numbers)

--line-numbersは、ルールの番号を表示するオプションです。以下の例では、INPUTチェインにルールが1つ登録されていて、番号が1番であることがわかります。

[root@server ~]# iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    LOG        icmp --  anywhere             anywhere             LOG level warning

7 ルールの追加、削除方法(-A,-D)

7.1 ルールの追加(-A)

-Aは既存ルールの末尾に新規ルールを追加するオプションです。

テスト用のルールを1つ作成します。

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

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

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 19 packets, 1344 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            LOG flags 0 level 4

作成したルールの末尾に新規ルールを追加してみます。

[root@server ~]# iptables -A INPUT -p tcp --dport 11111

ルールを確認します。既存ルールの末尾に新規ルールが追加されたことがわかります。

[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        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4
2        0     0            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111

7.2 ルールの削除(-D)

-Dはルールを削除するオプションです。書式は、-D <チェイン名> <ルールの番号>となります。

ルールを確認します。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 34 packets, 2404 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            LOG flags 0 level 4
2        0     0            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111

1番目のルールを削除します。

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

ルールを確認します。元の1番目のルールが削除されたことがわかります。

[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            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111

8 ルールの挿入、削除方法(-I,-D)

8.1 ルールの挿入(-I)

-Iは指定したルールの前に新規ルールを挿入するオプションです。

テスト用のルールを1つ作成します。

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

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

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 19 packets, 1376 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            LOG flags 0 level 4

元の1番目の前に新規ルールを挿入します。

[root@server ~]# iptables -I INPUT 1 -p tcp --dport 11111

なお、1は省略することができるので、以下のように実行することもできます。

[root@server ~]# iptables -I INPUT -p tcp --dport 11111

ルールを確認します。元のルールの上に新規ツールが挿入されたことがわかります。

[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            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111
2        0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4

8.2 ルールの削除(-D)

-Dはルールを削除するオプションです。

登録されているルールを確認します。

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

INPUTチェインの2番目のルールを削除してみます。

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

ルールを確認します。2番目のルールが削除されたことがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 22 packets, 1588 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0            tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111

9 ルールを置き換える方法(-R)

テスト用のルールを1つ作成します。

[root@server ~]# iptables -A INPUT -p icmp

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

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 61 packets, 4232 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0            icmp --  *      *       0.0.0.0/0            0.0.0.0/0

次に、元のルールを宛先UDPポート番号が11111番のパケットを受信するルールに置き換えます。

[root@server ~]# iptables -R INPUT 1 -p udp --dport 11111

ルールが置き換えられたことがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 69 packets, 4812 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0            udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:11111

10 カウンタをリセットする方法(-Z)

10.1 事前準備

テスト用のルールを1つ作成します。

[root@server ~]# iptables -A INPUT -p icmp

作成したルールを確認します。ICMPパケットの受信数(pkts)が0であることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 133 packets, 9844 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0            icmp --  *      *       0.0.0.0/0            0.0.0.0/0

クライアンで宛先をサーバにしてpingを実行します。なお、pingコマンドの使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

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

ルールを確認します。ICMPのパケット受信数が1になったことがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 190 packets, 13864 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    84            icmp --  *      *       0.0.0.0/0            0.0.0.0/0

10.2 カウンタのリセット

INPUTチェインのカウンタをリセットします。

[root@server ~]# iptables -Z INPUT

INPUTチェインのルールを確認します。ICMPのパケット受信数が0にクリアされたことがわかります。

[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            icmp --  *      *       0.0.0.0/0            0.0.0.0/0

11 ユーザ定義チェイン

11.1 ユーザ定義チェインの作成方法(-N)

-Nはユーザ定義チェインを作成するオプションです。ここでは、TESTという名前のユーザ定義チェインを作成します。

[root@server ~]# iptables -N TEST

ユーザ定義チェインに登録されているルールを確認します。ルールが何も登録されていないことがわかります。

[root@server ~]# iptables -L TEST
Chain TEST (0 references)
target     prot opt source               destination

11.2 ユーザ定義チェインの削除方法(-X)

-Xはユーザ定義チェインを削除するオプションです。

TESTという名前のユーザ定義チェインを削除します。

[root@server ~]# iptables -X TEST

チェインを確認します。TESTチェインが削除されたことがわかります。

[root@server ~]# iptables -L TEST
iptables: No chain/target/match by that name.

11.3 ユーザ定義チェインにルールを追加する方法(-A,-I)

TESTという名前のチェインを作成します。

[root@server ~]# iptables -N TEST

作成したユーザ定義チェインにルールを作成します。

[root@server ~]# iptables -A TEST -p icmp -j LOG

ユーザ定義チェインに登録されているルールを確認します。

[root@server ~]# iptables -nvL TEST
Chain TEST (0 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4

11.4 組み込みチェインにユーザ定義チェインを登録する方法(-A,-I)

[root@server ~]# iptables -nvL TEST
Chain TEST (0 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4

TESTチェインをINPUTチェインに登録します。

[root@server ~]# iptables -A INPUT -j TEST

INPUTチェインに登録されているルールを確認します。TESTチェインがターゲットとして登録されていることがわかります。

[root@server ~]# iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    TEST       all  --  anywhere             anywhere

11.5 ユーザ定義チェインの送信パケット数の確認方法

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

12 ルールの指定方法について

12.1 プロトコルを指定する方法(-p)

-pはプロトコルを指定するオプションです。/etc/protocolsに登録されているプロトコルを指定できます。具体的にはicmp,udp,tcp等があります。

テスト用のルールを1つ作成します。

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

さらに、テスト用のルールを1つ作成します。

[root@server ~]# iptables -A INPUT -p udp -j LOG

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

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

あと始末をします。

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

あと始末をします。

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

INPUTチェインのルールを確認します。ルールが全て削除されたことがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 11 packets, 816 bytes)
 pkts bytes target     prot opt in     out     source               destination

12.2 インタフェースを指定する方法

12.2.1 入力インタフェースを指定する方法(-i)

ipコマンドを使ってインタフェースを確認します。loとeth0の2つのインタフェースが存在することがわかります。

[root@server ~]# ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:78:10:73 brd ff:ff:ff:ff:ff:ff

eth0でICMPパケットを受信したら、ICMPパケットのIPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -I INPUT -p icmp -i eth0 -j LOG

作成したルールを確認します。受信インタフェースにeth0が指定されていることがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 37 packets, 2572 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  eth0   *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4
12.2.2 出力インタフェースを指定する方法(-o)

eth0からICMPパケットを送信したら、ICMPパケットのIPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -A OUTPUT -o eth0 -p icmp -j LOG

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

[root@server ~]# iptables -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 17 packets, 1880 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        icmp --  *      eth0    0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4

12.3 IPアドレスを指定する方法

12.3.1 送信元IPを指定する方法(-s)

送信元IPアドレスが192.168.122.15のICMPパケットを受信したら、IPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -s 192.168.122.153 -j LOG

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

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

テスト用に作成したルールを削除します。

[root@server ~]# iptables -D INPUT 1
12.3.2 送信先IPを指定する方法(-d)

送信先IPアドレスが192.168.122.128のICMPパケットを受信したら、IPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp -d 192.168.122.128 -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            192.168.122.128      LOG flags 0 level 4

12.4 ポート番号を指定する方法

12.4.1 送信元ポート番号を指定する方法(--sport)

送信元ポート番号が53番のUDPパケットを受信したら、IPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -I INPUT -p udp --sport 53 -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        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 LOG flags 0 level 4

digコマンドを実行するとDNSパケットがDNSサーバに送信されます。なお、digコマンドについては、digコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# dig ntp.nict.jp +short
133.243.238.164
133.243.238.163
133.243.238.244
133.243.238.243
61.205.120.130

ルールを確認すると、INPUTチェインに送信元ポート番号が53番のUDPパケット(DNS queryに対する応答)を1つ受信したことが記録されていることがわかります。

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 29 packets, 2132 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1   148 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 LOG flags 0 level 4

あと始末をします。作成したルールを削除します。

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

ルールを確認すると、作成したルールが削除されたことがわかります。

[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
12.4.2 送信先ポート番号を指定する方法(--dport)

送信先ポート番号が53番のUDPパケットを送信したら、IPアドレス等の情報をログに出力するルールを作成します。

[root@server ~]# iptables -I OUTPUT -p udp --dport 53 -j LOG

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

[root@server ~]# iptables -nvL OUTPUT --line-numbers
Chain OUTPUT (policy ACCEPT 36 packets, 3792 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 LOG flags 0 level 4

DNSパケットを送信するため、digコマンドを実行します。

[root@server ~]# dig ntp.nict.jp +short
61.205.120.130
133.243.238.164
133.243.238.163
133.243.238.244
133.243.238.243

ルールを確認すると、OUTPUTチェインに送信先ポート番号が53番のUDPパケット(DNS query)を1つ送信したことが記録されていることがわかります。

[root@server ~]# iptables -nvL OUTPUT --line-numbers
Chain OUTPUT (policy ACCEPT 56 packets, 6588 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    68 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 LOG flags 0 level 4

あと始末をします。作成したルールを削除します。

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

ルールを確認します。作成したルールが削除されたことがわかります。

[root@server ~]# iptables -nvL OUTPUT --line-numbers
Chain OUTPUT (policy ACCEPT 5 packets, 600 bytes)
num   pkts bytes target     prot opt in     out     source               destination

12.5 TCPの制御フラグを指定する方法

TCPヘッダにSYN,FIN,ACK等の制御ビットを定義するフィールドがあります。ここでは、特定の制御ビットが1になっているパケットをルールに登録する方法について説明します。

12.5.1 SYNパケットをルールに登録する方法

TCPコネクション確立時、以下のパケットをやり取りしてTCPコネクションを確立します。ここでは、SYNパケットを受信したら、SYNパケットのIPアドレス等の情報をログに記録するルールを追加してみます。なお、TCPコネクションの確立/開放の様子は、TCPコネクションの確立、解放シーケンス - hana_shinのLinux技術ブログを参照してください。

client                       server(11111)
  |                             |
  |----------- SYN ------------>| ★このパケットをiptablesのルールに指定する。
  |<---------- SYN +ACK --------|
  |----------- ACK ------------>|
  |                             |

SYNパケットを受信したら、SYNパケットのIPアドレス等の情報をログに記録するルールを追加します。

[root@server ~]# iptables -I INPUT -p tcp --dport 11111 --tcp-flags SYN SYN -j LOG

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

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 9 packets, 676 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 flags:0x02/0x02 LOG flags 0 level 4

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行します。クライアントでncコマンドを実行すると、クライアントからサーバにSYNパケットが送信されます。ここでは説明しませんが、この時の様子はtcpdumpコマンドを使って確認することができます。なお、tcpdumpコマンドの使い方は、tcpdumpの使い方(基本編) - hana_shinのLinux技術ブログを参照してください。

[root@client ~]# nc 192.168.122.128 11111

ルールを確認すると、FINパケットを1つ受信(左端のpkts)したことがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 68 packets, 6510 bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    60 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 flags:0x02/0x02 LOG flags 0 level 4

後始末をします。

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

ルールを確認します。作成したルールが削除されたことがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 7 packets, 504 bytes)
 pkts bytes target     prot opt in     out     source               destination
12.5.2 FINパケットをルールに登録する方法

TCPコネクション終了時、以下のパケットをやり取りしてTCPコネクションを解放します。ここでは、FINパケットを受信したら、FINパケットのIPアドレス等の情報をログに記録するルールを追加してみます。

       client                       server(11111)
        |                             |
Ctrl +c |                             |
        |----------- FIN ------------>| ★このパケットをiptablesのルールに指定する。
        |<---------- ACK -------------|
        |                             |
        |<---------- FIN -------------|
        |----------- ACK ------------>|
        |                             |

FINパケットを受信したら、FINパケットのIPアドレス等の情報をログに記録するルールを追加します。

[root@server ~]# iptables -I INPUT -p tcp --dport 11111 --tcp-flags FIN FIN -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        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 flags:0x01/0x01 LOG flags 0 level 4

サーバでncコマンドを実行します。

[root@server ~]# nc -kl 11111

クライアントでncコマンドを実行します。クライアントでncコマンドを実行すると、サーバとクライアント間でTCPコネクションを確立します。

[root@client ~]# nc 192.168.122.128 11111

クライントでCtrl + cを押下して、TCPコネクションを終了します。ncコマンドを終了すると、クライアントからサーバにFINパケットが送信されます。

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

ルールを確認すると、FINパケットを1つ受信(左端のpkts)したことがわかります。

[root@server ~]# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 98 packets, 6992 bytes)
 pkts bytes target     prot opt in     out     source               destination
    1    52 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 flags:0x01/0x01 LOG flags 0 level 4

12.6 ワイルドカードの使い方(+)

複数のインタフェース(eth0,eth1,...)を搭載しているマシンでは、1つづつインタフェースを指定するのは面倒です。"+"を使うと複数インタフェースを以下のように指定することができます。

[root@server ~]# iptables -A INPUT -i eth+ -p tcp --dport 11111

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

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 73 packets, 5104 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0            tcp  --  eth+   *       0.0.0.0/0            0.0.0.0/0            tcp dpt:11111

あと始末をします。作成したルールを削除します。

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

作成したルールが削除されたことがわかります。

[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

12.7 否定を指定する方法(!)

12.7.1 IPアドレスに否定を指定する方法

送信元IPアドレスが192.168.122.153以外のICMPパケットを受信したらログに出力するルールを作成します。

[root@server ~]# iptables -A INPUT -p icmp ! -s 192.168.122.153 -j LOG

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

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

クライアントでpingコマンドを1回実行します。宛先はサーバです。

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

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

[root@server ~]# iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 70 packets, 4876 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 LOG        icmp --  *      *      !192.168.122.153      0.0.0.0/0            LOG flags 0 level 4
12.7.2 他の指定方法

IPアドレス以外に、以下のものを否定の対象に指定できます。
・ポート番号
プロトコル
・インタフェース
・フラグメント(-! -fと指定すると、フラグメントされている場合先頭のパケット、フラグメントされていない場合は、フラグメントされていないパケット自身が対象になります)

13 ターゲット

ターゲットは、iptablesコマンドの使い方(ターゲットの使い方) - hana_shinのLinux技術ブログを参照してください。

Z 参考情報

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