nginx
letsencrypt

Let's encryptでnginxのBASIC認証つきSSLリバースプロキシ

More than 1 year has passed since last update.

開発用サーバーをEC2に移行したが、開発中のWebアプリを動かしてブラウザから見に行きたい。
一時的にせよ全世界に公開はマズイ感じがするので、BASIC認証ができるようにnginxでSSLリバースプロキシを組んだ。

Let's encryptの使いかた

サーバも何も入れてないところからのスタートの場合、Standaloneが簡単のようだ。

git clone https://github.com/letsencrypt/letsencrypt

--helpで依存パッケージをとってきたり、新バージョンを探し始めるので、注意。
443しかポート開けてなかったので、次のコマンドを実行した。質問に答えていくとキーが生成されている。すごい。

オプションはHow-to系のサイトを見てもよくわからないので(仕様が変わった?)、これも鵜呑みにせずにそのときの公式ドキュメントかhelpを見るのがよさそう。

./letsencrypt-auto certonly --standalone --standalone-supported-challenges tls-sni-01

追記:証明書の更新

Standaloneで証明書を更新しようとすると、Webサーバを止めないといけない、というのが欠点らしい。
cronなどで適当なタイミングで次のコマンドを起動するようにする。数秒くらい止まっても良いならコマンド実行時だけnginxを止めておけばよい。
止めたくない場合はwebrootプラグインを使えば良い、とのこと。

./letsencrypt-auto renew

nginxの設定

ubuntuのお作法に従うとnginx.confはあんまり編集してはダメなのかな・・?
基本的な設定はここを参考にした。

セキュリティ

SSLv3など古い機能がデフォルトで有効になっていたので蓋をする。基本的に自分しか見ないので、古いブラウザのサポートは気にせず高セキュリティ設定にした。
ssl_protocolsがちょっと冗長な感じもするが、意図した設定にはなっているみたいなので、細かいことは気にしない。

参考:Webサーバー nginx における SSL証明書設定の安全性向上 ~SSL Server Test で A+ 判定を目指して~

.htpasswdファイルの生成

ubuntuだと、apache2-utilsにコマンドが入っている。

htpasswd -c .htpasswd username

設定ファイル

/etc/nginx/sites-available/example, /etc/nginx/sites-enabled/example

server {
    listen 443;
    listen [::]:443;
    server_name example.juntaki.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.juntaki.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.juntaki.com/privkey.pem;

    ssl_session_timeout 5m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDH !aNULL !eNULL !SSLv2 !SSLv3';

    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=15768000; includeSubdomains";

    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
    location / {
        deny all;
    }
    location /8080/ {
        proxy_pass http://localhost:8080/;
        proxy_redirect default;
    }
}

/etc/nginx/conf.d/reverse_proxy.conf

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

まとめ

Let's encryptであっという間にSSLのキーがもらえる。
SSLでBASIC認証を使うことで、安全に開発用のプレビューができそう。