Djangoアプリデプロイ時のVPSサーバーでのSSL化（https）手法｜Let's Encrypt

# 本記事について
Djangoを開発しデプロイする際，SSL化させる方法を調べると，Word Pressの方法はばかリが目立ち，VPSを用いた場合の方法が書かれた記事が少なかったため，ここに記録します．
また，certbotプログラムを実行する際にエラーが生じ，突破方法を見つけるのに苦労したので，同じ境遇のに陥った人はぜひ参考にしてみてください．

## もくじ
+ 参考文献
+ 開発環境
+ SSL化
+ SSL化の更新
+ SSL化の自動更新


## 参考文献
+ [DjangoでWebサービスをリリースする手順](https://blog.codecamp.jp/django-release-basic)

今回，SSL化を実装してく上で，こちらの記事を参考にさせていただきました．
私が書く内容はほとんどこの記事と同じではありますが，エラーが出た際の対処法を加えて書きます．

## 開発環境
Ubuntu 20.04 x64
今回は，Djangoのデプロイとドメインを取得が完了している状態から始めます．

## SSL化
では実際にSSL化する方法を書いていきたいと思います．

### Let's Encrypt
SSL化は無料でできるLet's Encryptを使用します．
Let's EncryptはCertbotというプログラムを使用することで半自動的に設定することができます．
Certbotはgitからダウンロードしますが，そのURLは下のリンクです．
[https://github.com/certbot](https://github.com/certbot)

### Certbotのダウンロード
まず，サーバー上でUbuntuのコマンドを開き，/usr/localへ移動します．

``` 
cd /usr/local
```

そして，CertbotのプログラムをGitHubからダウンロードします．

```
git clone https://github.com/certbot/certbot.git
```

### Certbotプログラムの実行

ダウンロードが完了したら，certbotのディレクトリができているため，そこへ移動します．

```
cd certbot
```

そして，以下のコードでCertbotプログラムを実行します．

```
./certbot-auto certonly --standalone -d ドメイン名(example.com) -m メールアドレス --agree-tos -n
```

このコードを実行し，「Congratulations!」と表示が出れば成功なのですが，以下のエラーコードが生じることがあります．

```
Note, selecting 'python-is-python2' instead of 'python'
Note, selecting 'python-dev-is-python2' instead of 'python-dev'
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
```

この突破方法についてはこちらの[サイト](https://community.jitsi.org/t/script-for-ssl-certificate-creation-broken-on-20-04-focal-fossa/43555/27)で質問されており，解決案がいくつか出せれていますが，私は以下の方法で無事プログラムの実行を成功することができました．上記のコードの代わりに以下のコードを利用します．
違いは，文頭の./certbot-autoは使用せず，sudo certbotで実行します．
また，これを実行するため，certbotをインストールします．

```
sudo apt -y install certbot
sudo certbot certonly --standalone -d ドメイン名(example.com) -m メールアドレス --agree-tos -n
```

これでもダメな場合は[同サイト](https://community.jitsi.org/t/script-for-ssl-certificate-creation-broken-on-20-04-focal-fossa/43555/27)に他の手法が提案されていたため，参考にしてみてください．

### Nginxサーバーへのセット
まず，SSLの設定で必要なキーファイル(fullchain.pem, privkey.pem)は，「/etc/letsencrypt/live/ドメイン名/」に保存されています．
それでは，Nginxの設定ファイルをSSLモードに編集します．

```
vim /etc/nginx/sites-available/設定ファイル名
```

ポート番号を80から443に変更させ，キーファイルを紐づける内容を追加で記述する．

```
server {
    listen 443 ssl;
    server_name ドメイン名;

    ssl_certificate     /etc/letsencrypt/live/for-happy-in.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/for-happy-in.com/privkey.pem;

    ...省略...
}
```

以上を書き終えたら，Nginxを再起動してSSL化が完了となります，
実際に，https://ドメイン名で検索すると，表示されるはずです．

## SSL化の更新
Let's Encryptの有効期限は3カ月ですので，定期的に更新していかなければなりません．
Certbotから証明書を更新する場合は，以下のコードで更新することができます．

```
sudo service nginx status
sudo service nginx stop

cd /usr/local/certbot
./certbot-auto renew

sudo service nginx start
sudo service nginx status
```

または，

```
sudo service nginx status
sudo service nginx stop

sudo certbot renew

sudo service nginx start
sudo service nginx status
```

## SSL化の自動更新
certbitを自動更新するには，cronという定期的に指定したプログラムを実行できる仕組みを使います．
vimでファイルに以下のことを書き込んで更新することで自動更新できます．
下の例では，早朝の3時10分に更新しています．

```
sudo vim /etc/crontab
```
```
10 3 *  *  * root /usr/bin/certbot renew
```
または

```
10 3 *  *  * root certbot renew --pre-hook "sudo service nginx stop" --post-hook "sudo service nginx start"
```