前置き
サーバへの余計なトラフィックを DROP します。
/var/log/secure に sshd へ BruteForce/DoS の痕跡が記録されていて、今年に入ってその数がかなり多くなってきました。よそ様のサイトに「sshd のポートを非標準の番号へ変更して防御する」という記述が散見されますが、
手法が分散型の上に間隔が短いため、結果的に DDoS になることもあります。
「ssh サーバが IP 192.168.232.226 からの接続のためにポート 22 を開いたが、認証する前に切断された」という意味を持つ複数の記録。
Mar 10 07:26:57 MyHost sshd[710923]: Received disconnect from 192.168.232.226 port 43292:11: Bye Bye [preauth]
Mar 10 07:26:58 MyHost sshd[712577]: Received disconnect from 192.168.232.226 port 42130:11: Bye Bye [preauth]
…
普通にブルートフォースを受けています。
敵も然る者引っ掻くもの。ポートを変更したぐらいでは一時しのぎにしかなりません。
SSHGuard という優れたプログラムが公開されているので、これを利用します。
SSHGuard の動作は以下で、しつこくされればされるほど、強固に (1 → 3) ブロックします。
なお、下記 4-1 にある通り DROP するのは sshd ポートだけでなく、攻撃元 IP アドレスからの接続がすべて遮断されます。
- sshd に対して短期間に多くの認証失敗があると、接続元をブロックする。
→ そこから一定期間アクセスが無ければ、接続元のブロックを解除する。- 一定期間が終了する前に加えてアクセスがあれば、期間を延長してブロックする。
- それでもアクセスが止まなければ、接続元を永久にブロックする。
(冗談でも攻撃しないこと。メールや http/https 等も遮断されるので絶縁状態となります)
0. インストール要件
OS AlmaLinux 9.3 (Shamrock Pampas Cat) 本稿記述時の最新版 防御ソフト SSHGuard 2.4.2 firewalld 1.2.5 AlmaLinux に付属のもの ipset 7.11
1. firewalld の確認
$ LANG=C dnf info firewalld | egrep 'Name|Version|Release'
$ LANG=C dnf info ipset | egrep 'Name|Version|Release'
Name : firewalld Version : 1.2.5 Release : 2.el9_3
Name : ipset Version : 7.11 Release : 8.el9
2. EPEL のインストール
$ su
# dnf install epel-release #*1
*1が使用不能の場合はこちらを実行↓
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
# LANG=c dnf info epel-release | egrep 'Name|Version|Release'
# exit
Name : epel-release Version : 9 Release : 7.el9
$
3. SSHGuard のインストールと起動
3-1. SSHGuard をインストールする。
$ su3-2. 設定ファイルを用意する。
# dnf install sshguard
# LANG=c dnf info sshguard | egrep 'Name|Version|Release'
Name : sshguard Version : 2.4.2 Release : 7.el9
# cat /etc/sshguard.conf | grep -v '^#' | grep -v '^$'3-3. SSHGuard を起動する。
# vim /etc/sshguard.confjournalctl のオプションスイッチ
BACKEND="/usr/libexec/sshguard/sshg-fw-firewalld" LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -o cat -t sshd"
- -a : すべてのフィールドを出力する。
- -f : 最新のログを追跡して出力する。
- -b : 指定ブートからのログを出力する。(指定を省略しているので現在のブートが対象)
- -p info : SYSLOG と同じ指定レベルのログを出力する。(info を指定している)
- -n 1 : 指定行数を出力する。(1 行を指定している)
- -o cat : ログの内容だけを出力する。(タイムスタンプ等を出力しない)
- -t sshd : 絞り込む SYSLOG の ID を指定する。(sshd を指定している。-t sshd -t unix_chkpwd のように複数指定可能)
BLACKLIST_FILE=, WHITELIST_FILE= を明記する。# cat /etc/sshguard.conf | grep -v '^#' | grep -v '^$'
90: 攻撃スコアが 90 に達するとブラックリストに追加する (永久ブロック) という意味。
# Colon-separated blacklist threshold and full path to blacklist file. # Uncomment to add attackers hitting the threshold to the permanent blacklist # (default: disabled) BLACKLIST_FILE=90:/var/lib/sshguard/blacklist
# Full path to whitelist file. # Uncomment to consider IP addresses, address blocks or hostnames listed in this # file as friendlies that will never be blocked. # (default: disabled) WHITELIST_FILE=/etc/sshguard.whitelist
そうなる前に 30 分間おとなしくしていれば試行回数がリセットされる。(DETECTION_TIME=1800)
攻撃スコアは、ブロック時間に対する攻撃頻度によって増減する。
# touch /var/lib/sshguard/blacklist # このファイルに永久ブロックする IP アドレスが追記される。
BACKEND="/usr/libexec/sshguard/sshg-fw-firewalld" LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -o cat -t sshd" BLACKLIST_FILE=90:/var/lib/sshguard/blacklist WHITELIST_FILE=/etc/sshguard.whitelist
# cat /etc/sshguard.whitelist | grep -v '^#' | grep -v '^$' | wc -l
# vim /etc/sshguard.whitelist
0
自分の環境に合わせて、ブロックしない IP アドレス (または FQDN の一部)を記述する。
127.0.0.0/8 192.168.0.0/24 192.168.56.0/24 192.168.122.0/24
# systemctl start sshguard
# systemctl status sshguard | egrep 'Loaded:|Active:'
# exitenabled: インストールすると自動的に enable になる。
Loaded: loaded (/usr/lib/systemd/system/sshguard.service; enabled; preset: disabled) Active: active (running) since Wed 2024-04-10 15:44:51 JST; 3s ago
active になっていること。(起動していないと inactive になる)
$
4. 動作確認
4-1. firewalld の設定状況を確認する。
$ su4-2. ブロックリストの増加を確認する。
# firewall-cmd --list-all
ipset の登録タイミングは /usr/libexec/sshguard/sshg-fw-firewalld を参照。
public (active) target: default icmp-block-inversion: no interfaces: enp4s0f0 sources: services: cockpit ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv6" source ipset="sshguard6" drop rule family="ipv4" source ipset="sshguard4" drop
# firewall-cmd --info-ipset=sshguard4 | grep entries: | sed 's/ \+/\n/g' | tail
(IPv6 の場合は --info-ipset=sshguard6 とする)
# exit起動して少し放っておくと entries: (ブロックリスト) に IP アドレスが追加されていく。
entries: 192.168.16.117/32 192.168.1.36/32 10.2.0.39/32 192.168.224.167/32 192.168.223.124/32 10.2.1.11/32 192.168.149.150/32
(これはサンプル。実際はグローバルアドレスになる)
$
5. 間違えてブロック登録された IP アドレスの解除
5-1. firewalld の「実行時」から IP アドレスを解除。
$ su5-2. sshguard のブラックリストから IP アドレスを解除。(firewalld の「永続」に相当)
# firewall-cmd --ipset=sshguard4 --remove-entry=192.168.254.254/32
(192.168.254.254/32 は間違えて登録された IP アドレスの例)
(IPv6 の場合は --ipset=sshguard6 とする)
# systemctl stop sshguard
# vim /var/lib/sshguard/blacklist
(間違えて登録された IP アドレスを削除する)# systemctl start sshguard
# exit
$
6. おまけ
6-1. sshguard の様子を眺めることが可能。
$ tail -f /var/log/messages | grep sshguard6-2. GNOME では firewall-config からも設定を確認可能。
*2forever: 192.168.49.218, 10.2.168.209 が永久にブロックされた。
Mar 17 15:54:08 MyHost sshguard[767559]: Attack from "192.168.49.218" on service SSH with danger 10.
Mar 17 15:54:08 MyHost sshguard[767559]: Blocking "192.168.49.218/32" forever (3 attacks in 3 secs, after 3 abuses over 543 secs.) *2
Mar 17 15:54:11 MyHost sshguard[767559]: Attack from "10.2.168.209" on service SSH with danger 10.
Mar 17 15:54:13 MyHost sshguard[767559]: Attack from "10.2.168.209" on service SSH with danger 10.
Mar 17 15:54:14 MyHost sshguard[767559]: Attack from "10.2.168.209" on service SSH with danger 10.
Mar 17 15:54:14 MyHost sshguard[767559]: Blocking "10.2.168.209/32" forever (3 attacks in 3 secs, after 3 abuses over 522 secs.) *2
Mar 17 15:54:26 MyHost sshguard[767559]: Attack from "192.168.48.202" on service SSH with danger 2.
firewall-config をインストールする。
⇓
firewall-config を起動する。
⇓
firewall-config 画面
*3永久ブロックする IP アドレス (上図の「エントリー」) は SSHGuard が起動するたび firewalld の に登録されるため に登録されなくて良い。
⇔