Let's Encrypt on Amazon Linux 2


Amazon Linux 2 にできるだけスマートに Let's Encrypt をインストールする方法をまとめました。
漢字変換すら面倒くさかったので英語で書きました。時間が出来た時に日本語に書き直します。

Certbot をできるだけ書き換えないで Epel のレポジトリからインストールして、Certonly オプションで証明書を取得し、自分で Apache/Nginx の config を書き換えて設定する方法です。

あと、virtual host 設定で default-server 設定しなくて全然 SSL が handshake しないというエラーでもコケたという Nginx の config 初心者的なハマりについても解説しています。

This notes explains how to install Let's Encrypt onyo Amazon Linux 2.

# Simple Setup

## Condition: Initial Set-up

Run my concrete5 Ansible script to set-up basic web server.
https://github.com/concrete5cojp/ansible-c5-ma

This script will install all necesary repo and middlewares to run a PHP web application.

- You have properly set-up Apache or Nginx server
- You have properly set-up DNS record.

OR if you haven't installed epel repo, run the following command to install epel repo


```
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
```


## Step 1: Install Certbot

```
$ sudo yum install certbot python2-certbot-nginx # Nginx server
$ sudo yum install certbot python2-certbot-apache # Apache server
```

## Step 2: Install Let's Encrypt Certificatte 


```
sudo certbot
```

Then, follow the step to proceed.

- Select domains
- Select file authorization method

## Step 3: Set-up cron to auto-renew


### CentOS 6 / Amazon Linux 

```
$ sudo vi /etc/crontab
# Let's Encrypt Renewal - Nginx
39 11,23  *  *  * root /usr/bin/certbot renew --no-self-upgrade --renew-hook "service nginx reload -s"
# Let's Encrypt Renewal - Apache
39 11,23  *  *  * root /usr/bin/certbot renew --no-self-upgrade --renew-hook "service httpd restart"

```

### CentOS 7 / Amazon Linux 2 

```
$ sudo vi /etc/crontab
# Let's Encrypt Renewal - Nginx
39 11,23  *  *  * root /usr/bin/certbot renew --no-self-upgrade --renew-hook "systemctl restart nginx"
# Let's Encrypt Renewal - Apache
39 11,23  *  *  * root /usr/bin/certbot renew --no-self-upgrade --renew-hook "service httpd restart"

```


# Other Method

## Issue an certificate for the domain

```
$ sudo certbot certonly \
     --manual \
     --manual-public-ip-logging-ok \
     -d EXAMPLE.com \
     -d *.EXAMPLE.com \
     --cert-name EXAMPLE.com \
     -m nospam@EXAMPLE.com \
     --preferred-challenges dns-01
     --agree-tos \
     --debug
```

Register DNS record.
Get the full paths of key


## Set web server config

### Nginx Config

```
    ssl_certificate         /etc/letsencrypt/live/EXAMPLE.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/EXAMPLE.com/privkey.pem;
```

### Apache Config

Add `<VirtualHost *:443>` to your vhost config (if you're using vhosts)

```
SSLCertificateFile /etc/letsencrypt/live/DOMAIN/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/DOMAIN/chain.pem
SSLCACertificateFile /etc/letsencrypt/live/DOMAIN/fullchain.pem

```

# When you failed: TIPS

## How to renew let's encrypt manually

If you got the following error, you just renew manually

```
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/EXAMPLE.COM.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (coding.c5j.me) from /etc/letsencrypt/renewal/EXAMPLE.COM.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/EXAMPLE.COM/fullchain.pem (failure)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/EXAMPLE.COM/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)
```

Again.. you just get the certificate

```
$ sudo certbot certonly --manual  --preferred-challenges dns-01 --manual-public-ip-logging-ok --agree-tos \
    -d EXAMPLE.COM\
    -d *.EXAMPLE.COM
```


## Clear all Let's Encrypt Setting

```
sudo rm -R /opt/eff.org/certbot

```

## Make sure to set SSL on default-server


If you've got the following error in Nginx error log and keep failing to access SSL, you didn't set proper 443 config on your Nginx's default-server config.


```
no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: ***.***.***.***, server: 0.0.0.0:443
```

or

```
$ curl -i https://EXAMPLE.com
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to EXAMPLE.com:443
```


Even if you only need SSL access to additional virtual host server, you MUST set SSL settings on your default-server & ssl_certificate.

```
server {
    listen       80 default_server;
    listen       [::]:80;
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2;

    server_name  EXAMPLE.com;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

    charset      utf-8;

    access_log   /var/log/nginx/dummy_access.log main;
    error_log    /var/log/nginx/dummy_error.log warn;

    root         /var/www/html;

    ssl_certificate         /etc/letsencrypt/live/EXAMPLE.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/EXAMPLE.com/privkey.pem;


    location / {
    	index  index.html;
    }
}
```

## How to delete unused and/or old certificates

```
# Show which certificates are installed & get the certificate names to delete
$ sudo certbot certificates

# Delete the certificate
$ sudo certbot delete --cert-name example.com-0001
```

# Reference

This one is good article.
http://nopipi.hatenablog.com/entry/2019/01/08/013654

https://higherhope.net/?p=2710

https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9

Amazon Linux2でLet's Encrypt使おうとしたらコケた話
https://qiita.com/MysteriousMonky/items/f26316447c1ff390ce21
Amazon Linux2とLet's EncryptでSSL対応サーバを0から爆速構築
https://qiita.com/MysteriousMonkey/items/4d3d857c0e68d4bfff39

NginxでLet’s Encryptを使うためのメモ書き
https://worklog.be/archives/3352

Let's Encrypt の証明書をワイルドカードなやつにして自動更新できるようにした
https://k5342.hatenablog.com/entry/2018/04/07/002456

Let’s Encrypt で ‘-0001’ がついた証明書データを削除する方法
https://laboradian.com/how-to-delete-certificate-with-0001-lets-encrypt/