AlmaLinux 9/10 ネットワークセキュリティ設定手順書
(nftables ネイティブ移行済み・Deprecated警告回避版)
1. 前提条件の整理
従来の iptables や firewall-cmd --direct、および古い ipset コマンドは一切使用しません。すべて Firewalld の標準機能と Fail2ban の nftables アクションで完結させます。
2. Fail2ban の設定 (nftables 連携)
① グローバル設定の作成
/etc/fail2ban/jail.d/00-firewalld.local を作成し、デフォルトのアクションを nftables に指定します。これで古い ipset ドライバーが呼ばれなくなります。
ini
[DEFAULT]
# 許可する管理用IP(自分の環境に合わせて追記)
ignoreip = 127.0.0.1/8 192.168.0.0/16 10.0.0.0/8
# 古い firewallcmd-ipset は絶対に使わない
banaction = nftables-multiport
banaction_allports = nftables-allports
コードは注意してご使用ください。
② 各 Jail の有効化
各サービス(postfix, dovecot等)の .local ファイルを作成します。
※ banaction は 00-firewalld.local で指定済みのため、各ファイルには書かなくてOKです。
例:/etc/fail2ban/jail.d/postfix.local
ini
[postfix-postscreen]
enabled = true
port = smtp
filter = postfix-postscreen
logpath = /var/log/maillog
maxretry = 3
bantime = 1w
コードは注意してご使用ください。
3. 日本国内IP制限 (jpnip) の設定
① Firewalld 内に ipset (器) を作成
OSインストール直後に一度だけ実行します。
bash
firewall-cmd --permanent --new-ipset=jpnip --type=hash:net
コードは注意してご使用ください。
② 許可リスト (localip) の作成
/root/iptables/localip を作成し、常に許可したいプライベートIPなどを記述します。
text
10.0.0.0/8
192.168.0.0/16
コードは注意してご使用ください。
③ 自動更新スクリプト (jpip_setup.sh) の作成
/root/iptables/jpip_setup.sh として保存し、実行権限を与えます。
bash
#!/bin/bash
JPIP_FILE='/root/iptables/jpip'
LOCALIP_FILE='/root/iptables/localip'
APNIC_FILE='/root/iptables/delegated-apnic-latest'
# 最新リストの取得
curl -s -o $APNIC_FILE http://ftp.apnic.net
:> $JPIP_FILE
# 日本IPの抽出ループ
for ip in `cat $APNIC_FILE | grep "apnic|JP|ipv4|"`
do
IPADDR=`echo $ip | awk -F"|" '{ print $4 }'`
TMPCIDR=`echo $ip | awk -F"|" '{ print $5 }'`
FLTCIDR=32
while [ $TMPCIDR -ne 1 ]; do
TMPCIDR=$((TMPCIDR/2))
FLTCIDR=$((FLTCIDR-1))
done
echo "$IPADDR/$FLTCIDR" >> $JPIP_FILE
done
# ローカルIPの合流
if [ -f "$LOCALIP_FILE" ]; then
cat "$LOCALIP_FILE" >> "$JPIP_FILE"
fi
# Firewalldへの一括登録と反映
firewall-cmd --permanent --ipset=jpnip --set-entries-from-file="$JPIP_FILE"
firewall-cmd --reload
コードは注意してご使用ください。
4. 防御ルールの適用 (リッチルール)
Firewalld の推奨形式でルールを追加します。--direct は絶対に使用しません。
bash
# 1. 日本国内IP (jpnip) からの特定ポート接続を許可
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source ipset="jpnip" port port="465,587,143,993" protocol="tcp" accept'
# 2. それ以外の国からの上記ポート接続を拒否
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="465,587,143,993" protocol="tcp" drop'
firewall-cmd --reload
コードは注意してご使用ください。
5. 動作確認コマンド集
再インストール後に以下のコマンドで正常性を確認します。
警告の原因 (Direct Rule) が空か確認:
firewall-cmd --direct --get-all-rules → 何も出なければOK。
Fail2ban が nftables で動いているか確認:
nft list table inet f2b-table → elements にIPがあればOK(BANされるまでテーブルは作られません)。
日本IPセットの中身確認:
firewall-cmd --ipset=jpnip --get-entries | tail → 最後にローカルIPがあればOK。
1. 確認用スクリプトの作成
/root/iptables/check_security.sh として保存してください。
bash
#!/bin/bash
echo "=================================================="
echo " AlmaLinux 9/10 Security Config Check Script"
echo "=================================================="
# 1. 古い Direct ルールの確認 (空であるべき)
echo -n "[1/4] Checking Old Direct Rules (Should be empty)... "
DIRECT_COUNT=$(firewall-cmd --direct --get-all-rules | wc -l)
if [ "$DIRECT_COUNT" -eq 0 ]; then
echo "OK (Clean)"
else
echo "WARNING!"
firewall-cmd --direct --get-all-rules
fi
# 2. nftables (Fail2ban) の動作確認
echo -n "[2/4] Checking nftables (Fail2ban) Table... "
NFT_TABLE=$(nft list tables | grep "f2b-table")
if [ -n "$NFT_TABLE" ]; then
BAN_COUNT=$(nft list table inet f2b-table | grep "elements =" | wc -l)
echo "OK ($NFT_TABLE detected, Active Jails: $BAN_COUNT)"
else
echo "IDLE (No active bans yet, table not created)"
fi
# 3. jpnip セットの状態確認
echo -n "[3/4] Checking jpnip ipset (Firewalld Native)... "
JPNIP_COUNT=$(firewall-cmd --ipset=jpnip --get-entries | wc -l)
if [ "$JPNIP_COUNT" -gt 4000 ]; then
echo "OK (Total entries: $JPNIP_COUNT)"
else
echo "ERROR! (Entries too low: $JPNIP_COUNT)"
fi
# 4. ローカルIPが含まれているか確認
echo -n "[4/4] Checking Local IP in jpnip set... "
LOCAL_CHECK=$(firewall-cmd --ipset=jpnip --get-entries | grep -E "192.168.0.0/16|10.0.0.0/8")
if [ -z "$LOCAL_CHECK" ]; then
echo "MISSING! (Local IPs not found in jpnip)"
else
echo "OK (Found)"
fi
echo "--------------------------------------------------"
echo "Fail2ban Jail Status:"
fail2ban-client status | grep "Jail list"
echo "=================================================="
コードは注意してご使用ください。
2. 実行権限の付与と使用方法
bash
# 実行権限を付与
chmod +x /root/iptables/check_security.sh
# 実行
/root/iptables/check_security.sh
コードは注意してご使用ください。
このスクリプトでわかること
[1/4]: ここに何か表示されたら、また警告ログが出る状態に戻っています。
[2/4]: f2b-table があれば、Fail2ban が正しく nftables を操作しています。
[3/4]: 日本のIPリストが正しく読み込まれているか(4000件以上あれば正常)がわかります。
[4/4]: 自分が許可したローカルIPが消えていないか確認できます。
手動でたまにこれを叩くだけで、「今、警告なしで正しく守られているか」がひと目で分かります。
[root@home jail.d]# more /etc/fail2ban/jail.d/00-firewalld.local
# This file is part of the fail2ban-firewalld package to configure the use of
# the firewalld actions as the default actions. You can remove this package
# (along with the empty fail2ban meta-package) if you do not use firewalld
[DEFAULT]
ignoreip = 127.0.0.1/8 10.0.0.0/8 192.168.0.0/24
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/00-firewalld.conf
# This file is part of the fail2ban-firewalld package to configure the use of
# the firewalld actions as the default actions. You can remove this package
# (along with the empty fail2ban meta-package) if you do not use firewalld
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/16
banaction = firewallcmd-rich-rules[actiontype=<multiport>]
banaction_allports = firewallcmd-rich-rules[actiontype=<allports>]
[root@home jail.d]# more /etc/fail2ban/jail.d/apache-wplogin.local
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24
[apache-wplogin]
enabled = true
port = http,https
bantime = 1w
findtime = 1d
maxretry = 5
logpath = %(apache_access_log)s
blocktype = DROP
#banaction = firewallcmd-ipset
#banaction = iptables-ipset-proto6-allports
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/dovecot.local
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24
[dovecot]
enabled = true
maxretry = 3
findtime = 1d
bantime = 1w
blocktype = DROP
#banaction = firewallcmd-ipset
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/named-refused.local
[named-refused]
enabled = true
port = domain,953
protocol = tcp
filter = named-refused
logpath = /var/log/messages
banaction = nftables-multiport
bantime = 1h
[root@home jail.d]# more /etc/fail2ban/jail.d/postfix.local
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24
[postfix]
enabled = true
maxretry = 3
findtime = 1d
bantime = 1w
blocktype = DROP
#banaction = firewallcmd-ipset
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/postfix-postscreen.local
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24
[postfix-postscreen]
enabled = true
port = smtp
filter = postfix-postscreen
logpath = /var/log/maillog
maxretry = 1
findtime = 1d
bantime = 1w
ignoreip = 127.0.0.1/8 192.168.0.0/24 218.45.21.106/32 218.45.22.246/32
blocktype = DROP
#banaction = firewallcmd-ipset
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/postfix-sasl.local
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24
[postfix-sasl]
enabled = true
port = smtp
filter = postfix-sasl
logpath = /var/log/maillog
maxretry = 3
findtime = 1d
bantime = 1w
blocktype = DROP
#banaction = firewallcmd-ipset
banaction = nftables-multiport
banaction_allports = nftables-allports
[root@home jail.d]# more /etc/fail2ban/jail.d/recidive.local
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
maxretry = 2
findtime = 30d
bantime = -1
#banaction = firewallcmd-ipset
banaction = nftables-multiport
banaction_allports = nftables-allports