HTTP/2とTLSv1.3(draft-20)をnginx+OpenSSLで対応させる

せっかくなので、当サイトはhttp2に正式対応しました。

昔やったはずじゃ・・・と思っていたのですが、

http/2と似て非なるほぼ同じSPDYの対応でした。

SPDYはいつの間にやらchromeではhttp/2扱いされなくなり(googleが作ったのに)、chrome 51から非対応となってしまいました。

ということでこのブログもhttp1.1に戻っていたので、正式にhttp/2に対応しました。
この辺は別の話なのでこの記事が詳しいです。

EC2+nginxでhttp2対応できたとおもったらできてなかった話。(解決します)

ついでに、当サイトはTLSv1.3(draft-20)に対応しました(多分)。

なお、言っておきますが 現状のブラウザでは見れません。

新しくブラウザが出たとしても見れるかもわかりません。

正直まだstandardになってないですし、仕様は変更されるでしょうし、現状ここでの対応はほぼ無意味です。

ただ、TLSv1.3が正式対応になりOpenSSL1.1.1が正式リリースした時はこの記事は役立つと思います。多分。

OpenSSLのTLS1.3実装に関しては公式が使用方法を書いています。これがとても詳しいです。
Using TLS1.3 With OpenSSL

コネクションの方法など難しいところは置いておくとして、
実際に使用するところで気になるのは暗号化スイートがTLS1.3専用のものが用意されています。

  • TLS13-AES-256-GCM-SHA384
  • TLS13-CHACHA20-POLY1305-SHA256
  • TLS13-AES-128-GCM-SHA256
  • TLS13-AES-128-CCM-8-SHA256
  • TLS13-AES-128-CCM-SHA256

OpenSSLの現在の実装でTLS1.3はこの5つしかサポートされていません。

これ以外を使用してTLSv1.3認証を行おうとすると、当然ですが認証に失敗します。

そのためTLS1.2以下と併用するためにはTLS1.3の時だけ上のスイートを優先する必要があります。

nginx+OpenSSLでのTLSv1.3対応

nginxのmailline versionの最新版1.13.0にて、"ssl_protocols" でTLSv1.3を選択できるようになりました。

*) Feature: the "TLSv1.3" parameter of the "ssl_protocols" directive.

そのため、おなじみの構成であるnginx+OpenSSLでTLSv1.3を使えるようになります(厳密にはなる予定です)。

使用するnginxは1.13.0、OpenSSLは1.1.1-dev(master)です。

OpenSSLはTLSv1.3が正式になったら1.1.1をリリースすると言っていますので、実際に正式になった時もこの設定で動くと思います。

OpenSSL1.1.1(dev)のインストール

リポジトリなどではなくgitからmasterを落としてビルドします。gccなどが必要です。

後、libssl.soが無いと怒られたりしたので/usr/local/lib64/に動的リンクを貼ったりpathを通したりして動きました。

cd /usr/local/src/
git clone https://github.com/openssl/openssl
cd openssl
./config enable-tls1_3
make
make test
make install

/usr/local/bin/openssl version
OpenSSL 1.1.1-dev  xx XXX xxxx

nginx 1.13.0のインストール

こちらはリポジトリはあるのですが、OpenSSLを組み込む関係でこちらもソースコードからビルドが必要です。

このやり方だとyumなどで本体に入っているnginxは削除しました。

configureのオプションは各自吟味してください。

cd /usr/local/src/
wget http://nginx.org/download/nginx-1.13.0.tar.gz
tar zxvf nginx-1.13.0.tar.gz
cd nginx-1.13.0
./configure --prefix=/etc/nginx --sbin-path=/usr/local/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3
make
make install

ここで重要なのは--with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3です。
–with-opensslは先ほどのopensslのソースコードのpathです。nginxにバンドルします。

–with-http_v2_moduleはhttp/2対応のため、–with-openssl-opt=enable-tls1_3も設定しないと動きませんでした。

なので使うだけならOpenSSL1.1.1(dev)をmake installする必要ないのですが、openssl s_clientを使用するために使います。

あとはpathを通して、nginx -V で確認します。うまくいけば下のようになっているはずです。

nginx version: nginx/1.13.0
built by gcc <略>
built with OpenSSL 1.1.1-dev  xx XXX xxxx
TLS SNI support enabled
configure arguments: <略> --with-http_v2_module --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3

nginx設定

