ローカルアクセスやロボットのログを分けてみる。
#ローカルIPアドレス SetEnvIf Remote_Addr 127.0.0.1 local nolog SetEnvIf Remote_Addr 192.168.x.x local nolog #クローラ SetEnvIf Remote_Host msnbot search nolog SetEnvIf User-Agent googlebot search nolog #ログ振り分け CustomLog logs/access_log combined env=!nolog CustomLog logs/search_log combined env=search CustomLog logs/local_log combined env=local
SSLCipherSuiteで弱い奴を弾いてみる。
openssl ciphersコマンドで確認し、指定したパラメータをApache側へ反映する。
Apacheに限らず、同様の指定が可能なものであれば利用できる。
主に2008年以前のガラケーやandroid2.xなど、古い端末はもはや切り捨てる。
/usr/local/ssl/bin/openssl ciphers -v 'TLSv1.2:!aNULL:!eNULL:!RC2:!MD5:!DES:!IDEA:!EXP:!SEED:!MD5:!RC4@STRENGTH' ALLを指定、認証なし(eNULL)またはanonymous認証(aNULL)は除外、 輸出用暗号(EXP)、RC2、DES、IDEA、SEEDは弱い、不要などの理由で除外、 MacでMD5は除外。RC4もRFC7465で禁止された。 この設定では以下のスイートが利用可能。 スイート名 プロトコル 鍵交換方式 認証/署名方式 暗号方式 メッセージダイジェスト ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 DH-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(256) Mac=AEAD DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD DH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(256) Mac=AEAD DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256 DHE-DSS-AES256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(256) Mac=SHA256 DH-RSA-AES256-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(256) Mac=SHA256 DH-DSS-AES256-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(256) Mac=SHA256 ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD ECDH-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA384 ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA384 AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256 ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256 ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256 DH-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(128) Mac=AEAD DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD DH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(128) Mac=AEAD DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256 DHE-DSS-AES128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(128) Mac=SHA256 DH-RSA-AES128-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(128) Mac=SHA256 DH-DSS-AES128-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(128) Mac=SHA256 ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256 ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256 AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256
ブラウザ使用CipherSuites例。
Apache2.4.17 + OpenSSL1.0.2d で SSLHonorCipherOrder Off SSLCompression Off SSLProtocol all -SSLv2 -SSLv3 を設定した場合。 Chrome46 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 Firefox42 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256 Edge TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 IE11(Win10) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 IE11(Win8) TLSv1.2 ECDHE-RSA-AES256-SHA384
以下の条件のもと、SNIが使用可能。
もちろんブラウザの対応も必要。
1.Apache2.2.12以降
2.OpenSSL0.9.8h以降
3.OpenSSLがTLS拡張有効(enable-tlsext)でビルドされている
あとは普通に
NameVirtualHost *:443 SSLStrictSNIVHostCheck on
などとする。
IE8(Vista以降)以降、Firefox、Chrome、Opera11、Safari(Apple)は現状対応済み。
Android2.3.3(の標準ブラウザ)はダメだった( ´ω`)
Rewriteを書くのがとても苦手(´・ω・`)
なぜなら書いてある順番と適用順が直感的に結びつかないから。
なので適用順序をおさらい。
1.RewriteRuleを書いてある順番に見ていくよ(`・ω・´) ↓ 2.RewriteRuleにマッチしたかな?マッチしなかったら次のルール見てね。 ↓ 3.マッチした(`・ω・´)! ↓ 4.マッチしたルールの上にRewriteCondはある?なかったらRewriteだ! ↓ 5.あった(`・ω・´)! ↓ 6.RewriteCondにマッチしたかな?マッチしなかったら次のルール見てね。 ↓ 7.マッチした(`・ω・´)! ↓ 8.Rewriteだ! ↓ 9.書き換えた(`・ω・´)! ↓ 10.ルールにLフラグはあるかな?なかったら次のルール見てね。 ↓ 11.あった(`・ω・´)! ↓ 12.じゃあそれが最後のルールだから「書き換えたURIについて1.からまた繰り返す」よ。 ↓ 13.えー(´・ω・`)
多分よく引っかかるのは
・書いてある順番からしてRewriteCondを先に評価しがち。 →ルールが先。ルールにヒットしたあとコンディションを評価する。 ・Lフラグがあるのにループする。 →書き換えたあとのURIが(.*)などの正規表現にマッチしてループしている。
じゃないだろうか。
YSlowやPageSpeedで「キャッシュ期限を長めにしなされ」というアドバイスがある。
勿論、サイトの性質によって長く出来ない場合もあるが、原則静的コンテンツは変更頻度が低いものとして扱い
これらをmod_expiresで調整する。
例1) サイト全体で ・すべてのファイルを ・アクセス時刻から1ヶ月先を期限にする httpd.confに ExpiresActive On ExpiresDefault "access plus 1 month" この場合レスポンスヘッダには、例えば Cache-Control:max-age=2592000 Expires:Tue, 20 Nov 2012 11:04:05 GMT のようなヘッダがつく。
バーチャルホストごとに設定。 <VirtualHost *:80> ExpiresActive On ExpiresDefault "access plus 1 month" </VirtualHost>
ディレクトリごとに設定。 <Directory "/var/www/html/hoge"> ExpiresActive On ExpiresDefault "access plus 1 month" </Directory> Files、Locationも同様。
例2) ・あるディレクトリの ・画像ファイルだけを ・アクセス時刻から1ヶ月先を期限にする ・それ以外のすべてのファイルはアクセス時刻から1週間先を期限にする ・ただし日替わり画像があるので、それはファイル更新時刻から1日先を期限にする ExpiresActive On ExpiresDefault "access plus 1 week" <Directory "/var/www/images"> ExpiresActive On ExpiresByType images/png "access plus 1 month" ExpiresByType images/jpeg "access plus 1 month" ExpiresByType images/gif "access plus 1 month" ExpiresByType images/x-icon "access plus 1 month" </Directory> <Files "daily.png"> ExpiresDefault "modification plus 1 day" または ExpiresByType images/png "modification plus 1 day" </Files>
次はブラウザキャッシュではなく、サーバキャッシュ。
マニュアルに書いてある通りだが、以下のディレクティブは要注意。
CacheIgnoreCacheControl Off Onの場合、Cache-Controlリクエストヘッダを無視してキャッシュで返事するので スーパーリロード(Cache-Control: no-cache や Pragma: no-cache)しても キャッシュ期間中はサーバキャッシュが返る。
CacheIgnoreHeaders Set-Cookie キャッシュしたくないヘッダを列記する。Cookieキャッシュしたらコワイよね。
CacheIgnoreNoLastMod Off Onの場合、Last-Modifiedレスポンスヘッダを無視してキャッシュに貯め込む。
CacheStoreNoStore Off Onの場合、Cache-Control: no-storeを無視してキャッシュする。 no-sotreは「取り扱いが慎重な (例えばバックアップテープ上の) 情報の不注意な漏洩や保留を防ぐ事」が目的なので 基本、キャッシュしていいものではない。
CacheStorePrivate Off Onの場合、Cache-Control: privateを無視してキャッシュする。 privateは「レスポンスメッセージのすべてもしくは一部は、単一のユーザのために用意された物であり、 共有キャッシュによってキャッシュされてはならない」ので同じくキャッシュしていいものではない。
CacheIgnoreHeadersを除くこれらのディレクティブはデフォルトがOffなので、
よほどの事がない限りいじらない方がよいかと( ´ω`)
アプリケーションで吐くとよいのだが、サイトによってはApacheで一括して吐かせた方が楽な場合もあると思う( ´ω`)
X-Frame-Options: [DENY | SAMEORIGIN] クリックジャッキング防止に一定の効果があるヘッダ。 DENY:とにかくiframe frame表示は不可 SAMEORIGIN:自ドメインのみ表示可 今時フレーム、という感もあるが フレームを使っているアプリケーションは自前でSAMEORIGINを吐いている事が多い。
Access-Control-Allow-Origin: [* | URI] スクリプトによるクロスサイトリクエストの制御を行うヘッダ。 *:他ドメインからもアクセス許可 URI:指定ドメインのみアクセス許可 API提供サイトは"*"を指定すれば他サイトはJSONPでなくともリクエスト可能になる(CORS)。 また自サイトのURIを指定すれば自サイト内のXHRのみ許可され、SameOriginePolicy制約となる。
Strict-Transport-Security: max-age=expireTime [; includeSubdomains] HTTPSのサイトに一度でもHTTPSで接続すると 同サイトにHTTPで接続しようとしたときにブラウザにHTTPSで接続し直させる。 サーバでリダイレクト処理などを行わなくてよいため Man-In-the-Middle攻撃防止に一定の効果があるヘッダ。 max-age:有効時間(秒)。アクセス時刻+設定秒間、ブラウザは有効なhttpsサイトに接続する。 includeSubdomains:サブドメインを含めたい場合、記述する。 同ドメイン内にHTTPとHTTPSが混在していると、とにかくHTTPSで接続するので設定には注意が必要。
例1)AjaxでPOSTする先のファイル群があるディレクトリ <Directory "/var/www/html/bin"> Header always set Access-Control-Allow-Origin "http://www.example.jp" </Directory> 例2)ログインフォームを含むファイル群があるディレクトリ <Directory "/var/www/html/bin"> Header always set X-Frame-Options SAMEORIGIN </Directory> 例3)SSLで接続が必要なログイン画面 <Location "/login/"> Header always set Strict-Transport-Security "max-age=604800" </Location>
1.BEAST OpenSSLは0.9.6dで疾うの昔に対策済み。 ApacheもOpenSSLもまめに更新するべし。 Apache+OpenSSLだと実はこれだけでよさげ。 ブロックではなくストリームを使えばよろしいという流れがあり、RC4を使うことがあったが RC4自体RFC7465で禁止となった。
2.CRIME 圧縮しない。ためのオプションは以下。 SSLCompression Off 2.2系は2.2.24以降でインプリメントされているので忘れないように。
3.Lucky13 OpenSSL1.0.1dで対策済み。更新しましょう。
4.RC4マルチセッション攻撃 RC4使わない。
5.POODLE SSLv3を使わない。このためTLSv1以降に対応していないクライアントは接続出来なくなる。 SSLv2と同様に扱うだけ。
まとめると
SSLCompression Off SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite 'TLSv1.2:!aNULL:!eNULL:!RC2:!MD5:!DES:!IDEA:!EXP:!SEED:!MD5:!RC4@STRENGTH'
みたいな。SSLv3も無効にしたのでTLSv1.2だけが有効となる。
こうなるとTLSに対応していない端末やブラウザは接続出来なくなるのだが
そのようないにしえの端末は早々に切り捨てる方が世のため人のため(´・ω・`)
Chromeでカギマーククリック→接続タブ
で、以前は圧縮してあるしてないの説明が出ていたのだが今は出ない( ´ω`)
なのでopensslコマンドで直接見る。
openssl s_client -connect example.com:443 ●SSLCompression On の場合 New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 4096 bit Secure Renegotiation IS supported Compression: zlib compression ←ここ Expansion: zlib compression ←ここ SSL-Session: Protocol : TLSv1.2 Cipher : DHE-RSA-AES256-SHA == snip == Compression: 1 (zlib compression) ←ここ Start Time: 1375790533 Timeout : 300 (sec) Verify return code: 20 (unable to get local issuer certificate) ---
●SSLCompression Off の場合 New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 4096 bit Secure Renegotiation IS supported Compression: NONE ←ここ Expansion: NONE ←ここ No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-GCM-SHA384 ---
で、確認可能。
https://www.ssllabs.com/ssltest/index.html
でのテストだが、普通のWebサイト運用では100をもらえる事はないと思うw
専用クライアント使うとかブラウザ超限定とか、実運用で100もらえるのは特殊な環境じゃないかな・・・。
■採点基準(PDFより) Table 3. Protocol support rating guide Protocol Score SSL 2.0 20% SSL 3.0 80% TLS 1.0 90% TLS 1.1 95% TLS 1.2 100% TLSv1.2「のみ」対応でないと100%にはならない。 TLSv1.2「のみ」対応にすると、BEAST、CRIME判定もクリアする。 SSLv3もダメになった今、もはやTLSv1.2のみでよいかと。
Table 4. Key exchange rating guide Weak key (Debian OpenSSL flaw) 0% Anonymous key exchange (no authentication) 0% Key or DH parameter strength < 512 bits 20% Exportable key exchange (limited to 512 bits) 40% Key or DH parameter strength < 1024 bits (e.g., 512) 40% Key or DH parameter strength < 2048 bits (e.g., 1024) 80% Key or DH parameter strength < 4096 bits (e.g., 2048) 90% Key or DH parameter strength >= 4096 bits (e.g., 4096) 100% nginxはパラメータで4096bitのDHパラメータファイルを指定すれば良い。 DHパラメータファイルはOpenSSLなどで作成する。
Table 5. Cipher strength rating guide Cipher strength Score 0 bits (no encryption) 0% < 128 bits (e.g., 40, 56) 20% < 256 bits (e.g., 128, 168) 80% >= 256 bits (e.g., 256) 100% 256bit以上のCipherを指定する。 多くのAndroid標準ブラウザはつながらなくなるんじゃなかろうか( ´ω`)
80以上でGRADE Aなので、普通に構成していればGRADE Aでしょう。
あと、BEASTとCRIMEの判定もあるので参考にするとよいかも。
https://mozilla.github.io/server-side-tls/ssl-config-generator/
指針に使うとよいかも