ラベル SSH の投稿を表示しています。 すべての投稿を表示
ラベル SSH の投稿を表示しています。 すべての投稿を表示

2007年5月5日土曜日

SSHのbrute forceアタック対応

 自宅サーバーのログをチェックしていると、/var/log/auth.logにSSHに対してユーザを変えながら何度もアクセスしているログが大量に残っていた。どうもbrute forceアタックをされているようだ。brute forceアタックというのはユーザ、パスワードを総当りで破ろうとする力ずくの攻撃のこと。

● 主な対策方法

 SSHのbruteforceアタック対しての対策方法は主に以下があるようだった。
1.ポート番号を1024番以降(well-knownポート以外)に変える。
2.TCPWrapperやiptablesで特定のIPアドレスのみ接続を受け付ける。
3.iptablesのipt_recentを使って一定時間にアクセスがあったホストをはじく。
2は、今後自分が外からSSH経由でログインする場合は、IPアドレスを固定できないので使えない。1が、もっとも簡単なのだが、勉強がてら3の方法に挑戦してみた。

● iptables概要

iptablesの最小単位はパケットをどう扱うかというルールで、それをチェインというルールをひとまとめにしたものに追加していく。チェインは組み込み済みのもの以外にユーザが自分で定義することができる。そして、チェインはテーブルに属しており、テーブルには、用途に応じてfilter,nat,mangleという3種類がある。filterは通常のパケットの送受信に使うもので、INPUT,OUTPUT,FORWARDの組み込みチェインがある。他にNAT変換時に使うnatと、何に使うのかよくわからないがmangleというテーブルがある。今回はfilterテーブルに設定を行う。

● iptablesの設定

 以下のようにiptablesの設定を行う。

iptables -N SSHEvil
iptables -N SSH
iptables -A INPUT -j SSH -p tcp --dport 22

iptables -F SSHEvil
iptables -A SSHEvil -m recent --name badSSH --set
iptables -A SSHEvil -j LOG --log-level DEBUG --log-prefix "evil SSH user:"
iptables -A SSHEvil -j DROP

iptables -F SSH
iptables -A SSH -j ACCEPT -s 192.168.0.0/24
iptables -A SSH -p tcp ! --syn -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSHルール1
iptables -A SSH -p tcp --syn -m recent --name badSSH --update --seconds 600 -j REJECT
# SSHルール2
iptables -A SSH -p tcp --syn -m recent --name conSSH --rcheck --seconds 60 --hitcount 5 -j SSHEvil
# SSHルール3
iptables -A SSH -p tcp --syn -m recent --name conSSH --set
iptables -A SSH -p tcp --syn -j ACCEPT

 まず、filterテーブルに新規にSSHEvilとSSHというチェインを作成。3行目でINPUTチェインに対して22番ポート(SSHのポート)を受信した場合は、SSHチェインへ渡すように設定。filterテーブルには組み込みでINPUT,OUTPUT,FORWARDの3つのチェインが組み込まれている。INPUTは受信したパケットにFORWARDは他のインターフェースへ流すパケットに、OUTPUTは送信するパケットに対して適用される。

 4行目からはSSHEvliチェインに対してルールを設定する。 まず、-Fで全てのルールを削除。次にipt_recentモジュールのルール設定でbadSSHというリスト(-name)に送信元IPアドレスを記憶し(--set)、ログを出力してパケットを捨てるというルールを記述して、SSHEvliチェインは終了。 このように、SSHEvilチェインは一本道の単純なものでパケットは最終的に全て捨てられることになる。

 続いてSSHチェインのルール設定を行う。8行目で-Fで全てのルールを削除。ローカルアドレスは無条件で受信を許可する。続いてSYNフラグなし(!--syn)、TCP状態がESTABLISHEDならびにRELATED(--state)を指定することでTCPでの接続確立後のデータパケットは許可する。以降のルールは接続確立要求のパケット(--syn)を対象に設定する。送信元IPアドレスがbadSSHリストで(-name)600秒以内にアクセスがあるか(--seconds)チェックし、あった場合は受信時間を更新し(--updates)パケットを拒否する。  次のルールでは、送信元IPアドレスがconSSHリスト(-name)で60秒以内のアクセスが(--seconds)、5回以上ある(--hitcount)かチェックしあった場合は(--rcheck)SSHEvilチェインへ渡す設定をし、さらにconSSHというリスト(-name)に送信元IPアドレスを記憶し(--set)、最後にパケットを受け入れる。

● パケットフィルタの動作

SSH接続を要求してきたホストは、SSHルール3によりconSSHリストに登録された後要求を受け付ける。しかし、60秒に5回を超えてSSH接続をする場合は、その前にあるSSHルール2に該当することになりSSHEvilチェインへと移動し、badSSHリストに登録されてパケットは捨てられることになる。さらに接続しようとすると今度はSSHルール1に引っかかり、パケットは拒否されることになる。SSHルール1に引っかかった場合は、その都度時間が更新されるため、このルールから抜け出すためには600秒間アクセスを行わない必要がある。

● 問題点

 ただし、ここでいう接続はTCPレベルのものであり、SSHの接続が成功したかどうかを見ているわけではない。SSH接続が成功したとしても1回にカウントされてしまうので、正しいホストも1分間に5接続以上はできないことになる。

 また、IPアドレスで見ているため、NAT下からの複数ユーザの接続の場合は同じIPアドレスとみなされてしまうため接続できなくなる可能性がある。

とりあえず、自分の運用ではどららも問題になりそうもないので、この設定を使うことにする。

● 参考資料

iptables の ipt_recent で ssh の brute force attack 対策