ipset とは#
ipset は、Linux 上で IP アドレスの集合を効率的に管理するためのツールです。これを IP アドレスの「コンテナ」または「リスト」と考えることができますが、この「リスト」の検索速度は非常に速く、特にファイアウォールルールでの使用に適しています。
ipset の役割は、IP アドレスの集合を管理することです。
始める前に#
以下は中国本土のサーバーが海外 IP をブロックする例です - Ubuntu 24.04 LTS (Noble Numbat)
サーバーにアクセスするための他の非ネットワーク手段(VNC など)を確保して、誤った iptables ルールを復元できるようにしてください。
まず、指定された地域の IP 集合を持つ必要があります。以下のコマンドで取得できます:
# *他のより包括的なIP集合に変更することも可能です
# 中国のIPアドレス集合をダウンロード
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone
次に、ipset をインストールします。
sudo apt install ipset -y
最後に、集合を作成します。
# cnipという名前の集合を作成
ipset -N cnip hash:net
# 先ほどダウンロードしたIP集合のIPをcnip集合にインポート
for i in $(cat ./cn.zone ); do ipset -A cnip $i; done
ブロックを開始する#
ルールを有効にするためには、チェーンをクリアする必要があります。本番環境で直接操作しないでください。バックアップに注意してください。
# 既存のルールをバックアップ
iptables-save > ~/iptables.bak
# チェーンをクリア
iptables -F
iptables -X
# ローカルループを許可
iptables -A INPUT -i lo -j ACCEPT
# すべての海外IPをブロック(cnip集合に一致しないIP)(中国IP(cnip集合内のIP)のみアクセスを許可)
iptables -A INPUT -m set ! --match-set cnip src -j DROP
# または、中国IPのアクセスを許可しない場合は、感嘆符「! 」を外すことができます
注意#
まず、既存のルールをバックアップして、問題が発生しないようにしてください。
次に、IP アドレスのデータベースを定期的に更新する必要があります。
さらに、Docker などの特殊なチェーンは、自分で処理方法を考える必要があります。
最後に、サーバーの再起動はルールの消失を引き起こす可能性があるため、起動時に自動的に iptables ルールを実行するスクリプトを作成できます。
更新 2025-02-12#
今日は Docker で海外の IP をブロックすることを再試行しました(前述の続き)。
コンテナがホストネットワークモード(Host)の場合、ホストと一致するため、個別に変更する必要はありません。この状況はブリッジモード(Bridge)のみに該当します。
まず、Docker のブリッジトラフィックがどのチェーンの後でアドレス変換されるかを理解する必要があります(ここでは SNAT、送信元アドレス変換を指します)。SNAT されたアドレスは海外からのものであるかどうかを判断できず、SNAT が発生する場所は FORWARD チェーンの後のチェーン、つまり POSTROUTING チェーンです(PREROUTING→FORWARD→POSTROUTING)。
補足:DNAT(宛先アドレス変換)は FORWARD チェーンの前のチェーン、つまり PREROUTING チェーンで発生します。
理論は存在し、実践が始まります。
私たちは送信元アドレスを判断するだけでよいので、FORWARD チェーンの上でいくつかの操作を行う必要があります。
まず、既存の iptables ルールをバックアップします:iptables-save > ~/iptables.bak
次に、新しいルール(iptables-only-allow-cnip-docker という名前)をコピーし、元の 2 つのルールをコメントアウトします:
# 意味は転送されたトラフィックを直接DOCKERのチェーンに渡すことです
# -A FORWARD -j DOCKER-USER
# -A FORWARD -j DOCKER-ISOLATION-STAGE-1
コメントアウトが完了したら、以下のルールをコメントアウトした 2 つのルールの下に追加します。
iptables のルールは順番に実行されます。
# 意味はeth0ネットワークカードからのcnipに一致するIP集合のトラフィックをDOCKER関連のチェーンに渡すことです(cnipからのIPのみを許可)
# 注:eth0は私のローカルネットワークカードであり、他のネットワークカードがある場合は、自分で追加または変更してください。
-A FORWARD -i eth0 -m set --match-set cnip src -j DOCKER-USER
-A FORWARD -i eth0 -m set --match-set cnip src -j DOCKER-ISOLATION-STAGE-1
# cnipに一致しないIP集合のトラフィックをeth0ネットワークカードでドロップします(cnip以外のIPからのトラフィックをブロック)
# 注:eth0は私のローカルネットワークカードであり、他のネットワークカードがある場合は、自分で追加または変更してください。
-A FORWARD -i eth0 -m set ! --match-set cnip src -j DROP
変更が完了したら、ルールを iptables にインポートして有効にします。
iptables-restore < ~/iptables-only-allow-cnip-docker
効果#
- Docker ブリッジネットワーク
- ローカルネットワーク