こんにちは!新人のアナサピです!
今回はfirewalldで送信元IPをDROPした場合、そのIPからすでに通信中の接続も、その瞬間に切断されるのか検証してみました。
Botなどで大量にサーバへアクセスが来た際、手動でそのIPを遮断することがあります。
遮断後そのIPから接続はもちろん遮断されますが、通信中の遮断IPからの接続はどうなるのか確認していきます!
今回はweb-02からweb-01のApacheへHTTP接続した状態で、web-02からの通信をDROPします。
DROP追加前から存在しているHTTP通信と、DROP追加後に新しく開始するHTTP通信を比較して、挙動の違いを確認します。
実際の環境では遮断箇所がパケットフィルタやWAF側で遮断することもありますので、あくまでもfirewalldで遮断をする場合として見て頂ければ幸いです。
遮断箇所については以下の記事で紹介しておりますので、あわせてご覧ください!
検証環境
| 項目 | 内容 |
|---|---|
| 環境 | さくらのクラウド (石狩第1ゾーン) |
| 接続先 | web-01、Apache |
| 接続元 | web-02、curl |
| OS | どちらもAlmaLinux 10.1 |
| firewalld | 2.3.1 |
この記事ではIPアドレスをWEB01_IP、WEB02_IPと表記します。
web-01ではApacheとPHPが利用できる状態から検証を開始します。
300秒待機するindex.phpを用意する
firewalldを変更している間もHTTP通信を維持できるように、web-01のindex.phpで300秒待ってからレスポンスを返すようにします。
[root@web-01 ~]# cat /var/www/html/index.php
<?php
sleep(300);
echo "apache-ok\n";
[root@web-01 ~]#
index.phpへアクセスすると、HTTPリクエストを受け取ったあとPHPが300秒待機し、その後apache-okを返します。
今回の流れは次のようになります。
web-02からHTTP接続
↓
GET /index.php
↓
PHPで300秒待機
↓
待機中にfirewalldへDROP追加
↓
300秒後にapache-okを返す
この300秒の間に、TCP接続の確認やfirewalldの変更を行います。
変更前の状態を確認する
まずweb-01でApacheが起動していることを確認します。
[root@web-01 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
(省略)
Active: active (running) since Thu 2026-09-10 00:48:13 JST; 2min 41s ago
(省略)
[root@web-01 ~]#
状態がactive (running)なので、Apacheは問題なく起動しています。
続いてfirewalldのdropゾーンを確認します。
[root@web-01 ~]# firewall-cmd --list-all --zone=drop
drop
target: DROP
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@web-01 ~]#
sources、ports、rich rulesなどには何も設定されていません。
HTTP通信を開始する
web-02からindex.phpへアクセスします。
PHP側で300秒待機するため、このcurlはすぐには終了しません。
[root@web-02 ~]# curl http://WEB01_IP/index.php
(何も表示されない)
この状態では、web-02からweb-01へのTCP接続とHTTPリクエストはすでに開始されています。
web-01側ではindex.phpが実行され、300秒の待機中です。
TCP接続を確認する
curlを実行したまま、web-02の別ターミナルを開きます。
netstatでTCP接続を確認します。
[root@web-02 ~]# netstat -antp | grep 'WEB01_IP:80'
tcp 0 0 WEB02_IP:51844 WEB01_IP:80 ESTABLISHED 62082/curl
[root@web-02 ~]#
状態がESTABLISHEDになっています。
この接続が、firewalldの変更前から存在しているTCP接続です。
firewalldにDROPゾーンにWeb02のIPを追加する
index.phpが待機している間に、web-01でweb-02からの通信を遮断するために、DROPゾーンへweb-02のIPを追加します。
[root@web-01 ~]# firewall-cmd --zone=drop --add-source=WEB02_IP/32
success
[root@web-01 ~]#
今回は検証用の一時的な設定なので、--permanentは使用しません。
追加されたことを確認します。
[root@web-01 ~]# firewall-cmd --list-all --zone=drop
drop
target: DROP
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources: WEB02_IP/32
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@web-01 ~]#
これで、web-02のIPアドレスがDROPゾーンに追加されました。以降、web-02を送信元とする通信はDROPされます。
DROP追加後も既存接続を確認する
web-02で、先ほどから存在している接続をもう一度確認します。
[root@web-02 ~]# netstat -antp | grep 'WEB01_IP:80'
tcp 0 0 WEB02_IP:51844 WEB01_IP:80 ESTABLISHED 62082/curl
[root@web-02 ~]#
DROPゾーンへIPアドレスを追加した後も、変更前から存在していたTCP接続はESTABLISHEDのままです。
最初に実行したcurlも引き続きレスポンスを待っています。
DROP追加後に新しい接続を試す
既存接続が残っている状態で、web-02の別ターミナルから新しくHTTP接続を開始します。
接続待ちが長くならないように、接続タイムアウトを5秒に設定します。
[root@web-02 ~]# curl --connect-timeout 5 http://WEB01_IP/index.php
curl: (28) Failed to connect to WEB01_IP port 80 after 5002 ms: Connection timed out
[root@web-02 ~]#
DROP追加後に開始した新しいTCP接続はタイムアウトしました。
この時点では、同じweb-02からweb-01への通信でも次の違いがあります。
| 通信 | 結果 |
|---|---|
| DROP追加前から存在するTCP接続 | ESTABLISHEDのまま |
| DROP追加後に開始したTCP接続 | タイムアウト |
既存接続からレスポンスが返るか確認する
最初に実行したcurlは、そのまま待機させておきます。
index.phpの300秒の待機が終了すると、次のようにapache-okが返ります。
[root@web-02 ~]# curl http://WEB01_IP/index.php
apache-ok
[root@web-02 ~]#
このHTTP通信は、firewalldへDROPゾーンへIPアドレスを追加する前から存在していた接続です。
DROP追加後に新しい接続を作ろうとするとタイムアウトしましたが、すでに確立していた接続では、DROP追加後もサーバからレスポンスを受信できました。
つまり、今回の環境ではfirewalldのDROPゾーンへIPアドレスをを追加しても、通信中だったTCP接続がその瞬間にすべて切断されるわけではありませんでした。
DROPゾーンへ追加したIPアドレスを削除する
検証が終わったら、今回DROPゾーンに追加したweb-02のIPアドレスを削除します。
[root@web-01 ~]# firewall-cmd --zone=drop --remove-source=WEB02_IP/32
success
[root@web-01 ~]#
削除されたことを確認します。
[root@web-01 ~]# firewall-cmd --list-all --zone=drop
drop
target: DROP
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@web-01 ~]#
DROP削除後に再接続する
web-02から再びindex.phpへアクセスします。
今回は動作確認なので、PHP側の300秒待機が終わったあとにレスポンスが返ります。
[root@web-02 ~]# curl http://WEB01_IP/index.php
apache-ok
[root@web-02 ~]#
DROPゾーンから削除したことで、新しいTCP接続も再びできるようになりました。
今回の結果
今回の結果をまとめます。
| 状態 | DROP前から存在する接続 | DROP後の新規接続 |
|---|---|---|
| DROP追加前 | 通信可能 | 通信可能 |
| DROP追加後 | ESTABLISHEDのまま | タイムアウト |
| 300秒後 | apache-okを受信 | 接続不可 |
| DROP削除後 | - | 再び接続可能 |
今回の検証では、web-02からweb-01へのHTTP通信を開始し、PHPが処理中の状態でfirewalldのDROPゾーンへIPアドレスを追加しました。
DROP追加後に新しく開始したTCP接続はタイムアウトしました。
一方で、DROP追加前から存在していたTCP接続はnetstat上でもESTABLISHEDの状態が続き、PHPの処理が終了すると問題なく受信できました。
このことから、今回の環境ではfirewalldで送信元IPをDROPしても、すでに確立しているTCP接続が、その場で即座に切断されるわけではないことを確認できました。
最後までご覧いただきありがとうございました。