既にSSL設定が終わっているなら、このあたりの設定を変更するとOKです。再起動も忘れずに。

ssl.conf

#TLSv1.3用設定
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:ECDHE:!COMPLEMENTOFDEFAULT';

#http2用設定
listen 443 ssl http2

SSLv1.3の接続確認

最初に言ったようにブラウザだと確認できませんでした・・・draft-18のものはchromeのchrome://flags/でTLS1.3を指定すると見れます。

https://tls13.crypto.mozilla.org/

このサイトを見るとdraft-18対応済みのchrome/firefoxでは正常に確認でき、TLS1.3と表示されているのがわかります。

対応していないとchromeでは「サポートされていないプロトコルが使用されています」というレアな画面が出ます。

OpenSSLのSSL/TLS client機能で接続確認します。1.1.1は-tls1_3オプションでTLSv1.3で接続しに行きます。
一部省略。

>openssl s_client -connect blog.potproject.net:443 -tls1_3
CONNECTED(00000003)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:CN = potproject.net
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate

subject=CN = potproject.net

issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3026 bytes and written 270 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.3, Cipher is TLS13-AES-128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS13-AES-128-GCM-SHA256
    Session-ID:
    Session-ID-ctx:
    Master-Key: <master-key>
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: <StartTime>
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: no
---

これで正しいのかイマイチわかりませんが、TLS1.3認証は出来ていることが確認できます。

TLSv1.3の正式に決まるまでもう日は近いと思うので、その時にすぐに対応できればいいな・・・

小規模Mastodonインスタンスを運用するコツ

補足:ドキュメント移行によりリンク変更と、tasksに関しての追記を行いました。

最近は、twitterクローンであり分散型のSNSであるMastodonが勢力を伸ばしてきているところであり、自分もハマりつつあります。

実際に運用してみてわかった、大規模Mastodonインスタンスを運用するコツとしてpixiv.netが運営しているサーバpawoo.netでは、現時点で6万人以上のユーザ数を誇るほどの規模です。

その一方で、サーバ自体はオープンソースのため、誰でも立てることができ、立てたサーバはインスタンスとして他のサーバとつながることが出来ます。

実際に私も2,3日程運用して、おひとりさまで運用しております。その時のコツというレベルでもないですが、
これから構築する人に向けてはまりそうな点などをまとめておきます。

https://mastodon.potproject.net/@potpro

では、大規模に対してここでいう小規模とは何か、というと
・主に使用ユーザは1~100人程度を想定
・気軽に構築するため、公式のDockerを使用して構築
・SSLは無料のもの(Let’s Encrypt)を使用する
・サーバはVPS、月1000円~2000円程度
そして、
・ちょっとくらいのダウンは問題なし、データは出来るだけふっ飛ばさないようにする

とします。

VPSとコストに関して

基本的に小規模で運用している方々を見るに、

さくらVPSの1GB(972円/月)やAmazon EC2(従量課金、無料枠あり)が多いと思います。

私はコスパ重視で、お名前.com VPS メモリ 2GBプラン(1,099円/月、年払い)を使用しています。

メモリ2GBと仮想3コアあれば一人でロードアベレージは通常時0.1以下です。1-10人程度であればメモリ1GB以上の好きなVPSを選べばいいと思います。

自宅で管理したいなら、自宅鯖を構築するのも手ですが、固定IPアドレスの問題や安定稼働(停電で使えなくなるとか)を考えなくてはならないため、

その点ではVPSの方が優れているでしょう。

