Let's encrypt で無料SSL運用

Let's Encrypt(以下LE) の導入手順

導入手順

  • LE のダウンロード
  • 前処理: Port80 でドメインの所有証明
  • LEで証明書取得
  • DH対応
  • LE導入後のPort443,80設定
  • 自動更新設定

secure.example.com で導入例

LE のダウンロード

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

前処理: Port80 でドメインの所有証明

導入前のnginx のconfig

$ cat /etc/nginx/sites-enabled/secure.example.com
server {
  listen              80;
  server_name         secure.example.com;
  location '/.well-known/acme-challenge' {
  default_type "text/plain";
    root        /tmp/letsencrypt-auto;
  }

  location / {
    root        /tmp/letsencrypt-auto;
    #return              301 https://$server_name$request_uri;
  }
}

nginx に設定を反映しておく

$ sudo service nginx configtest && sudo service nginx reload

エラーだとnginxの設定がなにかおかしい。修正するまでくりかえす。

LEで証明書取得

$ MAIL="your_mail_address@example.com"
$ /home/cameong/letsencrypt/letsencrypt-auto certonly --webroot --webroot-path /tmp/letsencrypt-auto/ -d secure.example.com --server https://acme-v01.api.letsencrypt.org/directory -m $MAIL

下みたいになればok

Checking for new version...
Requesting root privileges to run letsencrypt...
   sudo /home/cameong/.local/share/letsencrypt/bin/letsencrypt certonly --webroot --webroot-path /tmp/letsencrypt-auto/ -d secure.example.com --server https://acme-v01.api.letsencrypt.org/directory -m your_mail_address@example.com

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/secure.example.com/fullchain.pem. Your
   cert will expire on 2016-07-20. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

この際、公開鍵, 秘密鍵が以下のPATHに設置される

path
証明書 /etc/letsencrypt/live/secure.example.com/fullchain.pem
秘密鍵 /etc/letsencrypt/live/secure.example.com/privkey.pem

Diffie-Hellman対応

暗号強度を強めるために、DH対応を行う。

$ sudo openssl dhparam -out /etc/ssl/private/dhparam.pem 2048

LE導入後のPort443,80設定

$ cat /etc/nginx/conf.d/secure.example.com
# HTTPS サーバの設定
server {
    listen 443 ssl;
    # nginx 1.9.5 以降の場合
    # listen 443 ssl http2;

    server_name secure.example.com;
    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/secure.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secure.example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    # 環境によっては off にすると動かないので注意 (default は on)
    ssl_session_tickets on;

    # 2048bit 推奨
    ssl_dhparam /etc/ssl/private/dhparam.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;

    ## HTTPS のみでサービスを提供する場合にだけ設定します
    #add_header Strict-Transport-Security max-age=15768000;

    # HPKP (HTTP Public Key Pinning) に対応すると更に安全性の高い設定になりますが、運用コストが上がるのでここでは省略します。

    # OCSP Stapling に対応すると暗号化通信の開始を早めることが出来ます。ここでは省略します。

    # ドキュメントルート
    root /var/www/html/secure.example.com;
    error_page 404 /404.html;
    access_log /var/log/nginx/secure.example.com_access.log main;
    error_log  /var/log/nginx/secure.example.com_error.log error;
}

server {
  listen              80;
  server_name         secure.example.com;
  location '/.well-known/acme-challenge' {
  default_type "text/plain";
    root        /tmp/letsencrypt-auto;
  }

  location / {
    return              301 https://$server_name$request_uri;
  }
}

自動更新設定

cat /usr/local/bin/auto-update_le.sh
#!/bin/bash
DOMAINS="-d secure.example.com -d www.example.com"
DIR=/tmp/letsencrypt-auto
LETSENCRYPT="/home/cameong/letsencrypt/letsencrypt-auto"
[ -d $DIR ] || mkdir -p $DIR
$LETSENCRYPT certonly --server https://acme-v01.api.letsencrypt.org/directory -a webroot --webroot-path=$DIR $DOMAINS --force-renew && service nginx reload

cronに設定する

cat /etc/cron.d/auto-update_le
# 毎月2日10:00に鍵を更新する
0 10 2 * * root bash /usr/local/bin/auto-update_le.sh > /var/log/auto-update_le.log 2>&1

HTTPS の強度測定

ssllabsでhttpsの強度を測定する。

参照

qiita.com

cameong.hatenablog.com

google webmaster tool ドメインを登録をnginx の設定だけで実現する

server ディレクションに以下を追加

/googledg2d2c1f4c67d739.htmlの箇所はwebmaster tool でアクセスするパスになります。

  location = /googledg2d2c1f4c67d739.html {
            rewrite ^/(.*)  $1;
            return 200 "google-site-verification: $uri";
    }

参考 How do I verify site ownership on Google Webmaster Tools through nginx.conf? - Server Fault

Let's Encrypt を自動更新するためのNginxの設定

example.com example.jpの2つのドメインをLet's Encrypt でtls 化しているとする。

ドメイン所有の確認の理由からPort80に設定を入れる。

nginx

Port 80 の設定

server {
  listen              80;
  server_name         example.com example.jp;
  location '/.well-known/acme-challenge' {
  default_type "text/plain";
    root        /tmp/letsencrypt-auto;
  }

  location / {
    return              301 https://$server_name$request_uri;
  }
}

自動更新 スクリプト

#!/bin/bash
DOMAINS="-d example.com -d example.jp"
DIR=/tmp/letsencrypt-auto
LETSENCRYPT="/PATH/TO/YOUR/letsencrypt-auto"
[ -d $DIR ] || mkdir -p $DIR
$LETSENCRYPT certonly --server https://acme-v01.api.letsencrypt.org/directory -a webroot --webroot-path=$DIR $DOMAINS --force-renew && service nginx reload

あとはこのスクリプトをcronなどに仕込む。

One-line certificate generation/renews with Letsencrypt and nginx · GitHub

chromeのHSTSキャッシュを削除する

http のリクエストが勝手にhttps にリダイレクトされる事案が発生しました。

状況としては↓な状況

beniyama.hatenablog.jp

サーバ側は設定を変更・再起動でよいけど ブラウザに残ったHSTS キャッシュが消えないかぎり、https にリダイレクトされ続けます。

キャッシュ消えるまで待つとかつらすぎるので、chromeのHSTSキャッシュを削除します

chromeのHSTSキャッシュを削除する方法

  • chrome://net-internals/#hsts をchrome のURLに入力し、移動する。
  • Delete domain の箇所に削除したいドメインを入力します。
  • Delete ボタンをクリックします。

gyazo.com

vpn 接続時に SSH2_MSG_KEXINIT でハングするときの対処

  • pritunl v1.18.902.26
  • Tunnelblick 3.5.7 (vpn client)

pritunl をつかってVPN環境が構築した。

モバイル回線だと特に不便なくVPN接続できていたのだが、有線にしたところssh が繋がらない状態になった。

% ssh app-001.cameong.local
:
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.2
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1
debug1: match: OpenSSH_6.6.1 pat OpenSSH*
debug1: SSH2_MSG_KEXINIT sent

どうやらMTUの設定値関係してそう。

MTU = 1454

この PPPoE では Ethernet の MTU = 1500 の世界の中に、 RFC2516 的には 6 バイトの PPPoE へッダと 2 バイトの ppp へッダを加える。このため、 1500 - ( 6 + 2 ) = 1492 バイトまでのパケットしか通れないことになる。つまり MTU = 1492 にする。 しかし NTT 東日本の場合、更に内部のネットワークの事情で 「MTU = 1454 にしておけば、必ずどこでも通る」ということになっているらしい。 これらの数字は、 通常の Ethernet の通信に使われる 1500より小さくなるので、問題が起きる。と言える。

MTU @ki.nu

たしかに mtu 1500 になっている。

// ifconfig
:
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
        inet 10.0.5.2 --> 10.0.5.2 netmask 0xffffff00

tunnelblick の設定にMTUの変更( link-mtu) を加える

   verb 2
   mute 3 
   push-peer-info
   ping 10
   ping-restart 60
   hand-window 70
   server-poll-timeout 4
   reneg-sec 2592000
   sndbuf 100000
   rcvbuf 100000
   remote-cert-tls server
+ link-mtu 1454
   comp-lzo no
   auth-user-pass
   key-direction 1

確認

% ifconfig 
:
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1384
        inet 10.0.5.2 --> 10.0.5.2 netmask 0xffffff00

mtu 1454より小さくなってるけど。

この設定で、ssh 接続可能になりました。

気になる謎

  • VPN接続なしの場合、en0 から接続してるのだが、en0 のmtu が1500 でも繋がるのなぜ。
  • link-mtu 1545 なのに実際は1384 になってるのなぜ。

詳しい方、教えてください!

追記

  • mtu 1454 だと時間がたったら、再度sshできなくなる。
  • mtu 1400 でトライ

AWS RDS mysql 5.7.10だと360日でアカウント強制無効化されるとか聞いてないよ

  • 日時: 2016/03/03

mysql 5.7 がAWS RDS で使えるということで、使ってみました。

そうすると、気になる記事を発見

アカウントの自動失効

MySQL 5.7で新しく追加された機能の1つに,アカウントの自動失効機能があります。これは最後にパスワードを変更した時間からデフォルトで360日が経過すると,そのアカウントをEXPIRE(無効化)しその後のログインを許可しないという強烈なオプションです。テストのために都度ビルドして利用するようなケースで問題になることは少ないかと思いますが,作成したイメージをそのまま長期間利用する(あるいは,ビルド時にユーザを作成し,その後アカウントが追加されることはあってもパスワードが変更されることはないようなケース)場合はこの機能をOFFにしておいた方がいいでしょう。

引用元

http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0010

MySQL 5.7.11でdefault_password_lifetimeのデフォルトは0に変更になりました!

引用元 http://yoku0825.blogspot.jp/2015/06/mysql-574defaultpasswordlifetime.html

とのことで

  • mysql 5.7.0 ~ 5.7.10 は 360日経過するとデフォルトでアカウントが無効化される
  • mysql 5.7.11 以降 デフォルトでアカウント無効化しない.
  • AWS のRDS mysqlは 5.7.10

AWS が気を利かせてデフォルト値を変更しててくれてないかなと期待して見てみると

mysql> select @@default_password_lifetime;
+-----------------------------+
| @@default_password_lifetime |
+-----------------------------+
|                         360 |
+-----------------------------+
1 row in set (0.01 sec)

はい、360日で無効化されてしまいますね。

AWSコンソールから default_password_lifetime を 0にするように変更します。

利用中のパラメーターグループを選択し、default_password_lifetime の値を0に変更します。

gyazo.com

変更後

mysql> select @@default_password_lifetime;
+-----------------------------+
| @@default_password_lifetime |
+-----------------------------+
|                           0 |
+-----------------------------+
1 row in set (0.00 sec)

無停止で変更できました。

これで強制無効化はなくなった。よかった。