Ubuntu20のHTTPS化、certbotのエラーが消えない

Ubuntu20.04 LTS、Nginx、DjangoのHTTPS化で、certbot-autoを使うためにはpython-virtualenvが必要ですがインストールできません。そこでpython3-certbot-nginxを使いました。

なお、サイトのHTTPS化において必要なSSL証明書の発行は無料のものと有料のものがあります。この記事では無料のSSL証明書を扱っているLet'EncryptでSSL証明書を発行します。

なお、無料の認証局Let'Encryptでは独自ドメインをHTTPS化することはできますが、IPアドレスのHTTPS化はできないので注意して下さい。例えば「https://snowtree-injune.com」は可能ですが、「https://128.128.128.128」のようなことはできないということです。

前の記事<<     >>

1.サブドメインをHTTPS化できるのか

私がHTTPS化したのはVPSサーバーのドメインですが、このVPSサーバーのドメインはサブドメインであり、メインのドメインは別のレンタルサーバーで使用しています。

メインのドメインとサブドメインを別のサーバーで扱い、サブドメインだけをHTTPS化できるのか不安でしたが、特に問題なくHTTPS化することができました。

2.python-virtualenvがインストールできない

ただ、HTTPS化を実行するにあたり、python-virtualenvがインストールできず苦労しました。おそらくUbuntu20.04 LTSとの相性の問題だと思うのですが、手順にミスがあるのかもしれません。

そこで、最初にうまくいかなかった手順を失敗例として簡単に紹介したいと思います。失敗例ではありますが「standaloneモード」と「webrootモード」については知っておいた方がよいと思いますので、ざっと目を通してください。

(1) cerbotのインストール

私は最初にcertbotをインストールしました。certbotのインストール先は、以下2行目のコマンド「git clone・・・」を実行したときのカレントディレクトリです。

なお、一般的にユーザーのみで使用するアプリケーションは「/home/user_name/」にインストールし、全ユーザーで共有するアプリケーションは「/usr/local/」にインストールするため、/usr/local/にインストールしました。

cd /usr/local
sudo git clone https://github.com/certbot/certbot

(2) Nginxの設定

Nginxの設定をする前に、certbotのstandaloneモードとwebrootモードの説明をします。

webrootモードでは、SSL証明書を発行するときにNginxなどのWebサーバーを利用します。したがって、NginxなどのWebサーバーが起動し、更にHTTPS化するドメインが利用可能な状態である必要があります。

それに対して、standaloneモードではNginxなどのWebサーバーの代わりに、cerbotがSSL発行用に用意した仮のWebサーバーを一時的に利用します。この一時的なwebサーバーは80番ポートを利用するために、webrootモードの時とは逆にNginxなどのwebサーバ-を停止させておかなければなりません。

従って、Nginxを使用しないstandaloneモードは、Nginxの設定をする必要がないため手順が簡単なのが長所です。一方、作業の間はWebサーバーを停止しなければならない点が欠点です。その間は自分のサイトにアクセスできなくなるので、運用中のサイトを停止する必要があります。

私の場合は新規のサイトなのでstandaloneモードでも良かったのですが、設定の練習のためにwebrootモードで実行することにしました。

さて、webrootモードを使用する最初の手順として、Nginxの設定ファイルを編集します。例えば私の環境では設定ファイルは「/etc/nginx/sites-available/」にありますので、この設定ファイルにワンタイムトークンの保存場所を追記します。

なお、ワンタイムトークンとは使い捨ての乱数であり、Let's EncryptがSSL証明書を発行するときにサーバーやドメイン所有者の識別に使用します。

以下のように、設定ファイルに6~7行目を追加すると、certbotコマンド実行時に「/usr/share/nginx/html」の下にディレクトリ「/.well-known/acme-challenge/」が作られ、そのディレクトリにワンタイムトークンが保存されます。

server {
    ・・・
    root /usr/share/nginx/html;  #ドキュメントルート
    ・・・
    #SSL証明書発行のためのワンタイムトークンの保存場所
    location /.well-known/acme-challenge {
    }
    ・・・
}

設定を変更したら忘れずにreloadします。

$ sudo systemctl reload nginx.service

以上でNginxの設定は終了です。

(3) python-virtualenvがインストールできない

ここからが、うまくいかなかったのですが、certbot-autoを実行するにはpython-virtualenvをインストールする必要があります。しかし、以下のようなエラーが発生してインストールできませんでした。

sudo apt -y install python-virtualenv
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package python-virtualenv is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'python-virtualenv' has no installation candidate

そこで、python-virtualenvをインストールせずに、以下のコードの実行を試みましたが同じエラーが発生してcertbot-autoが実行できませんでした。

sudo /usr/local/certbot/certbot-auto --webroot -w /usr/share/nginx/html -d ドメイン名 -m メールアドレス  --agree-tos
E: Package 'python-virtualenv' has no installation candidate

以上で失敗例の報告は終了です。

他にも「python-certbot-nginx」をインストールする方法も試しましたが、以下の5行目でエラーが発生しました。

$ sudo apt update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt update
$ sudo apt install python-certbot-nginx 

この後で説明する「python3-certbot-nginx」はpythonの後ろに3がついていますが、上記のコードは「python-certbot-nginx」ですので、注意して下さい。

3.python3-certbot-nginxを使用した認証

エラーを打開するためにpython3-certbot-nginxを使用してHTTPS化し、今度は成功しました。

python3-certbot-nginxは、Nginxを使用することを前提とするパッケージであり、必要な設定をほとんど自動で行ってくれます。したがって、先ほどの失敗例の手順のようにワンタイムトークンの保存先を指定する必要はありません。

ただ、Nginxを使う事を前提としたパッケージであるため、Nginxがインストールされており、更にHTTPS化したいドメインが使用可能な状態である必要はあります。

(1) Nginxの設定の確認

念のためNginxが正しく設定されているかどうかを「sudo nginx -t」で確認してみましょう。Nginxの設定ファイルをテストし結果を表示してくれます。また、実行するディレクトリはプロジェクト内でなくてもかまいません。なお、sudoが必要なので注意してください。

$ sudo nginx -t

Nginxの設定に問題なければ以下のように表示されます。

$ nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
$ nginx: configuration file /etc/nginx/nginx.conf test is successful

(2) ファイアウォールの設定

ファイアウォールの設定により80番、443番のポートを解放してください。80番はhttp、443はhttpsで使用するポート番号です。

なお、ファイアウォールの設定は以下の記事を参考にしてください。

ConoHa VPSにUbuntu。ufwでファイアウォール。

(3) python3-cerbot-nginxのインストール

python3-cerbot-nginxをインストールします。公式のリポジトリであり、非公式のリポジトリであるPPA(Personal Package Archive)を使用しなくてもすぐにインストール可能です。また、「python3-certbot-nginx」だけインストールすればよく、「certbot」のインストールは不要です。

$ sudo apt update
$ sudo apt install python3-certbot-nginx

では、いよいよ、certbotによりドメインをHTTPS化します。なお、certbotファイルはディレクトリ「/bin/」にインストールされています。

「-d ドメイン名」は、https化したいドメイン名を指定します。サブドメインをhttps化したいばあいには、ドメイン名の部分にサブドメインを記述します。

「-m メールアドレス」は、登録するメールアドレスを指定します。このオプションがない場合、インストール中に聞かれるので先に書いておきましょう。

「--agree-tos」を付けるとLet's Encrypteの規約に同意済みとして処理を進めます。規約を読みたい場合にはこのオプションは付けません。

sudo certbot --nginx -d ドメイン名 -m メールアドレス  --agree-tos

複数のドメインをHTTPS化したい場合には、以下のように指定します。

sudo certbot --nginx -d ドメイン名1 -d ドメイン名2 -m メールアドレス  --agree-tos

インストールを開始すると、メールアドレスを公開してもよいか聞かれるので、嫌な場合には「n」とします。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 

「http://ドメイン名/」でアクセスした場合に「https://ドメイン名/」にリダイレクトしない場合には「1」、リダイレクトする場合には「2」を選びます。基本的には「2」を選択することになるのではないでしょうか。

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

認証が成功すると、認証関係のファイルの保存場所が表示されます。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/【ドメイン名】/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/【ドメイン名】/privkey.pem
   Your cert will expire on 2020-08-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

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

(4) Nginxの設定ファイルが自動で更新される

「python3-certbot-nginx」を使った場合にはNginxの設定ファイルが自動で更新されます。自動更新された行の後ろには「# managed by Certbot」の記述が付加されるので、変更部分が一目でわかります。認証関係のファイルの保存先などが設定されています。

なお、私の場合「/etc/nginx/sites-available/」に保存されている設定ファイルが自動で書き換えられていました。

server {
    server_name 【ドメイン名】;
    root /usr/share/nginx/html;
    ・・・
    ・・・
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/【ドメイン名】/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/【ドメイン名】/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

以下の「# managed by Certbot」部分も自動追加された部分です。以下の設定により、「http://ドメイン名/」にアクセスしても「https://ドメイン名/」にリダイレクトされます。

server {
    if ($host = 【ドメイン名】) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

	listen 80;
	server_name 【ドメイン名】;
        root /usr/share/nginx/html;
        return 404; # managed by Certbot
}

では、更新のテストを行ってみましょう。「--dry-run」はテスト用オプションですので、実際の更新は行われません。

sudo certbot renew --dry-run

成功すると、以下のような注意事項が最後に表示されます。注意事項では証明書と秘密鍵が含まれるフォルダの定期的なバックアップを勧めています。

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

4.認証ファイルの更新

Let's EncryptのSSL証明書の有効期限は90日であるため、証明書を定期的に更新する必要があります。これは、cronにコマンドを登録することにより自動化できます。しかし、python-certbot-nginxを使用した場合は、定期更新のための設定ファイルが自動で作成されるため、自分で設定する必要はありません。

どのような設定になっているかを確認するために以下のコマンドを実行してみましょう。

sudo systemctl status certbot.timer

以下、実行結果です。1行目では1日2回certbotを実行すると書かれています。2行目では設定ファイルcertbot.timerが保存されているディレクトリが表示されます。3行目では実行の開始時間。4行目では次回の更新予定時間が表示されています。

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Tue 2020-12-08 22:20:30 JST; 54min ago
    Trigger: Wed 2020-12-09 06:34:19 JST; 7h left
   Triggers: ● certbot.service

上表示の2行目に表示される設定ファイルcertbot.timerは以下の通りです。

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.targetWantedBy=timers.target

なお、ディレクトリ「/etc/cron.d/」に保存されているcronの設定ファイル「certbot」をエディタで確認すると以下のように記述されています。上記「certbot.timer」の内容に従い「certbot」が書き換えられているのではないかと思います。

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

以上でHTTPS化の設定は完了し、自動更新の設定も終了しました。

5.(参考)自分で更新の設定を行う場合

参考までに自分で自動更新の設定ファイルを記述する方法を紹介します。

(1) crontabによる設定

cronの設定ファイルはエディタで直接作成することもできますが、ユーザー用の自動更新ファイルを作成するにはcrontabを実行する方法が楽です。

「crontab -e」を実行すると、以下のような画面が表示されます。設定ファイルを編集するエディタを選択するように求められますので、お好みのエディタを1~4の番号で指定します。

$ crontab -e
no crontab for user_name - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]: 

このエディタで編集したファイルは、ディレクトリ「/var/spool/cron/crontabs/」の中に、ファイル名が「ユーザー名」のファイルとして保存されます。先ほどの「/etc/cron.d/certbot」とは保存場所が違います。

設定ファイルには、例えば以下のような内容を記述します。

00 04 01 * * /bin/certbot renew -q --webroot-path /usr/share/nginx/html --post-hook "systemctl reload nginx.service"

なお、ユーザーの設定ファイルではなくシステムの設定ファイルの場合は、例えば以下のコードの「root」のようにユーザー名を指定する必要があります。設定方法を区別するようにしましょう。

00 04 01 * * root /bin/certbot renew -q --webroot-path /usr/share/nginx/html --post-hook "systemctl reload nginx.service"

(2) cronの主なコマンド

cronの主なコマンドは以下の通りです。2通りの記述方法があります。

$ sudo systemctl start cron  #cronの起動
$ sudo systemctl status cron  #cronのステータス確認
$ sudo systemctl stop cron  #cronの停止
$ sudo service cron start #cronの起動
$ sudo service cron status #cronのステータス確認
$ sudo service cron stop #cronの停止

私が実際にレンタルしたVPSサーバー

私が実際にレンタルしたVPSサーバーはConoHa VPSです。私は1GBのプランを申し込みました。VPSサーバーは一般のレンタルサーバーと異なりOSやアプリケーションを自由に設定できるので、Pythonで計算した結果をサイトに表示することもできます。

なお、ConoHa VPSの特長として、サーバーのディスクイメージを丸ごとバックアップできるイメージ保存機能を無料で使用することができます。コードを変更して元に戻せなくなった場合にも安心です。

また、ConoHa VPSは途中でプランをスケールアップできるだけでなく、スケールダウンすることもできます。つまり、2Gプランを1Gプランに変更することができます。ただし、512MBプランだけはスケールアップ・ダウン機能が使用できないので注意してください。

また、初期費用なしで3日だけ借り、3日分の費用だけ払うといったことも可能なので気軽に始められます。※時間課金(月の上限額は決まっています)

私からの友達紹介でクーポンをゲット

なお、以下のリンクから入ると、私からの友達紹介の扱いとなり1000円分のクーポンが支給されます。リンク先には「友達紹介」といった表記がないので「友達紹介」が適用されているのか不安になりますが大丈夫です。登録終了後にログインしたユーザーTop画面を確認すると支給されたクーポン1000円が表示されるはずです。

[ Conohaの友達紹介 ]

なお、友達紹介では個人情報が紹介者には開示されないので安心してご利用ください。

その他

Twitterへのリンクです。SNSもはじめました♪

液晶ペンタブレットを購入しました
 (1) モバイルディスプレイを買うつもりだったのに激安ペンタブレット購入

以下、私が光回線を導入した時の記事一覧です。
 (1) 2020年「光回線は値段で選ぶ」では後悔する ←宅内工事の状況も説明しています。
 (2) NURO光の開通までWiFiルーターを格安レンタルできる
 (3) NURO光の屋外工事の状況をご紹介。その日に開通!
 (4) 光回線開通!実測するとNURO光はやっぱり速かった
 (5) ネット上のNURO光紹介特典は個人情報がもれないの?