#freeze
**Tips [#u7f15710]

#contents

----
***ログ振り分け [#zfdc96cc]
ローカルアクセスやロボットのログを分けてみる。
 #ローカル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

***Ciphersの指定 [#y771b707]
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 [#t065cc85]
以下の条件のもと、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の順序 [#o21193ca]
Rewriteを書くのがとても苦手(´・ω・`)~
なぜなら書いてある順番と適用順が直感的に結びつかないから。~
なので[[適用順序>http://httpd.apache.org/docs/2.4/rewrite/tech.html#InternalRuleset]]をおさらい。
 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が(.*)などの正規表現にマッチしてループしている。
じゃないだろうか。

***ExpiresとCache-Control [#uaafc2c9]
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>

***mod_cache [#o1ff9f5f]
次はブラウザキャッシュではなく、サーバキャッシュ。~
マニュアルに書いてある通りだが、以下のディレクティブは要注意。~

 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は「レスポンスメッセージのすべてもしくは一部は、単一のユーザのために用意された物であり、
 共有キャッシュによってキャッシュされてはならない」ので同じくキャッシュしていいものではない。
Cache&#x49;gnoreHeadersを除くこれらのディレクティブはデフォルトがOffなので、~
よほどの事がない限りいじらない方がよいかと( ´ω`)

***セキュリティにまつわるヘッダ [#j81cc757]
アプリケーションで吐くとよいのだが、サイトによっては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>

***BEASTとCRIMEとあとなんか色々 [#ud0c1723]

 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に対応していない端末やブラウザは接続出来なくなるのだが
そのようないにしえの端末は早々に切り捨てる方が世のため人のため(´・ω・`)


***SSLCompressionの確認方法 [#n46c36ec]
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
  ---
で、確認可能。


***Qualys SSL Labs SSL Server Test [#f473043f]
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の判定もあるので参考にするとよいかも。~

***Mozilla SSL Configuration Generator [#q76c170b]
https://mozilla.github.io/server-side-tls/ssl-config-generator/~
指針に使うとよいかも

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS