Let’s Encryptから証明書を取得して常時HTTPS化


  • Let’ EncryptからHTTPS(暗号化)通信に必要な証明書を無料で発行してもらいました。
  • HTTPSが有効になるようにApacheの設定を変更して、暗号化されていることを示す鍵アイコンが表示されることを確認しました。
  • HTTPでのリクエストをHTTPSに転送して常時HTTPS化しました。
  • HTTPSの証明書には有効期限があるので、自動的に更新できるようにしました。

  • 証明書の取得
  • Apacheの設定
  • 証明書の自動更新

HTTPSはWebの通信を暗号化するために使われていると一般的には思われています。しかし実際には暗号化だけでなく、Webサイトを運営する会社・組織の身元を保証する1ためにも使われています。

そのため身元を保証してもらいたい会社・組織は審査を受ける必要が有り、時間とそれなりのお金をかけて証明書を発行してもらっていました。その結果としてユーザは安心してオンラインで買い物をしたり預金を確認できます。

一方、身元の保証は必要なく単純に安全な通信のためにHTTPSを使いたいという場合には、これまでのやり方は非常に手間がかかりハードルが高いものです。そこで誰でもHTTPSの暗号化機能を手軽に使えるようにするためLet’ Encryptプロジェクトが、Webサイトの身元は保証しないけど暗号化に使用できる証明書を機械的かつ無料で発行する実験が開始されました。

会社・組織の身元保証が無いので商業利用向きではありませんが、個人のWebサーバでも簡単にHTTPSを使って安全な通信を行えるようになりました。

ここではHTTPSに必要な証明書の取得方法からサーバの設定、証明書の更新方法について説明します。

証明書の取得

HTTPSの証明書は、専用のプログラムletsencryptを使用して取得します。

letsencryptをインストール

letsencryptは、Debianなどパッケージとして配布されている場合も有りますが、Ubuntuではまだパッケージになっていなのでgitコマンドを使ってプログラムを取得します2

$ sudo apt-get install git # gitをまずインストールする。
$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

HTTPSの証明書を取得

letsencrypt-autoコマンドを実行してHTTPSの証明書を取得します。

WebサーバにApacheを使用している場合は、次のコマンドを実行します3

ただしこのコマンドを実行するとサーバが一時的に停止します。ダウンタイムを最小にするには、--apacheの代わりに--webrootオプション(webroot mode)を使用します4

$ ./letsencrypt-auto --apache

実行すると必要なパッケージがインストールされ、証明書を取得するために必要な質問をいくつかされます。質問に答えてしばらく(1分程度)待つとHTTPS証明書が/etc/letsencrupt/live/に保存されます。

もしかすると、証明書を取得するときにHTTPSポートが開いている必要があったかもしれません。その場合は、次の「HTTPSポート(443)を公開」を参照してください。

証明書を取得するときに質問される項目は次の3つです。

  1. 現在のApacheがホストしているドメインの内で証明書に含めるドメイン名。
  2. 連絡先のメールアドレス。
  3. Let’s Encryptを使用するための決まりに同意するか。

1.で選択したドメイン名は、全て同じ証明書を使ってHTTPS通信が行えます(SAN Certificate?)。また-dオプションで事前に対象のドメイン名を指定しておくことができます。

複数のサーバ名を指定すると「複数のサーバ名はサポートしていない」というようなエラーが表示されますが、問題なく使えています。

2.と3.の質問は、それぞれ--email--agree-tosオプションで事前に指定しておけます。

オプションの詳しい説明は、

$ ./letsencrypt-auto --help all

で取得できます。説明が表示されるのが遅いので、次のようにリダイレクトを使って説明を保存しておくと後で参照しやすくなって便利だと思います。

$ ./letsencrypt-auto --help all > help.txt

--apacheオプションは、証明書の取得の他にインストールもするということですが、具体的に何をしているのか私には分かりませんでした5。Apacheの設定を変えてくれるということもありませんでしたし、インストール機能がないwebrootでも証明書は同じ場所に保存されました。

またletsencrypt-autoを実行すると、/var/log/letsencrypt/letsencrypt.logにログが記録されます。

HTTPSポート(443)を公開

HTTPSで通信するには、HTTPS用のポートに外部からアクセスできる必要が有ります。

HTTPSポートを開くためには、次のルールをiptablesの設定に追加します。既にHTTP用のルールが書かれていると思うので、その後ろあたりに追加するのが良いと思います。また二番目のようにmultiportモジュールを使ってHTTPポートとHTTPSポートをまとめてルールにすることもできます。

iptables -A INPUT -p tcp --syn -m state --state NEW --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --syn -m state --state NEW --dport 443 -j ACCEPT

# or

iptables -A INPUT -p tcp --syn -m state --state NEW -m multiport --dports 80,443 -j ACCEPT

iptablesの設定はサイトを守る上で非常に重要ですので、十分注意してください。

Apacheの設定

HTTPSの証明書を取得できたら、その証明書を使ってHTTPS通信ができるようにApacheの設定を変更します。

SSLモジュールを有効化

HTTPS通信をするには、ApacheのSSLモジュールを有効にします。

次のようにしてSSLモジュールを有効にしますが、もしかするとletsencrypt-auto --apacheが既にモジュールを有効にしているかもしれません。もちろん既にsslモジュールが有効になっているときにこのコマンドを実行してしまっても問題はありません。

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl # optional

a2ensite default-ssl/etc/apache2/sites-enabledにSSL用の雛形default-sslが作成されますが、000-default.confに設定を加えても問題ありません。

Apacheの設定変更

実際にHTTPSで通信するにするには、<VirtualHost *:80/>に加えて<VirtualHost *:443/>を加えます。

例えば、私の場合はVirtualHostなので、次のような内容を設定に追加しました。

<VirtualHost *:443>
    # これまでの設定内容をコピーする。

    SSLEngine		on
    SSLProtocol		all -SSLv2 -SSLv3

    # Apache 2.4.7まで
    SSLCertificateFile    /etc/letsencrypt/live/_MY_DOMAIN_NAME_/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/chain.pem

    # Apache 2.4.8以降
    # SSLCertificateChainFileが廃止になった。
    #SSLCertificateFile    /etc/letsencrypt/live/_MY_DOMAIN_NAME_/fullchain.pem
    #SSLCertificateKeyFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/privkey.pem

    # 使用したSSLプロトコルと暗号化方式をログに記録することもできます。
    #CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

その他の設定オプションは、/etc/apache2/sites-available/default-ssl.confを参照して設定に追加します。

また/etc/letsencrypt/options-ssl-apache.confに書かれているようなグローバル設定は、/etc/apache2/mods-enabled/ssl.confで設定します。

設定を変更したら、次のコマンドで設定の書き方に問題がないか確認しておきます。

$ sudo apachectl configtest

SSLで接続できるか確認

Apacheの設定が終わったら、サーバを再起動してHTTPSで接続できるか確認します。

$ sudo service apache2 restart

まずApacheがHTTPSのポートを見ているか確認します。ApacheがHTTPSポートで待っている場合は、次のように表示されます。何も出力がないときはポート番号に間違いがないか設定を再確認してください。

$ ss -lnt | grep 443
LISTEN     0      128                      :::443                     :::*

次にWebブラウザからWebページを開いてみます。この時URLの頭をhttp:からhttps:に変更してページにアクセスします。

Webページを開けない時は、ファイアウォールでHTTPSのポートが閉じられていないか確認してください。

HTTPを転送して常時HTTPS化

常時HTTPS化するかはサイト毎のポリシーですので必須ではありません。

常時HTTPS化するには、HTTPで接続を求めてきたリクエストを全てHTTPSにリダイレクトします。この例ではリダイレクトステータスをR=301で恒久的な移動を示す301にしています。

<VirtualHost *:80>
    ServerName www.nosuz.jp
    LogLevel warn
    #LogLevel warn rewrite:trace8
    CustomLog ${APACHE_LOG_DIR}/access.log
    ErrorLog ${APACHE_LOG_DIR}/error.log
    RewriteEngine On
    RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

アドレスバーの鍵表示

HTTPSでアクセスすると多くのWebブラウザでは、通信が暗号化されていることを鍵アイコンが表示されます。

しかしHTTPSでアクセスしているのに鍵アイコンが表示されないことが有ります。この時は、画像やJavaScriptの読み込みなど一部にHTTPでのアクセスが使われています。

鍵アイコンを表示させるには、ページのソースを開いてhttp://となっている部分を探して、その部分をhttps://またはhtpを削除して単に//と変更します6

証明書の自動更新

Let’s Encryptが発行する証明書の有効期間は90日なので、最低三ヶ月に一度証明書を更新する必要が有ります。もちろんここも人が介在すること無く証明書の更新を自動化できます。

更新処理の自動化にはcronサービスを使用するのが簡単です。例えば次のようなエントリーをrootのcrontabに登録すると、奇数月7の15日3時21分に更新処理が行われます。

21 3 15 */2 * /_PATH_/letsencrypt-auto certonly --text --renew-by-default --webroot -w /var/www-root -d www.example.jp > /var/log/letsencrypt/renew-cert.log 2>1 && service apache2 restart

参照と脚注

  1. Webデザイナーなら知っておくべき サーバ知識相談室

  2. Quick Start Guide – Let’s Encrypt

  3. Ngixサーバの場合は、--ngixオプションが将来使えるようになる予定です。しかし現在は、--webrootオプションを使うなど他の方法で証明書を取得する必要が有ります。

  4. webroot modeを使用すると、起動中のWebサーバを使用して証明書を取得します。そのため多少時間がかかる証明書を取得する過程でもサービスを停止しないですみます。ただしHTTPSを有効にするところでWebサーバの再起動が必要になります。

  5. Plugins – Let’s Encrypt

  6. URLがいきなり//で始まる場合は、現在のプロトコールでそのリソースにアクセスします。そのため<img src='//domain/img.png'>を含むページをHTTPで開いた場合はHTTPでimg.pngを取得し、HTTPSで開いた場合はHTTPSでimg.pngを取得します。

  7. crontabの月は時間や分とスタートが異なり1-12なので、*/2は1-12/*と同じ意味です。よって2で割り切れる順番の月、すなわち0番目1月、2番目3月…と奇数月にcrontabエントリーが実行されます。偶数月ならば、21 3 15 2-12/2 * commandとなります。


コメントを残す

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