<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>http://www.voip-info.jp/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Makoto2</id>
	<title>VoIP-Info.jp - 利用者の投稿記録 [ja]</title>
	<link rel="self" type="application/atom+xml" href="http://www.voip-info.jp/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Makoto2"/>
	<link rel="alternate" type="text/html" href="http://www.voip-info.jp/index.php/%E7%89%B9%E5%88%A5:%E6%8A%95%E7%A8%BF%E8%A8%98%E9%8C%B2/Makoto2"/>
	<updated>2026-04-09T23:13:44Z</updated>
	<subtitle>利用者の投稿記録</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>http://www.voip-info.jp/index.php?title=SIP-Fail2ban&amp;diff=8971</id>
		<title>SIP-Fail2ban</title>
		<link rel="alternate" type="text/html" href="http://www.voip-info.jp/index.php?title=SIP-Fail2ban&amp;diff=8971"/>
		<updated>2014-10-28T09:52:14Z</updated>

		<summary type="html">&lt;p&gt;Makoto2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;IAXでのFail2banは&#039;&#039;&#039;[[IAX-Fail2ban]]&#039;&#039;&#039;を参照してください。&lt;br /&gt;
==fail2ban==&lt;br /&gt;
ログファイルとiptablesを利用したファイアウォールの一種。Brute Forceアタックの対策に使いやすい。&amp;lt;br&amp;gt;&lt;br /&gt;
:http://www.fail2ban.org/&lt;br /&gt;
:http://sourceforge.net/projects/fail2ban/&lt;br /&gt;
==動作条件==&lt;br /&gt;
pythonとiptablesが必要。yum install python iptablesなどで入れておいて下さい。&lt;br /&gt;
==インストール==&lt;br /&gt;
まずSFからfail2banをダウンロードし、展開します。&lt;br /&gt;
 tar jxvf fail2ban-0.8.4.tar.bz2&lt;br /&gt;
展開したディレクトリでインストールを実行します。&lt;br /&gt;
 cd fail2ban-0.8.4&lt;br /&gt;
 python ./setup.py install&lt;br /&gt;
スタートアップ・スクリプトをコピーしておきます(CentOSなどRedHat系の場合の例)。&lt;br /&gt;
 cp files/redhat-initd /etc/init.d/fail2ban&lt;br /&gt;
&lt;br /&gt;
==設定==&lt;br /&gt;
===Asteriskのログフォーマットを変更する===&lt;br /&gt;
Fail2banはそのままではAsteriskのログの日付を認識できないため、Asteriskのログフォーマットを変更します。&amp;lt;br&amp;gt;&lt;br /&gt;
/etc/asterisk/logger.confを編集し、日付のフォーマット変更を行います。&amp;lt;br&amp;gt;&lt;br /&gt;
[general]セクションにある&lt;br /&gt;
 dateformat=%F %T&lt;br /&gt;
のコメントを外すか、もしこのエントリがなければ記述します。設定を変更したら、Asteriskを再起動するか、loggerモジュールのリロードを行って、変更を有効にします。これによりAsteriskのログの日付形式が以下のように変わりますので、確認してください。&lt;br /&gt;
 [2010-12-30 09:25:25] NOTICE[17537] chan_sip.c:.....&lt;br /&gt;
===Asterisk用の定義ファイルを作る===&lt;br /&gt;
/etc/fail2ban/filter.d ディレクトリに asterisk.conf という名前で以下のようなファイルを作ります。ここで指定したメッセージがBAN基準として使われるメッセージとなります。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Asterisk 1.8系の場合&lt;br /&gt;
 # Fail2Ban configuration file&lt;br /&gt;
 #&lt;br /&gt;
 #&lt;br /&gt;
 # $Revision: 250 $&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 [INCLUDES]&lt;br /&gt;
 &lt;br /&gt;
 # Read common prefixes. If any customizations available -- read them from&lt;br /&gt;
 # common.local&lt;br /&gt;
 #before = common.conf&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 [Definition]&lt;br /&gt;
 &lt;br /&gt;
 #_daemon = asterisk&lt;br /&gt;
 &lt;br /&gt;
 # Option:  failregex&lt;br /&gt;
 # Notes.:  regex to match the password failures messages in the logfile. The&lt;br /&gt;
 #          host must be matched by a group named &amp;quot;host&amp;quot;. The tag &amp;quot;&amp;lt;HOST&amp;gt;&amp;quot; can&lt;br /&gt;
 #          be used for standard IP/hostname matching and is only an alias for&lt;br /&gt;
 #          (?:::f{4,6}:)?(?P&amp;lt;host&amp;gt;\S+)&lt;br /&gt;
 # Values:  TEXT&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 failregex = Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - Wrong password&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - No matching peer found&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - Username/auth name mismatch&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - Device does not match ACL&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - Peer is not supposed to register&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;(:[0-9]{1,5})?&#039; - Not a local domain&lt;br /&gt;
 &lt;br /&gt;
 # Option:  ignoreregex&lt;br /&gt;
 # Notes.:  regex to ignore. If this regex matches, the line is ignored.&lt;br /&gt;
 # Values:  TEXT&lt;br /&gt;
 #&lt;br /&gt;
 ignoreregex =&lt;br /&gt;
Asterisk 1.6とそれ以前の場合&lt;br /&gt;
 # Fail2Ban configuration file&lt;br /&gt;
 #&lt;br /&gt;
 #&lt;br /&gt;
 # $Revision: 250 $&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 [INCLUDES]&lt;br /&gt;
 &lt;br /&gt;
 # Read common prefixes. If any customizations available -- read them from&lt;br /&gt;
 # common.local&lt;br /&gt;
 #before = common.conf&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 [Definition]&lt;br /&gt;
 &lt;br /&gt;
 #_daemon = asterisk&lt;br /&gt;
 &lt;br /&gt;
 # Option:  failregex&lt;br /&gt;
 # Notes.:  regex to match the password failures messages in the logfile. The&lt;br /&gt;
 #          host must be matched by a group named &amp;quot;host&amp;quot;. The tag &amp;quot;&amp;lt;HOST&amp;gt;&amp;quot; can&lt;br /&gt;
 #          be used for standard IP/hostname matching and is only an alias for&lt;br /&gt;
 #          (?:::f{4,6}:)?(?P&amp;lt;host&amp;gt;\S+)&lt;br /&gt;
 # Values:  TEXT&lt;br /&gt;
 #&lt;br /&gt;
 &lt;br /&gt;
 failregex = Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - Wrong password&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - No matching peer found&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - Username/auth name mismatch&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - Device does not match ACL&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - Peer is not supposed to register&lt;br /&gt;
             Registration from &#039;.*&#039; failed for &#039;&amp;lt;HOST&amp;gt;&#039; - Not a local domain&lt;br /&gt;
 &lt;br /&gt;
 # Option:  ignoreregex&lt;br /&gt;
 # Notes.:  regex to ignore. If this regex matches, the line is ignored.&lt;br /&gt;
 # Values:  TEXT&lt;br /&gt;
 #&lt;br /&gt;
 ignoreregex =&lt;br /&gt;
Asterisk 1.8とそれ以前ではログのホスト部分にポート番号を含む、含まないの違いがあるためfailregexの記述を変える必要がありますので注意してください。この部分に合致するメッセージが、ログファイルに現れたならばBAN基準になりますので注意して記述します。これ意外にも、引っかけたいメッセージがある場合にはそれも記述するとよいでしょう。&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===BANのアクションを作成する===&lt;br /&gt;
ここではUDPの5060ポート、つまりSIPだけをBAN対象としたいためアクションをSIP用に作成します。 /etc/fail2ban/action.d で以下のようにしてアクションを作成します。&amp;lt;br&amp;gt;&lt;br /&gt;
まず&lt;br /&gt;
 cp iptables-allports.conf iptables-sip.conf&lt;br /&gt;
を行って、全ポート用のアクションをコピーします。次に iptables-sip.conf を編集し、以下のようにBANとUNBANのエントリを修正します。&lt;br /&gt;
 # Option:  actionban&lt;br /&gt;
 # Notes.:  command executed when banning an IP. Take care that the&lt;br /&gt;
 #          command is executed with Fail2Ban user rights.&lt;br /&gt;
 # Tags:    &amp;lt;ip&amp;gt;  IP address&lt;br /&gt;
 #          &amp;lt;failures&amp;gt;  number of failures&lt;br /&gt;
 #          &amp;lt;time&amp;gt;  unix timestamp of the ban time&lt;br /&gt;
 # Values:  CMD&lt;br /&gt;
 #&lt;br /&gt;
 actionban = iptables -I fail2ban-&amp;lt;name&amp;gt; 1 -s &amp;lt;ip&amp;gt; -p udp --dport 5060 -j DROP&lt;br /&gt;
 &lt;br /&gt;
 # Option:  actionunban&lt;br /&gt;
 # Notes.:  command executed when unbanning an IP. Take care that the&lt;br /&gt;
 #          command is executed with Fail2Ban user rights.&lt;br /&gt;
 # Tags:    &amp;lt;ip&amp;gt;  IP address&lt;br /&gt;
 #          &amp;lt;failures&amp;gt;  number of failures&lt;br /&gt;
 #          &amp;lt;time&amp;gt;  unix timestamp of the ban time&lt;br /&gt;
 # Values:  CMD&lt;br /&gt;
 #&lt;br /&gt;
 actionunban = iptables -D fail2ban-&amp;lt;name&amp;gt; -s &amp;lt;ip&amp;gt; -p udp --dport 5060 -j DROP&lt;br /&gt;
-p udp と --dport 5060 を actionban と actionunban に追記します。&lt;br /&gt;
&lt;br /&gt;
===fail2banの設定ファイルを修正===&lt;br /&gt;
/etc/fail2ban にある jail.conf ファイルの最後に以下を追加します。&lt;br /&gt;
 [asterisk-iptables]&lt;br /&gt;
 &lt;br /&gt;
 enabled  = true&lt;br /&gt;
 filter   = asterisk&lt;br /&gt;
 action   = iptables-sip[name=ASTERISK, protocol=all]&lt;br /&gt;
            sendmail-whois[name=ASTERISK, dest=root, sender=fail2ban@example.net]&lt;br /&gt;
 logpath  = /var/log/asterisk/messages&lt;br /&gt;
 maxretry = 5&lt;br /&gt;
 findtime = 600&lt;br /&gt;
 bantime = 604800&lt;br /&gt;
*action&lt;br /&gt;
BAN処理のアクションを定義します。この例ではiptables-sipを実行します。その後、sendmail-whois で BANしたIPアドレスのwhois情報を dest= で指定された宛先に送ります。このとき使用されるメールのFrom:はfail2ban@exampleになりますので、適切なものに書き換えます。&amp;lt;br&amp;gt;&lt;br /&gt;
アクションの所で iptables-allports を指定するとSIPだけでなく、すべてのポートからの接続を蹴るように iptables に設定されます。『怪しい攻撃元』をブロックするという意味では、こちらのアクションの方がより安全と言えます。&lt;br /&gt;
*logpath&lt;br /&gt;
Asteriskのログファイルへのパスを記述します。&lt;br /&gt;
*maxretry&lt;br /&gt;
何回以上失敗したらBANするかの指定です。&lt;br /&gt;
*findtime&lt;br /&gt;
この時間内にmaxretryで指定した回数以上失敗するとBANします。上の例では600秒(10分)の間に、5回以上の失敗があった場合にはBANされます。&lt;br /&gt;
*bantime&lt;br /&gt;
ここで指定された期間がBAN期間になります。指定は秒数です。上の例では 60x60x24x7=604800、つまり1週間になります。&lt;br /&gt;
&lt;br /&gt;
==fail2banを起動する==&lt;br /&gt;
 /etc/init.d/fail2ban start&lt;br /&gt;
起動したら期待の動作をするかどうかを、よく確認してください。試しに故意に間違えたパスワードで5回以上ログインをしてみるなどです。&amp;lt;br&amp;gt;&lt;br /&gt;
起動に問題がなければ、fail2banが自動起動されるように登録しておけば良いでしょう。&lt;br /&gt;
 chkconfig --add fail2ban&lt;br /&gt;
===起動の確認===&lt;br /&gt;
iptables -L -v で確認すると&lt;br /&gt;
 61638 8222K fail2ban-ASTERISK  all  --  any    any     anywhere             anywhere&lt;br /&gt;
や&lt;br /&gt;
 Chain fail2ban-ASTERISK (1 references)&lt;br /&gt;
  pkts bytes target     prot opt in     out     source               destination&lt;br /&gt;
  61627 8216K RETURN     all  --  any    any     anywhere             anywhere&lt;br /&gt;
のようなエントリがあるはずです。&amp;lt;br&amp;gt;&lt;br /&gt;
BANされるとメールが送られ&lt;br /&gt;
   11  6424 DROP       udp  --  any    any    xxx.xxx.xxx.xx      anywhere            udp dpt:5060&lt;br /&gt;
のようなDROPのエントリが追加されているはずです。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==INVITEによるBrute force攻撃への対策==&lt;br /&gt;
REGISTERメッセージによる攻撃以外に、INVITEによるBrute force攻撃も確認されています。&lt;br /&gt;
&lt;br /&gt;
この攻撃時に出力されるログメッセージは以下のようなものになります。&lt;br /&gt;
&lt;br /&gt;
 Failed to authenticate user &amp;quot;Anonymous&amp;quot; &amp;lt;sip:anonymous@192.168.1.2&amp;gt;;tag=as105e401c &lt;br /&gt;
&lt;br /&gt;
このログメッセージの攻撃元IPアドレスが、FROMヘッダに記載されているIPアドレスになっています。&lt;br /&gt;
&lt;br /&gt;
このままでは、NAT配下のサーバーからの攻撃や、FROMヘッダが偽装された場合にfail2banで対応することができません。&lt;br /&gt;
&lt;br /&gt;
そこで、Asteriskへパッチを当てて、実際の攻撃元IPアドレスを表示するように修正します。&lt;br /&gt;
&lt;br /&gt;
===Asteriskへパッチを当てる===&lt;br /&gt;
&lt;br /&gt;
次のようなパッチをAsteriskに適用します。&lt;br /&gt;
&lt;br /&gt;
このパッチはAsterisk-1.4.40を対象にしていますが、1.6系、1.8系にも同様の修正で対応できます。&lt;br /&gt;
&lt;br /&gt;
 --- asterisk-1.4.40.orig/channels/chan_sip.c    2011-01-05 02:11:48.000000000 +0900&lt;br /&gt;
 +++ asterisk-1.4.40/channels/chan_sip.c 2011-03-10 17:59:26.000000000 +0900&lt;br /&gt;
 @@ -15456,7 +15456,7 @@&lt;br /&gt;
                                 ast_log(LOG_NOTICE, &amp;quot;Sending fake auth rejection for user %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
                                 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);&lt;br /&gt;
                         } else {&lt;br /&gt;
 -                               ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate user %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
 +                               ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate user %s (%s:%d)\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;), ast_inet_ntoa(sin-&amp;gt;sin_addr), ntohs(sin-&amp;gt;sin_port));&lt;br /&gt;
                                 transmit_response_reliable(p, &amp;quot;403 Forbidden&amp;quot;, req);&lt;br /&gt;
                         }&lt;br /&gt;
                         p-&amp;gt;invitestate = INV_COMPLETED;&lt;br /&gt;
 &lt;br /&gt;
こちらは Asterisk-1.8.23.0 用です。Asterisk-11.5.1 でもほぼ同じコードが使えます。&lt;br /&gt;
&lt;br /&gt;
 --- asterisk-1.8.23.0/channels/chan_sip.c.orig  2013-08-02 11:41:03.233638321 +0900&lt;br /&gt;
 +++ asterisk-1.8.23.0/channels/chan_sip.c       2013-12-06 14:51:08.698990909 +0900&lt;br /&gt;
 @@ -22673,7 +22673,7 @@&lt;br /&gt;
                         return 0;&lt;br /&gt;
                 }&lt;br /&gt;
                 if (res &amp;lt; 0) { /* Something failed in authentication */&lt;br /&gt;
 -                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
 +                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s (%s)\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;), ast_sockaddr_stringify(addr));&lt;br /&gt;
                         transmit_response(p, &amp;quot;403 Forbidden&amp;quot;, req);&lt;br /&gt;
                         sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);&lt;br /&gt;
                         return 0;&lt;br /&gt;
 @@ -23334,7 +23334,7 @@&lt;br /&gt;
                         goto request_invite_cleanup;&lt;br /&gt;
                 }&lt;br /&gt;
                 if (res &amp;lt; 0) { /* Something failed in authentication */&lt;br /&gt;
 -                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
 +                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s (%s)\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;), ast_sockaddr_stringify(addr));&lt;br /&gt;
                         transmit_response_reliable(p, &amp;quot;403 Forbidden&amp;quot;, req);&lt;br /&gt;
                         p-&amp;gt;invitestate = INV_COMPLETED;&lt;br /&gt;
                         sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);&lt;br /&gt;
 @@ -25164,7 +25164,7 @@&lt;br /&gt;
                 p-&amp;gt;lastinvite = seqno;&lt;br /&gt;
                 return 0;&lt;br /&gt;
         } else if (auth_result &amp;lt; 0) {&lt;br /&gt;
 -               ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
 +               ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s (%s)\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;), ast_sockaddr_stringify(addr));&lt;br /&gt;
                 transmit_response(p, &amp;quot;403 Forbidden&amp;quot;, req);&lt;br /&gt;
                 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);&lt;br /&gt;
                 ast_string_field_set(p, theirtag, NULL);&lt;br /&gt;
 @@ -25384,7 +25384,7 @@&lt;br /&gt;
                 if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */&lt;br /&gt;
                         return 0;&lt;br /&gt;
                 if (res != AUTH_SUCCESSFUL) {&lt;br /&gt;
 -                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;));&lt;br /&gt;
 +                       ast_log(LOG_NOTICE, &amp;quot;Failed to authenticate device %s (%s)\n&amp;quot;, get_header(req, &amp;quot;From&amp;quot;), ast_sockaddr_stringify(addr));&lt;br /&gt;
                         transmit_response(p, &amp;quot;403 Forbidden&amp;quot;, req);&lt;br /&gt;
 &lt;br /&gt;
                         pvt_set_needdestroy(p, &amp;quot;authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
パッチを当てて、Asteriskをコンパイルし直し、再起動します。&lt;br /&gt;
&lt;br /&gt;
すると、先ほどの攻撃時のログは以下のように出力されるようになります。&lt;br /&gt;
&lt;br /&gt;
 Failed to authenticate user &amp;quot;Anonymous&amp;quot; &amp;lt;sip:anonymous@192.168.1.2&amp;gt;;tag=as105e401c (123.45.67.89:5060)&lt;br /&gt;
&lt;br /&gt;
ログの(　)内に攻撃元の実IPアドレスが表示されるようになり、これを元にfail2banで攻撃を検知することができます。&lt;br /&gt;
&lt;br /&gt;
===fail2banへ設定を追加===&lt;br /&gt;
&lt;br /&gt;
修正したログに合わせたフィルタ設定をfail2banに追加します。&lt;br /&gt;
&lt;br /&gt;
/etc/fail2ban/filter.d/asterisk.conf の failregex の項目に以下を追加します。&lt;br /&gt;
&lt;br /&gt;
 NOTICE.* .*: Failed to authenticate user .* \(&amp;lt;HOST&amp;gt;:.*\)&lt;br /&gt;
&lt;br /&gt;
フィルタ追加後、fail2banを再起動し設定完了です。&lt;br /&gt;
&lt;br /&gt;
[[Category:セキュリティ]]&lt;/div&gt;</summary>
		<author><name>Makoto2</name></author>
	</entry>
</feed>