セキュリティ · 5 min read · Jan 10, 2026

DenyHostsを使用したSSH辞書攻撃の防止

DenyHostsを使用したSSH辞書攻撃の防止

Version 1.0
Author: Falko Timme
Last edited: 02/07/2006

このHowToでは、DenyHostsのインストールと設定方法を示します。DenyHostsはSSHへのログイン試行を監視するツールで、同じIPアドレスから何度も失敗したログイン試行があった場合、そのIPアドレスを/etc/hosts.denyに追加することで、さらなるログイン試行をブロックします。DenyHostsはcronまたはデーモンとして実行できます。このチュートリアルでは、DenyHostsをデーモンとして実行します。

DenyHostsのウェブサイトから:

“DenyHostsは、sshサーバーへの攻撃を阻止するためにLinuxシステム管理者が実行することを意図したスクリプトです。

あなたがsshログ(Redhatでは/var/log/secure、Mandrakeでは/var/log/auth.logなど)を見たことがあれば、あなたのサーバーにアクセスしようとしたハッカーの数に驚くかもしれません。幸運にも、彼らの誰も成功しなかったことを願っています(しかし、どうやって知ることができるでしょうか?)。その攻撃者があなたのシステムに侵入し続けるのを自動的に防ぐ方が良いのではないでしょうか?

DenyHostsは上記の問題に対処しようとしています…”

このチュートリアルはDebian Sargeシステムに基づいていますが、ほとんど変更なしに他のディストリビューションにも適用できるはずです。

まず最初に言いたいのは、これはそのようなシステムを設定する唯一の方法ではないということです。この目標を達成する方法はたくさんありますが、これが私の取る方法です。これがあなたにとって機能するという保証はありません!

1 インストール

DenyHostsはPythonで書かれているため、最初にPythonとPython開発ファイルをインストールする必要があります:

apt-get install python python2.3-dev python2.3

次に、次のようにDenyHostsをダウンロードしてインストールします:

cd /tmp
wget http://mesh.dl.sourceforge.net/sourceforge/denyhosts/DenyHosts-2.0.tar.gz
tar xvfz DenyHosts-2.0.tar.gz
cd DenyHosts-2.0
python setup.py install

これにより、DenyHostsが/usr/share/denyhostsにインストールされます。

2 設定

次に、DenyHostsの設定ファイル/usr/share/denyhosts/denyhosts.cfgを作成する必要があります。このためにサンプル設定ファイル/usr/share/denyhosts/denyhosts.cfg-distを使用できます:

cd /usr/share/denyhosts
cp denyhosts.cfg-dist denyhosts.cfg

次に、viなどのお気に入りのエディタでdenyhosts.cfgを編集する必要があります。私の設定は次のようになります:

| ############ これらの設定は必須です ############ ######################################################################## # # SECURE_LOG: sshdのログ情報を含むログファイル # 確信がない場合は、grep "sshd:" /var/log/* # # 処理するファイルは--fileコマンドライン引数で上書きできます # # RedhatまたはFedora Core: #SECURE_LOG = /var/log/secure # # Mandrake、FreeBSDまたはOpenBSD: SECURE_LOG = /var/log/auth.log # # SuSE: #SECURE_LOG = /var/log/messages # ######################################################################## ######################################################################## # HOSTS_DENY: 制限されたホストアクセス情報を含むファイル # # ほとんどのオペレーティングシステム: HOSTS_DENY = /etc/hosts.deny # # 一部のBSD(FreeBSD)Unix: #HOSTS_DENY = /etc/hosts.allow # # 別の可能性(次のオプションも参照): #HOSTS_DENY = /etc/hosts.evil ####################################################################### ######################################################################## # PURGE_DENY: DenyHostsが--purgeフラグで呼び出されたときに、 # この時間を超えたHOSTS_DENYエントリを削除します # # フォーマットは: i[dhwmy] # 'i'は整数(例: 7) # 'm' = 分 # 'h' = 時間 # 'd' = 日 # 'w' = 週 # 'y' = 年 # # 決して削除しない: PURGE_DENY = # # 1週間以上前のエントリを削除 #PURGE_DENY = 1w # # 5日以上前のエントリを削除 #PURGE_DENY = 5d ####################################################################### ####################################################################### # BLOCK_SERVICE: HOSTS_DENYでブロックすべきサービス名 # # 詳細はman 5 hosts_accessを参照 # # 例: sshd: 127.0.0.1 # 127.0.0.1からのsshdログインをブロックします # # 問題のあるホストのすべてのサービスをブロックするには: #BLOCK_SERVICE = ALL # 問題のあるホストに対してsshdのみをブロックするには: BLOCK_SERVICE = sshd # 問題のあるホストを記録するだけで、他には何も記録しない(ホストをリストするための補助ファイルを使用している場合)。 参照: # http://denyhosts.sourceforge.net/faq.html#aux #BLOCK_SERVICE = # ####################################################################### ####################################################################### # # DENY_THRESHOLD_INVALID: 失敗したログイン試行の数がこの値を超えた場合、 # 各ホストをブロックします。この値は無効な # ユーザーログイン試行(例: 存在しないユーザーアカウント)に適用されます # DENY_THRESHOLD_INVALID = 5 # ####################################################################### ####################################################################### # # DENY_THRESHOLD_VALID: 失敗したログイン試行の数がこの値を超えた場合、 # 各ホストをブロックします。この値は有効な # ユーザーログイン試行(例: /etc/passwdに存在するユーザーアカウント)に適用されますが、 # "root"ユーザーは除外されます # DENY_THRESHOLD_VALID = 10 # ####################################################################### ####################################################################### # # DENY_THRESHOLD_ROOT: 失敗したログイン試行の数がこの値を超えた場合、 # 各ホストをブロックします。この値は # "root"ユーザーのログイン試行のみに適用されます。 # DENY_THRESHOLD_ROOT = 5 # ####################################################################### ####################################################################### # # WORK_DIR: DenyHostsがデータを書き込むために使用するパス # (存在しない場合は作成されます)。 # # 注意: この値には絶対パス名を使用することをお勧めします # (例: /home/foo/denyhosts/data) # WORK_DIR = /usr/share/denyhosts/data # ####################################################################### ####################################################################### # # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS # # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES|NO # YESに設定すると、許可されたホストからの疑わしいログイン試行が # 発生した場合、それは疑わしいと見なされます。NOの場合、 # 許可されたホストからの疑わしいログインは報告されません。 # 許可されていないIPアドレスからのすべての疑わしいログインは常に報告されます。 # SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES ###################################################################### ###################################################################### # # HOSTNAME_LOOKUP # # HOSTNAME_LOOKUP=YES|NO # YESに設定すると、Denyhostsによって報告された各IPアドレスに対して、 # 対応するホスト名が検索され、報告されます # (利用可能な場合)。 # HOSTNAME_LOOKUP=YES # ###################################################################### ###################################################################### # # LOCK_FILE # # LOCK_FILE=/path/denyhosts # このファイルがDenyHostsが実行されるときに存在する場合、 # DenyHostsはすぐに終了します。そうでない場合、このファイルは # 呼び出し時に作成され、終了時に削除されます。これにより、 # 同時に1つのインスタンスのみが実行されることが保証されます。 # # Redhat/Fedora: #LOCK_FILE = /var/lock/subsys/denyhosts # # Debian LOCK_FILE = /var/run/denyhosts.pid # # その他 #LOCK_FILE = /tmp/denyhosts.lock # ###################################################################### ############ これらの設定はオプションです ############ ####################################################################### # # ADMIN_EMAIL: 新しく制限されたホストや疑わしいログインに関するメールを受け取りたい場合、 # このアドレスをあなたのメールアドレスに設定してください。これらの報告を受け取りたくない場合、 # このフィールドを空白のままにしてください(または--noemailオプションで実行してください) # ADMIN_EMAIL = # ####################################################################### ####################################################################### # SMTP_HOST = localhost SMTP_PORT = 25 SMTP_FROM = DenyHosts SMTP_SUBJECT = DenyHosts Report #SMTP_USERNAME=foo #SMTP_PASSWORD=bar # ####################################################################### ###################################################################### # # ALLOWED_HOSTS_HOSTNAME_LOOKUP # # ALLOWED_HOSTS_HOSTNAME_LOOKUP=YES|NO # YESに設定すると、WORK_DIR/allowed-hostsファイルの各エントリに対して、 # ホスト名が検索されます。tcp_wrappersとsshdのバージョンによっては、 # ホスト名がIPアドレスに加えてログに記録されることがあります。 # このオプションを指定することをお勧めします。 # #ALLOWED_HOSTS_HOSTNAME_LOOKUP=NO # ###################################################################### ###################################################################### # # AGE_RESET_VALID: 失敗したログイン試行の間の期間を指定します。 # この期間を超えると、このホストの失敗したカウントが0にリセットされます。 # この値はすべての有効ユーザー(/etc/passwd内のユーザー)に適用されますが、 # rootは除外されます。定義されていない場合、このカウントは決して # リセットされません。 # # PURGE_DENYセクションのコメントを参照してください(上記) # この値を指定する方法の詳細については、 # http://denyhosts.sourceforge.net/faq.html#timespecを参照してください # AGE_RESET_VALID=5d # ###################################################################### ###################################################################### # # AGE_RESET_ROOT: 失敗したログイン試行の間の期間を指定します。 # この期間を超えると、このホストの失敗したカウントが0にリセットされます。 # この値は"root"ユーザーアカウントへのすべてのログイン試行に適用されます。 # 定義されていない場合、このカウントは決してリセットされません。 # # PURGE_DENYセクションのコメントを参照してください(上記) # この値を指定する方法の詳細については、 # http://denyhosts.sourceforge.net/faq.html#timespecを参照してください # AGE_RESET_ROOT=25d # ###################################################################### ###################################################################### # # AGE_RESET_INVALID: 失敗したログイン試行の間の期間を指定します。 # この期間を超えると、このホストの失敗したカウントが0にリセットされます。 # この値は無効なユーザー名(/etc/passwdに表示されないもの)へのログイン試行に適用されます。 # 定義されていない場合、カウントは決してリセットされません。 # # PURGE_DENYセクションのコメントを参照してください(上記) # この値を指定する方法の詳細については、 # http://denyhosts.sourceforge.net/faq.html#timespecを参照してください # AGE_RESET_INVALID=10d # ###################################################################### ###################################################################### # # PLUGIN_DENY: 設定されている場合、この値は # HOSTS_DENYファイルにホストが追加されたときに呼び出される実行可能プログラムを指す必要があります。 # この実行可能ファイルには、追加されるホストが唯一の引数として渡されます。 # #PLUGIN_DENY=/usr/bin/true # ###################################################################### ###################################################################### # # PLUGIN_PURGE: 設定されている場合、この値は # HOSTS_DENYファイルからホストが削除されたときに呼び出される実行可能プログラムを指す必要があります。 # この実行可能ファイルには、削除されるホストが唯一の引数として渡されます。 # #PLUGIN_PURGE=/usr/bin/true # ###################################################################### ###################################################################### # # USERDEF_FAILED_ENTRY_REGEX: 設定されている場合、この値には # 特定のssh設定に対して追加のハッカーを特定するために使用できる # 正規表現が含まれる必要があります。この機能は、DenyHostsが使用する # 組み込みの正規表現を拡張します。このパラメータは複数回指定できます。 # 詳細については、このfaqエントリを参照してください: # http://denyhosts.sf.net/faq.html#userdef_regex # #USERDEF_FAILED_ENTRY_REGEX= # # ###################################################################### ######### デーモンモードに特有の設定 ########## ####################################################################### # # DAEMON_LOG: DenyHostsがデーモンモード(--daemonフラグ)で実行されるとき、 # これはDenyHostsがその状態を報告するために使用するログファイルです。 # ロギングを無効にするには、空白のままにします。(デフォルトは: /var/log/denyhosts) # DAEMON_LOG = /var/log/denyhosts # # ロギングを無効にする: #DAEMON_LOG = # ###################################################################### ####################################################################### # # DAEMON_LOG_TIME_FORMAT: DenyHostsがデーモンモードで実行されるとき # (--daemonフラグ) これはDAEMON_LOGメッセージのタイムスタンプ形式を指定します # (デフォルトはISO8061形式: 2005-07-22 10:38:01,745) # # このパラメータの可能な値についてはman strftimeを参照してください # # Jan 1 13:05:59 #DAEMON_LOG_TIME_FORMAT = %b %d %H:%M:%S # # Jan 1 01:05:59 #DAEMON_LOG_TIME_FORMAT = %b %d %I:%M:%S # ###################################################################### ####################################################################### # # DAEMON_LOG_MESSAGE_FORMAT: DenyHostsがデーモンモードで実行されるとき # (--daemonフラグ) これは各ログエントリのメッセージ形式を指定します。 # デフォルトでは次の形式が使用されます: # # %(asctime)s - %(name)-12s: %(levelname)-8s %(message)s # # "%(asctime)s"部分は、DAEMON_LOG_TIME_FORMATで定義された形式に展開されます # # この文字列はPythonのlogging.Formatterコンストラクタに渡されます。 # 可能な形式タイプの詳細については、 # http://docs.python.org/lib/node357.htmlを参照してください # # これがデフォルトです: #DAEMON_LOG_MESSAGE_FORMAT = %(asctime)s - %(name)-12s: %(levelname)-8s %(message)s # ###################################################################### ####################################################################### # # DAEMON_SLEEP: DenyHostsがデーモンモードで実行されるとき(--daemonフラグ) # これはDenyHostsがSECURE_LOGをポーリングする間のスリープ時間です。 # PURGE_DENYセクションのコメントを参照してください(上記) # この値を指定する方法の詳細については、 # http://denyhosts.sourceforge.net/faq.html#timespecを参照してください # DAEMON_SLEEP = 30s # ####################################################################### ####################################################################### # # DAEMON_PURGE: DenyHostsがデーモンモードで実行されるとき、 # HOSTS_DENY内の古いエントリを期限切れにするために、 # どのくらいの頻度でpurgeメカニズムを実行するべきか # PURGE_DENYが空白の場合、これは影響しません。 # DAEMON_PURGE = 1h # ####################################################################### ######### これらの設定は特有の ########## ######### デーモン同期 ########## ####################################################################### # # 同期モードは、DenyHostsデーモンが # 定期的に拒否されたホストデータを送受信できるようにします。 # これにより、世界中のDenyHostsデーモンが # 自動的に互いに禁止されたホストについて通知できます。 # このモードはデフォルトで無効になっています。 # SYNC_SERVERのコメントを解除する必要があります。 # # 詳細については、 # http:/denyhosts.sourceforge.net/faq.html#syncを参照してください # ####################################################################### ####################################################################### # # SYNC_SERVER: DenyHostデーモンと通信する中央サーバー。 # 現在、denyhosts.netが唯一の利用可能なサーバーですが、 # 将来的には、組織が内部ネットワークの同期のために # 自分のサーバーをインストールすることができるかもしれません。 # # 同期を無効にするには(デフォルト)、何もしないでください。 # # 同期を有効にするには、次の行のコメントを解除する必要があります: #SYNC_SERVER = http://xmlrpc.denyhosts.net:9911 # ####################################################################### ####################################################################### # # SYNC_INTERVAL: SYNC_SERVERのコメントが解除された場合、 # 同期を実行する間隔。デフォルトは1時間です。 # #SYNC_INTERVAL = 1h # ####################################################################### ####################################################################### # # SYNC_UPLOAD: DenyHostsデーモンが # 拒否されたホストを送信することを許可しますか? # このオプションはSYNC_SERVERが # コメント解除された場合にのみ適用されます。 # #SYNC_UPLOAD = no # # デフォルト: #SYNC_UPLOAD = yes # ####################################################################### ####################################################################### # # SYNC_DOWNLOAD: DenyHostsデーモンが # 他の人によって拒否されたホストを受信することを許可しますか? # このオプションはSYNC_SERVERが # コメント解除された場合にのみ適用されます。 # #SYNC_DOWNLOAD = no # # デフォルト: #SYNC_DOWNLOAD = yes # ####################################################################### ####################################################################### # # SYNC_DOWNLOAD_THRESHOLD: SYNC_DOWNLOADが有効な場合、このパラメータは # 他の人によってブロックされたホストをフィルタリングします。 # つまり、1に設定すると、単一のDenyHostsサーバーが # IPアドレスを拒否した場合、その拒否されたホストを受け取ります。 # #SYNC_DOWNLOAD_THRESHOLD = 10 # # デフォルト: #SYNC_DOWNLOAD_THRESHOLD = 3 # ####################################################################### |

SECURE_LOGLOCK_FILEをあなたのディストリビューションに適した値に設定してください!Debianの場合、これらは:

SECURE_LOG = /var/log/auth.log
LOCK_FILE = /var/run/denyhosts.pid

DenyHostsをデーモンとして実行したいので、デーモン制御スクリプト/usr/share/denyhosts/daemon-controlが必要です。再び、サンプルスクリプト/usr/share/denyhosts/daemon-control-distを使用して必要なファイルを作成できます:

cp daemon-control-dist daemon-control

/usr/share/denyhosts/daemon-controlを編集し、DENYHOSTS_BINDENYHOSTS_LOCK、およびDENYHOSTS_CFGの正しい値を設定してください。Debianの場合、これらは:

DENYHOSTS_BIN = “/usr/bin/denyhosts.py”
DENYHOSTS_LOCK = “/var/run/denyhosts.pid”
DENYHOSTS_CFG = “/usr/share/denyhosts/denyhosts.cfg”

私の/usr/share/denyhosts/daemon-controlファイルは次のようになります:

| #!/usr/bin/env python # denyhosts DenyHostsデーモンを起動/停止します # # chkconfig: 2345 98 02 # description: ssh試行をブロックするために # DenyHostsデーモンを有効化/無効化します # ############################################### ############################################### #### 設定をあなたの構成に合わせて編集してください #### ############################################### DENYHOSTS_BIN = "/usr/bin/denyhosts.py" DENYHOSTS_LOCK = "/var/run/denyhosts.pid" DENYHOSTS_CFG = "/usr/share/denyhosts/denyhosts.cfg" ############################################### #### 以下は編集しないでください #### ############################################### import os, sys, signal, time STATE_NOT_RUNNING = -1 STATE_LOCK_EXISTS = -2 def usage(): print "Usage: %s {start [args...] | stop | restart [args...] | status | debug | condrestart [args...] }" % sys.argv[0] print print "For a list of valid 'args' refer to:" print "$ denyhosts.py --help" print sys.exit(0) def getpid(): try: fp = open(DENYHOSTS_LOCK, "r") pid = int(fp.readline().rstrip()) fp.close() except Exception, e: return STATE_NOT_RUNNING if os.access(os.path.join("/proc", str(pid)), os.F_OK): return pid else: return STATE_LOCK_EXISTS def start(*args): cmd = "%s --daemon " % DENYHOSTS_BIN if args: cmd += ' '.join(args) print "DenyHostsを起動しています: ", cmd os.system(cmd) def stop(): pid = getpid() if pid >= 0: os.kill(pid, signal.SIGTERM) print "DenyHostsにSIGTERMを送信しました" else: print "DenyHostsは実行されていません" def debug(): pid = getpid() if pid >= 0: os.kill(pid, signal.SIGUSR1) print "DenyHostsにSIGUSR1を送信しました" else: print "DenyHostsは実行されていません" def status(): pid = getpid() if pid == STATE_LOCK_EXISTS: print "%sは存在しますがDenyHostsは実行されていません" % DENYHOSTS_LOCK elif pid == STATE_NOT_RUNNING: print "Denyhostsは実行されていません" else: print "DenyHostsはpid = %dで実行中です" % pid def condrestart(*args): pid = getpid() if pid >= 0: restart(*args) def restart(*args): stop() time.sleep(1) start(*args) if __name__ == '__main__': cases = {'start': start, 'stop': stop, 'debug': debug, 'status': status, 'condrestart': condrestart, 'restart': restart} try: args = sys.argv[2:] except: args = [] try: option = sys.argv[1] if option in ('start', 'restart', 'condrestart'): if '--config' not in args and '-c' not in args: args.append("--config=%s" % DENYHOSTS_CFG) cmd = cases[option] apply(cmd, args) except: usage() |

次に、そのファイルを実行可能にする必要があります:

chown root daemon-control
chmod 700 daemon-control

その後、DenyHostsのシステム起動リンクを作成して、システムが起動したときに自動的に開始されるようにします:

cd /etc/init.d
ln -s /usr/share/denyhosts/daemon-control denyhosts
update-rc.d denyhosts defaults

最後に、DenyHostsを起動します:

/etc/init.d/denyhosts start

DenyHostsは/var/log/denyhostsにログを記録しますので、ログに興味がある場合は確認してください。SSHデーモンはDebianでは/var/log/auth.logにログを記録します。両方のログを監視し、無効なユーザーまたは有効なユーザーで不正なパスワードを使用してSSH経由でログインを試みて、何が起こるかを確認できます。無効なログイン試行の閾値を超えると、接続を試みたIPアドレスは/etc/hosts.denyにリストされるはずです。次のようになります:

| # /etc/hosts.deny: システムにアクセスできないホストのリスト。 # マニュアルページhosts_access(5)、hosts_options(5) # および/usr/doc/netbase/portmapper.txt.gzを参照 # # 例: ALL: some.host.name, .some.domain # ALL EXCEPT in.fingerd: other.host.name, .other.domain # # ポートマッパーを保護する場合は、デーモン名に"portmap"を使用してください。 # "ALL"キーワードとIPアドレス(ホスト名やドメイン名ではない)を # ポートマッパーに使用できることを忘れないでください。 # portmap(8)および/usr/doc/portmap/portmapper.txt.gzを参照してください。 # # PARANOIDワイルドカードは、名前がアドレスと一致しないホストにマッチします。 # これを有効にすると、 # 検索されたホスト名を検証しないプログラムが # 理解可能なログを残すことができます。 # 過去のDebianバージョンでは、これがデフォルトでした。 # ALL: PARANOID sshd: 192.168.0.203 |

これは、IPアドレス192.168.0.203を持つシステムが、もはやSSHを使用して接続できないことを意味します。

IPアドレスが/etc/hosts.denyから再度削除されるかどうかを指定できます - /usr/share/denyhosts/denyhosts.cfg内のPURGE_DENY変数を確認してください。PURGE_DENY変数を有効にするには、次のように–purgeオプションでDenyHostsを起動する必要があります:

/etc/init.d/denyhosts start –purge

ただし、そこからIPアドレスを手動で削除することもでき、削除されると、これらのIPアドレスは再びSSH経由でログインを試みることができます。

リンク

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。