【Linux】Let’s Encryptで無料でSSL認証されたサーバを作る

内容

以前、「RaspberryPiでWebサーバを公開(WordPress)」という記事を執筆しました。この記事では、SSL証明書は使用せずに、非セキュア(?)なhttpのサイトの公開方法を紹介しました。

SSL証明書を無料で取得してhttpで公開してるサイトをhttps化しちゃいましょうってやつです。
何がいいかってなんか良くない?
なんか、うん。
暗号化通信って響きがもうかっこいいよね

Let’s Encryptとは

「そもそもLet’s Encryptってなんですの?」って人、絶対いますよね
どうやってこの記事までたどり着いたんですかねぇ…SSLとか証明書とかかな?
まぁいいけど、Let’s EncryptってのはSSL/TLS の暗号化通信に用いる証明書の認証局(CA; Certificate Authority)の1つ。
世界中には様々な認証局があるんだけど、Let’s Encrypt には次の特長がある

  • 自由に使える
  • 自動で署名される
  • オープン
  • 証明書の有効期間は90日
  • 期限が切れても自動で更新できる

って感じですかね

実際に入れてみる

筆者の動作環境

つまりこのサーバの動作環境はこんな感じ

  • Ubuntu18.04 LTS
  • Apache2.4.29

サーバが動いてさえいればなんら問題はない。ただ、Apacheのバージョンによっては使用するファイルが異なってきたりするかもしれない。

Let’s Encryptをインストールする

インストールするっていうとちょっと違うかも。
まぁ細かいことは気にしないでさっさと本題に入ろうか
まずは、certbotと言われる、Let’s Encryptと通信して証明書を取得するためのツールをゲットします。
リポジトリを登録することでaptコマンドでインストールできます

# add-apt-repository ppa:certbot/certbot
# apt update
# apt install certbot python-certbot-apache

ダウンロードしたら、certbot-autoコマンドを用いて証明書を発行していきます。

# certbot certonly \    # 証明書の作成
     --webroot \              # 既存のウェブサーバを使うモードを選択
     -w /var/www \            # 証明書を得たいWebサイトのドキュメントルート
     -d koron0902.ddns.net \  # 認証するドメイン名
     --email 

途中で規約に同意するかとか尋ねられると思いますが、同意しておいてください。
同意すると証明書を得ることができます。(同意しないとどうなるんだろ…やっぱり取得できないんだろうね)
certbotはサイトが存在しているかどうかの確認を「サイトにアクセスできるかどうか」で確認しています。
なんで、自宅サーバでルータのポート解放を行なっていなかったり、iptablesとかの設定でアクセス拒否しているとうまく証明書を得ることができません。

--webrootではなく--standaloneを使うと多分成功します。
うまく証明書を取得できるとこんな感じの文章が出てきます。

IMPORTANT NOTES:  
- Congratulations! Your certificate and chain have been saved at
    /etc/letsencrypt/live/secure.zem.jp/fullchain.pem. Your cert will
    expire on 2016-10-09. To obtain a new or tweaked version of this
    certificate in the future, simply run certbot-auto again. To
    non-interactively renew *all* of your certificates, run
    "certbot-auto renew"  
- If you lose your account credentials, you can recover through e-mails sent to 

すると、証明書関連のファイルが/etc/letsencript/live以下に保存されています。
今回認証に使ったドメインはkoron0902.ddns.netなので、証明書が保存されているフォルダは/etc/letsencript/live/koron0902.ddns.netになります。

# ls -l /etc/letsencrypt/live/koron0902.ddns.net 
total 0
 lrwxrwxrwx 1 root root 42 Sep 15 12:38 cert.pem -> ../../archive/koron0902.ddns.net/cert1.pem 
lrwxrwxrwx 1 root root 43 Sep 15 12:38 chain.pem -> ../../archive/koron0902.ddns.net/chain1.pem 
lrwxrwxrwx 1 root root 47 Sep 15 12:38 fullchain.pem -> ../../archive/koron0902.ddns.net/fullchain1.pem 
lrwxrwxrwx 1 root root 45 Sep 15 12:38 privkey.pem -> ../../archive/koron0902.ddns.net/privkey1.pem 

これで、証明書の取得は終わりです

Apacheに証明書を適用する

最後に、実際にSSL通信を行うためにApacheにさっき取得したSSL証明書を適用します。
/etc/apache2/site-available内に、default-ssl.confがあると思います。
これが、SSL通信用の設定ファイルの雛形になります。
これをコピーして使います。

cd /etc/apache2/sites-available/
sudo cp default-ssl.conf 000-default-ssl.conf

必要になる設定は、

  • SSLEngine <– そもそもSSLを使うかどうか
  • SSLCertificateFile <– 証明書のファイルを指定
  • SSLCertificateKeyFile <– 証明書の鍵を設定

の3つです。
で、これをそれぞれ次のようにします。

  • SSLEngine on
  • SSLCertificateFile /etc/letsencrypt/live/ドメイン名/fullchain.pem
  • SSLCertificateKeyFile /etc/letsencrypt/live/ドメイン名/privkey.pem

ファイル全体でまとめるとこんな感じ


                                 SSLOptions +StdEnvVars
                 
                 
                 BrowserMatch "MSIE [2-6]" \
                                 nokeepalive ssl-unclean-shutdown \
                                 downgrade-1.0 force-response-1.0
                 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
         
  

で、そしたら保存
あー、アクセスコントロールは各自で設定お願いします。
でもって、Apacheに関しても一つ二つやることがある。
まずは、SSLのモジュールを有効化してやる。

# a2enmod ssl

で、Apacheで有効になってるサイトは/etc/apache2/site-enabledにシンボリックリンクが貼られるんだけどどうするかってのもちゃんとコマンドがある。
今回のファイルは000-default-ssl.confだから

# a2ensite 000-default-ssl.conf

これで、site-enabledにシンボリックリンクが貼られてるからあとはApacheを再読み込みするだけ。

# service apache2 reload

これでサイトにアクセスしてみてちゃんとSSL通信が有効になってたら成功。
なってなかったらまた確認するなり他のサイトも見てみるなり諦めるなり選択肢はたくさんあるから頑張って

–2019年3月1日追記–

期限が切れたら自動で更新されるって冒頭で書いてるけど切れたらやっぱ怖いのでcronで更新をスケジュールしてみよう.

# crontab -e

# &は小文字に置き換えて
00 0 1 */2 * /usr/bin/certbot-auto renew --force-renew && service apache2 restart

そういえば最近はバージョン管理ツールでcertbotがインストールできるみたいなのでそれを試してもいいかも

-2019年3月8日追記-

今はfedoraでサーバを公開してるんですが,dnfで入れたcertbotをアプデしたら下記のエラーが

SSLCertificateFile: file '/etc/letsencrypt/live/koron0902.ddns.net/fullchain.pem' does not exist or is empty

そこでファイルを見てみる...ちゃんとあるやん......

要因はパーミッションが勝手に変更されていたというものでした.

# sudo ls -l /etc/letsencrypt/
合計 28
drwx------. 3 root root 4096  1月  3 04:23 accounts
drwx------. 3 root root 4096  1月  3 04:24 archive
drwxr-xr-x. 2 root root 4096  3月  8 05:09 csr
drwx------. 2 root root 4096  3月  8 05:09 keys
drwx------. 3 root root 4096  1月  3 04:24 live
drwxr-xr-x. 2 root root 4096  3月  8 05:09 renewal
drwxr-xr-x. 5 root root 4096  1月  3 04:23 renewal-hooks

てことで,archiveliveの権限変更

# chmod 755 live archive

こんでOK!!

-2019年07月14日追記-

SSL証明書が有効になるのはhttpsプロトコルでアクセスしてきた場合のみ.しかしサイトにアクセスしてくる人が非SSLサイトにアクセスしてこないとも限らない.そこで,80ポートにアクセスしてきたら443ポートにリダイレクトするような設定をしよう.

  
                                                   
 DocumentRoot /var/www
 ServerName 任意  
 RewriteEngine On   
 RewriteCond %{HTTPS} off   
 RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
 
 

で,これを設定した時に不都合がある.というのも,Let’s Encryptの証明書発効は80ポートにアクセスしてサイトが存在するかどうかを確認するプロセスが含まれている.しかしこの設定を有効化してしまうと80ポートにアクセスしてきた時のレスポンスが301であるためにサイトの存在証明ができない.

そこで,証明書の更新にはapache等で立てているサーバを参照するのではなく,certbot自体のサーバを代替サーバとして存在確認を行うようにする.

# service apache2 stop
# certbot-auto renew --standalone
# service apache2 start

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です