ドキュメント

Apache用モジュールをコンパイルできるようにする

  • httpd-devel (apxs) をインストールしておく。
    # yum install httpd-devel

バーチャルホスト設定

設定

  • /etc/httpd/conf.d/VirtualHosts.conf
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
    # Use name-based virtual hosting.
    NameVirtualHost *:80
     
    <VirtualHost *:80>
        ServerName    www.takeash.net
        DocumentRoot    /var/www/html/
    </VirtualHost>
     
    <VirtualHost *:80>
        ServerName    vh1.takeash.net
        DocumentRoot    /var/www/vh1-html/
        <Directory "/var/www/vh1-html">
    #		AllowOverride	All
        </Directory>
    </VirtualHost>

エラー対策

  • バーチャルホストが表示されない。
    • エラーメッセージ
      [warn] _default_ VirtualHost overlap on port 80, the first has precedence
    • 原因
      NameVirtualHost ディレクティブが設定されていない。
    • 対処
      NameVirtualHost ディレクティブを設定する。
      httpd.conf を修正するより conf.d に VirtualHosts.conf として専用のファイルを作成しておく方が忘れなくていいかも。

Digest 認証

  • 認証、承認、アクセス制御
  • mod_auth_digest
    • レルム/ユーザ/パスワード追加
      htdigest [-c] passwdfile <realm> <username>
    • /etc/httpd/conf.d/DigestAuth.conf
      すべてを展開すべてを収束
        1
        2
        3
        4
        5
        6
        7
        8
        9
       10
       11
       12
      
       
       
       
       
       
       
       
       
       
       
       
       
      
      <Directory "/var/www/html/Download/<realm>">
          AllowOverride AuthConfig
          AuthType Digest
          AuthName "<realm>"
          AuthUserFile /var/www/passwd/passwords_digest
          Require user <username>
          Options None
          Options Indexes
          DirectoryIndex index.html index.htm index.php
          Order allow,deny
          Allow from all
      </Directory>

mod_ssl

  • インストール
    # yum install mod_ssl

自己署名証明書使用

  • SAN 項目を追加した設定ファイルを作成。
    # cd /etc/pki/tls/
    # cp openssl.cnf openssl-san.cnf
  • openssl.cnf と openssl-san.cnf の差分
    --- openssl.cnf
    +++ openssl-san.cnf
    @@ -104,7 +104,7 @@
     ####################################################################
     [ req ]
     default_bits           = 2048
    -default_md             = sha1
    +default_md             = sha256
     default_keyfile        = privkey.pem
     distinguished_name     = req_distinguished_name
     attributes             = req_attributes
    @@ -222,6 +222,11 @@
    
     basicConstraints = CA:FALSE
     keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    +subjectAltName=@alt_names
    +
    +[ alt_names ]
    +DNS.1=takeash.net
    +DNS.2=*.takeash.net
    
    [ v3_ca ]
    
  • 証明書フォルダへ移動
    # cd certs/
  • サーバー用秘密鍵作成 (server.key)
    # openssl genrsa -aes128 2048 > server.key
  • パスフレーズ削除
    httpd 再起動時にパスフレーズが要求されないようにするため。
    # openssl rsa -in server.key -out server.key
  • サーバー用自己署名証明書作成 (server.crt)
    # openssl req -utf8 -new -key server.key -x509 -days 3650 -out server.crt -set_serial 0 \
        -subj '/C=JP/ST=Tokyo/L=Chuo-ku/O=TakeAsh.net/CN=takeash.net' -extensions v3_req -config ../openssl-san.cnf
    • サブジェクト例 (TakeAsh.net)
      C国名コードJP
      ST都道府県Tokyo
      L区市町村Chuo-ku
      O組織名TakeAsh.net
      CNコモンネーム(ドメイン名)takeash.net
    • 証明書確認
      「X509v3 extensions - X509v3 Subject Alternative Name」項目が存在すれば SAN が含まれている。
      # openssl x509 -in server.crt -text
      ...
          X509v3 Subject Alternative Name:
              DNS:takeash.net, DNS:*.takeash.net
      ...
  • /etc/httpd/conf.d/ssl.conf (抜粋)
    SSLCertificateFile /etc/pki/tls/certs/server.crt
    SSLCertificateKeyFile /etc/pki/tls/certs/server.key
    DocumentRoot "/var/www/html"
    SSLProtocol all -SSLv2 -SSLv3
  • httpd 再起動
    • CentOS 6
      # service httpd restart
    • CentOS 7
      # systemctl restart httpd

Certbot 使用

  • Certbot 使用前準備
    • ホスト名が正引きできること。(ワイルドカード不可)
    • バーチャルホストのサーバ名と要求するドメイン名のどれかが一致すること。
    • https でアクセス可能になっていること。
      • https ポート解放
        # firewall-cmd --add-service=https --permanent
  • Certbot インストール (EPEL リポジトリ)
    # yum install python-certbot-apache
  • 証明書取得
    取得に成功すると「/etc/letsencrypt/live/<ドメイン1>/」に証明書が作成される。
    # certbot --apache certonly -m <メールアドレス> -d <ドメイン1> [-d <ドメイン2> ...] --agree-tos
  • /etc/httpd/conf.d/ssl.conf (抜粋)
    SSLCertificateFile /etc/letsencrypt/live/<ドメイン1>/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン1>/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン1>/chain.pem
  • 自動更新スクリプト /etc/cron.monthly/certbot.sh
      0
      1
    
    #!/bin/bash
    /bin/certbot renew

Certbot 使用(ワイルドカード)

  • Certbot インストール (EPEL リポジトリ)
    # yum -y install yum-utils
    # yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
    # yum install certbot-apache
  • 証明書取得(手動)
    途中HTTPへのテキストファイルの配置とDNSへのTXTレコードの追加を指示されるので、追加してからEnterを押して先へ進む。
    取得に成功すると「/etc/letsencrypt/live/<ドメイン>/」に証明書が作成される。
    # certbot certonly --manual --server https://acme-v02.api.letsencrypt.org/directory -d "*.example.com" -d example.com
  • /etc/httpd/conf.d/ssl.conf (抜粋)
    SSLCertificateFile /etc/letsencrypt/live/<ドメイン>/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/<ドメイン>/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/<ドメイン>/chain.pem
  • apache 再起動
    # systemctl restart httpd.service
  • 証明書更新
    「--manual」で取得した場合は「renew」による自動更新ができないので、既存の証明書を削除し同名で取得し直す。
    # certbot delete
  • 証明書の有効期限を表示
    getExpireDate.sh
      0
      1
      2
      3
      4
      5
      6
      7
      8
    
    #!/bin/bash
     
    CommonName=example.net
     
    NotAfter=`openssl x509 -noout -dates -in /etc/letsencrypt/live/${CommonName}/fullchain.pem | \
      grep notAfter | \
      sed -e "s/notAfter=//" | \
      date -f - --iso-8601`
    echo ${NotAfter}

mod_security

インストール

  • EPELリポジトリ
    # yum install mod_security mod_security_crs

設定

  • /etc/httpd/conf.d/mod_security.conf (抜粋)
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
    
     
     
     
     
     
    
        # Maximum request body size we will
        # accept for buffering
        #SecRequestBodyLimit 131072
        SecRequestBodyLimit 5242880
        SecRequestBodyNoFilesLimit 51200
  • /etc/httpd/modsecurity.d/modsecurity_localrules.conf
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
    # Drop your local rules in here.
     
    # White List IP
    SecRule REMOTE_ADDR "@pmFromFile /etc/httpd/modsecurity.d/whitelist_ip.txt" \
            "phase:1,id:'1000001',nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"
     
    # White List URI
    SecRule REQUEST_URI "@pmFromFile /etc/httpd/modsecurity.d/whitelist_uri.txt" \
            "phase:1,id:'1000002',nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"
     
    # White List URI 2
    SecRule REQUEST_URI "@rx ^\/Etc\/" \
            "phase:1,id:'1000003',nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"
     
     # White List Sub-Domain
     SecRule REQUEST_HEADERS:Host "@pmFromFile /etc/httpd/modsecurity.d/whitelist_subdomain.txt" \
             "phase:1,id:'1000004',nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"
     
    # ZmEu Attack / phpMyAdmin
    SecRule REQUEST_URI "@rx (?i)\/(php-?My-?Admin[^\/]*|mysqlmanager|myadmin|pma2005|pma\/scripts|w00tw00t[^\/]+)\/" \
            "severity:alert,id:'0000013',deny,log,status:400,msg:'Unacceptable folder.',severity:'2'"
    • mod_security-2.7.1 でエラーが出るから適当にid追加したけど、idの振り方のルールってどこにあるのかな?
      ModSecurity: No action id present within the rule
  • /etc/httpd/modsecurity.d/whitelist_ip.txt
    mod_security による制限を行わない IP アドレスを列挙する。
    コメントは行頭から「#」で始める。
    # localhost
    127.0.0.1
    
    # example.com
    xxx.xxx.xxx.xxx
    
    # example.net
    yyy.yyy.yyy.yyy
  • /etc/httpd/modsecurity.d/whitelist_uri.txt
    mod_security による制限を行わない URI を列挙する。
    /cgi-bin/etc/PrintEnv.cgi
    /cgi-bin/etc/PrintEnv_txt.cgi
    /cgi-bin/etc/index.cgi
    /cgi-bin/etc/testCGI.cgi
  • /etc/httpd/modsecurity.d/whitelist_subdomain.txt
    mod_security による制限を行わないホスト名を列挙する。
    # WebApp1
    vh1.takeash.net
  • /etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_20_protocol_violations.conf
    • id:958291 "Range: 0-", mp4 等のストリーミングや分割ダウンロードが行われるファイルのダウンロードで引っかかる。

mod_geoip

インストール

  • EPELリポジトリ
    yum install mod_geoip

設定

  • /etc/cron.monthly/updateGeoIP
    データベースの自動更新スクリプト
      0
      1
      2
      3
    
    wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
    gunzip GeoIP.dat.gz
    mv -f GeoIP.dat /usr/share/GeoIP/GeoIP.dat
    /sbin/restorecon -v /usr/share/GeoIP/GeoIP.dat
  • GeoIP が表示されない場合は、SELinux のラベルを確認。
    # ls -Z /usr/share/GeoIP/
    Good) unconfined_u:object_r:usr_t:s0
    NG)   unconfined_u:object_r:admin_home_t:s0
    ベルが正しくない場合は下記コマンドで修正する。
    # sealert -a /var/log/audit/audit.log
    # /sbin/restorecon -v /usr/share/GeoIP/GeoIP.dat
    ベル修正後、httpd を再起動すること。
    # service httpd restart

Apacheでhttp-equiv属性値を反映させる

  • デフォルトでは、LastModifiedしか反映されない。
  • apxsはhttpd-devel-xxx.rpmをインストールすることで使用できるようになる。
  • うちの Fedora Core 3 環境だとmod_html_metaのコンパイルでエラーが出るんでまだ使えていない。引き続き検討。

Apache に DoS 攻撃対策 mod_evasive

cgi-bin ディレクトリでファイル名を省略したときに index.cgi を実行する設定

  • httpd.conf に ScriptAliasMatch を追加する。
  • 修正前
    すべてを展開すべてを収束
      1
    
     
    
    ScriptAlias /cgi-bin/ /var/www/cgi-bin/
  • 修正後
    すべてを展開すべてを収束
      1
      2
      3
      4
    
     
     
     
     
    
    ScriptAliasMatch ^/cgi-bin/(.*)\.cgi /var/www/cgi-bin/$1.cgi
    ScriptAliasMatch ^/cgi-bin/(.*)/? /var/www/cgi-bin/$1/index.cgi
    ScriptAliasMatch ^/cgi-bin$ /var/www/cgi-bin/index.cgi
    ScriptAlias /cgi-bin/ /var/www/cgi-bin/
  • index.cgi の例
    すべてを展開すべてを収束
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
    
     
     
     
     
     
     
     
     
     
     
     
     
    
    #!/usr/local/bin/perl
     
    use strict;
    use warnings;
    use utf8;
    use CGI::Pretty;
     
    my $q = new CGI;
    my $host = $q->url(-base => 1);
    print $q->redirect( $host . '/' );
     
    # EOF
    

Basic認証にタイムアウトを設定する


リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Tue, 26 Jun 2018 12:33:03 JST (20d)