目的
インターネットに晒されたサーバを運用している方ならご存じのとおり、特にSSHポートは常に攻撃されていることに気づきます。証明書認証やソースIPを絞ることで実質的な被害はありませんが、ログに常に攻撃の痕跡があるのは精神衛生上よくはないです。
There were 17477 failed login attempts since the last successful login.
特にIBM Cloud VPCの仮想サーバはクラシックインフラストラクチャーの仮想サーバとは違い、標準でSSL-VPN接続がないため、踏み台としてパブリックからSSHを許可するケースは多いでしょうし、作業場所のパブリックIPアドレスが固定ではないため、ソースIPで絞れないケースもあると思います。
そこで、fail2banというツールを使って、攻撃元を自動ブロックしてみます。
手順
前提
- OSはRed Hat Enterprise Linux 8を使用
EPELリポジトリの有効化
fail2banはEPELにありますのでリポジトリを有効化します。
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
fail2banのインストール
fail2banをインストールします。また、今回はバックエンドとしてjournalを使用するため、fail2ban-systemdもインストールします。
# dnf install fail2ban fail2ban-systemd
設定
fail2banの設定ファイルは/etc/fail2ban/以下にあります。個別の設定は/etc/fail2ban/jail.localや/etc/fail2ban/jail.d/で行うのが習わしです。今回はjail.localを使用します。
[DEFAULT]
ignoreip = 127.0.0.1/8 10.244.0.0/24 # ローカルのIPは無視
[sshd]
enabled = true
bantime = 30m # 30分間ブロック
maxretry = 3 # 3回の攻撃検知でブロック
[recidive] # 再犯者を長期ブロック
enabled = true
port = ssh # 長期ブロックしたいポート(複数ある場合は,区切りで指定可)
maxretry = 2 # 2回の攻撃検知で長期ブロック
個別カスタマイズではない部分はjail.confの値が使われます。
[DEFAULT]
findtime = 10m # 10分以内に攻撃検知
[recidive]
bantime = 1w # 1週間ブロック
findtime = 1d # 1日以内に攻撃検知
結果として次のようなルールになります。
- sshで10分以内に3回攻撃検知(ログイン失敗)したら30分間ブロック
- それを1日に2回検知したら1週間長期ブロック
firewalldの起動
fail2banはfirewalldを使用します。IBM Cloud VPCの仮想サーバはfirewalldが有効になっていないので開始します。
# systemctl enable firewalld
# systemctl start fiwarelld
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
fail2banの起動
# systemctl enable fail2ban
# systemctl start fail2ban
確認
起動すると早速ブロック(BAN)が開始されています。
# tail -f /var/log/fail2ban.log
2020-10-11 12:12:22,788 fail2ban.filter [7414]: INFO [sshd] Found 222.186.42.57 - 2020-10-11 12:12:17
2020-10-11 12:12:22,789 fail2ban.filter [7414]: INFO [sshd] Found 222.186.42.57 - 2020-10-11 12:12:21
2020-10-11 12:12:23,077 fail2ban.actions [7414]: NOTICE [sshd] Ban 35.192.99.43
2020-10-11 12:12:23,826 fail2ban.actions [7414]: NOTICE [sshd] Ban 122.168.195.223
2020-10-11 12:12:24,385 fail2ban.actions [7414]: NOTICE [sshd] Ban 222.186.30.112
2020-10-11 12:12:25,016 fail2ban.actions [7414]: NOTICE [sshd] Ban 222.186.42.57
2020-10-11 12:12:28,601 fail2ban.filter [7414]: INFO [sshd] Found 222.186.42.57 - 2020-10-11 12:12:28
2020-10-11 12:12:32,856 fail2ban.filter [7414]: INFO [sshd] Found 222.186.42.57 - 2020-10-11 12:12:32
2020-10-11 12:12:36,614 fail2ban.filter [7414]: INFO [sshd] Found 222.186.42.57 - 2020-10-11 12:12:36
2020-10-11 12:12:36,966 fail2ban.actions [7414]: NOTICE [sshd] 222.186.42.57 already banned
コマンドラインで現在の状況が確認できます。
# fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: recidive, sshd
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 30
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 5
|- Total banned: 5
`- Banned IP list: 35.192.99.43 122.168.195.223 222.186.30.112 222.186.42.57 198.12.249.249
# fail2ban-client status recidive
Status for the jail: recidive
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=fail2ban.service PRIORITY=5
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
実体はfirewalldのrich ruleを使ってブロックをしています。
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="35.192.99.43" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
rule family="ipv4" source address="122.168.195.223" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
rule family="ipv4" source address="222.186.30.112" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
rule family="ipv4" source address="222.186.42.57" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
rule family="ipv4" source address="198.12.249.249" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
rule family="ipv4" source address="218.92.0.249" port port="ssh" protocol="tcp" reject type="icmp-port-unreachable"
これを仕込むと、/var/log/secureのログイン失敗ログがあからさまに減りますので気持ちいいです。fail2banはかなり細かい設定やルールが他にもありますので、ガイドを参考にカスタマイズしてみてください。