サーバの SSL 証明書の設定をチェックしてくれるサービスはObservatory by Mozilla など、いろいろなサービスがありますがシェルスクリプトから簡単にチェックできるtestssl.sh が便利だったのでメモ。これはオフラインでも利用できるので、インターネットから到達できないようなサーバも評価することができます。
/bin/bash based SSL/TLS tester: testssl.sh
testssl.sh is a free command line tool which checks a server's service on any port for the support of TLS/SSL ciphers, protocols as well as recent cryptographic flaws and more.
使い方としてはgit clone
してからスキャンをかけるだけですね。
何もオプションをつけないと結果がコンソールにしか出力されないので、--html
オプションでレポートを生成しておくと良いと思います。
サーバ移行を機にサイトを原則として HTTPS 運用することにして、HTTP Strict Transport Security (HSTS)をさらに一歩推し進めてプリロードに対応させてみました。
HSTS プリロードは、HSTS 有効化している場合でも、最初の1度のアクセスは暗号化のない状態 ( HTTP ) で行われるという脆弱性を無くすために、ブラウザ側で HSTS に対応したドメインの一覧を持っておく(プリロード)ことで、最初の1度目のアクセスから HTTPS が使われるようになるという仕組みです。
プリロードの申請はドメイン単位(サブドメインは不可)なので、Apache HTTPd の場合にはドメインの全てのウェブサーバの設定に以下のような設定を追加しておきます。includeSubDomains を指定するとサブドメインの全てに HSTS が効きます。HTTP でしかアクセスができないサイトがあると接続エラーになってしまうので、そのようなサイトがないかどうかを良く確認してから設定を変更する必要があることに注意が必要です。
あとはHSTS Preload List への登録フォームを使って登録するだけです。
もしウェブサーバに設定の不備があれば、このフォームにドメイン名を入れた時点でエラーが出るので、修正してから登録作業を繰り返します。
Apache の conf や .htaccess で複雑なアクセス制御を書くためにはSatisfy any を使わざるをえないことが多くて大変でしたが、「人間とウェブの未来 - Apache 2.4系でのモダンなアクセス制御の書き方」で2.4 からはずいぶんまともな書き方ができることが分かったのでメモ。
例えば、以下のルール。アクセス元が 192.168.* か、もしくは user が hoge の場合にはアクセスを許すというルールは以前は以下のように Satisfy any を使って表現する必要がありました。
これが 2.4 では以下のように<RequireAny> というディレクティブで括れるようになった*1のでルールが明確になりました。
これで古いルールをコピペしつづける運用ともおさらばできそうです。
ウェブから手軽に httpd の設定をチェックできるツールについてはこれまでもいろいろと紹介しました(先日もQualys SSL Labs の SSL Server Testを取り上げました)が、Mozilla が運営しているObservatory by Mozilla を使うと複数のサービスをまとめてチェックできることが分ったのでメモ。
Observatory by Mozilla is a project designed to help developers, system administrators, and security professionals configure their sites safely and securely.
FQDN を入力するだけで手軽に診断できるので、ウェブサーバを運用している場合には一度チェックしておくと良いと思います。
遅ればせながらサイトをHTTP Strict Transport Security (HSTS) に対応させてみました。
HSTS とは httpd 側から特定のヘッダを送ることにより、ウェブブラウザに対して特定のドメインでは HTTP ではなく強制的に HTTPS を使わせる仕組みです。この仕組みの便利なところは、HTML の記述に左右されず、特定のドメイン単位で HTTPS を導入できるようになることです。
仕様についてはRFC 6797 で定められています。日本語の情報が良ければ Mozilla の「HTTP Strict Transport Security - Web セキュリティ | MDN」がわかりやすいと思います。
今回は単純に以下のようなヘッダを挿入しておきました。
先日、Chrome 56 から SHA-1 のサポート打ち切りが発表されたので、ウェブサーバの管理者は今のうちに証明書の状態をチェックしておく必要があります。もちろんサーバに入っている httpd の設定ファイルや証明書を確認しても良いのですが、公開されているサーバであればQualys SSL Labs の SSL Server Test を使うのが楽です。
SSL Server Test (Powered by Qualys SSL Labs)
This free online service performs a deep analysis of the configuration of any SSL web server on the public Internet.
使い方はHostname の欄に調べたいサーバの名前を入力し、Submit ボタンを押すだけ。最終的な結果が出るまで2~3分かかるのでそのまましばらく待ちましょう。
SHA-1 の問題についてはSignature algorithm の欄を確認して SHA-1 がなければ OK。最近発行された証明書であれば SHA256withRSA などになっていると思います。
Apache と Tomcat の連携は mod_proxy_ajp を使うと簡単に実現できます。
例えば、<Location> ディレクティブと組み合わせて以下のような設定にすると、Apache へのアクセスを全て Tomcat に向けることができます。
上記の例は設定がシンプルなだけでなく、Tomcat 側に新しいアプリを追加したような場合でもイチイチ Apache の設定を変更する必要がないので便利なのですが、Apache 側に置いてある静的なコンテンツを返したいときや、 manager や host-manager のような管理用の WebApp を Apache からアクセスさせたくないような場合などに、一部の Path だけを ProxyPass の対象から除外したいという場合があります。
これについていろいろ調べてみたところ、以下のように書くと除外パスが設定できるようです(ここでは manager と host-manager を除外しています)。
ちょっとわかりづらいですが、Apache で Location を複数書いた場合の扱いについては「セクションのマージ方法」に記載があるとおり、設定ファイルに現れた順番に処理(上書き)されるため、除外するパスは <Location / > の定義よりも後に書く必要があります。ProxyPass しない場合には 「!」 だけを書けば良いというのは初めて知りました。
Apache のVirtualHost 設定を一覧化する方法をいつも忘れるのでメモ。
こんな感じで IPベース、名前ベースの一覧を得ることができます。
最近は VPS が安いので1台のサーバにいくつも VirtualHost をする必要性はないのかもしれませんが。。。。
Apache + Unicorn + Redmine という組み合わせで運用していて、リバースプロキシのApache に HTTPS -> HTTP の変換をやらせるように設定してみたのですが、Redmine のリダイレクトが HTTP になっていることがあって HTTPS だけで運用しようとすると HTTP にリダイレクトされたときにサーバから応答が帰ってこないように見えるので困ってしまいました。
何か良い方法がないかと思って検索してみると、意外とはまりやすいポイントのようで、解決方法をいくつか見つけることができました。大きく分けるとバックエンドが投げる Location ヘッダを無理矢理書き換える方法か、バックエンド側にX_FORWARDED_PROTO というヘッダを投げてリバースプロキシの外側が HTTPS であるとバックエンドに解釈してもらうという方法があるようです。今回はどちらかというと根本的な対応に思える後者の対応を取ることにしました。こちらの方法であれば HTTP 側には影響を与えないので、そのまま使い続けることができます。
やり方としては以下の行を Apache の設定ファイルに書き込むだけと簡単です。
† 参考
普通、運用中の httpd を再起度するときは restart ではなく graceful を使うと思います。
が、systemd の場合は graceful とやってもそんなの知らないよと言われてしまうので systemd の流儀を調べてみました。
systemd の場合は /usr/lib/systemd/system 以下にある .service ファイルに定義が書いてあるので、これを眺めてみると一撃で解決。systemctl reload httpd という感じで、reload を使うのが正しいようです。
/usr/lib/systemd/system/httpd.service