サーバ機の設定などには SSH と通してコマンドラインで行っている。(Xサーバはインストールしてない)
で、最近(というかかなり前から)は SSHポートへの不正アクセスが続いている。たとえばこんな感じ。
Nov 21 03:55:25 lxsrv2 sshd[18317]: Failed password for illegal user guest from 211.221.225.3 port 56334 ssh2
Nov 21 03:55:25 lxsrv2 sshd[18317]: Received disconnect from 211.221.225.3: 11: Bye Bye
Nov 21 03:55:25 lxsrv2 sshd[18318]: input_userauth_request: illegal user admin
Nov 21 03:55:25 lxsrv2 sshd[18318]: Could not reverse map address 211.221.225.3.
Nov 21 03:55:25 lxsrv2 sshd[18318]: Failed password for illegal user admin from 211.221.225.3 port 56353 ssh2
Nov 21 03:55:25 lxsrv2 sshd[18318]: Received disconnect from 211.221.225.3: 11: Bye Bye
Nov 21 03:55:26 lxsrv2 sshd[18319]: input_userauth_request: illegal user admin
Nov 21 03:55:26 lxsrv2 sshd[18319]: Could not reverse map address 211.221.225.3.
Nov 21 03:55:26 lxsrv2 sshd[18319]: Failed password for illegal user admin from 211.221.225.3 port 56379 ssh2
Nov 21 03:55:26 lxsrv2 sshd[18319]: Received disconnect from 211.221.225.3: 11: Bye Bye
Nov 21 03:55:27 lxsrv2 sshd[18320]: input_userauth_request: illegal user user
Nov 21 03:55:27 lxsrv2 sshd[18320]: Could not reverse map address 211.221.225.3.
Nov 21 03:55:27 lxsrv2 sshd[18320]: Failed password for illegal user user from 211.221.225.3 port 56418 ssh2
Nov 21 03:55:27 lxsrv2 sshd[18320]: Received disconnect from 211.221.225.3: 11: Bye Bye
ウチのサーバは SSH認証にプレインテキストではなく、鍵方式を使っているのでクライアント側に鍵を持っていて、かつパスワードが合致しない限りログインを突破されることはない。そのため、このような攻撃を受けてもまあほぼ安心なわけだがログインしようとしている輩がいるということが気持ち悪いにはちがいない。
サンプルで挙げた 211.221.~で始まるIPアドレスは韓国からのものだ。
スパムメールにおいても中国韓国台湾からのものが多いため、IPアドレス範囲をここに決め打ちで
先日、SMTPアクセスは拒否するように設定した。これで驚くほどスパムメールが激減した。
プライベートでも仕事上でも上記の国には全く縁はないので、何ら問題は起こっていない。
ウチのサーバの場合、SSHアクセスにも同様にすればいいのは確かだが、
ここでは動的にファイやウオールすることを考えてみた。
アクセス制限するために必要なコマンドは iptables である。これを使えば通信プロトコル、発信元IPアドレス、発信先IPアドレス、発信ポート番号、目的ポート番号などを指定してアクセス制限することが可能である。また動的に一定時間の間に特定のポートへのアクセスが規定回数を越えたら接続を制限するというような使い方もできる
で以下のサイトを参考にしてスクリプトを作成してみた(^^;
○ (ひ)メモ 2005-09-20 (Tue)
http://d.hatena.ne.jp/hirose31/20050920/1127208718
○ Debian GNU/Linux 3.1(sarge)運用ノート
http://www.musicae.ath.cx/diary/?200506c&to=200506272#200506272
スクリプトはまず丸写しでやろうと思ったらエラーが出る。
なぜかというと iptables のバージョン(1.2.8)が古く recent モジュールが無いためらしい。
上記サイトでは ver1.3.3 にアップデートすればOKということだったので Red Hat用の rpm モジュールを rpmseek.com というサイトで探すのだが同じバージョンまでしか見つからない。仕方なくFedora Core用のモジュールをダウンロードして無理やりインストールしようとしたが、今度は依存関係が問題で連鎖的に他のモジュールもインストールしないとならないというエラーメッセージが出る。該当モジュールをダウンロードしてやってみようとしても、さらに依存関係に問題があったり競合が発生している。
ウチで使っているのは RedHat7.1 という古いバージョンなので iptables をアップデートするのは諦めた。
その代わり動的に iptables コマンドを発行するスクリプトを考えてみた。
参考にしたのは以下のサイト。
○ Blocking repeated failed login attempts via SSH
http://bsdwiki.com/wiki/Blocking_repeated_failed_login_attempts_via_SSH
また iptables 自体の設定を参考にしたのは以下のサイト
○ ステートフルパケットフィルタを使ったサービスの公開
http://www.atmarkit.co.jp/flinux/rensai/iptables01/iptables01a.html
ということで iptables のバージョンが 1.2.8以下(1.2.9からは recent モジュールがある)の場合の動的な SSH攻撃防御スクリプトを紹介する。
◎ まず 動的でない部分のスクリプトを実行する
赤字部分が今回の記事に関連する部分の記述です。
その他の部分の記述はそのまま書いてもダメです。あなたの環境に合わせて変更するなり追加、削除してください。
---- /root/iptables_script/iptbl.sh
#! /bin/sh
any='0.0.0.0/0'
local_all='192.168.1.0/24'
my_server='192.168.1.98'
rooter='192.168.1.3'
#Flush & Reset
iptables -F
iptables -X
#Deafult Rule
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## scan ssh attack and drop
iptables -N SCAN_SSH
iptables -I SCAN_SSH -p tcp --dport 22 -j ACCEPT
## logging ssh attack
iptables -N DROP_SSH
iptables -A DROP_SSH -j LOG --log-level warning --log-prefix "SSH ATTACK:"
iptables -A DROP_SSH -j DROP
#loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
## Accept Samba
iptables -A INPUT -i eth0 -s $local_all -d $local_all -p udp --dport 137:138 -j ACCEPT
iptables -A INPUT -i eth0 -s $local_all -d $local_all -p tcp --dport 139 -j ACCEPT
## Accept SFS access
iptables -A INPUT -i eth0 -s $local_all -d $any -p tcp --dport 8141 -j ACCEPT
## Access SWAT access
iptables -A INPUT -i eth0 -s $local_all -d $any -p tcp --dport 901 -j ACCEPT
## Allow querying DNS server
##iptables -A OUTPUT -p udp -s $my_server -d $any --dport 53 -j ACCEPT
## Allow ICMP (PING) local machines and server
iptables -A INPUT -p icmp --icmp-type echo-request -s $local_all -d $my_server -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -s $local_all -d $my_server -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -s $my_server -d $local_all -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -s $my_server -d $local_all -j ACCEPT
# Accept WWW connection
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -d $my_server --dport 80 -j ACCEPT
##iptables -A OUTPUT -p tcp -s $my_server --sport 80 -d $any -j ACCEPT
# Accept POP connection
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -d $my_server --dport 110 -j ACCEPT
##iptables -A OUTPUT -p tcp -s $my_server --sport 110 -d $any -j ACCEPT
# Accept SMTP connection
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -d $my_server --dport 25 -j ACCEPT
##iptables -A OUTPUT -p tcp -s $my_server --sport 25 -d $any -j ACCEPT
# Accept SSH connection
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $local_all -d $my_server --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -d $my_server --dport 22 -j SCAN_SSH
# Accept Proxy connection
iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $local_all -d $my_server --dport 8140 -j ACCEPT
#logging
iptables -N LOGGING
iptables -A LOGGING -j LOG --log-level warning --log-prefix "DROP:" -m limit
iptables -A LOGGING -j DROP
iptables -A INPUT -j LOGGING
#iptables -A OUTPUT -j LOGGING
◎ 次に動的部分の記述
クーロンで3分毎に起動されるように設定しています。
*/3 * * * * /root/iptables_script/scan_sshd_attack.sh
うちの場合 /var/log/secure というファイルにアクセス失敗ログが残ります。
これは /var/log/auth.log だったりもするみたいです。
でうちの設定では secure ファイルは1週間に1回ログローテーションを行っているため
このファイルには不正アクセスログがどんどん溜まります。
しかし、とりあえず直近の10分間ぐらいを不正アクセスのアクセス制限に使えばいいので
下記スクリプトの egrep -i "$MIN_1|$MIN_9" というコマンドで最近のログだけを抽出しているわけです。
---- /root/iptables_script/scan_sshd_attack.sh
#!/bin/sh
MIN_1=`date --date '1 minutes ago' | sed -f /root/sedscr/min_10.sed`
MIN_9=`date --date '9 minutes ago' | sed -f /root/sedscr/min_10.sed`
/sbin/iptables -F SCAN_SSH
/sbin/iptables -A SCAN_SSH -p tcp --dport 22 -j ACCEPT
for ips in `cat /var/log/secure | egrep -i "$MIN_1|$MIN_9" | sed "s/illegal user //" | grep sshd | grep "Failed password for" | awk '{print $11}' | sort | uniq -ud` ; do
echo $ips
/sbin/iptables -I SCAN_SSH -p tcp -s $ips --dport 22 -j DROP_SSH
done
◎ sed コマンドスクリプト
上記クーロンスクリプトで実行している sed コマンド
---- /root/sedscr/min_10.sed
s/^[^ ]* \([0-9 ]*月\|[a-zA-Z]\{3\}\) \([0-9 ]\{2\}\) \(.\{4\}\).*/\1 \2 \3/
s/11月/Nov/
s/12月/Dec/
s/1月/Jan/
s/2月/Feb/
s/3月/Mar/
s/4月/Apr/
s/5月/May/
s/6月/Jan/
s/7月/Jal/
s/8月/Aug/
s/9月/Sep/
s/10月/Oct/
とりあえず、このスクリプトで防御できてます。
最初数分はアタックされるけれども、それを検出したら10数分間は同一IPアドレスからのSSH接続を拒否します。
コメントする