Skip to content

Instantly share code, notes, and snippets.

@nnks1010
Last active December 2, 2018 04:57
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nnks1010/5d545a5a44719539587e3431f840470c to your computer and use it in GitHub Desktop.
Save nnks1010/5d545a5a44719539587e3431f840470c to your computer and use it in GitHub Desktop.
🔒🔑Let's Encrypt!!

これは 高知工科大 Advent Calendar 2017 の1日目の記事です

どうもはじめまして。高知工科大 情報学群3年のNtomoya改めnnksです。相変わらず音ゲー大好き人間です.
今年は自分がアドベントカレンダー立ち上げましたがみなさん参加してくれてとてもありがたいです.

それなのに1日目の記事を書かないのはどうなん??と思い1日前に書いてる所存です:innocent:

Let's Encrypt!!

みなさんWebサーバ建ててますか??Webサーバを立てると通信の暗号化をしてみたいですよね.
しかし証明書の発行にはお金がかかります:weary:

そんな時に助けてくれるのがLet's Encryptです!

Let's Encrypt とは?

一言で言うとドメイン認証のSSLサーバ証明書を無料かつ簡単に発行することのできるサービスです.
要は:lock:絶対にWeb上の通信を暗号化させたいマン🔒ですね.詳しくは公式をみてね.日本語版の総合ポータルサイトもあるよ.

このツールを使えば今日からあなたもセキュアな通信をすることができます.ではでは早速やってみましょう!

導入

最初に注意ですがこのLet's Encryptはドメイン認証ですので当然ドメインが必要です.
ドメイン登録をしていないという人は.moeで好きなキャラの名前でドメインを取得しましょう:blush:

自分が行った環境は以下のような感じです

  • OS: Ubuntu 16.04
  • Webサーバ: nginx

インストール

自分はgitから直接インストールを行いました

$ git clone https://github.com/letsencrypt/letsencrypt ~/.letsencrypt
$ cd ~/.letsencrypt/
$ ./certbot-auto --help

--help コマンドが実行されればインストール成功です.ちなみに certbot-auto コマンドはルート権限が必要です.

証明書の取得

Webサーバが動作している環境で example.com というドメイン名で運用していて, /var/www/html/ にあるAppサーバの証明書を取得したい場合は

$ ./certbot-auto certonly --webroot -w /var/www/html/ -d example.com

これだけでいけちゃいます.マジ便利かよ〜:heart::blush::tada:

-w がドメイン名に対応したAppサーバのDocumentRootで -d がドメイン名です.複数ドメインで証明書を取得したい場合は

$ ./certbot-auto certonly --webroot -w /var/www/html/ -d example.com -d www.example.com

みたいな感じでいけます.

ちなみに現在はワイルドカード証明書が発行できませんが(*.example.comみたいなやつ)2018年1月にワイルドカードの証明書の発行を行えるようになります.やったね!

インストールできたかを確認するには /etc/letsencrypt/live/example.com/ 下に証明書があるのでそこを確認してあったらokです.

$ sudo ls /etc/letsencrypt/live/example.com/
# => cert.pem  chain.pem  fullchain.pem  privkey.pem

証明書取得の自動化

Let's Encryptで取得した証明書は90日間しか有効期限がありません.なので期限が切れる前に新しい証明書を発行しなければなりません.

これってめんどくさいですよね?そのため,crontabでの自動化をします.

$ sudo crontab -e
# 毎月1日の5:00に証明書の更新を行い,nginxを再起動する
0 5 1 * * /path/to/.letsencrypt/cerbot-auto renew && systemctl reload nginx 

/path/to/の所にはインストールした所の絶対パスを書いてください.
cerbot-auto renew とは有効期限が近づいてる証明書をチェックして新しい証明書に更新してくれるコマンドです.ほんと便利ですね.

SSLの設定

すぐに証明書の取得終わっちゃいましたね...それではこれから実際にnginxでSSLの設定を行なっていきたいと思います.

お好みのvimエディタでnginxの設定ファイルを開いて編集してください

$ sudo nvim /etc/nginx/sites-available/default

自分のnginxの設定を載せておきます(なんかおかしな所あったら言ってください).
それと設定の説明をするのは:shit:めんどいんで各自調べてみてください.
調べてる途中に知ったんですがSSLの設定を生成してくれる便利なサイト(Mozilla SSL Configuration Generator)があったのでそれを活用するのが良さそうですね.

server {
    # httpへのアクセスをhttpsへリダイレクトさせる
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
}

server {
    # SSL configuration

    # SSL と HTTP/2 の有効化
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl on;

    # 取得した証明書の追加
    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    # SSLセッション情報のタイムアウト時間の指定
    ssl_session_timeout 1d;

    # Perfect Forward Security (PFS) の有効
    # 鍵を作成する必要がある
    # $ mkdir /etc/nginx/ssl
    # $ cd /etc/nginx/ssl
    # $ sudo openssl dhparam 2048 -out dhparam.pem
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # POODLEの対応 (SSLv1.0, v2.0, v3.0 の無効化)
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # サーバ側の暗号化スイートを優先
    ssl_prefer_server_ciphers on;

    # 使用する暗号スイートの明示
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

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

    # Online Certificate Status Protocol (OCSP) の有効
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;

    root /var/www/html/;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name www.example.com;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
}

編集を終えたらnginxを再起動して完了です.

$ sudo nginx -t
$ sudo systemctl restart nginx

設定したWebサーバのセキュリティの高さはSSL Server Testで確認することができます.
脆弱性が入るとスコアが下がるので月1で確認して常にセキュアなサーバを目指しましょう!!

最後に

🎉Let's Encrypt!!!!🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment