2015年2月25日水曜日

Content Security Policy

ApacheでContent Security Policyを設定したメモ。


httpd.confで設定する例。

Header set Content-Security-Policy "default-src 'self'; script-src 'self', 'unsafe-inline', www.example.com"


とりあえずレポートだけ見たい場合の例。
Header set Content-Security-Policy-Report-Only \
"default-src 'none';\
 script-src 'self';\
 object-src 'none';\
 img-src 'self';\
 media-src 'none';\
 frame-src 'none';\
 font-src 'none';\
 connect-src 'none';\
 style-src 'self';\
 report-uri /csp-report.php?v=1"

レポートでどのポリシーに違反したのか見やすくするため、xxxx-srcを全部書いた。
何がエラーになるか分かるように基本厳し目に、使わなそうなのはとりあえずnoneにしている。
report-uriのパラメータ(v=1)は後述。

右辺の書き方については下記参照。
CSP policy directives - Security | MDN

はまりそうなとこだけ書くと、

  • 'none'・'self'・'unsafe-inline'・'unsafe-eval'はシングルクォーテーションも含めて書く必要がある。
  • データスキーム(data:)はコロンも含めて書く。
    (mod_pagespeedを使っていると、気づかない間にデータスキームが使われていたりする。)
    ちなみに、スキームはデータに限らず、"https:"など特定のスキーム限定を指定できるみたい。
  • URLはスキームを省略可(例:www.example.com)。省略した場合、元のページと同じスキームと同じもののみ許可する。
    ポートも同様。
  • URLで別のスキームを許可したい場合、別途記載が必要。
    例:元のページがhttpで、読み込むCSSがhttpsの場合、httpsのURLも書く必要がある。
    ワイルドカードが使えるという説明もあったが、下記のどちらも駄目だった(ブラウザによる?)
  • *://www.example.com
  • *//www.example.com
  • URLのサブドメインはワイルドカード(*)が使える。
    サブドメインをワイルドカードにすると、サブサブ(...略)ドメインまでワイルドに適用される。
    ただしサブドメイン無しには適用されないらしい。


レポートをログに書き出すPHPの例。
<?php
if (!$_GET || $_GET['v'] < 1) {
        exit;
}
$report = json_decode(file_get_contents('php://input'), true);
$log = date('[Y-m-d H:i:s] ') . $_SERVER['HTTP_USER_AGENT'] . ' ';
$log .= var_export($report['csp-report'], true) . "\n";
error_log($log, 3, '/var/log/csp-report.log');

Content-Security-Policy-Report-Onlyの例でreport-uriにパラメータを付けたのは、このPHPの2行目で古いポリシーを無視するため。
ブラウザによってはキャッシュしてしまうようで、古いポリシーに基づき送信してくることがあり、ノイズになるので。
ポリシーを変えたら、パラメータの数字とPHPの2行目の数字を両方インクリメントする。

ログファイルはApacheが書き込めるように権限設定しておく。

(2015/3/2 追記)
logrotateも追加しておく。(phpのlogrotate設定をコピーして作成。)
/var/log/csp-report.log { missingok notifempty}

(追記終わり)

また、ModSecurityを使っている場合はレポートがModSecurityではじかれないように注意。

ログを見ていると、違反URLとして報告される"about"はabout:blankだと思うけど、"asset"って何だろう?



ちなみに、Gmailのポリシーはこんな感じだった。
script-src https://*.talkgadget.google.com 'self' 'unsafe-inline' 'unsafe-eval' https://talkgadget.google.com https://www.googleapis.com https://www-gm-opensocial.googleusercontent.com https://docs.google.com https://www.google.com https://s.ytimg.com https://www.youtube.com https://ssl.google-analytics.com https://apis.google.com https://clients1.google.com https://ssl.gstatic.com https://www.gstatic.com blob:;frame-src https://*.talkgadget.google.com https://www.gstatic.com 'self' https://accounts.google.com https://apis.google.com https://clients6.google.com https://content.googleapis.com https://mail-attachment.googleusercontent.com https://www.google.com https://docs.google.com https://drive.google.com https://*.googleusercontent.com https://feedback.googleusercontent.com https://talkgadget.google.com https://isolated.mail.google.com https://www-gm-opensocial.googleusercontent.com https://plus.google.com https://wallet.google.com https://www.youtube.com https://clients5.google.com https://ci3.googleusercontent.com;object-src https://mail-attachment.googleusercontent.com;report-uri /mail/cspreport

見やすく整形。
script-src
https://*.talkgadget.google.com
'self'
'unsafe-inline'
'unsafe-eval'
https://talkgadget.google.com
https://www.googleapis.com
https://www-gm-opensocial.googleusercontent.com
https://docs.google.com
https://www.google.com
https://s.ytimg.com
https://www.youtube.com
https://ssl.google-analytics.com
https://apis.google.com
https://clients1.google.com
https://ssl.gstatic.com
https://www.gstatic.com
blob:
frame-src
https://*.talkgadget.google.com
https://www.gstatic.com
'self'
https://accounts.google.com
https://apis.google.com
https://clients6.google.com
https://content.googleapis.com
https://mail-attachment.googleusercontent.com
https://www.google.com
https://docs.google.com
https://drive.google.com
https://*.googleusercontent.com
https://feedback.googleusercontent.com
https://talkgadget.google.com
https://isolated.mail.google.com
https://www-gm-opensocial.googleusercontent.com
https://plus.google.com
https://wallet.google.com
https://www.youtube.com
https://clients5.google.com
https://ci3.googleusercontent.com
object-src
https://mail-attachment.googleusercontent.com
report-uri
/mail/cspreport

scriptは'unsafe-inline'も'unsafe-eval'も許可してしまっているが、imgも含めて*を使っていないのは立派。
style等は(defaultも)指定していないが、不要という判断か、指定すると差し障りがあるのか、どちらだろう?

また、1バイトを削るのにもこだわるGoogleがわざわざこれだけの文字列を送信するのは、セキュリティの方が重要だからということだろう。
サブドメインをワイルドカードでまとめれば随分減りそうだが、Googleともなると使っているサブドメインも膨大なので、セキュリティが担保しづらくなるのだろう。
policy-uriを指定してポリシーをXMLでやりとりしてキャッシュを効かせれば総通信料は減りそうだが、柔軟性とのトレードオフか。
report-uriも送信料を増やすが、これ無しは運用的にきっと難しいだろう。

2015年2月16日月曜日

Windowsで Tomcatの Java参照先を変える方法

WindowsでJavaをUpdateしたら、Tomcatが起動しなくなった。

[info]  [ 6796] Commons Daemon procrun (1.0.15.0 32-bit) started
[info]  [ 6796] Running 'Tomcat7' Service...
[info]  [ 6844] Starting service...
[error] [ 6844] Failed creating java C:\(略)\jre7\bin\client\jvm.dll
[error] [ 6844] 指定されたパスが見つかりません。
[error] [ 6844] ServiceStart returned 1
[error] [ 6844] 指定されたパスが見つかりません。
[info]  [ 6796] Run service finished.
[info]  [ 6796] Commons Daemon procrun finished


原因
UpdateによりJavaのバージョンが8(1.8)になり、Javaのあるフォルダが変わっていた。

対策
Tomcatの、(Tomcat7.0の場合)Tomcat7w.exeを実行すると、設定ダイアログが表示される。
その中で、jvm.dllのpathを指定する箇所あがあるので、今あるjvm.dllを指定する。


参考:shin'nosukeさんのアレグロモデラート:Tomcat サービスが使う JRE (JDK)の場所

2015年2月14日土曜日

grepの技いろいろ


基本形

grep 'keyword' path/to/dir

各出力行の前に、入力ファイルにおける行番号を表示する
grep -n 'keyword' path/to/dir

再帰的にディレクトリ内を検索する
grep -r 'keyword' path/to/dir

正規表現で検索する
grep -E 'reg|exp' path/to/dir

ファイルの拡張子を限定する
grep --include='*.html' 'keyword' path/to/dir

検索結果をUnicodeに変換する
grep 'keyword' path/to/dir | nkf -w

キーワードをShift_JISにして検索する
grep `echo "キーワード" | nkf -s` path/to/dir


組み合わせるとこんな感じ?(正規表現はSJIS検索と同居でき無さそうなので除外)
grep -nr --include='*.html' `echo "キーワード" | nkf -s` path/to/dir | nkf -w


2015年1月25日日曜日

自己証明書の作り方 2015年版


Apache用(他でも使えると思うけど)の、自己署名のサーバ証明書(SSL証明書、改め、TLS証明書?)の作り方のメモ。

条件

  • 秘密鍵はパスフレーズ無し=暗号化しない
  • 2048ビット
  • SHA-2

コマンド
# 秘密鍵作成(2048ビットを指定、暗号化指定は無し)
openssl genrsa -out server.key 2048
# CSR作成
openssl req -new -key server.key -out server.csr
# 証明書作成(SHA-256を指定、期間は適当に)
openssl x509 -req -in server.csr -signkey server.key -days 3650 -out server.crt -sha256

手元のブラウザで、"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"になった(最強?)

参考:CentOS OpenSSLを使用したSSL用の秘密鍵と証明書の作成 | kakiro-web カキローウェブ

tags