kubota-dit
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    [HACK#59 ARPスプーフィングの検出](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack59-arp%E3%82%B9%E3%83%97%E3%83%BC%E3%83%95%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E6%A4%9C%E5%87%BA) [HACK#60 スタティックARPテーブルの活用](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack60-%E3%82%B9%E3%82%BF%E3%83%86%E3%82%A3%E3%83%83%E3%82%AFarp%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E6%B4%BB%E7%94%A8) [HACK#61 SSHでの総当たり攻撃からサーバを守る](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack61-ssh%E3%81%A7%E3%81%AE%E7%B7%8F%E5%BD%93%E3%81%9F%E3%82%8A%E6%94%BB%E6%92%83%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E5%AE%88%E3%82%8B) [HACK#62 ネットワークの状況把握](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack62-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E7%8A%B6%E6%B3%81%E6%8A%8A%E6%8F%A1) [HACK#63 脆弱性のスキャン](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack63-%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3) [HACK#64 時刻同期の確保](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack64-%E6%99%82%E5%88%BB%E5%90%8C%E6%9C%9F%E3%81%AE%E7%A2%BA%E4%BF%9D) [HACK#68 ネットワーク盗聴の検知](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack68-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E7%9B%97%E8%81%B4%E3%81%AE%E6%A4%9C%E7%9F%A5) [HACK#69 攻撃者を追跡する](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack69-%E6%94%BB%E6%92%83%E8%80%85%E3%82%92%E8%BF%BD%E8%B7%A1%E3%81%99%E3%82%8B) [HACK#70 Unixサーバでウイルススキャン](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack70-unix%E3%82%B5%E3%83%BC%E3%83%90%E3%81%A7%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3) [HACK#71 最新の脆弱性情報を追跡する](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack71-%E6%9C%80%E6%96%B0%E3%81%AE%E8%84%86%E5%BC%B1%E6%80%A7%E6%83%85%E5%A0%B1%E3%82%92%E8%BF%BD%E8%B7%A1%E3%81%99%E3%82%8B) # HACK#59 ARPスプーフィングの検出 ## 概要 - Arpwatchを用いてMAC/IPアドレスペアが変わるなどの異常な振る舞いを検知する ### ARPとは - IPアドレスからイーサネットのMACアドレスの情報を得られるプロトコル LAN上のコンピュータ間で通信を行うためにはMACアドレスが必要<br> → ARPは既知のIPアドレスもとにMACアドレスを問い合わせ(ARPリクエスト)、該当コンピュータからMACアドレスを受け取る(ARPリプライ)<br> → IPアドレスとMACアドレスのペアはARPテーブルに記録され、これをもとに通信を行う ### ARPスプーフィングとは ARPリクエストとAPRリプライはその対応を考慮して処理されていない<br> → 偽のARPリプライも受け取ってしまう<br> → 悪意あるユーザーから大量にARPリプライが送られてくると、常に偽のMACアドレスがARPテーブルに記録されてしまう → 正規のコンピュータと通信ができない ## 実践 Arpwatchは、プロミスキャスモードでネットワークを一定期間監視してMAC/IPアドレスペアを記録することで、記録したペアと差異が出た場合にsyslogにアラートを出す ※プロミスキャスモード:ネットワークカード(NIC)の動作モードの1つで、同一ネットワーク内を流れるすべてのパケットを受信して読み込む 下記でArpwatchをインストールしてMAC/IPアドレスペアを監視する方法を解説する ### 確認方法 1. まず、Arpwatchをインストールします <pre> # yum -y install arpwatch </pre> 2. インストールが完了したら、arpwatchを起動します <pre> # /etc/init.d/arpwatch start [自動起動したい場合] # chkconfig arpwatch on </pre> 以上によりLAN上を飛び交うARPパケットの情報を収集することができます では、下記コマンドを実行してArpwatchのログを見てみましょう 実行結果にある「new station」がマシンを検知した時のログです <pre> # grep arpwatch /var/log/messages (RedHat系の場合) Feb 16 21:22:01 dojo yum[3296]: Installed: 14:arpwatch-2.1a15-16.el6.x86_64 Feb 16 21:23:17 dojo arpwatch: listening on eth0 Feb 16 21:23:23 dojo arpwatch: new station 192.168.1.125 8:0:27:e8:b8:e7 Feb 16 21:23:23 dojo arpwatch: new station 192.168.1.1 0:1e:31:75:32:6 Feb 16 21:31:52 dojo arpwatch: new station 192.168.1.63 bc:ee:7b:77:5f:1d Feb 16 21:32:29 dojo arpwatch: new station 192.168.1.30 bc:ee:7b:77:66:f3 Feb 16 21:33:47 dojo arpwatch: new station 192.168.1.115 bc:ee:7b:77:5f:51 </pre> また、「new station」が検知された場合は、下記の内容のメールが届くので、「mail」コマンドで閲覧できます <pre> # mail From: arpwatch To: root Subject: new station (ホスト名) I/F名 hostname: ホスト名 ip address: IPアドレス interface: I/F名 ethernet address: MACアドレス ethernet vendor: ↑のベンダー名 timestamp: 日時 </pre> この情報を元にARPスプーフィングが行われていないかを確認します # HACK#60 スタティックARPテーブルの活用 ## 概要 - 前HACKでは、ARPスプーフィングを検出する方法を紹介したが、このHACKでは事前にMACアドレスが登録されているARPテーブル(スタティックARPテーブル)を用いてARPテーブルの汚染を防ぐ - スタティックARPテーブルを用いることで、偽のMACアドレスになっている可能性が大幅に低くなる ## 実践 ARPテーブルにMACアドレスを手動で登録するには、下記コマンドを実行する <pre> # arp -s IPアドレス MACアドレス </pre> スタティックARPテーブルにより十分なセキュリティを確保するためには、LAN上のすべてのデバイスのMACアドレスをARPテーブルに登録しておく必要があるが、上記コマンドでは非常に手間がかかる そこで、下記に同一ネットワーク上のデバイスのMACアドレスを一括登録する方法を示す ### 確認方法 1. まず、同一ネットワーク上のデバイスのMACアドレスを一括登録するシェルスクリプトを作成します<br> ※テキストではperlスクリプトを用いていますが、その理解のためにはperlの理解も必要となるので、ここではシェルスクリプトを用います <pre> [s_arp.sh] #!/bin/bash nmap -sP $1 | tee host-list.txt loopCount=$(grep -c 'MAC Address:' host- list.txt) TEXT=$(grep 'Nmap scan report for' host-list.txt | cut -d ' ' -f 5) ipList=( `echo $TEXT | tr -s ',' '\n'`) TEXT=$(grep 'MAC Address:' host-list.txt | cut -d ' ' -f 3) macList=( `echo $TEXT | tr -s ',' '\n'`) rm -f arpList touch arpList for i in `seq ${loopCount}` do num=`expr $i - 1` echo "${ipList[$num]} ${macList[$num]}" >> arpList done arp -f arpList </pre> 2. 作成したシェルスクリプトを下記のように実行します <pre> # ./s_arp.sh 192.168.1.0/24 </pre> すると、「192.168.1.0/24」のネットワーク下のデバイス全てをARPテーブルに登録できます 最後にARPテーブルの中身を確認し、登録が行われていたら成功です <pre> # arp Address HWtype HWaddress Flags Mask Iface 192.168.11.8 (incomplete) eth0 buffalo.setup ether 74:03:bd:f9:c4:fb CM eth0 192.168.11.128 (incomplete) eth0 192.168.11.10 ether 2c:d0:5a:a7:74:54 CM eth0 192.168.11.2 ether 38:71:de:c9:b0:87 CM eth0 </pre> # HACK#61 SSHでの総当たり攻撃からサーバを守る ## 概要 - SSHでパスワード認証を行っている場合に、適切な対策を行って総当たり攻撃を防止する - SSHのポート変更 - パスワード認証から鍵認証に変更する - SSHDに対するファイアウォールのルールを設定する<br> ※総当たり攻撃:考えられるすべてのパスワードパターンをリストアップして片っ端から検証する攻撃 - 十分強度を持ったパスワードを設定していれば問題ないが、総当たり攻撃によってさらに危険な攻撃が発生してしまうかもしれない<br> → そのために総当たり攻撃を防止する対策をとる ## 実践 SSHのポート変更は、標準の22番ポートではなく別のポートでリスンさせる それにより、総当たり攻撃によりログに記録される大量のログインエラーを削減でき、重要な攻撃ログの見落としを防止できる しかし、ポートスキャンなどの手法で変更後のポートを暴かれてしまう可能性もある パスワード認証から鍵認証に変更すると、秘密鍵がなければSSH接続できなくなるので、不正なログインの防止に役立つ SSHDに対するファイアウォールのルールを設定すると、鍵認証への変更より柔軟にログインユーザーを制限できる ### 確認方法 #### SSHのポート変更 /etc/ssh/sshd_configを下記のように変更して再起動します <pre> # vi /etc/ssh/sshd_config [sshd_config] Port 22000(22000番ポートに変更) # /etc/init.d/sshd restart </pre> では、ポートが変更されているか確認しましょう <pre> # netstat -luntp : tcp 0 0 0.0.0.0:22000 0.0.0.0:* LISTEN 4843/sshd : tcp 0 0 :::22000 :::* LISTEN 4843/sshd : </pre> 続いてSSH接続ができるかどうか確認しましょう <pre> # ssh localhost (接続失敗) # ssh -p 22000 localhost (接続成功) ※ポート番号を指定しないと接続できなくなります </pre> #### パスワード認証から鍵認証に変更する まず、下記コマンドで公開鍵と秘密鍵を生成しましょう <pre> # ssh-keygen -t rsa [rsa]は暗号方式 Generating public/private rsa key pair. Enter file in which to save the key (/home/dojo/.ssh/id_rsa): (←空Enter[鍵の保存場所]) Enter passphrase (empty for no passphrase): (←パスフレーズを入力) Enter same passphrase again: (←もう一度パスフレーズを入力) Your identification has been saved in /home/dojo/.ssh/id_rsa. Your public key has been saved in /home/dojo/.ssh/id_rsa.pub. The key fingerprint is: 8c:af:3c:25:c4:55:ea:ee:05:4e:00:b1:36:fb:ce:16 dojo@dojo.local The key's randomart image is: +--[ RSA 2048]----+ | o. .. | | o .. | | +.... | | . oo= | | ... S | | .E=.. | | .++ . | | +oo . | | .=.. | +-----------------+ </pre> 次に下記コマンドで「~/.ssh」の配下の公開鍵「id_rsa.pub」の内容を「authorized_keys」に追記しましょう これにより、毎回パスフレーズを入力する必要がなくなります <pre> # cat ~/.ssh/id_rsa.pub >> authorized_keys </pre> 次に下記コマンドで「.ssh」と「authorized_keys」のパーミッションを所有者のみ読み書きできるようにします ここでパーミッションを適切に設定していないと鍵認証に失敗します <pre> # chmod 700 ~/.ssh # chmod 600 ~/.ssh/authorized_keys </pre> 上記コマンドを実行しても鍵認証に失敗する場合は下記コマンドも実行してホームディレクトリのパーミッションを変更しましょう <pre> # chmod 755 ~ </pre> 最後に、パスワード認証を無効にして、sshサーバを再起動しましょう <pre> # vi /etc/ssh/sshd_config [sshd_config] PasswordAuthentication no # service sshd restart </pre> では、sshでログインしてみましょう 下記のようにパスワードを求められなかったら鍵認証の成功です <pre> root@localhost's password: </pre> #### SSHDに対するファイアウォールのルールを設定する <b>sshdの接続元を制限する</b> 1. まず、下記コマンドで192.168.1.XXX から192.168.1.YYY へsshの応答があることを確認しましょう <pre> # ssh 192.168.1.YYY </pre> 2. 次に、下記コマンドで192.168.1.XXXからのsshのパケットを破棄するルールを設定しましょう <pre> # iptables -A INPUT -p tcp --dport 22 -s 192.168.1.XXX -j DROP </pre> 3. 最後に、下記コマンドで192.168.1.XXX から192.168.1.YYY へsshの応答がないことを確認しましょう <pre> # ssh 192.168.1.YYY </pre> <b>ログを解析してIPを制限する</b> これを実現するにはスクリプトを書かなければ難しいと判断しました。 実際にスクリプトを作ってみたので、下記にアクセスし、3つのスクリプトを入手してください。 [auto-block-by-ipaddress-start.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-start.sh) [auto-block-by-ipaddress-init.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-init.sh) [auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh) 動作方法としては上記3つのスクリプトを同じディレクトリにコピーし、[auto-block-by-ipaddress-start.sh]を実行します。 動きとしては以下のようになります。 1. スクリプトを実行するとログファイルを[inotify]で監視を開始する 1. ssh接続のパスワード認証で失敗した時のログを拾い、ファイルに書き出す 1. 書き出したファイルを調べ、同じIPアドレスが一定以上検出された場合は、iptablesにそのIPアドレスからのsshの接続を破棄するルールを追加する 上記の方法で[ログを解析してIPを制限する]仕組みを実現しました。 ではそれぞれスクリプトの内容を見て行きましょう。 まず起動スクリプト\[[auto-block-by-ipaddress-start.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-start.sh)\]です。 ``` #!/bin/bash -eu trap "exit 0" 3 # QUITシグナルで停止 WATCH_DIR="/var/log/" # 監視するディレクトリ FILE_PATTERN="secure" # ファイル名正規表現 COMMAND="./auto-block-by-ipaddress-exe.sh" # ファイル更新時に実行するコマンド # 初期化処理を行う ./auto-block-by-ipaddress-init.sh # メッセージの出力 echo " inotifywaitによる監視を開始します" # --formatで"ディレクトリ ファイル名 イベント"の形式で出力するように指定 inotifywait -e MODIFY -m -r ${WATCH_DIR} --format "%w %f %e" | \ while read LINE; do # --format指定した通りに変数に格納 declare -a eventData=(${LINE}) dirPath=${eventData[0]} fileName=${eventData[1]} # ファイル名パターンマッチング (マッチしなかったら無視) [[ $fileName =~ ${FILE_PATTERN} ]] || continue # (DEBUG)イベントがあったファイルを表示 echo "${dirPath}${fileName}" # コマンドの実行 ${COMMAND} done ``` 流れとしては以下のようになります。 1. 必要な変数の宣言、初期化 1. 初期化処理を行うスクリプト\[[auto-block-by-ipaddress-init.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-init.sh)\]の実行 1. [inotifywait]コマンドを実行し[/var/log/secure]ファイルを監視する 1. [/var/log/secure]に変更が行われる度に、\[[auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh)\]を実行する これにより、認証関連のログを出力する[/var/log/secure]にログが書き込まれる度に、ログ解析を行う\[[auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh)\]が実行されるようになります。 では\[[auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh)\]を見て行く前に初期化処理を行うスクリプト\[[auto-block-by-ipaddress-init.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-init.sh)\]を見て行きましょう。 ``` #!/bin/bash # メッセージの表示 echo "初期化処理を開始します..." # 失敗の限度回数 FAILED_LIMIT=2 # 接続拒否を設定する[hosts.deny]の絶対パス HOSTS_DENY_PATH="/etc/hosts.deny" # ログに記載されている接続に失敗したIPを記載するファイルのパス FailedLogIpPath="FailedLogIP" # ログに記載されている接続に失敗したIPを記載するファイルのパス FailedIpListPath="FailedIPList" # 接続を拒否しているIPが記載されているファイルのパス RejectIpListPath="RejectIPList" # 新しく書き込まれたログを洗い出すための差分ファイルを作成 cat /var/log/secure > PreSecureLog # 各ファイルの初期化 rm -f ${FailedLogIpPath} && touch ${FailedLogIpPath} rm -f ${FailedIpListPath} && touch ${FailedIpListPath} rm -f ${RejectIpListPath} && touch ${RejectIpListPath} # 以下の内容は日付による制限ができてから実装する ######################################################################################################### ## これまでに接続に失敗したことがある接続元IPの一覧を[FailedLogIP]ファイルに書き出す #cat /var/log/secure | grep ".*sshd.*Failed.*" | rev | cut -d' ' -f4 | rev | sort > ${FailedLogIpPath} #chmod 600 ${FailedLogIpPath} # ## これまでに接続に失敗したことがある接続元IPの一覧を[FailedIPList]ファイルに書き出す #cat ${FailedLogIpPath} | uniq > ${FailedIpListPath} #chmod 600 ${FailedIpListPath} # ## これまでに接続に失敗したことがある接続元IPの一覧を配列[srcIpList]に格納する #srcIpList=($(cat ${FailedIpListPath} | tr -s ',' '\n')) # ## for文で使用するループ回数 #ipListCount=$(grep -c "" ${FailedIpListPath}) # ## ssh接続の接続に失敗した回数によって、接続元IPアドレスからのsshを拒否する #for i in $(seq ${ipListCount}) #do # num=$(expr $i - 1) # FailedCount=$(grep -c "${srcIpList[$num]}" ./FailedLogIP) # if [ $FailedCount -gt $FAILED_LIMIT ]; then # addRule="sshd : ${srcIpList[$num]}" # echo ${addRule} # if [ -n "$(grep "${addRule}" ${HOSTS_DENY_PATH})" ]; then # echo "\"${addRule}\" already exists in hosts.deny" # else # echo ${addRule} >> ${HOSTS_DENY_PATH} # fi # echo "${srcIpList[$num]}" >> ${RejectIpListPath} # fi #done ######################################################################################################### # メッセージの表示 echo "初期化処理完了" ``` このスクリプトは基本的にファイルの初期化を行っています。スクリプトを実行するとファイルが作られるのですが、そのファイルに過去のデータが残っていては不整合が発生するので、このスクリプトで初期化を行っています。 そして、大量のコメントアウトされている行があるのですが、これは現在書き出されているログを解析し、IPを制限するスクリプトです。 ただし、このスクリプトは日付による制限や解除されることを全く想定していないので、永遠に接続ができなくなってしまうので、実用性に欠けています。 そのため、日付による制限、あるいは別の手段を用いる方法が実装されるまでは使用しません。あくまで参考程度です。 では、最後にログ解析を行うスクリプト\[[auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh)\]を見て行きましょう ``` #!/bin/bash # 失敗の限度回数 FAILED_LIMIT=2 # 監視ファイル WATCH_DIR="/var/log/secure" # ログに記載されている接続に失敗したIPを記載するファイルのパス FailedLogIpPath="FailedLogIP" # ログに記載されている接続に失敗したIPを記載するファイルのパス FailedIpListPath="FailedIPList" # 接続を拒否しているIPが記載されているファイルのパス RejectIpListPath="RejectIPList" # 新しく書き込まれたログを洗い出すための差分ファイルのパス PreSecureLogPath="PreSecureLog" # 検索するルールを確立 rule="^DROP.*${FailedIp}.*tcp dpt:ssh" # 新規に書き込まれたログの取得 diff ${PreSecureLogPath} ${WATCH_DIR} > temp # 差分ファイルを更新 cat ${WATCH_DIR} > ${PreSecureLogPath} # DEBUG cat temp # ssh接続失敗のログの場合、IPアドレスの抽出する FailedSshLog=$(grep ".*sshd.*Failed.*" temp) #echo ${FailedSshLog} # 変数[FailedSshLog]が空文字ではない場合 if [ -n "${FailedSshLog}" ]; then # 出力されたログの中で、IPアドレスだけを抽出する FailedIp=$(echo ${FailedSshLog} | rev | cut -d' ' -f4 | rev) # 抽出されたログが既に拒否設定を行っている場合、その旨を表示する if [ -n "$(grep "${FailedIp}" ${RejectIpListPath})" ]; then echo "FailedIp[${FailedIp}] already reject" # そうでない場合 else # 抽出したアドレスをファイルに追記し、その旨を表示する echo ${FailedIp} >> ${FailedLogIpPath} echo "\"${FailedIp}\" add FailedLogIp" # もし、ファイルに抽出したIPアドレスが既定値をこえていた場合、 # そのIPアドレスからの接続を遮断する設定を行う if [ $(grep -c "${FailedIp}" ${FailedLogIpPath}) -gt ${FAILED_LIMIT} ]; then # 現在のiptablesの設定を出力 iptables -L > CurrentIptablesRule # iptablesに接続元を遮断するルールが追加されている場合、その旨を表示する if [ -n "$(grep "${rule}" CurrentIptablesRule)" ]; then echo "\"${rule}\" already exists in iptables" # そうでない場合、iptablesに追加する else iptables -I INPUT -s ${FailedIp} -p tcp --dport ssh -j DROP fi echo "${FailedIp}" >> ${RejectIpListPath} echo "\"${FailedIp}\" add RejectIpList" fi fi fi ``` 流れとしては以下のようになります。 1. 必要な変数の宣言、初期化 1. 以前のログファイル(初期化処理で作成)と新規ログファイルの差分を出し、新規に書き込まれたログだけを抽出し、差分用ログファイルを更新 1. 抽出したログを[grep]コマンドで「sshのログイン認証に失敗したログ」を検索する 1. 検索した結果、ログが存在していた場合のみIPアドレスのみを抽出する。そうでない場合は処理を終了する。 1. 抽出したIPアドレスが既に拒否設定を行っていた場合、その旨を表示する<b>(異常)</b>。そうでない場合、そのIPアドレスをファイルに記録する。 1. そのIPアドレスで記録したファイルを検索し、規定値以上記録されていた場合、iptablesに「そのIPアドレスからのsshを拒否する」ルールを追加する処理を行う。そうでない場合は処理を終了する 1. iptablesにそのルールを追加する際、既に同意義のルールが存在していた場合、その旨を表示し、追加を行わない。<b>(異常)</b>。 1. 拒否設定を行ったIPアドレスをメモしたファイルに追加する これにより、認証に失敗しすぎた送信元IPアドレスをiptablesで拒否するルールが自動で追加されるようになります。 では、実際に確認してみましょう。わかりやすくするために、スクリプトをフォルダにまとめましょう。 ``` # mkdir auto-block-by-ipaddress # cd auto-block-by-ipaddress # cp {3つのスクリプト} ./ # ./auto-block-by-ipaddress-start.sh 初期化処理を開始します... 初期化処理完了 inotifywaitによる監視を開始します Setting up watches. Beware: since -r was given, this may take a while! Watches established. ``` ``` 別の端末 or 新しいタブ # ssh 192.168.1.XXX root@192.168.1.32's password: (← 空Enter以外の不正なパスワード) Permission denied, please try again. root@192.168.1.32's password: (← 不正なパスワード) Permission denied, please try again. root@192.168.1.32's password: (← 不正なパスワード) Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). ``` ``` 初期化処理を開始します... 初期化処理完了 inotifywaitによる監視を開始します Setting up watches. Beware: since -r was given, this may take a while! Watches established. /var/log/secure 775a776 > Mar 16 10:21:23 localhost sshd[3135]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.32 user=root /var/log/secure 776a777 > Mar 16 10:21:25 localhost sshd[3135]: Failed password for root from 192.168.1.32 port 38072 ssh2 "192.168.1.32" add FailedLogIp /var/log/secure 777a778 > Mar 16 10:21:28 localhost sshd[3135]: Failed password for root from 192.168.1.32 port 38072 ssh2 "192.168.1.32" add FailedLogIp /var/log/secure 778a779 > Mar 16 10:21:32 localhost sshd[3135]: Failed password for root from 192.168.1.32 port 38072 ssh2 "192.168.1.32" add FailedLogIp "192.168.1.32" add RejectIpList /var/log/secure 779a780,781 > Mar 16 10:21:32 localhost sshd[3136]: Connection closed by 192.168.1.32 > Mar 16 10:21:32 localhost sshd[3135]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.32 user=root /var/log/secure ``` ``` 別の端末 or 新しいタブ # ssh 192.168.1.XXX (← 応答がなくなっている) ``` このように、応答がなくなっていれば、成功しています。 監視をしていた端末に「"192.168.1.32" add RejectIpList」が出力されていると思います。このメッセージが出力されると、iptablesにルールを追加されたということになります。 ちなみにsshする時に、最初に[空Enter以外]という記載していますが、[空Enter]を一番最初に入力すると、認証に失敗したという扱いになりません。これはおそらく、Enterを連打しすぎて誤ってパスワードを入力したことを防ぐためにこのような仕様になっていると思われます。(余談ですが、このような事を防ぐ設計のことをフールプルーフといいます) では実際にiptablesを確認してみましょう。 ``` 779a780,781 > Mar 16 10:21:32 localhost sshd[3136]: Connection closed by 192.168.1.32 > Mar 16 10:21:32 localhost sshd[3135]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.32 user=root /var/log/secure ^C # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 192.168.1.32 anywhere tcp dpt:ssh ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination ``` [DROP tcp -- 192.168.1.32 anywhere tcp dpt:ssh ]が先頭に追加されているのがわかります。 これで、接続元IPアドレスの制限ができていることが証明されました。 しかし、このスクリプトにはいくつか考慮しなければならない点があります。 1つ目は本にも記載されている「例外的にブロックしないリスト(ホワイトリスト)」の導入です。 信頼できる接続元IPにもかかわらず、そのIPが誤ってパスワードを間違えてしまった場合、接続ができなくなってしまいます。 それを防ぐためにもホワイトリストの導入は必要ですが、現在、このスクリプトは接続拒否のルールを先頭に追加するようになっています。つまり、必ず一番最初にチェックされるようになっているため、ホワイトリストとして導入したiptablesのルールが無視されてします。 そのため、スクリプト\[[auto-block-by-ipaddress-exe.sh](https://github.com/careerbeat/dit-ehime/blob/kubota-branch/NetworkSecurityHacksFolder/HACK%2361/auto-block-by-ipaddress-exe.sh)\]のiptablesにルールを追加する部分を適切に修正しなけばなりません。 下記のように記述することで、ルールを追加する場所を指定することができます。 ``` iptables -I {番号} INPUT -s ${FailedIp} -p tcp --dport ssh -j DROP ``` オプション[-I]だけですと、先頭に追加するという意味になってしまいます。その後に追加したい場所を数字で指定することで、任意の場所に追加することができます。 ホワイトリストのルールより後に追加されるように番号を指定することで、ホワイトリストとブラックリストの導入を適切に行うことができるようになります。 そしてもうひとつ考慮しなければならないのはサービス化とアクセス権限です。現在、このスクリプトはフォアグラウンドで実行されるようになっているため、その間そのコンピュータは操作を行うことができません。そのため、バックグラウンドで実行されるようにサービス化を行わなければなりません。 そこにつきまとうリスクがアクセス権限の設定です。適切に行わなければ、悪意あるユーザーがファイルの改ざんを行い、不整合が発生する可能性があります。 このスクリプトを実運用にはまだまだ考慮しなければならない点が多いので、改善、参考にしながらよりよいサービスにできるように改善していきましょう。 <b>単位時間のSYNパケットを制限する</b> 今回は二通りのやり方があったので、その二つを紹介する ### 方法1 一つは[ipt_recent]モジュールを用いた制御法である。 ### 参考URL - http://qiita.com/shimohiko/items/17f837c5ed0a050ca48d #### ipt_recentとは? > - 指定した条件にマッチしたパケットの source IP アドレスを、リストに記 録する > - 「パケットの source IP アドレスがリスト中に存在したら」という条件を 使えるようにする > - IP アドレスを記録するリストはいくつでも作れるので「このプロトコ ルならこのリスト」等の処理が可能 > - また、リストにはパケットの source IP アドレスに加えてタイムスタ ンプも記録されるので、「直近 n 秒の間に記録があったら」や「n 回 以上記録があったら」といった条件も指定できます。 (http://www2s.biglobe.ne.jp/~nuts/labo/inti/ipt_recent.html) この機能を利用して「単位時間のSYNパケットを制限する」を実現します。 まず、sshのフィルタリングルールがわかりやすくなるように「ssh(port: 22)」パケットを処理する専用のチェイン「SSH」とssh接続を拒否する用のチェイン「SSHATACK」を作りましょう。 ``` # iptables -N SSH # iptables -N SSHATTACK ``` そして、宛先ポートがssh(22)のSYNパケットを「SSH」チェインに飛ぶように「INPUT」チェインにルールを追加します。 ``` # iptables -A INPUT -p tcp --dport ssh -m state --state NEW -j SSH ``` ではさっそくこの「SSH」チェインにルールを追加してきます。ちなみに[ipt_recent]モジュールは[-m recent]で利用することができます。 ``` # iptables -A SSH -m recent --name sshbadcon --rcheck --seconds 600 -j REJECT # iptables -A SSH -m recent --name sshcon --rcheck --seconds 60 --hitcount 3 -j SSHATTACK # iptables -A SSH -m recent --name sshcon --set # iptables -A SSH -j ACCEPT ``` 色々ざっと追加しましたが、一つ一つ解説していきます。 まず、一番上に追加したルールですが、これは接続拒否リスト「sshbadcon」の中身をチェックし、直近600秒以内で該当する送信元IPが記録されていたら「REJECT」するというルールです。 ``` # iptables -A SSH -m recent --name sshbadcon --rcheck --seconds 600 -j REJECT ``` 次に、二番目に追加したルールですが、これは接続履歴リスト「sshcon」の中身をチェックし、直近60秒以内で該当するIPが3回記録されていたら「SSHATACK」チェインに飛ばします。 「SSHATACK」チェインで接続拒否リスト「sshbadcon」に記録させる処理を行います。 ``` # iptables -A SSH -m recent --name sshcon --rcheck --seconds 60 --hitcount 3 -j SSHATTACK ``` そして、三番目と四番目のルールですが、これは上記のルールに該当しなかった正常な通信ということで、接続履歴リスト「sshcon」に送信元IPを記録して、アクセスを許可します。 ``` # iptables -A SSH -m recent --name sshcon --set # iptables -A SSH -j ACCEPT ``` この4つのルールにより、「60秒以内に3回ssh接続を試みた送信元IPを[SSHATACK]チェインに飛ばす」、というルールが実現しました。 あとは「SSHATACK」チェインのルールを設定するだけです。 ``` # iptables -A SSHATTACK -m recent --name sshbadcon --set # iptables -A SSHATTACK -j REJECT ``` このルールにより「SSHATACK」チェインに来たパケットの送信元IPを接続拒否リスト「sshbadcon」に登録します。その後、その接続を拒否します。 これで「単位時間のSYNパケットを制限する」という内容を実現できました。 iptablesの設定を確認してみます。 ``` # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination SSH tcp -- anywhere anywhere tcp dpt:ssh state NEW Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain SSH (1 references) target prot opt source destination REJECT all -- anywhere anywhere recent: CHECK seconds: 600 name: sshbadcon side: source reject-with icmp-port-unreachable SSHATTACK all -- anywhere anywhere recent: CHECK seconds: 60 hit_count: 3 name: sshcon side: source all -- anywhere anywhere recent: SET name: sshcon side: source ACCEPT all -- anywhere anywhere Chain SSHATTACK (1 references) target prot opt source destination all -- anywhere anywhere recent: SET name: sshbadcon side: source REJECT all -- anywhere anywhere reject-with icmp-port-unreachable ``` 設定できているので、あとはきちんと動作するか確認してみましょう。 ``` # ssh {設定を行った端末のIPアドレス} [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 ssh: connect to host 192.168.1.32 port 22: Connection refused ``` このように、60秒以内に3回ssh接続をすると、それ以降の通信がREJECTされるようになりました。 もし上手くいかない場合はiptablesの順番を疑ってみてください。iptablesは上から順に処理していくので、正しい順番で追加しないと想定通りの動作をしてくれません。 これで「ipt_recent」による「単位時間のSYNパケットを制限」は完了です。 ではもう一つの方法について説明します。 ### 方法2 もう一つは[hashlimit]モジュールを用いた制御法である。 ### 参考URL - http://qiita.com/homihomu/items/778770a1c1b3b2371fe0 - http://blog.atgw.jp/archives/1959 ### hashlimitとは? > hashlimit制御イメージはこのような感じです > - 通信を行うクライアントは「送信元IPアドレス」と「宛先ポート」でまとめられて対象グループとなります。まとめ方は「--hashlimit-mode srcip,dstport」で指定しています > - 対象グループごとにチケットが割り当てられます。チケットを持っていると対象グループは通信を行うことができます。通信を行うごとにチケットを消費します。 > - 初期状態では30枚のチケットを持っています。その枚数は 「--hashlimit-burst 30」で指定しています > - チケットは1分ごとに1枚追加されます。追加のペースは「--hashlimit 1/m」で指定しています > - チケットは最大で30枚持つことができます。あふれたチケットは削除されます。最大数は「--hashlimit-burst 30」で指定しています(初期枚数と同じ) >(備考:チケット,対象グループなどの言葉は説明の為に付けたもので、一般的な名称ではありません) (http://qiita.com/homihomu/items/778770a1c1b3b2371fe0) つまり、「特定の通信」をするための「権利」を設け、その権利が供給される速度を制限することで、頻繁に通信ができなくなるという仕組みです。 今度はこれを利用して「単位時間のSYNパケットを制限する」を実現します。 まず、方法1と同じようにわかりやすくするためにhashlimit専用のチェイン「HASHCHECK」を作ります。 ``` # iptables -N HASHCHECK ``` そして、これも方法1と同じように宛先ポートがssh(22)のSYNパケットを「HASHCHECK」チェインに飛ぶようにします。 ``` # iptables -A INPUT -p tcp --dport ssh -m state --state NEW -j HASHCHECK ``` それができたら「HASHCHECK」チェインにルールを追加しましょう。 ``` # iptables -A HASHCHECK -m hashlimit --hashlimit-name ssh_limit --hashlimit 2/m --hashlimit-burst 3 --hashlimit-mode srcip --hashlimit-htable-expire 120000 -j ACCEPT ``` 少しルールが長いですが、それぞれのオプションには以下の意味があります。 ``` --hashlimit-name ssh_limit ・・・ハッシュテーブル名を「ssh_limit」とする --hashlimit 2/m ・・・時間あたりの接続数を「2/分」に設定 --hashlimit-burst 3 ・・・バースト値(上記--hashlimit値を無視して接続できる数)を「3」に設定 --hashlimit-mode srcip ・・・制限対象を「送信元IPアドレス」で識別する --hashlimit-htable-expire 120000 ・・・最後のパケットから120000ミリ秒(120秒=2分)でリセットする ``` これにより、最初の接続は3回まで無制限で許可されるが、それ以降は1分間に2回の制限が掛るようになります。 最後のパケットから2分たった場合、リセットされるようになります。 あとは、このルールで許可されなかったパケットをREJECTするだけです。 ``` # iptables -A HASHCHECK -j REJECT ``` これで「単位時間のSYNパケットを制限する」という内容を実現できました。 iptablesの設定を確認してみます。 ``` # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination HASHCHECK tcp -- anywhere anywhere tcp dpt:ssh state NEW Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain HASHCHECK (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere limit: up to 2/min burst 3 mode srcip htable-expire 120000 REJECT all -- anywhere anywhere reject-with icmp-port-unreachable Chain SSH (0 references) target prot opt source destination Chain SSHATTACK (0 references) target prot opt source destination ``` ではきちんと動作するか確認してみましょう。 ``` # ssh {設定を行った端末のIP} [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied, please try again. root@192.168.1.32's password: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). [root@localhost ~]# ssh 192.168.1.32 ssh: connect to host 192.168.1.32 port 22: Connection refused (3回接続を行ったので制限が掛かった) [root@localhost ~]# ssh 192.168.1.32 ssh: connect to host 192.168.1.32 port 22: Connection refused [root@localhost ~]# ssh 192.168.1.32 root@192.168.1.32's password: (30秒経過したので、チケットが追加された) ``` このように接続を3回行ったあと、30秒毎にしか接続できないようになっていればOKです。 これで「hashlimit」による「単位時間のSYNパケットを制限」は完了です。 ### [ipt_recent]と[hashlimit]の比較 単位時間のSYNパケットを制限する方法として2つ紹介しましたが、どちらを使うのが良いのでしょうか。 以下は私の見解です。 - より<b>強い効果</b>を求めるなら[ipt_recent] - より<b>柔軟な制限</b>を求めるなら[hashlimit] #### より強い効果を求めるなら[ipt_recent]の理由 [ipt_recent]は単位時間辺りに既定値を超えた接続があると、一定時間その送信元IPからの接続を遮断します。 対して[hashlimit]は単位時間当たりに既定値を超えた接続があると、一定時間、連続で接続できる回数を制限します。 つまり、[ipt_recent]は悪意がある攻撃が判明した場合、接続を拒否しますが、[hashlimit]は悪意がある攻撃が判明した場合、接続できる回数を制限するだけです。 よって、接続そのものを遮断できる[ipt_recent]のほうがより強力な制限を掛ける事が可能となるのです。 [hashlimit]でも同じような事はできそうですが、「単位時間当たりに既定値を超えた接続」の時間と「一定時間、連続で接続できる回数を制限」の時間をそれぞれ別々に設定することができません。 そのため、時間を短くすると直ぐに攻撃が再開できるようになり、時間を長くすると一般のユーザーまで「悪意がある攻撃」と判断されかねないリスクが発生します。 このような不都合が発生するのであれば[ipt_recent]を使った方が良いでしょう。 #### より柔軟な制限を求めるなら[hashlimit]の理由 [ipt_recent]は送信元IPによる判断しかできませんが、[hashlimit]はそれに加え以下を組み合わせることができます。 - 送信元ポート: srcport - 宛先IP : dstip - 宛先ポート : dstport 送信元だけでIPではなく、宛先IPも組み合わせることで接続先サーバー毎に制限を設けることが可能になります。 このような場合は[hashlimit]を使った方が良いでしょう。 しかし、これはあくまで私個人の見解なので、本来はもっと様々な特徴があるかもしれません。 そのため、あくまで参考程度でお願いします。 余談ではありますが、sshで接続を行う際に標準では3回までのパスワード入力の機会が与えられていますが、以下の設定でチャレンジ回数を制限することができる。 ``` # vim /etc/ssh/sshd_config #PermitRootLogin yes #StrictModes yes MaxAuthTries 1 ----チャレンジ回数を1回に設定 #MaxSessions 10 ``` # HACK#62 ネットワークの状況把握 ## 概要 - Nmapでポートスキャンを行い、ネットワーク上のデバイスサービスを把握する - Nmapは不正アクセスのための偵察ツールと認識されていることが多いが、ネットワーク管理には必要なツールである ## 実践 ### ポートスキャンの仕組み TCPの場合は、スリーウェイハンドシェイク(3ステップ)の機能を利用する ステップ1:対象のサーバにSYNフラグを立てたパケット(SYNパケット)を送信<br> ※SYNパケット:TCPで接続を確立する際に、クライアントからサーバに送られるパケット ステップ2:対象サーバーで該当のポート番号がオープン(サービスが起動)であれば、対象サーバーは「SYN+ACKパケット」を 返信<br> ※ACKパケット:接続を許可するパケット ステップ3:対象サーバーにACKパケットを送信 UDPの場合は、UDPパケットを該当サーバーに送信した時に、 何も返信がなければサービスが起動していると判断する サービスが停止していてポートがクローズしていると、「ICMP port unreachable」のメッセージが返信される ### 確認方法 #### TCPコネクトスキャンを行う - 下記コマンドでTCPのコネクトスキャンを行います <pre> $ nmap {ホスト名 or IPアドレス} </pre> - また、以下のようにIPアドレスの範囲やネットワークも指定できます <pre> $ nmap 192.168.1.1-254 $ nmap 192.168.1.0/24 </pre> - 実行するとポートとその状態、サービスが分かります - root権限で実行するとより詳細な結果が得られます ### TCPハーフスキャンを行う - スリーウェイハンドシェイクをステップ2で終わらせます - コンピュータのログに記録されません <pre> $ nmap -sS 192.168.1.XXX </pre> - -Oオプションをつけると、OSの種別判定もできます ### スキャン結果をXMLフォーマットで出力する - 下記の形式のオプションをつけるとスキャン結果をXMLフォーマットで出力できます <pre> -oX XMLファイル名 </pre> <pre> $ nmap -sS -O -oX scandata.xml 192.168.1.XXX </pre> - 出力したxmlはperlを用いることでデータベース化もできる # HACK#63 脆弱性のスキャン ## 概要 - Nessusを用いて、ネットワーク上のコンピュータがの各サービスが、不正アクセスを受ける可能性のあるセキュリティホールを調査する - サービスが正常に稼働していれば問題ないと判断するのは不十分である(不正アクセスを受けたときに不具合が発生する可能性がある) ## 実践 Nessusはサービスが動作するポートを探り当て、実際のそれらに接続して既知の攻撃コード(エクスプロイトコード)で攻撃を試みる ※エクスプロイトコード:ソフトウェアの保安上の弱点(脆弱性、セキュリティホール)を利用して不正な動作が起きる様子を再現するプログラム そして、エクスプロイトコードの有効・無効を記録しながらすべてのサービスを検査する 下記でNessusを用いたセキュリティホールの調査方法について解説する ### 確認方法 ここでは、最新バージョンのNessus 6.Xを用います #### Nessusのインストール及び初期設定 1. まず、```http://www.tenable.com/products/nessus/select-your-operating-system```からRPMパッケージ「Nessus-6.10.4-es6.x86_64.rpm」をダウンロードしましょう ![63-1](https://cloud.githubusercontent.com/assets/25141356/24533859/38e5a74a-1605-11e7-95dd-162c796c5d33.png) ![63-2](https://cloud.githubusercontent.com/assets/25141356/24533872/55c90f82-1605-11e7-85c7-0df6baa25e57.png) 2. 下記コマンドを実行して「Nessus-6.10.4-es6.x86_64.rpm」をインストールしましょう <pre> # cd ダウンロード # rpm -ivh Nessus-6.10.4-es6.x86_64.rpm </pre> 3. ```https://www.tenable.com/products/nessus-home``` にアクセスして、無償ライセンス用のアクティベーションコードを取得しましょう ※アクティベーションコード:正規のライセンスの保持確認のために行われる認証処理に必要なコード ① 「Register for an Activation Code」の下部にEmailアドレスなどの必要事項を入力します ② 「I agree to the terms of service」にチェックを入れます ③ 「Register」ボタンをクリックします ![64-4](https://cloud.githubusercontent.com/assets/25141356/24534380/a1f02cc6-1608-11e7-9157-fb1ec8ae4e4e.png) ④ 入力したEmailアドレスにアクティベーションコードが届きます ![65-5](https://cloud.githubusercontent.com/assets/25141356/24534490/527b77a8-1609-11e7-9952-18bcf3d3d8b1.png) こちらのコードは1回しか使用できないため、取扱いには注意してください。 4. 下記コマンドを実行してNessusサービスを起動しましょう <pre> # service nessusd start </pre> 5. ```https://localhost:8834/``` にアクセスして初期設定を行いましょう <pre> [ポイント] ・「Initial Account Setup」では管理画面へのログイン用アカウントを作成します ・「Product Registration」では取得したアクティベーションコードを入力します </pre> #### Nessusを用いた脆弱性のスキャン 1. ```https://localhost:8834/``` にアクセスして管理画面にログインします 以下のような画面が出てきた場合は、「エラー内容」を押下して、「例外を追加...」を押下すると「セキュリティ例外の追加」ダイアログが表示されます。 ![63-5](https://cloud.githubusercontent.com/assets/25141356/24537221/b1a9c3a8-161b-11e7-8dbb-f6f05f3a63cf.png) ダイアログ表示後は、「セキュリティ例外を承認」を押下することでNessusのユーザ登録画面に遷移します。 ![63-6](https://cloud.githubusercontent.com/assets/25141356/24537252/ea486138-161b-11e7-89cb-d8ca6c6bf447.png) 画面表示後は以下のように、ユーザの作成とアクティベーションコードの入力を行ってください。 ![63-7](https://cloud.githubusercontent.com/assets/25141356/24537288/12a7637c-161c-11e7-9cc1-3007c1d9ac8d.png) 作成するユーザ名とパスワードは任意で構いません。 今回はユーザ名を"root"、パスワードを"vagrant"としています。 ![63-8](https://cloud.githubusercontent.com/assets/25141356/24537296/249097fc-161c-11e7-9253-736877f0f6b1.png) Emailアドレスに届いたアクティベーションコードを入力してください。 ![63-9](https://cloud.githubusercontent.com/assets/25141356/24537317/412f6d5c-161c-11e7-9c4c-5e3cf1fdb0c2.png) アクティベーションコードの入力が完了すれば、Nessusのダウンロードが開始します。 ダウンロード完了後、先ほど登録したユーザでログインを行います。 ![6-11](https://cloud.githubusercontent.com/assets/25141356/24538435/1ebce2a6-1624-11e7-87d4-a24eb7aedac5.png) 1. Nessusのスキャンのポリシーを設定します ![6-12](https://cloud.githubusercontent.com/assets/25141356/24538458/40561478-1624-11e7-8fac-e5ee24238912.png) 2. 「Policies」→「New Policy」の順でクリックします ![6-13](https://cloud.githubusercontent.com/assets/25141356/24539138/079bdf4c-1628-11e7-998d-feed6a9a297d.png) 3. 「Basic Network Scan」をクリックします(ここでは、例として「Basic Network Scan」を選択しています) ![63-20](https://cloud.githubusercontent.com/assets/25141356/24539088/cdc2e46e-1627-11e7-8b96-7df6ba23a38d.png) 4. 「Name」を入力して「Save」をクリックします ![6-14](https://cloud.githubusercontent.com/assets/25141356/24538546/d18655b6-1624-11e7-8fc5-aa1324ae13aa.png) 5. Nessusで脆弱性スキャンを行います 6. 「Scans」→「New Scan」の順でクリックします ![6-15](https://cloud.githubusercontent.com/assets/25141356/24539156/25beb5e4-1628-11e7-9f4b-17d3ef6d0227.png) ![6-16](https://cloud.githubusercontent.com/assets/25141356/24539192/3eca477e-1628-11e7-9bb5-943494a3309d.png) 7. 「User」→ 設定済みポリシーの順でクリックします ![6-17](https://cloud.githubusercontent.com/assets/25141356/24539211/5f871f96-1628-11e7-8656-0a7d866e4c87.png) ![6-18](https://cloud.githubusercontent.com/assets/25141356/24539239/91fa10e6-1628-11e7-925b-933c9d297a5b.png) 8. 「Name」及び「Targets」を入力して「Launch」(Save右の▼)をクリックしてスキャンを開始します ![6-19](https://cloud.githubusercontent.com/assets/25141356/24539954/f56f38d8-162b-11e7-8938-6016d79166fb.png) スキャン終了後「My Scans」の中の該当スキャンをクリックすると結果が表示されます ![63-22](https://cloud.githubusercontent.com/assets/25141356/24540143/de1d1a28-162c-11e7-8cca-44ff6f82b094.png) # HACK#64 時刻同期の確保 ## 概要 - NTP(Network Time Protocol)を利用して、自動で時刻の同期を行う - 複数コンピュータ間で起きた事象を調査するときに、時刻にずれがあるとログの整合性が取りづらく、解析が非表示困難になる ## 実践 NTPは0.1秒の高精度で時刻の同期を行う NTPはLinuxやFreeBSD、OpenBSDにオプショナルパッケージとして含まれているので、CentOS6でも設定だけで利用可能である NTPで時刻を同期するためには/etc/ntp.confで時刻情報を提供しているNTPサーバーを指定しなければならない サーバーを指定した後は、クライアントntpdで時刻同期を行う 下記にNTPで時刻同期を行う詳細な方法を解説する ### 確認方法 1. まず、NTPの設定ファイル「ntp.conf」を編集し、NTPサーバを指定します <pre> # vi /etc/ntp.conf [ntp.conf] server ntp.nict.jp ※ntp.nict.jpは日本の標準時刻を提供するNTPサーバー </pre> 2. 起動時に自動的にntpdが立ち上がるようにして、再起動しましょう <pre> # chkconfig ntpd on # reboot </pre> 以上でNTPサーバの設定は完了して時刻の同期が行われるようになりました また、ntpdはマシン固有のクロック周期に依存する時刻のずれも自動的に修正します その設定を有効にするには「/etc/ntp.conf」に以下を追記する必要があります <pre> # vi /etc/ntp.conf driftfile /etc/ntp.drift </pre> # HACK#68 ネットワーク盗聴の検知 ## 概要 - ArpwatchやSniffDetを用いてネットワークが盗聴されていることを検知する - ネットワークスニファなどのネットワークアナライザツールは、パケット監視などネットワーク管理に役立つが、悪用された場合にはネットワークが盗聴され、パケットが改ざんされるなどの被害が発生する ## 背景 ### ネットワーク盗聴の仕組み ネットワークは接続形態によって以下のような2つに分類できる #### シェアードネットワーク - 端末がシェアードハブにつながっている接続形態 - ある1台の端末から送信されたパケットは、全ての端末が受信して自分宛てでない場合は破棄する - パケットが全ての端末に送信されるため「シェアード」という言葉がついている #### スイッチドネットワーク - 端末がスイッチングハブにつながっている接続形態 - 現在主流となっている接続形態 - スイッチングハブに接続された各端末のMACアドレスを記憶し、ある1台の端末から送信されたパケットは、MACアドレスによって送信先の該当端末にのみ送信される - MACアドレスを記憶できる量には限界があり、それを超えるとシェアードハブのような振る舞いをする ここで、シェアードネットワークのような自分の端末に全てのパケットが送信されてくる場合に、自分の端末のポートをプロミスキャスモードにしておくと、全てのパケットを受信してその内容が見れてしまう(これがいわゆるネットワークの盗聴) #### プロミスキャスモード - ネットワークカード(NIC)の動作モードの1つで、同一ネットワーク内を流れるすべてのパケットを受信して読み込む - パケットを受信したことは、真の受信者に気付かれない 簡単に前述したが、スイッチドネットワークにおいてもネットワークが盗聴される可能性はゼロでない 偽のMACアドレスを持つフレームを大量に送信し続けると、スイッチングハブがMACアドレスを記憶できる量に達して真のMACアドレスを記憶できなくなり、その結果同一ネットワーク内の全ての端末にパケットが送られてしまう ### ネットワーク盗聴の検知 まず、偽のMACアドレスを持つフレームが大量に送信されていることを検知する方法として、「Arpwatch」というツールを使用することができる 不審なIPアドレスとMACアドレスの組み合わせがネットワークを流れ続けると、Arpwatchのログもそれによって溢れかえる そのログを見ることで攻撃を簡単に発見できる 次に、ネットワークを盗聴しているユーザーがいるかどうかを検知するためには、プロミスキャスモードになっているポートを探せば良い プロミスキャスモードになっているポートを探すには「SniffDet」というツールを用いると良い ## 前提知識 SniffDetは下記のような特徴を持つ - プロミスキャスモードの検出に役立つ - 複数の手法によってネットワークスニファを検出できる - ARPテスト:プロミスキャスモードでネットワークスニファを実行しているコンピュータのプロトコルスタックのARPクエリの扱いを調査 - DNSテスト:偽IPアドレスからの逆引きクエリを検知してプロミスキャスモードのコンピュータを検知 ## 確認方法 CentOS6では、SniffDetのインストールに成功していません ただし、ifconfigコマンドによって現在操作中の端末のポートがプロミスキャスモードかどうかを確認できる ifconfigコマンドの実行結果に下記のような記述があればプロミスキャスモードで動作しています <pre> UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1 </pre> プロミスキャスモードは下記のコマンドで無効化できます <pre> ifconfig [インタフェース名] -promisc </pre> # HACK#69 攻撃者を追跡する ## 概要 - ファイアウォールのログをDShieldに提供して、世界全体のネットワーク攻撃の現状を知る - 世界全体のネットワーク攻撃の現状を知るためには、あらゆる端末のログを集計して分析することが必要である ## 背景 ネットワーク攻撃は日々多種多様化している それらの攻撃にいち早く対処するためには、どのポートへのどこからのどのような攻撃が1番多いかを知る必要がある しかし、個人の環境では統計的な情報を得るのが難しい そこで、DShieldからネットワーク攻撃の統計的な情報を入手する ## 前提知識 ### DShieldとは - distributed intrusion detection system の略 - ネットワーク上の攻撃の情報を集めているプロジェクト - 世界中のファイアウォールからデータを収集する - 一般ユーザーからもWebインタフェース経由でログをアップロードできる - インターネット上で1番トラブルを起こしている人を示した「Top 10 Most Wanted」や最も攻撃をされたポートを示した「Top 10 Target Ports」などの情報が提供されている ## 確認方法 まず、DShieldを実行するための環境を作ります。 最初にiptablesのログが出力されるように設定を行いましょう。 ログを出力したい場合はチェイン先を「LOG」にすることで出力することができます。 <pre> 例: # iptables -A INPUT -j LOG --log-prefix "[iptables firewall] : " --log-level=info </pre> 「--log-prefix」を指定することで、出力されるログメッセージに接頭辞を付けることができ、iptablesのログを判別しやすくなります。 また、「--log-level」を指定することで、syslogのプライオリティを指定することもできます。\([HACK#73 参照](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E4%B8%83%E7%AB%A0-%E3%83%AD%E3%82%B0%E3%81%AE%E5%8F%96%E5%BE%97#hack73-syslog%E3%81%AE%E9%81%8B%E7%94%A8%E7%AE%A1%E7%90%86)) しかし、例に記載しているルールは実際に使わないでください。このルールでは受信したパケット全てをログに出力するようになり、正常な通信までもDShieldに送信することになってしまいます。 それだとこちらの内部情報まで送信する可能性があり、DShield側も攻撃ではない不要なログを収集することになってしまうので、送信するログは選別するようにしましょう。 例えば、[HACK#61](https://github.com/careerbeat/dit-ehime/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3HACKS-Wiki-%E7%AC%AC%E5%85%AD%E7%AB%A0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3#hack61-ssh%E3%81%A7%E3%81%AE%E7%B7%8F%E5%BD%93%E3%81%9F%E3%82%8A%E6%94%BB%E6%92%83%E3%81%8B%E3%82%89%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E5%AE%88%E3%82%8B)の「単位時間のSYNパケットを制限する」の内容で、「ブルートフォースアタック」と判断するルールがありましたが、その時にログを出力するようにすれば良いでしょう。 プライオリティも設定してログの出力先を分けるなどするとよりわかりやすくログを管理することができるでしょう。 ログの設定が完了したら、次にDShield用のアカウントの作成をします。 <pre> # useradd _dshield # passwd _dshield </pre> そして、作成したアカウントのホームディレクトリの配下に`bin`ディレクトリを作成します。 (一度ログインをして作成しているのは、ディレクトリのオーナーが`_dshield`になるようにするためです) 既にある場合は作成しなくて構いません。 <pre> # su - _dshield $ mkdir /bin $ exit </pre> それができましたら、DShieldのクライアントをダウンロードして展開します。 <pre> # wget http://www.dshield.org/clients/framework/iptables.tar.gz # tar xvfz iptables.tar.gz </pre> そして、解凍したフォルダ内に移動し、パールのスクリプト`iptables.pl`を作成したアカウントの[bin]ディレクトリ内にコピーします。 それと、ログの送信時の設定を行うファイル`dshield.cnf`と拡張子が`.lst`のファイル全てを`/etc`にコピーします。 <pre> # cd iptables # cp iptables.pl ~_dshield/bin/ # cp dshield.cnf *.lst /etc </pre> これで環境の方は完了です。 では次に設定ファイルを編集します。 上記でコピーした`/etc/dshield.cnf`を編集します。 DShieldに送信されたログが自分でも確認できるように、`cc`に自分宛てのメールアドレスを記述します。 <pre> cc=root@dojo.local (任意) </pre> そして、[Sendmailの設定](https://github.com/careerbeat/dit-ehime/wiki/Wiki%E3%81%AB%E5%87%BA%E3%81%A6%E3%81%8F%E3%82%8B%E6%9C%AC%E3%81%A7%E3%81%AF%E3%82%AB%E3%83%90%E3%83%BC%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E5%BF%85%E8%A6%81%E6%83%85%E5%A0%B1#sendmail%E8%A8%AD%E5%AE%9A)をすれば、準備は完了です。 では実際に実行してみましょう。 本来はcronで定期的にログを送信するのが一般的にですが、とりあえず実行できるということだけ確認します。 <pre> # su - _dshield $ cd bin $ ./iptables.pl </pre> 実行後、DShieldに送信したログのコピーが`cc`に設定したアドレスへ送られてきます。 自分へ送信されてくるまでに時間がかかるようですので、次の日に確認するようになると思います。 ※AM10時のログのコピーがPM7時に届きました。 # HACK#70 Unixサーバでウイルススキャン ## 概要 - ClamAVを用いて、Windowsと同様にUnix環境でもウイルススキャンが行えるようにする - Unix環境上でのウイルス対策は、それほど重視されてこなかったが、近年その重要性が増してきた ## 背景 Unixを狙うウイルスはWindowsに比べて数が少ないため、感染しないと誤認されてきた その理由は、単純にWindowsよりも利用者数が少ないからである 例として、金銭を目的とした攻撃は、より多くの金銭を手に入れるためより多くの利用者がいるWindowsをターゲットとする しかし、UnixはオープンソースのOSであるため、技術者が開発しやすい反面、攻撃者に研究しやすいという問題がある 攻撃手法の研究によって効率の良い手法が確立されれば、攻撃が増加する可能性がある また、Unixはサーバーとして利用されることも多いため、攻撃の被害が広範囲に及ぶ可能性もある そこで、Unixにもウイルススキャンツールを導入して、ウイルス対策を行う ## 前提知識 ### ClamAVとは - オープンソースで提供されているアンチウイルスソフトウェアである - ウイルスデータベースは最大1日数回アップデートされて、2011年7月20日現在では1,000,066 件のウイルスパターンを保有している - ウイルスの検出だけでなく、他のソフトと組み合わせればリアルタイムスキャンをしたり、ウイルス検出時にメール通知することもできる ## 確認方法 ### CentOS6にClamAVをインストール 1. ClamAVをインストールするにはEPELリポジトリが必要になので、ない方は[こちら(未リンク)]()から導入してください。 2. 次に、ClamAVをインストールします <pre> # yum -y install clamd </pre> 3. 次に、ウイルス定義ファイルを最新化します  - ウイルス定義ファイルの更新設定 - /etc/freshclam.confの8行目付近「Example」をコメントアウト(ウイルス定義ファイル更新機能の有効化) - /etc/freshclam.confの141行目付近に「NotifyClamd /etc/clamd.conf」を追加(ウイルス定義ファイルの更新をclamdに通知) - freshclamコマンドを実行してウイルス定義ファイルを最新化する 4. 次に、ClamAVを設定します - /etc/clamd.confの195行目付近「User ~」をコメントアウト(root権限で実行するように) 5. 最後に、ClamAVを起動します <pre> # /etc/rc.d/init.d/clamd start # chkconfig clamd on(自動起動の設定) </pre> 試しにウイルススキャンしてみましょう <pre> # clamscan --infected --remove --recursive -r /home --infected:ウイルスに感染したファイルのみを出力する --remove:ウィルスを発見次第削除する --recursive:サブディレクトリごと再帰的に検査し、圧縮ファイルは再帰的に解凍して検査する -r /home:スキャン対象ディレクトリ </pre> 結果中の「Infected files」がウイルスの検出数です 参考)https://centossrv.com/clamav.shtml ### SendmailにてClamAVでメールスキャンを行う 1. まず、ClamAVを設定します - /etc/clamd.confの85行目付近が「LocalSocket /var/run/clamav/clamd.sock」となっていることを確認 - /etc/clamd.confの101行目付近「TCPSocket 3310」をコメントアウト(TCP通信無効化) - clamdを再起動 <pre> # /etc/rc.d/init.d/clamd restart </pre> 2. 次に、clamav-milterをインストールして設定します <pre> # yum -y install clamav-milter </pre> - /etc/clamav-milter.confの21行目付近を「MilterSocket /var/run/clamav/clamav-milter.sock」に変更 - /etc/clamav-milter.confの189行目付近に「AddHeader Add」を追加(受信メールのヘッダに情報追加) 3. 次に、clamav-milterを起動します <pre> # /etc/rc.d/init.d/clamav-milter start # chkconfig clamav-milter on(自動起動の設定) </pre> 4. 最後にsendmailを設定して再起動します - /etc/mail/sendmail.mcの最終行に下記を追加する <pre> INPUT_MAIL_FILTER(`clamav', `S=local:/var/run/clamav/clamav-milter.sock, F=, T=S:4m;R:4m')dnl define(`confINPUT_MAIL_FILTERS', `clamav') </pre> - sendmail.mcからsendmail.cfを作成する <pre> # m4 /usr/share/sendmail-cf/m4/cf.m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf </pre> - sendmailを再起動する <pre> # /etc/rc.d/init.d/sendmail restart </pre> 試しに自分宛てにメールを送ってみましょう <pre> mail [アカウント名]@[ホスト名] </pre> 届いたメールのヘッダに「X-Virus-Status: Clean」という記載があればウイルススキャンされています # HACK#71 最新の脆弱性情報を追跡する ## 概要 - セキュリティ関連のメーリングリストやRSSフィード、Cassandraを用いて、最新の脆弱性情報を入手する - 常にデバイスの脆弱性の最新情報を把握して、最新のパッチを確実に適用していくのは非常に手間がかかる ## 背景 デバイスの脆弱性の最新情報の提供は、メーカーとそのようなサポート契約を結んでいない限りは提供されない デバイスの脆弱性の最新情報を把握できずに、最新のパッチを適用していないと、世の中に脆弱性が公開されてしまっているので、それを狙った攻撃を研究してしかけられる可能性がある そのためデバイスの脆弱性の最新情報を常に把握して、最新のパッチを適用することはネットワーク上の脅威から資源を守るために必要不可欠である このHACKではセキュリティ関連のメーリングリストやRSSフィード、Cassandraを用いて、デバイスのあらゆる脆弱性の最新情報を大きな手間をかけずに入手する方法を紹介する ## 前提知識 ### メーリングリスト - まずメーリングリストとは、複数の人に同時に電子メールを配信する仕組みである - オープンソースプロジェクトのベンダ(製品の供給業者)は、セキュリティ勧告やパッチのお知らせをBuqTraqやFull-Disclosureにポスト(投稿)する - BuqTraq:ベンダがベンダ内部で発見した脆弱性や外部から報告された脆弱性を提供 - Full-Disclosure:ベンダから欠陥修正の協力を得られなかった情報を提供 - 多くのオープンソースプロジェクトはそれ自体にメーリングリストを持っているので、その中からセキュリティに関連するメーリングリストを購読することでデバイスの脆弱性の最新情報を入手する ### RSSフィード - まずRSSフィードとは、XMLベースのデータ形式の一種で、サイト内の新着記事の一覧や個々の記事の更新日や本文の要約などを含んでいる - デバイスの脆弱性の最新情報は、RSSフィードでも提供されている - このRSSフィードを購読することで情報を入手できる ### Cassandraの利用 - Cassandraに登録後、ベンダと製品名を入力すると関連する情報を電子メールで報告してくれる ## 確認方法 今回確認することができたメーリングリストは2つあります。 ## [Bugtraq](http://www.securityfocus.com/) ### Bugtraqとは? >Bugtraq(バグトラック)は、コンピュータセキュリティに関するメーリングリストである。脆弱性に関する議論(攻撃方法やそのexploit、回避方法や解決方法も含まれる)、脆弱性を持つ製品情報などが主な議題として挙げられる。 >2009年現在もなお、発表される脆弱性の情報はほとんどBugtraqが網羅しており、最大手の交流の場として知られる。(https://ja.wikipedia.org/wiki/Bugtraq) #### 特徴 - 言語は英語 - 最新の情報が入手できる - タイトルにCVE番号が入っているものは、米国の団体の「共通脆弱性識別子」 - 深刻度はCVSSでレベル分けされている - 重要度が高いものは日頃から追いかける よって、最新の脆弱性情報を入手したいのであればこちらのメーリングリストに登録するのが良い。ただし、言語が英語なので英語ができる必要があります。 登録は下記の手順でできます。 #### 登録方法 1. [Bugtraq](http://www.securityfocus.com/) にアクセス 1. 登録するメールアドレスを入力 1. 「Bugtraq」のみをチェック 1. 「Subscribe」で仮登録 1. 登録アドレスに確認メールが届く 1. 確認メールに空メールを返信して登録完了 もうひとつは以下である。 ## [JPCERT/CC](https://www.jpcert.or.jp/announce.html) ### JPCERT/CCとは? >JPCERT/CCはインターネットを介して発生する侵入やサービス妨害などのコンピュータセキュリティインシデントを日本国内のサイトに関する報告の受け付け、対応の支援、発生状況の把握、手口の分析、再発防止のための対策の検討や助言などを、技術的な立場から行なっています。(https://www.jpcert.or.jp/about/brief/) よって収集できる情報は日本国内のものに限りますが、セキュリティインシデントなどの情報を少なからず知ることができます。 #### 特徴 ##### Weekly Report > 前の週のセキュリティ関連情報のうち、JPCERT/CC が重要と判断したものを抜粋してまとめたものです。 ##### 注意喚起 > 深刻且つ影響範囲の広い脆弱性などに関する情報を告知するための文書です。 ##### お知らせ > ゴールデンウィークや年末年始などの長期休暇の前に注意すべき点などを簡単に紹介する文書です。 (https://www.jpcert.or.jp/announce.html) 登録方法は以下である。 #### 登録方法 1. 「announce-ctl@jpcert.or.jp」 宛に下記のようなメールを送る ![default](https://cloud.githubusercontent.com/assets/25141440/23943276/503db3b0-09b2-11e7-9a24-cc69b4ee1d5a.PNG) これにより登録したメールアドレスに脆弱性や攻撃についての情報が送られてきます。 その他本で挙げられていたサイトや機関に関しては既に活動を停止しており、確認することができませんでした。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully