IPintel ガイド

国別IPブロック & fail2ban 設定ガイド

海外からの不正アクセスをブロックして、サーバーを守る方法をステップバイステップで解説します。

1. なぜ国別IPブロックが必要なのか

インターネットに公開されたサーバーには、日々膨大な不正アクセスが届きます。 SSH(リモート接続)へのパスワード総当たり攻撃、メールサーバーへの不正ログイン試行、 Webサイトへの脆弱性スキャンなどが代表的です。

これらの攻撃の多くは特定の国・地域から集中して行われます。 日本国内向けのサービスであれば、サービス提供に不要な国からのアクセスを一括でブロックすることで、攻撃の大部分を未然に防ぐことができます。

対策しない場合

  • - SSHへの総当たり攻撃でサーバーに高負荷
  • - メールサーバーへの不正ログイン試行
  • - ログが攻撃で埋まり正常な監視が困難
  • - 万が一侵入されると被害甚大

対策した場合

  • - 不要な国からのアクセスをカーネルレベルで遮断
  • - サーバー負荷の大幅軽減
  • - ログが見やすくなり異常を発見しやすい
  • - fail2ban と組み合わせて二重防御

2. 仕組みの全体像

国別ブロックと fail2ban は、それぞれ異なるレイヤーでサーバーを守ります。 両方を組み合わせることで、より強固な防御が実現します。

防御の2層構造

外部からのアクセス

[第1層] ipset による国別ブロック

│ ブロック対象国 → 即座に DROP(サーバーに負荷をかけない)

│ 許可国 → 通過

[第2層] fail2ban による動的ブロック

│ ログインに3回失敗 → そのIPを自動BAN

│ 繰り返し犯 → 長期BAN

正常なアクセスのみサービスに到達

それぞれの役割

ツール役割特徴
ipset国単位のIPブロック数万件のIPを高速処理。カーネルレベルで動作
fail2ban不正アクセスの自動検出・BANログを監視し、攻撃パターンを検出して自動対応
IPintel API国別IPリストの提供GeoLite2ベースの最新IP範囲を各種形式で出力

3. IPintel 国別IP API の使い方

IPintelは、国ごとのIPアドレス範囲をさまざまな形式で提供するAPIを公開しています。 ブラウザで国を選んでダウンロードすることも、curl コマンドで取得してスクリプトに組み込むこともできます。

ブラウザから使う場合

国別IPブロックリストページで、国を選んで形式を指定するだけでダウンロードできます。 コマンド操作が不慣れな場合はこちらが簡単です。

3.1 APIエンドポイント

エンドポイント説明
GET /api/v1/country/list国一覧(IPレンジ数・更新日付つき)
GET /api/v1/country/{code}/export1か国分をエクスポート
GET /api/v1/country/bulk-export複数国を一括エクスポート

3.2 エクスポート形式

format パラメータで出力形式を指定します。 お使いのファイアウォールに合った形式を選んでください。

形式用途対象環境
plain1行1CIDRのテキスト汎用(スクリプトで加工する場合)
ipsetipset restore 形式iptables + ipset 環境(本ガイド推奨)
iptablesipset作成 + iptablesルール例iptables 環境
firewalldfirewall-cmd スクリプトRHEL/Rocky Linux/AlmaLinux(firewalld環境)
nftablesnft 定義ファイル最新Linux(Debian 11+, Ubuntu 22.04+ 等)

3.3 使用例(curl)

中国(CN)とロシア(RU)のIPをipset形式で取得する例:

# 複数国を一括取得(ipset形式)
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=ipset"

# 出力例:
# create blocked_countries hash:net family inet hashsize 65536 maxelem 1000000 -exist
# flush blocked_countries
# add blocked_countries 1.0.1.0/24 -exist
# add blocked_countries 1.0.2.0/23 -exist
# ...

firewalld形式で取得する例:

# firewalld形式で取得(RHEL/Rocky Linux向け)
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=firewalld"

# nftables形式で取得(Debian/Ubuntu向け)
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=nftables"

3.4 パラメータ一覧

パラメータ説明デフォルト
countriesカンマ区切りの国コード(ISO 3166-1)必須
format出力形式(上記5種類)plain
set_nameipset/nftablesのセット名blocked_countries
downloadtrueでファイルとしてダウンロードfalse

4. ipset で国別ブロックを設定する

ipset は、Linuxカーネルレベルで大量のIPアドレスを効率的に管理するツールです。 iptablesで1件ずつルールを書くのと比べ、数万件のIPでも高速に判定できます。

ここでは最も一般的な iptables + ipset の組み合わせで解説します。 firewalld・nftables環境の方は、APIからそれぞれの形式で取得して適用してください。

4.1 ipset のインストール

# RHEL/Rocky Linux/AlmaLinux
sudo dnf install ipset ipset-service

# Debian/Ubuntu
sudo apt install ipset

4.2 IPintel APIからリストを取得して適用

1コマンドで、IPリストの取得からipsetへの適用まで完了します。

# 中国・ロシアのIPレンジを取得してipsetに適用
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=ipset" \
  | sudo ipset restore -exist

4.3 iptables でブロックルールを追加

# ipset に含まれるIPからのアクセスを DROP
sudo iptables -I INPUT -m set --match-set blocked_countries src -j DROP

# 確認
sudo iptables -L INPUT -n --line-numbers | head -5

4.4 再起動後もルールを維持する

ipset の内容はサーバー再起動で消えるため、永続化が必要です。

# ipset の内容をファイルに保存
sudo ipset save > /etc/ipset.conf

# ipset-service を有効化(起動時に自動読み込み)
sudo systemctl enable ipset

# iptables ルールの永続化
sudo iptables-save > /etc/sysconfig/iptables    # RHEL系
# sudo netfilter-persistent save                # Debian/Ubuntu

4.5 firewalld 環境の場合

Rocky Linux/AlmaLinux など firewalld を使用している環境では、APIから firewalld 形式で取得して実行します。

# firewalld形式のスクリプトを取得して実行
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=firewalld" \
  | sudo bash

# drop ゾーンに ipset を追加(初回のみ)
sudo firewall-cmd --permanent --zone=drop --add-source=ipset:blocked_countries
sudo firewall-cmd --reload

4.6 nftables 環境の場合

最新の Debian/Ubuntu など nftables を使用している環境向けです。

# nftables形式で取得してファイルに保存
curl -s "https://ipintel.daily-techlog.com/api/v1/country/bulk-export?countries=CN,RU&format=nftables" \
  > /tmp/blocked_countries.nft

# 適用
sudo nft -f /tmp/blocked_countries.nft

# ブロックルールを追加(初回のみ)
sudo nft add rule inet filter input ip saddr @blocked_countries drop

5. fail2ban で不正アクセスを自動ブロック

fail2ban は、サーバーのログを監視して、パスワード総当たりなどの不正アクセスを検出すると、 攻撃元IPを自動的にブロック(BAN)するツールです。 国別ブロックをすり抜けた攻撃や、許可国からの攻撃に対する防御として機能します。

5.1 インストール

# RHEL/Rocky Linux/AlmaLinux
sudo dnf install epel-release
sudo dnf install fail2ban

# Debian/Ubuntu
sudo apt install fail2ban

# サービスを有効化して起動
sudo systemctl enable --now fail2ban

5.2 基本的な考え方

fail2ban の設定は「jail(監獄)」という単位で管理します。 各 jail がサービス(SSH、メール等)ごとのログを監視し、不正を検出するとそのIPをBANします。

設定項目意味
maxretry何回失敗でBANするか3(3回失敗でBAN)
findtimeこの時間内の失敗回数をカウント600(10分)
bantimeBANする時間(秒)86400(24時間)
ignoreipBANしないIP127.0.0.1/8(自分自身)

5.3 設定ファイルの作成

デフォルトの jail.conf は直接編集せず、jail.local に設定を書きます(アップデートで上書きされないため)。

sudo vi /etc/fail2ban/jail.local
[DEFAULT]
# 自分のIPはBANしない(自分のグローバルIPに変更してください)
ignoreip = 127.0.0.1/8 ::1

# デフォルトのBAN設定
bantime  = 3600    # 1時間
findtime = 600     # 10分以内に
maxretry = 5       # 5回失敗でBAN

# --------------------
# SSH ブルートフォース対策
# --------------------
[sshd]
enabled  = true
port     = ssh
maxretry = 3
bantime  = 86400   # 24時間

# --------------------
# メールサーバー(Postfix + Dovecot)
# --------------------
[postfix]
enabled  = true
port     = smtp,465,submission
maxretry = 3
bantime  = 3600

[postfix-sasl]
enabled  = true
port     = smtp,465,submission,imap,imaps
maxretry = 3
bantime  = 86400

[dovecot]
enabled  = true
port     = imap,imaps,pop3,pop3s
maxretry = 3
bantime  = 3600

# --------------------
# 繰り返し犯(recidive)
# --------------------
# fail2banに何度もBANされるIPを長期BAN
[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 604800  # 1週間
findtime = 86400   # 24時間以内に
maxretry = 3       # 3回BANされたら

5.4 設定を反映

# 設定ファイルの構文チェック
sudo fail2ban-client -t

# 再起動して反映
sudo systemctl restart fail2ban

# 状態確認
sudo fail2ban-client status

6. 自動更新の設定

国別IPリストは定期的に更新されます。週1回程度の自動更新スクリプトを設定しておくと、 常に最新のリストでブロックできます。

6.1 更新スクリプト

sudo vi /usr/local/bin/update-country-blocklist.sh
#!/bin/bash
# 国別IPブロックリスト自動更新スクリプト
set -euo pipefail

# === 設定 ===
API_URL="https://ipintel.daily-techlog.com/api/v1/country/bulk-export"
COUNTRIES="CN,RU,KP,IR"      # ブロックする国(カンマ区切り)
FORMAT="ipset"                # 出力形式
SET_NAME="blocked_countries"  # ipset名
LOG="/var/log/country-blocklist.log"

log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG"; }

log "--- 更新開始: countries=$COUNTRIES ---"

# IPintel API からブロックリストを取得
TMP=$(mktemp)
HTTP_CODE=$(curl -s -o "$TMP" -w "%{http_code}" \
  "$API_URL?countries=$COUNTRIES&format=$FORMAT&set_name=$SET_NAME")

if [ "$HTTP_CODE" != "200" ]; then
  log "ERROR: API HTTP $HTTP_CODE"
  rm -f "$TMP"
  exit 1
fi

# ipset に適用
ipset restore -exist < "$TMP"
rm -f "$TMP"

# iptables ルールがなければ追加
if ! iptables -C INPUT -m set --match-set "$SET_NAME" src -j DROP 2>/dev/null; then
  iptables -I INPUT -m set --match-set "$SET_NAME" src -j DROP
  log "iptables ルール追加"
fi

# 永続化
ipset save > /etc/ipset.conf

COUNT=$(ipset list "$SET_NAME" 2>/dev/null | grep -c "^[0-9]" || echo "0")
log "完了: $COUNT エントリ"
# 実行権限を付与してテスト実行
sudo chmod +x /usr/local/bin/update-country-blocklist.sh
sudo /usr/local/bin/update-country-blocklist.sh

# ログを確認
cat /var/log/country-blocklist.log

6.2 cron で定期実行

# root の crontab を編集
sudo crontab -e

# 毎週日曜 5:00 に更新
0 5 * * 0 /usr/local/bin/update-country-blocklist.sh

6.3 systemd timer で定期実行する場合

cron の代わりに systemd timer を使うこともできます(ログ管理やエラー通知が便利です)。

# サービスファイル
sudo tee /etc/systemd/system/country-blocklist.service > /dev/null << 'EOF'
[Unit]
Description=Update country IP blocklist from IPintel
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/update-country-blocklist.sh
EOF

# タイマーファイル
sudo tee /etc/systemd/system/country-blocklist.timer > /dev/null << 'EOF'
[Unit]
Description=Weekly country blocklist update

[Timer]
OnCalendar=Sun 05:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

# 有効化
sudo systemctl daemon-reload
sudo systemctl enable --now country-blocklist.timer

# 状態確認
systemctl list-timers | grep country

7. 動作確認・トラブルシューティング

7.1 ipset の確認

# ipset 一覧
sudo ipset list -name

# エントリ数の確認
sudo ipset list blocked_countries | grep "Number of entries"

# 特定IPがブロック対象か確認
sudo ipset test blocked_countries 1.2.3.4
# → "1.2.3.4 is in set blocked_countries." ならブロック対象

7.2 fail2ban の確認

# 全jail の状態
sudo fail2ban-client status

# 特定jail の詳細(BANされたIP一覧)
sudo fail2ban-client status sshd

# リアルタイムでログを監視
sudo tail -f /var/log/fail2ban.log

7.3 よくある問題と対処法

Q: 自分がBANされてSSH接続できなくなった

→ VPS管理画面のコンソールからログインし、sudo fail2ban-client set sshd unbanip 自分のIP で解除してください。 今後のために ignoreip に自分のIPを追加しておきましょう。

Q: fail2ban が起動しない

sudo fail2ban-client -t で設定の構文エラーを確認してください。 また journalctl -u fail2ban -e でエラーログが見られます。

Q: ipset がサーバー再起動後に消える

sudo ipset save > /etc/ipset.conf で保存し、sudo systemctl enable ipset でサービスを有効化してください。 RHEL系では ipset-service パッケージが必要です。

Q: 特定のIPだけブロックを解除したい

sudo ipset del blocked_countries 1.2.3.4/32 でipsetから削除できます。 fail2banのBANは sudo fail2ban-client set sshd unbanip 1.2.3.4 で解除できます。

Q: ブロックが効いているか確認したい

sudo iptables -L INPUT -v -n | head -10 で DROP ルールの「pkts」「bytes」が増えていれば、ブロックが機能しています。

このガイドの内容を実践すれば、サーバーのセキュリティは大きく向上します。

ご質問・ご要望は [email protected] までお気軽にどうぞ。