開発環境を構築する(Windows Apache2.0編)その2

開発環境を構築するシリーズまとめリンク

開発環境を構築する(Windows版PHP4編) - ぱせらんメモ
開発環境を構築する(Windows版PHP5編) - ぱせらんメモ
開発環境を構築する(Windows Apache2.0編) - ぱせらんメモ
開発環境を構築する(Windows Apache2.0編)その2 - ぱせらんメモ
開発環境を構築する(Windows Tomcat 5.5編) - ぱせらんメモ


今回はPHP4/5共存以外の設定をざっと書き出してみる。
念のために書いておくとあくまで開発環境の設定であり、実際の稼働環境ではやってはいけない設定もあるので注意。


以下の設定は基本的にWindows版のデフォルト設定(httpd.default.confあるいはインストール直後のhttpd.conf)を元とする。

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

主にReverse Proxyであれこれマッピングするために。

LoadModule rewrite_module modules/mod_rewrite.so

こちらもあれこれURLに小細工するために。

#DocumentRoot "C:/Apache Group/Apache2/htdocs"
DocumentRoot "C:/var/www/html"
             :
             :

#
# This should be changed to whatever you set DocumentRoot to.
#
#<Directory "C:/Apache Group/Apache2/htdocs">
<Directory "C:/var/www/html">
             :
             :

Windowsでも一応/var/www/htmlというディレクトリを作成して、そこをドキュメントルートにしている。
ちなみにcgi-binはC:/var/www/cgi-bin、さらにバーチャルホストはC:/var/www/vhosts/port8080とかC:/var/www/vhosts/www.example.com/htmlというルールで作成している。

#CustomLog logs/access.log common

SetEnvIf Request_URI "default.ida" wormlog nolog
SetEnvIf Request_URI "root.exe" wormlog nolog
SetEnvIf Request_URI "cmd.exe" wormlog nolog
SetEnvIf Request_URI "Admin.dll" wormlog nolog
SetEnvIf Request_URI "favicon.ico" nolog
CustomLog logs/worm_log common env=wormlog
CustomLog logs/access.log combined env=!nolog

デフォルトで設定されているcommon access.logは使わない。
基本的な攻撃アクセスにはwormlogとnologというフラグを立てる。それぞれ「ワームである」「ログに記録しない」という意味付け。
そしてCustomLogでwormlogだけとそれ以外を保存する。access.logのほうはcommonではなくcombinedにする。

ServerTokens Full

これは本番環境ではProdにしなければならない設定だが、開発環境なのでFullにしておく。
インストール直後の状態でFullになっていると思うので特に変更はなし。

#ScriptAlias /cgi-bin/ "C:/Apache Group/Apache2/cgi-bin/"
ScriptAlias /cgi-bin/ "C:/var/www/cgi-bin/"

#
# "C:/Apache Group/Apache2/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
#
#<Directory "C:/Apache Group/Apache2/cgi-bin">
<Directory "C:/var/www/cgi-bin">
             :
             :

CGIディレクトリの設定。ここもデフォルトから/var/www/cgi-binに変更しておく。
まぁ普段PHPしかやらないから関係ないんだけど。

AddDefaultCharset Off

このディレクティブはWindows版のデフォルト設定ファイルには記述されていないので気にしなくてもよい(デフォルトはOffだから)が、せっかくなので記しておく。

# mod_security
Include conf/security.conf

最後にmod_securityの設定ファイルを読み込んで基本的な設定は完了。security.confの内容は後述する。
拡張設定をIncludeディレクティブで読み込むスタイルはパッケージの真似。こうすると見通しも良いしOn/Offも楽でいいね。

NameVirtualHost *:80

<VirtualHost *:80>
    ServerAdmin root@localhost
    DocumentRoot C:/var/www/html
    ServerName localhost
    ErrorLog logs/error_log
    CustomLog logs/worm_log common env=wormlog
    CustomLog logs/access.log combined env=!nolog

    <Directory "C:/var/www/html">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>

    Include conf/php4.conf

    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass /php5/ http://localhost:8080/
    ProxyPassReverse /php5/ http://localhost:8080/
</VirtualHost>

最後と言いつつ本当の最後はバーチャルホストの設定。内容はまぁ様々。
ちなみにhttpd.confに書くのはデフォルトのみで、そのほかのport8080とかwww.example.comなどは

Include www.example.com

などと外部ファイルにして読み込む。
ログファイルなどはかぶらないようにwww.example.com-access.logなどとする。

security.conf

mod_security 1.x系の設定。内容はどっかからコピペしたのでよくわからない(ぉぃ
そのうちマニュアル読もうとは思うんだが、思った以上に機能が豊富なのね。
しかも気がついたら2.x系になってて、この設定ファイル互換性なくなってるし。

LoadModule security_module modules/mod_security.so

<IfModule mod_security.c>
    # Turn ModSecurity On
    SecFilterEngine On

    #SecFilterScanPOST On
    SecFilterCheckURLEncoding On
    SecFilterCheckUnicodeEncoding Off

    # Accept almost all byte values
    SecFilterForceByteRange 1 255

    # Server masking is optional
    # SecServerSignature "Steffen :)"

    #SecUploadDir logs
    #SecUploadKeepFiles Off

    # Only record the interesting stuff
    SecAuditEngine RelevantOnly
    SecAuditLog logs/sec.log

    ## -- Common attacks --------------------

    SecFilterDefaultAction "deny,log,msg:'Common attacks',status:403"

    #Web Proxy GET Request
    SecFilter "^GET (http|https|ftp)\:/"
    #Web Proxy HEAD Request
    SecFilter "^HEAD (http|https|ftp)\:/"
    #Proxy POST Request
    SecFilter "^POST (http|https|ftp)\:/"
    #Proxy CONNECT Request
    SecFilterSelective THE_REQUEST "^CONNECT "

    # Only accept request encodings we know how to handle.
    SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Type "!(^application/x-www-form-urlencoded$|^multipart/form-data;)"

    # Do not accept GET or HEAD requests with bodies
    SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chain
    SecFilterSelective HTTP_Content-Length "!^$"

    # Restrict which request methods can be used
    SecFilterSelective REQUEST_METHOD "!^(GET|HEAD|POST)$"

    # Restrict protocol versions.
    SecFilterSelective SERVER_PROTOCOL "!^HTTP/(0\.9|1\.0|1\.1)$"

    # Require Content-Length to be provided with every POST request.
    SecFilterSelective REQUEST_METHOD "^POST$" chain
    SecFilterSelective HTTP_Content-Length "^$"

    # Don't accept transfer encodings we know we don't know how to handle
    SecFilterSelective HTTP_Transfer-Encoding "!^$"

    ## -- PHP attacks --------------------

    SecFilterSignatureAction "log,deny,msg:'PHP attack'"

    # Possible code execution attack (targets valid PHP streams constructs)
    SecFilterSelective ARGS_NAMES "^php:/"

    #phpBB attack
    SecFilterSelective ARG_highlight "(\x27|%27|\x2527|%2527)"

    ## -- Awstats-------------------------

    SecFilterSignatureAction "log,deny,msg:'Awstats Attack'"
    SecFilterSelective ARGS_NAMES "configdir"

    ## -- SQL Injection Attacks --------------------

    SecFilterSignatureAction "log,deny,msg:'SQL Injection attack'"

    # Generic
    SecFilterSelective ARGS "delete[[:space:]]+from"
    SecFilterSelective ARGS "drop[[:space:]]+database"
    SecFilterSelective ARGS "drop[[:space:]]+table"
    SecFilterSelective ARGS "drop[[:space:]]+column"
    SecFilterSelective ARGS "drop[[:space:]]+procedure"
    SecFilterSelective ARGS "create[[::space:]]+table"
    SecFilterSelective ARGS "update.+set.+="
    SecFilterSelective ARGS "insert[[:space:]]+into.+values"
    SecFilterSelective ARGS "select.+from"
    SecFilterSelective ARGS "bulk[[:space:]]+insert"
    SecFilterSelective ARGS "union.+select"
    SecFilterSelective ARGS "or.+1[[:space:]]*=[[:space:]]1"
    SecFilterSelective ARGS "alter[[:space:]]+table"
    SecFilterSelective ARGS "or 1=1--'"
    SecFilterSelective ARGS "'.+--"

    # MySQL
    SecFilterSelective ARGS "into[[:space:]]+outfile"
    SecFilterSelective ARGS "load[[:space:]]+data"
    SecFilterSelective ARGS "/\*.+\*/"


    ## -- Command execution --------------------

    SecFilterSignatureAction "log,deny,msg:'Command execution attack'"

    SecFilterSelective ARGS_VALUES "^(uname|id|ls|rm|kill)"
    SecFilterSelective ARGS_VALUES "^(ls|id|pwd|wget)"
    SecFilterSelective ARGS_VALUES ";[[:space:]]*(ls|id|pwd|wget)"
</IfModule>


さて、普段使ってるhttpd.confを上からコピペしただけのような気がする*1が、だいたいこんな感じということで。

*1:まったく同じ内容というわけではない。