iptables を使用した Linux での ICMP トラフィックの遮断

CompTIABeginner
オンラインで実践に進む

はじめに

この実験では、Linux の強力なコマンドライン・ファイアウォールユーティリティである iptables を使用して、インバウンド(受信)ICMP トラフィックをブロックする方法を学びます。ネットワークの接続確認によく使われる ping コマンドのプロトコルである ICMP パケットを破棄(DROP)するようにファイアウォールを設定します。これは、プロトコルレベルでネットワークアクセスを制御し、Linux システムを保護するための基本的なスキルです。

まず、nmap を使用して予備のネットワークスキャンを行い、システムのオープンポートを確認します。次に、ping を実行して、初期状態で ICMP トラフィックが許可されていることを確認し、基準(ベースライン)を確立します。実験の核心部分では、すべてのインバウンド ICMP パケットを破棄する特定の iptables ルールを作成して適用します。最後に、ルールが有効であることを確認し、再度マシンに ping を試行して、リクエストが正常にブロックされることをテストします。

nmap によるオープン TCP/UDP ポートのスキャン

このステップでは、nmap ツールを使用して、自身のシステムのオープンなネットワークポートをスキャンする方法を学びます。ネットワークポートは、オペレーティングシステムにおける通信の終端点です。プログラムがネットワークから情報を受け取りたいとき、特定のポートで「待機(リスン)」します。オープンポートをスキャンすることは、マシンのセキュリティを評価する際の基本的な第一歩です。なぜなら、開いている各ポートは攻撃者にとって潜在的な侵入経路になる可能性があるからです。

まず、ベース環境には含まれていない nmap をインストールする必要があります。新しいソフトウェアをインストールする前に、パッケージリストを更新するのが良い習慣です。

次のコマンドを実行してパッケージリストを更新します。

sudo apt-get update

次に、以下のコマンドを実行して nmap をインストールします。

sudo apt-get install -y nmap

nmap とその依存関係がインストールされていることを示す出力が表示されます。

次に、nmap でスキャンする対象を指定するために、マシンの IP アドレスを確認する必要があります。これは ip コマンドで確認できます。

ip addr show

eth0ens33 のようなエントリを探してください。IP アドレスは inet の横に表示されます。172.16.50.13/24 のような形式で表示されます。

出力から IP アドレスを特定する方法:

  1. state UP になっているインターフェースを探します(通常は eth0)。
  2. inet で始まる行を探します(inet6 ではありません)。
  3. / の前の IP アドレス部分のみを控えます(例:inet 172.16.50.13/24 と表示されている場合、IP アドレスは 172.16.50.13 です)。
  4. ループバックインターフェース(lo、IP 127.0.0.1)は無視してください。

この実験の以降のステップでは、実際の IP アドレスのプレースホルダーとして <your_IP_address> を使用します。

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:04:c3:1d brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 172.16.50.13/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
       valid_lft 1892159940sec preferred_lft 1892159940sec
    inet6 fe80::216:3eff:fe04:c31d/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:1d:45:49:f8 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

これで最初のスキャンを行う準備が整いました。まずはオープンな TCP(Transmission Control Protocol)ポートのスキャンから始めましょう。TCP はコネクション型のプロトコルで、SSH(ポート 22)や HTTP(ポート 80)などの多くの一般的なサービスで使用されます。nmap-sT オプションは、TCP コネクトスキャンを実行します。

重要: <your_IP_address> は、前のステップで確認した実際の IP アドレスに置き換えてください。例えば、IP が 172.16.50.13 の場合、コマンドは nmap -sT 172.16.50.13 になります。

<your_IP_address> を自身の IP に置き換えてコマンドを実行します。

nmap -sT <your_IP_address>

出力には「open(開放)」状態のポートがリストされます。通常、システムではデフォルトで SSH ポート(22)が開いており、他のポートで追加のサービスが動作している場合もあります。

Starting Nmap 7.80 ( https://nmap.org ) at 2025-07-01 14:08 CST
Nmap scan report for iZrj93qpoj98oqswu96cqfZ (172.16.50.13)
Host is up (0.00013s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
3000/tcp open  ppp
3001/tcp open  nessus

Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds

次に、UDP(User Datagram Protocol)ポートをスキャンしましょう。UDP はコネクションレス型のプロトコルで、DNS(ポート 53)や DHCP(ポート 67/68)などのサービスで使用されます。UDP スキャンは TCP スキャンよりも低速で信頼性が低くなる傾向があります。UDP スキャンでは sudo を使用すると、より精度の高い結果が得られます。-sU オプションは UDP スキャンを実行するよう nmap に指示します。

注意: <your_IP_address> は実際の IP アドレスに置き換えてください。

sudo nmap -sU <your_IP_address>

出力にはポートが open|filtered と表示されることがあります。これは、nmap がポートが開いているのか、それともファイアウォールがスキャンをブロックしているのかを判断できないことを意味します。これは UDP スキャンでは一般的な結果です。

Starting Nmap 7.80 ( https://nmap.org ) at 2025-07-01 14:09 CST
Nmap scan report for iZrj93qpoj98oqswu96cqfZ (172.16.50.13)
Host is up (0.0000060s latency).
Not shown: 998 closed ports
PORT     STATE         SERVICE
68/udp   open|filtered dhcpc
5353/udp open|filtered zeroconf

Nmap done: 1 IP address (1 host up) scanned in 1.29 seconds

これらのスキャンを完了することで、マシン上でネットワーク接続を待機しているサービスを正常に特定できました。

ping による初期ネットワーク接続の確認

このステップでは、ファイアウォールルールを適用する前に、システムがネットワークリクエストに応答することを確認するために ping コマンドを使用します。ping コマンドは、ターゲットホストに対して ICMP(Internet Control Message Protocol)の「エコーリクエスト(echo request)」パケットを送信します。ホストが到達可能で応答するように設定されている場合、「エコーリプライ(echo reply)」パケットを返します。これは、基本的なネットワーク接続をテストするための根本的な方法です。

この種のトラフィックをブロックするファイアウォールルールを作成する前に、まずトラフィックが現在許可されていることを確認する必要があります。これにより、後でルールをテストした際に、ブロックの原因が他の既存のネットワーク問題ではなく、作成したルールによるものであると確信できます。

ここでは「ループバック」アドレスである 127.0.0.1 に対して ping を行います。この特別な IP アドレスは常に自身のマシンを指すため、外部接続を必要とせず、またマシンの割り当て済み IP アドレスを知らなくても、ローカルのネットワークスタックをテストできます。

4 つのパケットだけを送信して停止させるには、-c 4 オプションを使用します。これを使用しない場合、pingCtrl+C で手動で停止するまで実行され続けます。

ターミナルを開き、次のコマンドを実行します。

ping -c 4 127.0.0.1

4 つのパケットが送信され、4 つ受信されたことを示す出力が表示されるはずです。これは、システムが ICMP リクエストに正しく応答していることを示しています。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.053 ms

--- 127.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3070ms
rtt min/avg/max/mdev = 0.045/0.051/0.055/0.003 ms

0% packet loss(パケット損失 0%)の行は、接続が完全に機能していることを裏付けています。基準が確立されたので、この通信をブロックするファイアウォールルールを設定する準備が整いました。

ICMP パケットを破棄する iptables ルールの作成

このステップでは、Linux カーネルのネットワークパケットフィルタリングルールを管理するための標準的なコマンドラインユーティリティである iptables を使用して、シンプルなファイアウォールルールを設定します。先ほど ping コマンドでテストした ICMP トラフィックをブロックするルールを作成します。

iptables は、テーブル(Tables)、チェイン(Chains)、ルール(Rules)のシステムで動作します。

  • テーブル: 特定の目的のためのチェインの集合です。最も一般的に使用されるのは filter テーブルで、これがデフォルトであり、パケットフィルタリングに使用されます。
  • チェイン: 順番にチェックされるルールのリストです。インバウンド(受信)トラフィックには INPUT チェインが使用されます。
  • ルール: パケットの条件(プロトコルや送信元アドレスなど)とターゲット(パケットをどうするか、例:ACCEPT(許可)や DROP(破棄))を指定します。

まず、現在のルールセットを確認しましょう。iptables はカーネル設定を変更するため、sudo を使用する必要があります。-L オプションは、デフォルトの filter テーブル内のルールをリスト表示します。

sudo iptables -L

INPUTFORWARDOUTPUT の 3 つのデフォルトチェインが表示されます。この環境では、Docker がすでに FORWARD チェインにいくつかのルールを作成し、コンテナネットワーク用のカスタムチェインを追加しているのが確認できるかもしれません。INPUT チェインと OUTPUT チェインは、通常のトラフィックに対して依然としてデフォルトの ACCEPT ポリシーを使用しています。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

それでは、インバウンド ICMP パケットをブロックするルールを追加しましょう。INPUT チェインに新しいルールを追加(-A: Append)します。

コマンドの構成は以下の通りです:

  • sudo iptables: ファイアウォールを管理するコマンド。
  • -A INPUT: INPUT チェインにルールを追加する。
  • -p icmp: このルールを icmp プロトコルを使用するパケットに適用する。
  • -j DROP: パケットが一致した場合、DROP ターゲットにジャンプする。これは応答を返さずにパケットを静かに破棄することを意味します。

次のコマンドを実行してルールを作成します。

sudo iptables -A INPUT -p icmp -j DROP

成功した場合、このコマンドは何も出力しません。これで、あらゆる送信元からのすべてのインバウンド ICMP パケットを破棄するようにカーネルファイアウォールに指示したことになります。

ファイアウォールルールの確認とブロックのテスト

最後のステップでは、新しいファイアウォールルールが正常に追加されたことを確認し、再度システムに ping を試行してその効果をテストします。この検証プロセスは、セキュリティポリシーが正しく実装されていることを確認するために、ネットワーク管理において非常に重要です。

まず、ルールリストを再度表示して、新しく追加されたルールを確認しましょう。先ほどと同じコマンドを実行することで、ファイアウォールの現在の状態を確認できます。

sudo iptables -L

INPUT チェインの下に新しいルールが表示されているはずです。出力には、icmp プロトコルに一致するパケットが DROP ターゲットに送られることが明確に示されています。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       icmp --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

ルールが適用されていることが確認できたので、テストしてみましょう。ステップ 2 で使用したのと同じ ping コマンドを実行します。

ping -c 4 127.0.0.1

今回は応答がありません。コマンドは数秒間停止したようになり、その後終了します。出力には 100% packet loss(パケット損失 100%)と表示されます。これは、指示通りにカーネルのファイアウォールがインバウンド ICMP パケットを静かに破棄しているため、期待通りの動作です。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

--- 127.0.0.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3055ms

これで ICMP トラフィックのブロックに成功しました!iptables で作成したルールは永続的ではなく、システムの再起動時にクリアされます。しかし、ルールを手動で削除する方法を知っておくことは良い習慣です。追加したときと全く同じルールを指定し、-D(Delete)フラグを使用することで削除できます。

ルールを削除して接続を復元しましょう。

sudo iptables -D INPUT -p icmp -j DROP

ルールが削除され、接続が復元されたことを確認するために、最後にもう一度 ping を実行します。

ping -c 2 127.0.0.1

今度は ping が成功し、ファイアウォールルールが正常に削除されたことが確認できるはずです。

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.058 ms

--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1024ms
rtt min/avg/max/mdev = 0.048/0.053/0.058/0.005 ms

まとめ

この実験では、Linux システムにおける初期のネットワーク調査方法を学びました。まず、マシンの IP アドレスを特定した後、nmap ツールをインストールしてオープンな TCP および UDP ポートをスキャンしました。続いて、ping コマンドを使用してネットワーク接続の基準(ベースライン)を確立し、システムが ICMP トラフィックを正常に受信して応答していることを確認しました。

実験の核心では、iptables ファイアウォールユーティリティを使用してネットワークトラフィックを操作しました。INPUT チェインにすべてのインバウンド ICMP パケットを DROP する特定のルールを構築して適用し、ping のようなツールを効果的にブロックしました。最後に、現在の iptables ルールセットを表示して新しいルールが有効であることを確認し、再度マシンに ping を試行してリクエストが期待通りにタイムアウトすることを確認することで、ブロックのテストを完了しました。