Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 1 year has passed since last update.
概要
Apache の設定について共通化できるセキュリティ設定とその各項目についてまとめた。
設定例
必須設定
cat << _EOF_ > /etc/httpd/conf.d/security.conf# バージョン情報の隠蔽ServerTokens ProductOnlyHeaderalwaysunset "X-Powered-By"# httpoxy 対策RequestHeaderunsetProxy# クリックジャッキング対策Headeralwaysset X-Frame-Options "SAMEORIGIN"# XSS対策Headeralwaysset X-XSS-Protection "1; mode=block"Headeralwaysset X-Content-Type-Options "nosniff"# XST対策TraceEnableOff<Directory /var/www/html># .htaccess の有効化AllowOverrideAll# ファイル一覧出力の禁止Options -Indexes</Directory>_EOF_cat /dev/null> /etc/httpd/conf.d/autoindex.conf;cat /dev/null> /etc/httpd/conf.d/userdir.conf;cat /dev/null> /etc/httpd/conf.d/welcome.conf;注意事項
- 外部サイトからiframeで呼び出しできなくなる
任意設定
cat << _EOF_ > /etc/httpd/conf.d/security-strict.conf# DoS 攻撃対策LimitRequestBody 10485760LimitRequestFields 50# slowloris 対策RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500# HTTPメソッドの制限<Directory /var/www/html>Require method GET POST</Directory><Directory "/var/www/cgi-bin">Requireall denied</Directory>_EOF_注意事項
- GET/POST 以外使えなくなる
- cgi-bin が使えなくなる
想定環境
本記事は主に CentOS でYum を使って Apache をインストールしている想定での情報のため、環境に合わせて適宜読み替えること。
対象とするApache のバージョンは、現在サポートされている2.4 のみ1。詳細はApache HTTP Server のサポート期限 を参照。
デフォルト値検証の環境情報
- CentOS 7.2.1511 (CentOS-7-x86_64-Minimal-1511.iso)
- Apache 2.4.6 (
yum install httpd) - PHP 5.4.16 (
yum install php)
ポリシー
- Yum によるパッケージ管理
- ソースからコンパイル?そんなものウチにはないよ。
- デフォルトの設定ファイルに極力手を入れない
- コストパフォーマンス優先
- 成立の可能性が低い脆弱性への対応で汎用性やシンプルさが失われるような設定は避ける
設定項目
情報の隠匿(隠蔽)
バージョンなどの情報隠匿については、セキュリティ対策としての実効性に関する議論2 が一応ある。
バージョン情報(ServerTokens)
Server: Apache/2.4.6 (CentOS) PHP/5.4.16Apache 2.23 / 2.44 共にServerTokens ディレクティブのデフォルト値はFull のため、 HTTP ヘッダーに上記のように Apache のバージョンが出力される。
ServerTokens ProductOnly上記のようにServerTokens ディレクティブにProd またはProductOnly を指定することで、以下のように Apache のバージョン情報を隠蔽できる。
Server: ApacheServerSignature
Apache/2.2.15 (CentOS) Server at 192.168.56.101 Port 80ServerSignature ディレクティブは、 サーバーが生成するドキュメント(エラーメッセージ、mod_proxy における FTP のディレクトリーリスト、 mod_info の出力等)の最下行に上記のような出力を付与する設定を行う。
ServerSignatureOffApache 2.25 / 2.46 共にデフォルト値はOff になっているが、CentOS 6.x の Apache 2.2 ではディストリビューション側の設定でOn になっているためか、書き換える必要がある。
なお、 httpd.conf の設定を変更していない場合、<Directory "/var/www/html"> 内で指定しないと機能しない。
TRACEメソッドの無効化(XST対策)
TraceEnableOffXSS と TRACE メソッドを組み合わせたXST (クロスサイトトレーシング)攻撃への対策。
BASIC認証のIDとパスワード等が漏洩する危険があるが、サポート切れの古いOSなど攻撃成立条件は限定的78 である。
なお、TRACE メソッドは<Limit> や<LimitExcept> ディレクティブでは制限できない。9
エンティティタグ(ETag)
過去の Apache では HTTP ヘッダーに出力する ETag に inode 番号を強制的に利用していた10ため、ETag ヘッダーからファイルの inode 番号を入手されるリスクがあった。11
ETagを削除してLast-Modified ヘッダーを使えば HTTP ヘッダーのサイズがその分少なくなるというメリットがある。ETag を出力しない設定は以下の通り。
FileETagNone上記設定ではうまく ETag が消えない場合は、以下のように消すことも可能。
Headerunset ETagFileETag 設定の挙動検証
| FileETag | ETag |
|---|---|
| (未指定) | "220-529841bdd9a78" |
| MTime Size | "220-529841bdd9a78" |
| All | "905069-220-529841bdd9a78" |
| INode | "905069" |
| MTime | "529830adcea90" |
| Size | "220" |
公式リファレンスのデフォルト値は未だにFileETag INode MTime Size と記載されている10が、検証環境で検証したところデフォルトではMTime Size だった。~~リファレンスの更新漏れか、あるいはディストリビューションのパッケージでデフォルト値を変更しているか。~~はてブで指摘があったのでソースを調べたら12Apache本体のデフォルト値が 2.4.0 から変わってたので、やはりリファレンスの更新漏れの模様。(英語版13は正しく修正されている by@matuuさん)
-<default>FileETag INode MTime Size</default>+<default>FileETag MTime Size</default> <contextlist><context>server config</context><context>virtual host</context> <context>directory</context><context>.htaccess</context> </contextlist> <override>FileInfo</override>+<compatibility>The default used to be "INode MTime Size" in 2.3.14 and+earlier.</compatibility>-#define ETAG_BACKWARD (ETAG_MTIME | ETAG_INODE | ETAG_SIZE) #define ETAG_ALL (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)+/* This is the default value used */+#define ETAG_BACKWARD (ETAG_MTIME | ETAG_SIZE) if (ctx->finfo.filetype != APR_NOFILE) { return apr_psprintf(ctx->pool, "\"%" APR_UINT64_T_HEX_FMT "-%"- APR_UINT64_T_HEX_FMT "-%" APR_UINT64_T_HEX_FMT "\"",+ APR_UINT64_T_HEX_FMT "\"",- (apr_uint64_t) ctx->finfo.inode, (apr_uint64_t) ctx->finfo.size, (apr_uint64_t) ctx->finfo.mtime); }X-Powered-By
X-Powered-By: PHP/5.4.16HTTP ヘッダーに上記のように PHP などのバージョンが出力されている場合があるので、以下のように Apache 側でヘッダーを強制削除する。
Headeralwaysunset "X-Powered-By"PHP の場合は以下のように php.ini のexpose_php ディレクティブ14 で非表示にする設定が可能だが、Apache 側で一元的に強制削除した方が設定漏れのリスクがないだろう。
expose_php=OffOptions -Indexes
<Directory /var/www/html>Options -Indexes</Directory>Apache 2.0/2.2/2.4 共にOptions のデフォルト値はAll。DirectoryIndex ディレクティブ15 で指定したファイル (index.html等) がディレクトリー内に無い場合に mod_autoindex がディレクトリー内のファイル一覧を整形して返す。
autoindex.conf
cp /dev/null /etc/httpd/conf.d/autoindex.confまたは
> /etc/httpd/conf.d/autoindex.conficonsの設定等が記載されているが、ディレクトリ一覧は表示させないため利用しない。ファイル自体を削除するとアップデート時に再作成されるので、空ファイルにする。
welcome.conf
cp /dev/null /etc/httpd/conf.d/welcome.confまたは
> /etc/httpd/conf.d/welcome.confドキュメントルートに index.html がない場合など Forbidden になると OS のウェルカムページが表示されるが、余計な情報になるので削除。autoindex.conf と同様に削除するとアップデート時に再作成されるため空ファイルにする。
セキュリティ設定
AllowOverride
<Directory /var/www/html>AllowOverrideAll</Directory>/etc/httpd/conf.d/userdir.conf の<Directory "/home/*/public_html"> で指定されているAllowOverride 以外はすべてNone が指定されているので、.htaccess を利用するためにドキュメントルート配下を個別に許可する。
HTTP メソッドの制限
<Directory /var/www/html>Require method GET POST</Directory>X-Frame-Options(クリックジャッキング対策)
Headeralwaysappend X-Frame-Options SAMEORIGINX-Frame-Options HTTP レスポンスヘッダーは、ブラウザーがページを<frame> または<iframe> の内部に表示することを許可するかを示すことができる。
クリックジャッキング対策として IE8 から実装されたオプションヘッダー。
自分のサイトのコンテンツが他のサイトに埋め込まれないことを保証する。16
X-Frame-Options に対応するブラウザーのバージョンは IE8 以上、Firefox 3.6.9 以上、Chrome 4.1.249.1042 以上、Safari 4 以上、Opera 10.50 以上。18
Google、Twitter、Yahoo! JAPAN などでSAMEORIGIN が指定されている。
Facebook ではDENY が指定されている。
X-XSS-Protection(XSSフィルター機能)
Headeralwaysset X-XSS-Protection "1; mode=block"X-XSS-Protection はブラウザの XSS フィルター機能を制御できるレスポンスヘッダー。0 は無効、1 は有効(部分的書き換え)、1; mode=block は有効(表示の完全な停止)を意味する。
サイトの XSS 対策に問題はなく誤検知をなくしたい場合は0 を、そうでない場合は1; mode=block を指定するのが望ましく、デフォルトの1 の状態は望ましくない。19
Google、Twitter、Yahoo! JAPAN などで指定されている。
Facebook では0 が指定されている。
X-Content-Type-Options
Headeralwaysset X-Content-Type-Options nosniffX-Content-Type-Options レスポンスヘッダーの値にnosniff を設定して送信すると、Internet Explorer が MIME Sniffing 機能で content-type 宣言を回避するのを防止できる。20
Facebook、Twitter、Yahoo! JAPAN などで指定されている。
Content Security Policy (CSP)
素人にはお勧めできない。
https://content-security-policy.com/
http://blog.hash-c.co.jp/2013/12/Content-Security-Policy-CSP.html
httpoxy 対策
Foo: Bar っていう header 送ったら CGI の spec 的には HTTP_Foo = Bar にしてくれるっていう仕様を突いて PROXY: xxx っていうheader送ると HTTP_PROXY書き換えられるんじゃねっていう脆弱性。21
HTTPOXY Vulnerability Checking Tool でテストできる。
以下のソフトウエアが影響を受ける。22
- PHP (CVE-2016-5385)
- GO (CVE-2016-5386)
- Apache HTTP Server (CVE-2016-5387)
- Apache Tomcat (CVE-2016-5388)
- HHVM (CVE-2016-1000109)
- Python (CVE-2016-1000110
LimitRequestBody
このディレクティブはリクエストボディに許されるバイト数を指定する。
ディレクティブが書かれたコンテキスト(サーバ全体、ディレクトリ、ファイル、ロケーション)内で許容する HTTP リクエストメッセージボディのサイズに制限をかけることができる。
デフォルト値は0 で無制限。上限は2147483647 (2GB) まで。
LimitRequestBody 1048576010MiB に制限したい場合は上記のように記述。リファレンスで DoS 攻撃を避けるのに有効としている。
なお、PHP では以下のデフォルト値が設定されているので併せて確認したい。
memory_limit=128Mpost_max_size=8Mupload_max_filesize=5MLimitRequestFields
このディレクティブは HTTP リクエストにおいて許可するリクエストヘッダフィールド数を指定する。
デフォルト値は100 になっている。
LimitRequestFields 50リファレンスには「リクエストヘッダーフィールドの数が 20 を超えることはほとんどない。」23 とある。また、DoS 攻撃を避けるのに有効としている。
なお、値を 20 に設定していたら特定の Web ページで Chrome においてのみ Bad Request が返されたとする報告があり、参照する Web ページやブラウザによって挙動が異なることもあるようだ。24
RequestReadTimeout
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500slowloris25 対策で実装された mod_reqtimeout モジュールで使用できるディレクティブ。
2.2.15 以降に実装され、2.3.15 以降はデフォルトで有効になった。
AWS の ELB を利用している場合、 ELB のConnection Settings: Idle Timeout の値が Apache のRequestReadTimeout header の最低値よりも大きいと、 Apache のエラーログに 408 が大量に吐かれてしまうようなので注意。26
セキュリティテスト
CentOS 7.2.1511 に yum で Apache をインストールして設定変更していないケースをテストした結果。
[root@localhost program]# perl ./nikto.pl-h 127.0.0.1-***** SSL support not available(see docsforSSLinstall)*****- Nikto v2.1.6---------------------------------------------------------------------------+ Target IP: 127.0.0.1+ Target Hostname: 127.0.0.1+ Target Port: 80+ Start Time: 2016-01-16 10:00:00(GMT9)---------------------------------------------------------------------------+ Server: Apache/2.4.6(CentOS) PHP/5.4.16+ Server leaks inodes via ETags, header found with file /, fields: 0x220 0x529841bdd9a78+ The anti-clickjacking X-Frame-Options header is not present.+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the siteina different fashion to the MIMEtype+ PHP/5.4.16 appears to be outdated(current is at least 5.6.9). PHP 5.5.25 and 5.4.41 are also current.+ Apache/2.4.6 appears to be outdated(current is at least Apache/2.4.16). Apache 2.2.31 is also currentforthe 2.x branch.+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST+ Retrieved x-powered-by header: PHP/5.4.16+ OSVDB-3092: /test.php: This might be interesting...+ 8225 requests: 0 error(s) and 10 item(s) reported on remote host+ End Time: 2016-01-16 10:00:11(GMT9)(11 seconds)---------------------------------------------------------------------------+ 1 host(s) testedApache 関連記事
- Apacheセキュリティ設定
- Apache HTTP Server のサポート期限
- Apache のログをコマンドラインで集計する
- Apache の情報をコマンドラインで取得する
- IPアドレスから国や都市を判別する (GeoIP)
- Apache チューニング スクリプト
Apache 2.2 は2017年7月11日に 2.2.34 をリリースし、2017年12月31日をもって2.2系の開発終了を宣言している。
Apache HTTP Server のサポート期限 #Apache - Qiita -qiita.com↩ApacheやOSのバージョンを表示しないようにする方法や、PHPでX-Powered-Byを応答しなくする方法が紹介された記事ですが、コメント欄や260件以上の登録を集めたはてなブックマークでは賛否両論になっています。
サーバのバージョンは隠すのが常識? | スラド オープンソース -opensource.srad.jp↩このディレクティブは、クライアントに送り返す Server 応答ヘッダ内に、サーバの一般的な OS 種別や、 コンパイルされて組み込まれているモジュールの情報を含めるかどうかを指定します。
core - Apache HTTP サーバ バージョン 2.2 -httpd.apache.org↩このディレクティブは、クライアントに送り返す Server 応答ヘッダ内に、サーバの一般的な OS 種別や、 コンパイルされて組み込まれているモジュールの情報を含めるかどうかを指定します。
core - Apache HTTP サーバ バージョン 2.4 -httpd.apache.org↩https://httpd.apache.org/docs/2.2/ja/mod/core.html#serversignature↩
https://httpd.apache.org/docs/2.4/ja/mod/core.html#serversignature↩
http://blog.tokumaru.org/2013/01/TRACE-method-is-not-so-dangerous-in-fact.html↩
http://httpd.apache.org/docs/2.4/ja/mod/core.html#fileetag↩↩2
http://www.iss.net/security_center/reference/jp/vuln/apache-mime-information-disclosure.htm
ただ、検証および調査したところ Apache 2.4.0 からはデフォルト値はMTime Sizeになっており、2.4 系ではセキュリティ面では本設定は気にする必要はない。
2.2 系ではFileETag MTime SizeまたはFileETag Noneを指定するといいだろう。↩https://github.com/apache/httpd/commit/ba86234a7e627a50fdedc50b49ceaf40465911cb↩
https://httpd.apache.org/docs/2.4/ja/mod/mod_dir.html#directoryindex↩
https://developer.mozilla.org/ja/docs/HTTP/X-Frame-Options
| 設定値 | 内容 |
|---|---|
|DENY| サイト側の意図に関わらず、ページをフレーム内に表示することはできない。同じサイトのページをフレーム内に読み込むことも不可能になる。 |
|SAMEORIGIN| 自身と生成元が同じフレーム内に限りページを表示することができる。外部サイトのフレーム内にページを読み込むことを不可能にする。 |
|ALLOW-FROM uri| 指定された生成元に限り、ページをフレーム内に表示できる。Chrome、Safariは未対応。17 |↩Issue 511521 - chromium - `X-Frame-Options` does not support the `allow-from` directive. - Monorail↩
2008/9/3 - Internet Explorer 8 のセキュリティ Part VI: Beta 2 の更新項目↩
http://b.hatena.ne.jp/entry/294900783/comment/yosuke_furukawa↩
http://httpd.apache.org/docs/2.4/mod/core.html#LimitRequestFields↩
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme