SSH への総当たり攻撃(brute force attack)と防衛
Posted by yoosee on Debian at 2005-11-08 23:42 JST
1
SSHに対するブルートフォース攻撃への対策
sshd へのパスワード総当たり攻撃は今年の前半くらいから非常に増えていて、「実際に guest や test などのアカウント名を乗っ取られた」と言うケースも実はそこそこの頻度で聞いている。仕事では既に防御スクリプトを仕込んでいるサーバもあるが、無防備なサーバに実際にどれくらいの攻撃が来ているのか、ログを見てみた。
2
存在しないユーザへの攻撃
sshd へのアクセスが失敗すると、少なくとも FreeBSD や Debian では /var/log/auth.log にメッセージが残る。上が存在しないユーザ、下が存在するユーザへの総当たり攻撃ログの例これを ruby のワンライナーで名前の部分だけ切り出してみる。以下で使ったのは某所サーバの 11月分のログ。Nov 8 11:29:47 example sshd[81317]: Failed password for invalid user jiseitai from 211.93.0.248 port 59039 ssh2
Nov 8 11:29:47 example sshd[81317]: Failed password for root from 211.93.0.248 port 59039 ssh2
# grep -c invalid /var/log/auth.log
18125
# ruby -e '
names = Array.new
File.open("/var/log/auth.log").each do |line|
if /invalid user (\w+) from/ =~ line then
names.push $1
end
end
puts names.uniq.join(", ")' > list
# wc list
1 8367 687528,367種類のアカウント名で、約18,000回もアタックしてきているようだ。
3
攻撃元 IP アドレス
上記の ruby ワンライナーを少し変えて ip アドレスを抽出してみる。# ruby -e '
ips = Hash.new(0)
File.open("/var/log/auth.log").each do |line|
if /Failed password for .+ from ([0-9\.]+) port/ =~ line then
ips[$1] += 1
end
end
ips.sort{|a,b| b[1]<=>a[1]}.each do |ip, count|
puts "#{count} - #{ip}"
end'という感じで。先の攻撃は見てみると 50 IP Addresses から来てるようだ。100件越えが 17件で、うち 1,000件越えが以下の 4件whois で調べてみると、韓国、中国、米国という見事に典型的な攻撃元になっている。5,272 - 219.240.75.45 (HANANET-HIGHBAN-MANTECH, Hananet Korean - hanaro.com)
3,387 - 211.93.0.248 (UNICOM, China United Telecommunication Corp. - cnuninet.com)
3,134 - 64.251.25.85 (INFOLINK-BLK-100, Infolink Information Services Inc. - infolink.com)
2,609 - 8.3.7.89 (LVLT, Level 3 Commucations, Inc. - level3.com)
4
総当たり攻撃を防御するスクリプトや仕組み
こうした攻撃を防衛するには、例えば sshd の待ち受け port を標準の 22/tcp から変更したり、knockd を使って port を閉じたり、または ssh のパスワードによる認証を切ってしまう方法がある。しかしどれもユーザに通知なり利用形態の変更を強いるため、大勢で使っている場合には多少導入し辛い。と言うことでサーバ側で攻撃アクセスのみを拒否する仕組みがあると便利なことも多い。原理としては基本的に上記のようなログから 攻撃元の IP アドレスを抜き出して deny するものと、フロー制御的に短時間に複数回数の ssh アクセスがあった場合に deny する方法がある。
- maxlogins.pl
- FreeBSD 用となっているが hosts.allow に追加する形なので Linux あたりでも使えそう。ログに複数回の ssh login failure があると IP アドレスを deny に追加する
- sshdfilter
- これも原理は似たようなもので、libwrap の代わりに iptables を使うのが異なる点。当然 *BSD では使えないけど、ipf に書き換えればいい気もする。
- Blocking repeated failed login attempts via SSH
- これも似たようなもの。
- ipt_recent
- これは Linux iptables の ipt_recent モジュールを使って一定時間内の同一 IP アドレスからの繰り返しアクセスを拒否する仕組み。
5
SSH brute force 攻撃からサーバを守る - まとめ
最初に挙げた春山さんのものと結局たいして変わらないわけだが一応書いとく。- 特定IPアドレスのみからのアクセスを許可し、他は全拒否する
- sshd の listen port を 22/tcp から他の任意の port に変更する
- sshd.conf の Port 22 を 22 以外の任意の数字に変更
- もしくはport 22 に knockd を使う
- パスワードによる認証を禁止する (PasswordAuthentication no, ChallengeResponseAuthentication no)
- 総当たり攻撃の防御スクリプトを導入する
- ログから攻撃を検知し、libwrap や iptables, ipf 等で拒否
- iptables の機能を使って同じIP空の連続アクセスを自動拒否


http://sourceforge.jp/pro ... /2/winf2005.pdf