Raspberry Pi (Linux)

FireHOL Level3 導入

ルーターでのDNAT構成において、FORWARDチェインでのルールを一部変更。

FireHOL Level1・Level2 だけでは、中国系からの SMTP SPAM が一部漏れてくる為、これまで中国全域(CN zone)を丸ごと DROP していました。

しかし、メールサーバ側で zen.spamhaus による強力なフィルタリングが効くため、国単位(CN zone)の大味なブロックは必ずしも必要ではない状況になっていた。

そこで、IP国家ブロックではなく、より精度の高い “悪性アドレス集合ベースの防御” に切り替える方針へ変更。

変更点

CN zone(中国 IP 全域 DROP)を廃止

代わりに FireHOL Level3 を追加

FireHOL Level3 は、既知のスパム・ボットネット・脆弱性スキャンなど
“より積極的に悪性と判定されているアドレス” を対象に含むため、
国家単位のブロックよりも 必要十分で副作用の少ないブロック を実現できます。

現行のフィルタ構成(説明付き)

以下は現在の iptables ルールセットに、解説を付加したものです。

■ INPUT チェーン(WAN→自サーバの防御)
Chain INPUT (policy DROP)

→ 基本は DROP。必要な通信だけを例外許可する「ホワイトリスト方式」。

1 ACCEPT RELATED,ESTABLISHED

既存の通信の戻りはすべて許可(最重要ルール)。
接続中の HTTP/HTTPS や SSH の応答を止めないため。

2 ACCEPT all br0

LAN 内(192.168.1.x)からのアクセスは完全許可。
管理用のローカル接続を遮断しないようにするため。

3 DROP firehol_level1

外部からの新規接続で、FireHOL Level 1(悪性度高)に該当するホストを遮断。
→ 基本のマルウェア・スパム送信元の大半を撃退。

サーバーアクセス制限を強化

半年近く続いている不審なアクセスについて、現在のところ原因は特定できていないものの、個人的には以前の人間関係や環境が影響している可能性も否定できないと感じている。

ただし、技術的には海外クラウドやスキャナーによる通常の自動アクセスである可能性も高く、どちらとも断定はできない。
とはいえ、同じパターンが長期にわたって続くことや、アクセスの時間帯・性質に一定の特徴があることから、単なる一般的なトラフィック以上の何かを感じてしまうのも正直なところだ。

この数か月、アクセス動向を観察するために、あえて設定を変えて反応を見てきたが、期待したような建設的な兆候は得られず、むしろ予測しづらい動きが多かった。
また、海外アクセスを数日間だけ開放した際には、20年以上続けているブログ「海辺の放浪記」の古い記事まで一気に取得される動きがあり、さすがに気味の悪さを感じた。

そこで今回、海外からの不審な接続を減らす目的で、ルーター側のDNATや iptables/ipset ルールを大幅に見直し、より厳格なアクセス制御に切り替えた。

① ブラックリスト → 国別ブロックが先頭
2 DROP firehol_level1 (FireHOLで公開されているIPブラックリスト)
3 DROP firehol_level2 (FireHOLで公開されているIPブラックリスト)
4 DROP cn_block  (中国全域)
5 DROP other_block (その他、しつこく不審アクセスがあったネットワーク)

→ 海外 AWS/GCP/中国/その他 が最初に落ちる。

② LAN → WAN を許可
12 ACCEPT br0→ppp0 192.168.1.0/24 → ANY

→ 家庭内のPCやスマホの外向き通信は全部通る。

③ WAN → LAN(サーバー)を「国内限定」許可
13 SSH (22) 国内
15 HTTP (80) 国内
16 HTTP (80) サーチボット
17 HTTPS (443) 国内
18 HTTPS (443) サーチボット

やはり中国・・・

FireHOL Level 1-> FireHOL Level 2 の順にDROP条件を追加していったが、やはりSPAMメールのアクセスが漏れてくるので、結局中国全域のDROPを追加。

中国は野良サーバーの排除を行わないと、国として信頼できないですよ!(笑)

ここまでやれば、殆どSPAMメールのアクセスが漏れてくることは無いが、全ての攻撃を消すことは不可能。

順序 ipset        説明
1   firehol_level1   広範囲かつ静的な脅威をブロック
2   firehol_level2   最新かつ動的な脅威をブロック
3   cn_block      中国全域をブロック
4   other_block    その他のブロックリスト

システムリブートでのiptables/ipset自動復旧

停電や再起動のあと、PPPoEが自動接続されてもiptablesがデフォルトのままではセキュリティレベルが低い状態でサーバが公開されます。

そこで、リブート時にipsetによる制限などを自動復旧する内容を実装しました。

overlayfs環境などで設定復元を安定させるには工夫が必要です。

そこで、PPPoE確立後に自動でiptables/ipsetを初期化し、ブート後一度だけ外部リストをDL更新する構成を組みました。
結果として、停電やリブートが起きても、何もしなくても通信制御が完全に復元されます。

?? 背景

PPPoEは起動時に自動接続されるよう設定済み(/etc/network/interfaces)

iptables・ipsetの設定は /mnt/data/sh/restore_japan_only.sh にまとめてある

外部サイトから更新リストをDLする重い処理(update_ipset.sh)は再接続のたびに実行したくない

/etc/ppp/ip-up.d/ は overlayfsで直接編集できない

解決策の方針

/etc/ppp/ip-up.d/ にラッパースクリプトを1本だけ置く

まず軽量な restore_japan_only.sh を即実行して通信ルールを復元

ブート後の最初の接続時だけ update_ipset.sh をバックグラウンドで走らせる

/run/update_ipset_done で再実行を防止(再起動時に自動リセット)

実際のスクリプト

/etc/ppp/ip-up.d/99boot_update_ipset

#!/bin/bash

Run restore_japan_only.sh immediately and update_ipset.sh only once after boot

FLAG_FILE="/run/update_ipset_done"
LOGFILE="/var/log/update_ipset.log"

echo “$(date ‘+%Y-%m-%d %H:%M:%S’) [ip-up] PPPoE connected” » “$LOGFILE”

軽量な初期化スクリプト(iptables/ipsetの空構築)

echo “Running restore_japan_only.sh…” » “$LOGFILE”
bash /mnt/data/sh/restore_japan_only.sh » “$LOGFILE” 2>&1

ブート後初回のみ、ipset更新処理をバックグラウンドで実行

if [ ! -f “$FLAG_FILE” ]; then
echo “First PPPoE connection detected ? running update_ipset.sh…” » “$LOGFILE”
/mnt/data/sh/update_ipset.sh » “$LOGFILE” 2>&1 &
touch “$FLAG_FILE”
else
echo “update_ipset.sh already executed, skipping.” » “$LOGFILE”
fi

Spamhaus DROPリストを利用した ipset によるスパム対策

不眠症による早起きで、暇なんでまとめた(笑)

●はじめに

サーバをインターネットに公開していると、常に海外からの不正アクセスやスパムメールの試行が行われています。
特に SMTP (port25) はボットネットや踏み台サーバからの接続が多く、メールサーバ管理者にとって大きな負担となります。

そこで有効なのが Spamhaus の DROP/EDROP リストを活用したフィルタリングです。
このリストは「正規用途が一切ない、完全に不正利用されているネットレンジ」だけを収録しており、誤判定のリスクが極めて低いのが特徴です。

これを ipset に取り込み、iptables と組み合わせることで効率的にスパム元を遮断できます。

MTAのDB参照にて拒否することを併用しますが、LOGが汚れがちになるのでリストに登録分はあらかじめルーターやホストでDROPする内容です。

●ipset と Spamhaus DROP リスト

・iptables はルールが多くなると管理や処理が重くなる
・ipset を使うと「大量のIPレンジ」を一つの集合として扱えるため、効率的なフィルタリングが可能
・Spamhaus DROPリストは数千?数万の不正レンジを提供しており、これを ipset にまとめるのが最適

●実装手順

  1. ipset作成

sudo ipset create spamhaus_drop hash:net family inet hashsize 1024 maxelem 65536

  1. 自動取得スクリプト作成

/usr/local/bin/update_spamhaus_ipset.sh

#!/bin/bash
IPSET_NAME=“spamhaus_drop”

ipsetが存在しない場合は作成

if ! ipset list -n | grep -q “^${IPSET_NAME}$”; then
ipset create ${IPSET_NAME} hash:net family inet hashsize 1024 maxelem 65536
fi