このレベルでどのくらい運用できるのかはまあやっぱり実際に試してみないとわかりませんが、100ユーザくらいなら多分大丈夫(と思いたい。

この部分に関しては公式ドキュメントのResources-needed.mdが参考になります。まだ3つしか参考がありませんが、多分増えていくと思います。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Resources-needed.md

この記事はあくまで小規模が目的のため、ユーザ1000くらいを目指すなら、
脱Docker、PostgreSQLやRedisの別サーバー管理、Sidekiq threadsの増加、nginxのチューニング、ロードバランスなどが必要になってきますので、
その部分は他の誰かが解説してくれることでしょう。

Dockerコンテナの作成と構築

基本的に、公式DocumentのDocker Guideを読んで作成してください。
更新が激しいので、ここでは構築方法は解説しません。
何故なら構築方法が変更され、この記事の情報が古くなる可能性が高いからです。

自分がハマった点は、必ず公開用に立てるのであれば、タグ付きのリリース版を使用してください。
https://github.com/tootsuite/mastodon/releases
単純にgit cloneをしてクローンした最新のmasterブランチはうまく動作しない可能性が高いです。
タグ付きのreleaseブランチは、このようなコマンドでチェックアウトできます。

git clone https://github.com/tootsuite/mastodon.git
cd mastodon
git checkout $(git tag | tail -n 1)

アップデート

アップデートも余計なことはせず、公式ドキュメントのDocker Guide – updatingを見て行ってください。
公式DocumentにあるThings to look out for when upgrading Mastodon(Mastodonをアップデートするときの注意点)に記載されていることも重要なので参考にしましょう。
ミスったらデータ消えたり上手く動かなくなるのでここは慎重に。
https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Production-guide.md#things-to-look-out-for-when-upgrading-mastodon

このアップデート手順通りに行えば、すぐに新しくコンテナが立ち上がることでダウンタイムも数秒で済みますし、
まず失敗することはないと思われます。

しかし、万が一の時を含め、バックアップとデータ永続化は行っておきましょう。

データ永続化

一部のデータをホストOS側にマウントすることで、コンテナを誤って削除してもデータが保持される状態にします。
docker-compose.ymlの最初のコメントアウト部分を外すことで、ホストOS側のディレクトリに保存されます。
左側がホストOSのパスとなっているので、変更すれば好きな部分におけます。

version: '2'
services:

  db:
    restart: always
    image: postgres:alpine
### Uncomment to enable DB persistance
    volumes:
      - ./postgres:/var/lib/postgresql/data

  redis:
    restart: always
    image: redis:alpine
### Uncomment to enable REDIS persistance
    volumes:
      - ./redis:/data
(略)

この作業を忘れたまま本番稼働させてしまった場合は、次で紹介するdocker cpコマンドでバックアップを取り、
バックアップをマウントするディレクトリと同じ場所に置き、アップデートを行ってください。

バックアップ

小規模といえど、データのバックアップは行いたいです。

#データベース
PostgreSQLコンテナ : /var/lib/postgresql/data
#キャッシュデータ
Redisコンテナ : /data
#取得した画像等のデータ
Mastodon-webコンテナ :  /mastodon/public/system
#sidekiqデータ
sidekiqコンテナ :  /mastodon/public/system

この4つが基本的なバックアップ対象のデータです。
一番重要なのはデータベースですが、
現バージョンでは、取得した画像等のデータも一度紛失すると再取得を行ってくれず、
タイムラインに取得済みのアバター画像が何も表示されない悲しい状態に陥ってしまいます。

Dockerの場合、Docker cpコマンドを使用することでDockerコンテナからホストOSにコピーが出来ます。
例として、

docker cp mastodon_db_1:/var/lib/postgresql/data /mastodon_data/postgresql

という形です。
mastodon_dataディレクトリにpostgresqlデータが入っていることが確認できると思います。

その他、構築時に使用した.env.productionファイルも無くした場合は再構築が簡単ではなくなるため、バックアップしておいてください。
無くしてしまった場合は、稼働しているMastodon-webサーバから
docker exec -it mastodon_web_1 env
から取得することは一応可能です。

SSL対応

Mastodonサーバでは、SSLの対応はほぼ必須です。

一応httpでも動作しますが、httpとhttpsは共存できないため、httpsのサーバからリモートフォローすることが出来ない、などの弊害があるようです。

今ではLet’s encryptなどを使用してSSL対応は簡単にできるので、個人でも敷居はかなり下がっていると思います。

公式のProduction Guideでは、nginxをリバースプロキシにして、動作することが推奨されています。
公式のProduction Guideをメインに、SSLの設定は自分の過去の記事あたりにその辺は結構書いているので、よければ参考にしてください。

Centos+nginxでLet’s encrypt(certbot)導入と自動更新まで

証明書は期限が切れると使えなくなり、アクセスしてもエラーが出て正常に使えないため、Let’s Encryptを使う場合は自動更新の設定を行うこともおすすめします。

また、公式ではssl_protocols TLSv1.2;になっているため、ちょっと古いブラウザなどで使用できない可能性もあります。
使うべきではないとされているSSLv3を除いて、広く対応を行いたければ、ssl_protocols TLSv1 TLSv1.1 TLSv1.2;に変更することをお勧めします。

Cronjobs

運用するにつれ、他のインスタンスからデータを持ってきて表示するため、放置しているとデータはどんどん溜まっていきます。
それを解消するため、公式で要らないデータ等を削除できるRakeタスクが用意されています。
※特にmastodon:dailyタスクにはPuSHの購読更新処理が含まれるため、外部インスタンスから自分のトゥートが見えなくなる可能性があります。
自分も更新しなくても大丈夫だと思っていたのですが、mastodon:dailyに関しては必ず1日に1回は動かしてください(多くてもOK)。

https://github.com/tootsuite/mastodon/blob/master/lib/tasks/mastodon.rake

#いらないやつもろもろを消してくれるタスク(日一で動作)
0 3 * * * cd /var/www/mastodon && docker-compose run --rm web rake mastodon:daily
#1週間以上前の画像動画キャッシュを削除(週一で動作)
0 3 * * 1 cd /var/www/mastodon && docker-compose run --rm web rake mastodon:media:remove_remote

自分はこのようにしてcrontabで動作させています。

swapの設定

Mastodonに限らないことですがメモリが少なくなっても賄えるようにswapを設定しましょう。
swapがあれば仮想メモリとして退避することができ、遅くはなりますが少ないメモリでもリソースが確保できます。
Mastodonは1ユーザでもそこそこメモリを食います。最低でも1GB、よくて2GBはほしいところです。

特に上に書いているmastodon:dailyタスクは、動作するだけでかなりのメモリを食います。自分もメモリ不足ギリギリ回避な感じでした。

メモリ1GBの場合は3GB、2GBの場合はswapは2GB確保と合計4GBは確保しておけばととりあえず大丈夫と思います。
(Linuxディストリビューションでコマンドが違ったりします。これはcentos7の参考例です。)

//2GB確保、当然ストレージに2GB空きが無いと作れません
if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

まとめ

Mastodonを個人で運用するメリットとして、
・データを勝手に改ざんされたり削除される心配はない
・逆に自分の好きなようにデータを弄れる
・おひとり様サーバならサーバ負担に悩まされることもない(htmlのレスポンスは100ms以下!)
・SNSを運用してるって、なんかカッコいいじゃん。自分だけの空間にするもよし、鯖管で皆を導くのもよし。

という点があり、自分もかなり満足して使っています。

私は個人的にMastodonで個人鯖を立てる人を応援しております。もっとたくさん増えて、個人鯖連合を作ろう。

[nginx]Let’s EncryptでSSLのセキュリティをA+にするまで

potproject.net Advent Calendar 2016
5日目の記事です。

nginx advent calenderになりつつある。この頃。
10日目くらいからアプリやガジェット系のネタを入れていく次第です。


先日の記事で、nginxでLet’s Encryptを使ってSSLの設定行いました。

しかし、指摘したようにこれだとセキュリティがイマイチなので、

再度設定し直してセキュリティをさらに向上させようと思います。

まず、現在のセキュリティがどのレベルかを見るため、

Qualys SSL Labs の SSL脆弱性診断を使って、テストしてみます。

bef

こういう結果になりました。特に鍵交換が弱いですね。

この部分に関してはDH鍵交換のデフォルトが1024ビットのため、既に弱くなっているからだとか。

まあ1024ビットでも高い専用機じゃないと解読できないレベルらしいので、

こんなしょぼい個人サイトだったらまあ本来はまず問題はないんですが・・・
2048ビットのDH鍵交換をopensslで作成し、使用します。

DH交換用の鍵作成

openssl dhparam -out /etc/nginx/dhparam.pem 2048

セキュリティを高める鍵だけあって、サーバーによっては生成にかなり時間がかかります。こっちだと2分くらい。

自分も生成中にこの記事を書いてました。

他にも、前に紹介したMozilla SSL Configuration Generatorを参考に、いろいろと設定します。

後、せっかくなのでSSL設定を共通化できるようにSSLだけ設定をまとめることにします。

nginxの場合、 include /etc/nginx/ssl.conf; という風に書けばそのままインクルードして使えます。

/etc/nginx/ssl.conf;

# 共通鍵と秘密鍵
ssl_certificate /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;

# セッションの設定
ssl_session_cache shared:SSL:50m;
ssl_session_timeout  1d;
ssl_session_tickets off;

# 2048ビットのDH鍵交換を使う
ssl_dhparam /etc/nginx/dhparam.pem;

# SSLv3を禁止し、TLSを使う
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# SSL暗号化スイートの使用設定
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;

# HSTSの有効化
add_header Strict-Transport-Security max-age=15768000;

# OCSP認証とステープリング(キャッシュみたいなもの)を有効にする
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

## OCSPレスポンスを行うRoot CA 証明書(fullchainでOK)
ssl_trusted_certificate /etc/letsencrypt/live/blog.potproject.net/fullchain.pem;

これをインクルードして設定。nginxの再起動も忘れずに。

af

これでA+になりました。やったぜ。

・・・でもこれが原因でレスポンスなんかがめちゃくちゃ遅くなるんだったら戻しますけどね。

セキュリティより可用性の方が大事ですわな。

Centos+nginxでLet’s encrypt(certbot)導入と自動更新まで

react-nativeをとりあえずすぐ実機で動かしてみる
そろそろモチベとネタが落ちてきた。どこまで続くか・・・

potproject.net Advent Calendar 2016
3日目の記事です。


ちょっと前にLet’s encryptの導入方法などを書いていましたが、

もはや古くなっている感じだと思います。

というよりいつの間にやら日本語ポータルとか出来ていたりと、かなり充実してきていてびっくりです。
手順も前とかなり変わってきているので、新しく書き直します。

今回はcertbotクライアントを使用し、自動更新までやります。

certbotは元々letsencrypt-autoだったクライアントの名前が変わったものっぽいです。

yumなんかでもインストールが可能になりました。

certbotのインストール(centos7)

epelリポジトリからインストール可能です。

yum install epel-release
yum install certbot

これで終了。初期と比べると手軽になったものです。

Apacheの場合はpython-certbot-apacheというパッケージも必要らしいです。

centbotからSSL証明書の発行

ここで、同じようにApache,nginx,webroot,standaloneといういろいろなプラグインを選べます。

  • Apache : Apacheに最適化したプラグイン。設定を自動書き換え。
  • nginx : nginxに最適化されたプラグイン。設定を自動書き換え。アルファ版らしい
  • webroot : rootにファイルを置くことで認証。Apacheでもnginxでも使える
  • standalone : 自動的にWebサーバを立ち上げて認証。但し現状の鯖は停止する必要あり
  • manual : 手動で認証。Webサーバーを止める必要が無かったりするらしいが結構難しい

個人的にですが、Let’s encryptの導入設定はstandaloneを自分はおすすめします。前も言ってた気がしますが。

Apacheやnginxのプラグインは楽だと思いがちですが、実際Apacheは必要パッケージが無いと動かなかったり、nginxはまだアルファ版だったり不安要素が残ります。

そして上2つの一番嫌なところは、自動的に認証してくれるということで、Apacheやnginx設定を変更されてしまうのです。

これが設定破壊されそうで怖い。

webrootは指定したWebのrootに勝手にファイル置かれて、認証後もそのままなのでなんか気持ち悪いです。(アクセス出来ちゃいますし)

なので自分は自動で楽に使えるstandalone版を使っています。

止まっちゃうのは致し方ないけれど、個人レベルであれば数秒くらいは容認できますよね。

certbot

これをコマンドに打ち込むことでGUI設定が出来ます。全てコマンドで自動化も出来るらしいですが、

手順に沿ったほうが確実かなと。
完了すればSuccessfulが表示され、

秘密鍵: /etc/letsencrypt/live/ドメイン名/privkey.pem

公開鍵: /etc/letsencrypt/live/ドメイン名/cert.pem
に鍵が配置されます。

Webサーバ設定(nginx)

この辺は試行錯誤が必要と思いますが、おおむねこんな感じです。http2対応版。

//略//
server {
    # TCP PORT Setting
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    # ServerName & Root
    server_name [ドメイン名];
    root /var/www/;

    #SSL Setting
    ssl_certificate /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ...
    //略//
}

ssl_ciphersは受け付ける暗号化スイートの優先順位らしいです。

!がついているものは使用しない。MD5とかは当然除外です。
これが最低限の設定。もっとセキュリティを高めるにはssl_ciphersやssl_protocolsを的確に設定したほうがいいらしい。

例えば、MD5は上の例で除外されてますが、他にも外すものは結構あるでしょう。つうか暗号スイートなんて数が多すぎて流石に普通把握できない。  
他にもSSLv3は最近POODLEという脆弱性が一時期人気になって一躍有名になったので外したい。

そこで、MozillaさんがSSL設定ジェネレータを公開しているということを知った。

これすごく使えますね。しかもセキュリティもMozillaなのでピカイチです。

Mozilla SSL Configuration Generator
https://mozilla.github.io/server-side-tls/ssl-config-generator/

    #DH鍵交換に使用するパラメータファイル
    ssl_dhparam /path/to/dhparam.pem;

    #SSLプロトコルの指定と暗号化スイートの優先度設定
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS ヘッダ
    add_header Strict-Transport-Security max-age=15768000;

このあたりをしっかり設定することでセキュリティが上がって大手企業レベル並のセキュリティを確保できそうです。

・・・鯖負担は上がりそうですが。

証明書の自動更新

2回目以降は一々入力せず同じ内容に更新できるようになります。

これはletsencrypt-auto時代には無かった気がします。

certbot renew

使えるオプションとして –quiet でログ出力しない、 –dry-run で更新テスト(実際には更新しない)が出来ます。

更新できる回数は週に何回だと決められているようで、それを突破すると更新できなくなるので使いすぎに注意。
これを押すだけで自動更新、ってまあコマンド打ってたら自動じゃないじゃんということで、これをそのまま自動実行デーモンであるcronに登録します。
今回はnginxです。apacheならapache(httpd)でお願いします。

crontab -e

0 1 1 * * root service nginx stop && certbot renew -force-renew && service nginx start

一度サーバを止めて、更新後にまたサーバをスタートしたいので、こういう風に書きました。

どっちにしろサーバを止める必要があるならこれが一番かなと思います。
これでSSL導入完了。せっかくなのでhttpは止めるかリダイレクトしましょう。


4日目 →

AWS Certificate Managerが提供開始。AWSで無料SSLが提供される

New – AWS Certificate Manager – Deploy SSL/TLS-Based Apps on AWS https://aws.amazon.com/jp/blogs/aws/new-aws-certificate-manager-deploy-ssltls-based-apps-on-aws/

きたか・・・

というか今までありませんでしたね。そういえば。
最近はさくらも共有SSLなら無料になりましたし、ただ共有SSLなのでちょっとアレですが。
これは共有SSLではなく独自が配布されそうです。実際に見てないから確定とは言えないけど
ただ、EC2単体やS3単体で動作せず、Amazon ELB(ロードバランサー)とCloudFront(CDN)をかまさないと動作しないらしい。
つまりは無料というよりELBやCDN使ってくれれば特典として使えるといったほうが正しいかも。

Let’s Encryptもいいのですが、こういう風に各VPS提供サービスがみんなSSLを配布してくれたら楽でいいなあ。
更新も自動でやってくれるようだし。
あと、個人的に好きなだけなんですがVerified:Amazonとなるのがいい。ちょっとうらやましい。
US East (バージニア北部)のみ現在対応。日本ユーザーは日本かUS Westが多いと思うので、よりすぐ導入しようとしてもまだ使えないかも。

SSL証明書”Let’s Encrypt”でhttps環境を構築した

ついに、以前記事で紹介したLet’s Encryptがpublic Betaになり、誰でも使えるようになりました。

それ以前に、自分はClosed Betaに参加していたので、それで実は結構前から動かしていました。
今回は、どんな感じで動くのかのレビュー記事です。

前の記事:無償利用で使えるSSL証明書”Let’s Encrypt”を仮想環境で動かしてみたかった
Preview版ではvirtualenvを自分で作成しないとならないため、割と手間でしたが、今回は、
ダウンロードした後に./letsencrypt-autoというコマンドを打つだけで、
必要なもののインストールから、let’s Encrypt clientのコンパイル、Apacheやnginxのインストール、そしてSSLの導入、全てを自動で行ってくれるようになり、さらにわかりやすく、楽になりました。
これだけでhttps対応のWebサーバが最初から作れるっていうことですね。

自分のサーバのnode.jsでプロキシを組んでるので、SSL証明書はnode.jsに組み込みます。
なので、スタンドアローン版を選択し、生成された証明書を手動で組み込みます。
スタンドアローンの場合、本当にそのドメインが存在しているか確認のため、80/443ポートを使ってlet’s EncryptのAPIにアクセスしてるような挙動をします。
なので、既にWebサーバを立てている人は一時的にサーバが使えなくなります。まあ設定は数分で終わりますが。
Apacheやnginxの場合でも、自動で作ると(多分)SSLの設定も勝手に作られちゃうと思うので、
知識のある人ならスタンドアローンで証明書だけ作って、自分で設定を作って組み込んだほうがいいかもしれません。

証明書に関しては、/etc/letsencrypt/liveに格納されています。

  • privkey.pem (サーバ秘密鍵)
  • cert.pem (サーバ証明書[公開鍵])
  • chain.pem (中間CA証明書)
  • fullchain.pem (サーバ公開鍵+中間CA証明書)
    が入ってます。
    node.jsの場合は、privkey.pem、cert.pemを組み込めば動きました。
    node.jsのhttps対応に関しては、この記事を参考に。
    [node.js]HTTPS通信に対応させてみる(SSL-リバースプロキシ環境を構築する)
    そして、導入したものがこちら。
    letsencrypt
    オレオレ証明書ではなく、ちゃんとLet’s Encryptから正式なものと証明されています。
    これで毎回Chromeさんに情報抜き取られるサイトかもしれないという報告を受けなくて済みます。自分のサイトなのに。
    まだ証明書の期限は短く、3カ月(90日)となっていますが、
    ベータではなく正式版になれば、期間が延び、自動更新も可能になるかもしれません。

無償利用で使えるSSL証明書"Let's Encrypt"を仮想環境で動かしてみたかった

lets
Let’s EncryptのDeveloper版がなんか公開されてましたので、なんとなく使ってみました。
まだdeveloper版なので本番環境では使えません。というか、セキュリティ的に使うなよ!絶対使うなよ! って感じです。
・・・いや、さすがに怖いのでまだ本番では使わないのですが。

Let’s Encryptに関しては、ニュースサイトなどで取り上げてるところも多かったので、知ってる人は知ってると思いますが、
簡単に言うと無償で使えるSSL/TLS証明書(ちゃんとした署名付き)が使えます。
これをやっているのでfirefoxのMozillaさんやネットワークのラスボスCiscoさんなんかが参加してる団体です。なので多分セキュリティ的にも問題ないはずです。
無料で容易なHTTPS導入を支援する「Let’s Encrypt」、2015年に運用開始へ

このLet’s encryptのソースはgithubにあります。てっきりサイトで証明書だけ発行してダウンロードするタイプと思ったら、
そんなわけではなくインストールして端末からコマンドで発行します。
コマンド1発で証明書を生成することができますが、同時にapacheやnginxサーバーなども作ってくれたりもする様子。こりゃ簡単ですね。
Let’s Encryptは、無償で使える以外にも簡単にすぐ扱えることもコンセプトなので、インストールからサーバ構築まで多分数行で終わります。素敵です。

そんなわけで、動かす。仮想環境はご存知Ubuntu15.04を用意。ダウンロードで1時間掛かりました

インストール方法はここにあります。Using the Let’s Encrypt client
Ubuntuであれば、githubからファイルをダウンロードした後、sudo ./bootstrap/ubuntu.shと打つと自動で必要なパッケージを取得してきます。
その後、インストールは、
virtualenv --no-site-packages -p python2 venv
./venv/bin/pip install -r requirements.txt acme/ . letsencrypt-apache/ letsencrypt-nginx/
と打てばいいそうです。
virtualenvとは、pythonの仮想環境らしいのですが、なぜこれを使うかというと、元々のpythonに上書きしてぶっ壊さないようにらしいです。
ちゃんと、注意書きにぶっ壊しても知らねーぞと書いてありました。

で、ここで動かない。どうやら一括でインストールしたはずなのにpipが入っておらず実行できない。
ということで、sudo apt-get install python-pipで手動インストール。
まだpreview版なせいか、いろいろ警告出てる気がするのですがようやく動いた。

動かすにはこれを入力。
sudo ./venv/bin/letsencrypt auth すると・・・
lets2
わざわざGUIで操作できる親切設計。
lets3

今のところ、立てられるサーバはapacheだけの模様。
その後、メールアドレス登録やドメイン名が求められます。
が、途中でエラー出るし、メールアドレスには届かないし・・
githubの説明にも書いてないので、まだ動かないのだろうか。というかまだ認証鯖が動いてないから動かない?
まあpreviewなんで。こんな感じで動きますよってことですね。

今、ベータプログラムの募集なんかを行っているようです。
https://letsencrypt.org/2015/09/14/our-first-cert.html

公式ブログによると、正式公開は2015/11/16の週(General availability: Week of November 16, 2015)とのことなので、気長に待ちましょう。