ark-56789 備忘録

ark-56789 備忘録

IT系のSEである筆者の備忘録ページ

Amebaでブログを始めよう!
近年、セキュリティの重要性は、皆様もご存知の通りです。
Linuxサーバをインストールし、そのまま運用すると言うことは、悪意あるユーザーからの様々な攻撃に対して、無防備な状態で対応できず、サービスの停止や最悪の場合、サーバのダウンなどを引き起こされてしまいます。

と言うことで、しておくべきセキュリティ対策をまとめてみました。

目次


  • 1.プロダクトやモジュールのアップデート
  • 2.Firewallの設定
  • 2-1.基本的な設定値
  • 3.TCP Wrapper(hosts.allow・hosts.deny)の設定
  • 4.SSHDの設定
  • 5.その他の設定
  • 6.想定される攻撃への対応


  • 1.プロダクトやモジュールのアップデート



    最低限、これはしないといけません。
    頻度は月に1度メンテナンス日を設けて、サーバコマンドでのアップデートを実施すれば良いかと思いますが、緊急性の高いセキュリティホールが見つかった場合は、迅速に対応することが大切です。

    ただ、phpやmysqlなど、現在アプリケーションで使用しているミドルウェアをアップデートする場合は注意しましょう。
    例えばphpを使用している場合、php5.3系からphp5.4系へのバージョンアップの場合は、プログラムが使用できなくなる可能性があるため、最大限の注意を払って下さい。
    php5.3.1からphp5.3.16へのアップデート(php5.3系からphp5.3系の最新)は問題ないです。少なくとも筆者がこれまで運用してきたサーバでは、何も問題は起こりませんでした。
    下記コマンドにてアップデートを行います。


    RedHat系
    # yum update
    Debian系
    # apt-get update
    # apt-get upgrade


    2.ファイアウォールの設定


    ファイアウォールは、サーバのセキュリティレベルを高める上で、無くてはならない存在です。適切に設定し、アタックから身を守りましょう。

    基本的に、ファイアウォールを設定する際は、必要なポートだけを空けるようにしましょう。他は全て拒否します。

    2-1.基本的な設定値


    以下は基本的な設定です。
    SSHは出来ればポートを変更しておいた方が良いでしょう。デフォルトポートを使用している場合、アタックを受ける可能性が高まります。

    # SSH アクセス回数制限つきで空ける
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m hashlimit --hashlimit-name ssh_limit --hashlimit 1/second --hashlimit-burst 1 --hashlimit-htable-expire 120000 -j ACCEPT

    # HTTP/HTTPS/SMTP
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT

    ※無用なポートは絶対空けないようにしましょう。
    ※パスワード付きサービスは時間当たりの接続数を制限してポートを開放しましょう。

    2-2.hashlimitについて


    ブルートフォースアタックやDDoSアタック等に対処するための定番として、良く使用される設定です。
    今回の設定ではSSHへの接続は「1秒間に1回まで」と言うアクセス制限になります。それを超えた場合、2分間アクセスを抑制します。
    その2分間の間に、SSHに1回以上アクセスがあれば制限をかけ、その後は毎分1アクセスのみ通過させ、後は捨てると言うことになります。
    2分が過ぎると、また同じ処理を繰り返します。


    3.TCP Wrapper(hosts.allow・hosts.deny)の設定


    ファイアウォールはパケットでのフィルタでしたが、TCP Wrapperはサービスソフトウェア側でフィルタをかけます。
    TCP Wrapperにてフィルタをかける場合は、ApacheやPostfix等、TCP Wrapperに対応している必要があります。



    # vi /etc/hosts.deny
    ALL: ALL

    # vi /etc/hosts.allow
    ALL: 172.16.1.1 192.168.1.1
    sshd: 10.100.10.10 210.1.1.1


    上記の例だと、172.16.1.1及び192.168.1.1については全アクセスを許可し、10.100.10.10と210.1.1.1についてはSSHのみ許可しています。

    TCP WrapperはIPアドレスやドメイン名について制限を与えるため、IPを偽装して攻撃される場合についての対処としては、あまり意味を成しません。が、設定しないよりは遥かにマシですので、設定をしておくべきです。

    4.SSHDの設定


    SSHで接続される = 悪意あるユーザーに乗っ取られるとほとんど同じ意味ですので、不用意に甘い設定ですと、本当に痛い目を見ます。
    設定を行い、後々のトラブルを回避しておきましょう。

    4-1.各種設定


    下記で大体セキュリティ関連の設定が出来ます。

    # vi /etc/ssh/sshd_config
    # ポート番号変更
    -Port 22
    +Port 20202
    # ssh2のみ使用する
    Protocol 2
    # Rootログインを許可しない
    -#PermitRootLogin yes
    +PermitRootLogin no
    # 空パスワードを許可しない
    -#PermitEmptyPasswords no
    +PermitEmptyPasswords no
    # 公開鍵ログインを許可する
    -#PubkeyAuthentication yes
    +PubkeyAuthentication yes
    # パスワードログインを許可しない
    -#PasswordAuthentication yes
    +PasswordAuthentication no
    # チャレンジレスポンスログインを許可しない
    -#ChallengeResponseAuthentication yes
    +ChallengeResponseAuthentication no


    4-2.秘密鍵・公開鍵作成


    # ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (~/.ssh/id_rsa):[空Enter]
    Enter passphrase (empty for no passphrase):[任意のパスワード]
    Enter same passphrase again:[任意のパスワード]
    Your identification has been saved in id_rsa.
    Your public key has been saved in id_rsa.pub.
    The key fingerprint is:
    99:3c:a8:66:e8:11:db:e0:a0:32:5b:4e:2c:82:6e:4a xxxx@xxx
    The key's randomart image is:

    鍵を作成すると、作成したユーザーのホームディレクトリに「.ssh」フォルダが出来上がるので、秘密鍵のパーミッションが「600」or「400」となっていることを確認します。
    # ls -l ~/.ssh/
    -rw------- 1 [username] [username] 1743 id_rsa   <-- 秘密鍵
    -rw-r--r-- 1 [username] [username] 401 id_rsa.pub <-- 公開鍵

    作成した公開鍵をログイン用に設定します。

    # cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
    # chmod 600 ~/.ssh/authorized_keys

    ここまで出来たら、後は~/.ssh/id_rsaをクライアントPCに保存するなり、なんなりすると接続出来るようになります。



    5.その他の設定


    悪意あるユーザーに余計な情報を与えないために、バージョン情報等は隠しておく方が良いでしょう。ただ、隠したとしても脆弱性がある場合は、簡単に攻撃されますので最新のバージョンや、設定を適宜行うことが重要です。

    5-1.Apache


    # レスポンスヘッダにバージョン等を表示しない
    -ServerTokens OS
    +ServerTokens ProductOnly
    # エラーページが表示された際に、Apacheの情報が表示されないようにする
    -ServerSignature On
    +ServerSignature Off
    # TRACEメソッドの無効化
    +TraceEnable Off


    ※TraceEnableをなぜ無効化しなければならないか。

    TRACEメソッドは例えばtelnetなんかでデータを取得すると、200が帰ってきた後に入力した内容がそのまま返されます。
    これの怖いところは、悪意あるユーザーがTRACEメソッドが発行されるように、ブラウザに埋め込まれた状態でアクセスされると、ブラウザで入力したBASIC認証のユーザー名やパスワードが漏れてしまいます。
    つまり、いくらでもユーザー情報を入手できてしまう。と言うことです。
    これがあまりにも怖いので、無効化しています。

    5-2.postfix


    メールサーバは結構踏み台にされたりすることが多いため、タイトな設定を行う必要があります。踏み台にされて、直ぐに対応できるならば問題ありませんが、時間が空いてしまうと、SPAMメールの送信場所になったりするので、注意して設定する必要があります。

    ■SMTPサーバーのコマンドを無効化する


    メールサーバーにコマンドを送ることで、アカウントの有無を確認できるため、アカウントのリストが作成できます。アカウントリストを作成するのは、システム侵入の事前準備として重要な作業となります。無効化にしておいた方がよいでしょう。

    # vi /etc/postfix/main.cf
    # EXPN/VRFYコマンドを拒否
    disable_vrfy_command = yes
    # HELOコマンド使用の要求
    smtpd_helo_required = yes
    # バージョン非表示
    smtpd_banner = $myhostname ESMTP $mail_name


    ■踏み台サーバーにならないために


    ブラックリストを利用したり、送信元クライアント、ドメインによる制限やリレー制御もしておく必要があります。オープンリレー(誰でも自由にメール送信を依頼できるメールホスト)にしてしまうと、SPAMの温床となるので、出来る限りセキュアな設定をすることが大切です。

    ■ブラックリストの利用



    # vi /etc/postfix/main.cf

    smtpd_client_restrictions =
       permit_mynetworks,
       reject_rbl_client relays.ordb.org,
       reject_rbl_client spamcop.net,
       reject_rbl_client dynablock.wirehub.net,
       reject_rbl_client opm.blitzed.org,
       reject_rbl_client sbl.spamhaus.org,
       reject_rbl_client list.dsbl.org,
       reject_rbl_client cn-kr.blackholes.us,
       reject_rbl_client brazil.blackholes.us,
       reject_rbl_client russia.blackholes.us
       check_client_access hash:/etc/postfix/reject_client,
       reject_unknown_client, //逆引きができないホストの接続を拒否
       permit


    /etc/postfix/reject_clientは下記にて有効化します。

    ■送信元クライアントによる制限



    # vi/etc/postfix/reject_client
    192.168.1.254 REJECT
    192.168.100 REJECT

    ファイルに追記してから下記コマンドを実行します。
    # /usr/sbin/postmap /etc/postfix/reject_client
    # postfix reload


    ■送信元ドメインによる制限



    # vi /etc/postfix/main.cf
    smtpd_sender_restrictions =
       hash:/etc/postfix/reject_sender
       reject_unknown_sender_domain,
       reject_non_fqdn_sender


    # vi /etc/postfix/reject_sender
    spam@spam.com REJECT
    spam.org REJECT

    ファイルに追記してから下記コマンドを実行します。
    # /usr/sbin/postmap /etc/postfix/reject_sender
    # postfix reload


    そのほかにもSMTP認証を使用したり、TLSにて経路を安全にする等の方法がありますが、その方法については別の機会にまとめます。


    5-3.php


    phpでも基本的なセキュリティ対策をしておきましょう。バージョン情報等が出てしまうと、あっという間に攻撃の対象になってしまいます。

    # vi /etc/php.ini
    # 一部関数の制限
    disable_functions = phpinfo,eval
    # HTTPヘッダーにPHPバージョン等を表示しない
    expose_php = Off
    # エラー内容をWebページに表示しない
    display_errors = Off
    # セッションIDを独自の文字列に変更
    session.name = [独自の文字列]
    # セッションの保存場所
    session.save_path="/var/lib/php/tmp"


    上記で基本的なセキュリティ設定は完了です。ただ、開発中の場合や、どうしても制限をかけた関数が使用したい場合は一部変更してやる必要があります。



    6.想定される攻撃への対応


    実際に攻撃されてから対応することもありますが、最初から想定される攻撃も中にはありますので、気休め程度かもしれませんが、予防と言う意味もこめて、下記に対策を記述しておきます。

    6-1.SSHへのブルートフォースアタック


    ログインIDやパスワードに対して総当りで攻撃してきます。
    これはほぼ確実に体験することになると思います。
    運用が始まってからの対応方法としては、ログを確認してその都度/etc/hosts.denyに書き加えていくのが定番ですが、あらかじめ出来る対応はファイアウォールによる制限でしょう。
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m hashlimit --hashlimit-name ssh_limit --hashlimit 1/second --hashlimit-burst 1 --hashlimit-htable-expire 120000 -j ACCEPT


    また、「denyhosts」と呼ばれるツールを使用して、自動で/etc/hosts.denyに追加することも可能です。
    「denyhosts」については以下の様に導入します。
    こちらからDenyHosts-2.6.tar.gz をダウンロード
    # tar zxvf DenyHosts-2.6.tar.gz
    # cd DenyHosts-2.6
    # python setup.py install
    # cd /usr/share/denyhosts/
    # cp denyhosts.cfg-dist denyhosts.cfg
    # cp daemon-control-dist daemon-control
    # chmod 700 daemon-control


    設定例を以下に示します。

    # vi /usr/share/denyhosts/denyhosts.cfg
    # 2週間経過すると拒否対象から解除してあげる
    PURGE_DENY = 2w
    # 拒否解除を2回行うとそれ以降は解除しない
    PURGE_THRESHOLD = 2
    # 「存在しないユーザでの認証失敗3回」で拒否ホストに認定
    DENY_THRESHOLD_INVALID = 3
    # 「存在するユーザでの認証失敗10回」で拒否ホストに認定
    DENY_THRESHOLD_VALID = 10
    # 「rootユーザでの認証失敗1回」で拒否ホストに認定
    DENY_THRESHOLD_ROOT = 1
    # メールにて通知
    ADMIN_EMAIL = hogehoge@hogehoge.com
    # メールタイトルを指定する
    SMTP_SUBJECT = DenyHosts Setting hosts.deny


    自動起動設定及び起動を行います。

    # cd /etc/init.d/
    # ln -s /usr/share/denyhosts/daemon-control denyhosts
    # chkconfig denyhosts on
    # service denyhosts start


    間違って自分のホストが登録されてしまった場合は
    /etc/hosts.allowにIPを追加しましょう。


    6-2.dovecotへのブルートフォースアタック


    dovecotに対しブルートフォースアタックが仕掛けられることもあります。こちらもSSHと同じように回数制限をしてやることで対策をとることが出来ます。
    iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 110 -m hashlimit --hashlimit-name pop_limit --hashlimit 1/second --hashlimit-burst 1 --hashlimit-htable-expire 120000 -j ACCEPT


    6-3.webサービスに対するDoS攻撃


    悪意あるユーザーが大量のトラフィックをサイトに対して送ってくきます。これにより、表示されるまでの時間がものすごくかかってしまうとか、最悪Webサービスがダウンしてしまう事になってしまう、やっかいな攻撃方法です。F5(更新)を連打することでも簡単に出来てしまいます。
    これに関してはログを確認し、特定のIPアドレスを制限することで対応可能です。
    .htaccessに対して以下の様に設定します。

    # vi .htaccess
    order allow,deny
    allow from all
    deny from [ログで確認したIPアドレス]


    6-4.webサービスに対するDDoS攻撃


    悪意あるユーザーが無関係なPCに侵入して、それらのPCから一斉に、対象のWebサイトへ大量のトラフィックを送ってきます。これもものすごくやっかいな攻撃方法です。
    やはりWebサイトが遅くなったり、Webサービスのダウンが確認されます。
    これに関してもログを確認し、特定のIPアドレスを制限することで対応可能ですが、数が多くなりすぎるため、ある程度最初に予防しておくことが大切です。
    と言うことで、下記よりアクセス頂き、日本国外からのアクセスを制限する.htaccessをダウンロードします。
    「日本国外からのアクセスを制限する.htaccess」

    この.htaccessはDoS攻撃を予防するときにも使用できますので、参考にどうぞ。

    ■積極的な対応方法


    積極的に対応していくのであれば「mod_dosdetector」をお勧めします。
    mod_dosdetectorはクライアントのIPアドレスの一覧を保持し、IPに紐付けてアクセス数や時間を記録、一定時間内のアクセス数が設定した値を超えた場合に、環境変数に1をセットします。
    このツールを使用することで、DoS攻撃と思われるアクセスをシャットアウトすることが自動で出来るようになります。

    こちらよりダウンロードして下さい。
    # apacheの設定

    # Exclude images, stylesheets and javascript files

    SetEnvIf Request_URI ".*(common|download|ajax|json|image|gif|jpe?g|ico|js|css|png|html).*" NoCheckDoS
    SetEnvIf Remote_Addr 123.50.201.29 NoCheckDoS


    # Mod_DoSDetector configuration
    DoSDetection on
    DoSPeriod 30
    DoSThreshold 40
    DoSHardThreshold 45
    DoSBanPeriod 3600
    DoSTableSize 100
    DoSShmemName mod_dosdetector
    #DoSIgnoreContentType ^(image/|application/|text/javascript|text/css)
    # You can log requests which are suspected to be DoS attacks
    LogFormat "%{SuspectHardDoS}e %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" dosdetector
    CustomLog logs/dos_suspect_log dosdetector env=SuspectDoS

    # send a 503 response with mod_rewrite

    RewriteEngine On
    RewriteCond %{ENV:SuspectDoS} .+
    RewriteCond %{HTTP_USER_AGENT} !Googlebot
    RewriteCond %{HTTP_USER_AGENT} !Yahoo
    RewriteCond %{HTTP_USER_AGENT} !MSN
    RewriteCond %{HTTP_USER_AGENT} !google
    RewriteCond %{HTTP_USER_AGENT} !yahoo
    RewriteCond %{HTTP_USER_AGENT} !msn
    RewriteRule .* - [R=503,L]

    ErrorDocument 503 "Server is busy."


    上記の設定内容はドキュメントルート内に記述して下さい。
    バーチャルドメインを使用中の場合は、バーチャルドメイン用の設定ファイルに記述してみて下さい。

    7.まとめ


    セキュリティ対策の難しいところは、「これで完璧だ」と言い切れないところにあります。どれだけ一生懸命にセキュリティ対策をしても、未知の脆弱性に対してはやはり弱く、セキュリティ対策など嘲笑うかのように攻撃されます。
    しかし、何もしてないよりも、やはり何かしらの対策を行うべきだと思いますし、対策を行う事で、ノウハウも溜まっていきますので、今後も頑張ってセキュリティ対策をしていきましょう。