!!!SSH パスワード認証に対する総当たり攻撃への対抗 {{category OpenSSH,nolink}}ssh のパスワード認証に対しての総当たり攻撃(ブルートフォースアタック)に対しての対応策はいくつかあるが、パスワード認証を無効に出来なかったり、攻撃側も新たな攻撃手段を用いてきます。 対抗手段として「ログインに複数回失敗したらパケットフィルタなどでアクセス禁止にする」という方法があり、そのためのツールがあります。詳しくは、[SSH パスワード認証に対する総当たり攻撃への対抗ツール|http://www.st.ryukoku.ac.jp/~kjm/security/sshbook/brute.html] を参照。 !!セキュリティ対策 総当たり攻撃以外の攻撃も含めて、リスクを軽減するセキュリティ対策。 書籍「[実用SSH 第2版 ― セキュアシェル徹底活用ガイド|http://www.oreilly.co.jp/books/4873112877/]」の [付録 G|ftp://ftp.oreilly.co.jp/4873112877/ssh_sample04.pdf](サンプルPDF) から抜粋。 *最新版へのバージョンアップ **既知の脆弱性の対策などが行われているので適に更新する。 *特権を分離 **脆弱性を付いて攻撃された場合に、乗っ取られる危険を減らせる。 *unixのパスワード認証を無効 / 強度の高いパスワードのを使用 **PasswordAuthentication を "no" にする。(パスワード認証しない) **PermitEmptyPasswords も同じく "no" にする。(空文字禁止) **パスワード作成コマンドなどで、十分な強度のパスワードを作成、使用する。 *root(スーパーユーザ)のログインを禁止 **PermitRootLogin を "no" にする。(ルートログイン不可) **必要なら "without-password" にして公開鍵を使用する。 *許可するユーザの見直し **不要なユーザの削除、ログインの不要なユーザの禁止する。 **DenyUsers, AllowUsers, DenyGroups, AllowGroups を適に設定する。 *正引き出来ないIPアドレスからの接続を拒否 **UseDNS を "yes" にする。 *TCP 22番ポート以外で動かす **攻撃ツールは、通常SSHのウェルノウンポート22番をスキャンし攻撃する。 *パケットフィルタなどを利用し接続を拒否 **攻撃してくるところは拒否する。 !!参考リンク *「実用SSH 第2版 ― セキュアシェル徹底活用ガイド」サポートページ **http://www.st.ryukoku.ac.jp/~kjm/security/sshbook/ *SSH パスワード認証に対する総当たり攻撃への対抗ツール **http://www.st.ryukoku.ac.jp/~kjm/security/sshbook/brute.html *実用SSH 第2版 ― セキュアシェル徹底活用ガイド (O'Reilly Japan の書籍紹介とサンプル) **http://www.oreilly.co.jp/books/4873112877/ **ftp://ftp.oreilly.co.jp/4873112877/ssh_sample04.pdf !!!総当たり攻撃への対抗ツールを使う ssh の brute force attack (総当たり攻撃)が五月蠅いので、総当たり攻撃への対抗ツールを使ってフィルターで弾く様にします。 選考基準は、OpenBSD で使用するので、iptables, ipfw ではなく pf でブロック出来ること。==また、inetd を使用しないので hosts.allow, hosts.deny もパス。== (sshdは、hosts.allow, hosts.deny を見てくれるみたい) Python, Ruby は入っていないので、perl もしくは、ネイティブで動くもの。 と言うことで今回は、BruteForceBlocker と言うのを使用します。 !!!BruteForceBlocker 総当たり攻撃への対抗ツールの一つ。perlスクリプトで書かれており、OpenBSD に標準装備されている pf を利用してアクセスをブロックします。Ver.1.2以降から、ブロックしたIPをプロジェクトサイトに報告、他のユーザと共有出来るようになった。 ■プロジェクトサイト *BruteForceBlocker **http://danger.rulez.sk/projects/bruteforceblocker/ !!BruteForceBlocker の取得 プロジェクトサイトからtarボールを取得し、展開します。最新版は 1.2.3 (2007/11/20 現在)です。 $ wget http://danger.rulez.sk/projects/bruteforceblocker/bruteforceblocker-1.2.3.tar.gz $ tar xzf bruteforceblocker-1.2.3.tar.gz !!BruteForceBlocker のインストール rootになってインストールします。INSTALL に書かれているパスにそれぞれファイルをコピーする。 *perlスクリプト : /usr/local/sbin/bruteforceblocker.pl *設定ファイル : /usr/local/etc/bruteforceblocker.conf *ブロックリスト : /var/db/ssh-bruteforce # cd bruteforceblocker # mkdir -p /usr/local/etc/ /usr/local/sbin/ # cp -p bruteforceblocker.conf /usr/local/etc/ # chown root:weel /usr/local/etc/bruteforceblocker.conf # cp -p bruteforceblocker.pl /usr/local/sbin/ # chown root:weel /usr/local/sbin/bruteforceblocker.pl # touch /var/db/ssh-bruteforce ■ 補足 ■ "/usr/local/etc/" ディレクトリがなかったりするので作成する。 `cp -p 〜` でタイムスタンプを維持してコピーする。そのままだと、オーナーも維持されるので "root:weel" に変える。 "/var/db/ssh-bruteforce" がないと、pf の読み込みで失敗する(失敗した気がする)のでダミーを作る。 !!必須の perl ライブラリ 必要な perl ライブラリを CPAN から取得してインストールする。まぁ、入ってたら必要ないし、足りなければ動かしてエラーが出るので、臨機応変に!? # perl -MCPAN -e shell cpan> install Sys::Syslog cpan> install Sys::Hostname cpan> install LWP::UserAgent cpan> install Net::DNS::Resolver !!BruteForceBlocker のブロック設定 ブロックリストの内容をパケットフィルタに適応されるように、pf 設定ファイル /etc/pf.conf にブロックリストの読み込みとブロック設定の記述を追加する。 # BruteForceBlocker table persist file "/var/db/ssh-bruteforce" block in log quick proto tcp from to any port ssh テーブル名の "bruteforce" とブロックリストの "/var/db/ssh-bruteforce" は設定ファイルに合わせる。 !!BruteForceBlocker の起動設定 sshd からの syslog の内容から不正ログインのユーザを拾い出すので、syslog の設定ファイルに /etc/syslog.conf にスクリプトを実行するように追加する。 # BruteForceBlocker auth.info;authpriv.info | exec /usr/local/sbin/bruteforceblocker.pl !!BruteForceBlocker の設定 BruteForceBlocker の設定ファイル /usr/local/etc/bruteforceblocker.conf を環境に合わせて修正する。まぁ、デフォルトでもそのまま動くはず。 ::email :::新たにIPをブロックした場合、メールを送信するメールアドレスを設定する。 :::メール機能を無効にする場合は、定義しないか空文字にする。 ::table :::pfに設定したブロックするIPリストのテーブル名を設定する。 ::tablefile :::pfで読み込むブロックするIPリストのファイル名を設定する。 ::max_attempts :::何回失敗したらブロックするか、許容する失敗の回数を設定する。 ::timeout :::number of seconds of inactivity needed before resetting IP counter ::report :::ブロックしたIPをプロジェクトサイトにリポートするか。 :::有効にする場合は、1 をセットする。 ::debug :::デバッグを有効にするか。有効にする場合は、1 をセットする。 ::use_remote :::ブラックリストをプロジェクトサイトから取得してpfのテーブルに追加するか。 :::有効にする場合は、1 をセットする。 ::mindays :::use only those IPs from blacklist which were reported in last x days ::mincount :::use only those IPs which were reported from at least x different source machines ::mail :::レポートメールを送るための mail のロケーションをしていする。 ::pfctl :::pf に ブロックIPの追加など制御に利用する pfctl のロケーションをしていする。 ::whitelist :::ブロックしないIPのホワイトリストを設定する。 !!使ってみて プロジェクトサイトからブロックリストが共有されるので、攻撃を一度も受けていなくてもフィルターに登録され最初から拒否される。 しかし、なぜか syslog から連携されない。パイプでスクリプトを実行しているのだが、実行されない…。なぜだ? ざっとスクリプトを見た感じ、起動時に拒否リストを取りに行くので、名前付きパイプを作成して、syslogからパイプに出力、パイプを入力元にしてスクリプトを常駐させる。っていうのが正解なのかな…。 うーむ、名前付きパイプで起動しっぱなしも失敗してる気が…。とりあえず、使う人が限られてるからポート番号変更して逃げようかな…。