Let's Encrypt を使用したhttpsサーバの組み立てかた

# Env
```bash:command(bash)
~# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
~#
```

Running on the VPS  
WebService(80)はすでに使用中  
追加でHTTPS化したいというお話し

# switch to root
```bash:command(bash)
sudo su -
```
security 的に嫌だというヒトは、各コマンドの前にsudoを付与してください。

# pkg install and toEnable
```bash:command(bash)
a2enmod ssl
a2enmod headers
apt -y install certbot
```

# create certifacate
| Domain | DocumentRoot | Contact e-mail address |
| - | - | - |
| hogefoo.example.net | /var/www/html/hogefoo | letsencrypt-box@example.net |
| foohoge.example.net | /var/www/html/hogefoo | letsencrypt-box@example.net |

```bash:command(bash)
certbot certonly  \
   --webroot \
   -d hogefoo.example.net \
   -w /var/www/html/hogefoo \
   -m letsencrypt-box@example.net \
   -d foohoge.example.net \
   -w /var/www/html/foohoge \
   -m letsencrypt-box@example.net \
   --agree-tos -n

certbot certificates
```

```bash:log
~# certbot certonly  \
>   --webroot \
>   -d hogefoo.example.net \
>   -w /var/www/html/hogefoo \
>   -m letsencrypt-box@example.net \
>   --agree-tos -n
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for hogefoo.example.net
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
 
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/hogefoo.example.net	/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/hogefoo.example.net/privkey.pem
   Your cert will expire on 2021-11-16. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - 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.
 - 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

~# 
~# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: hogefoo.example.net
    Domains: hogefoo.example.net
    Expiry Date: 2021-11-16 00:10:48+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/hogefoo.example.net/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/hogefoo.example.net/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
~# 
```
Note - 実際のログとは一部異なります。

# File check
```bash:command(bash)
ls -lvh \
   /etc/letsencrypt/live/*/cert.pem \
   /etc/letsencrypt/live/*/fullchain.pem \
   /etc/letsencrypt/live/*/chain.pem \
   /etc/letsencrypt/live/*/privkey.pem
```

# Config Backup and rename
```bash:command(bash)
ls -lvAh /etc/apache2/sites-*/ssl.conf
if [ -f /etc/apache2/sites-available/ssl.conf ] ; then mv /etc/apache2/sites-available/ssl.conf /etc/apache2/sites-available/ssl.conf.origin ; fi
if [ -L /etc/apache2/sites-enabled/ssl.conf ] ; then rm -f /etc/apache2/sites-enabled/ssl.conf ; fi
```

# Config 投入
```bash:command(bash)
cat << EOF > /etc/apache2/sites-available/ssl.conf
<VirtualHost *:443>
   ServerName hogefoo.example.net
   DocumentRoot /var/www/html/hogefoo

   SSLEngine on
   SSLHonorCipherOrder on
   Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
   SSLProtocol -all +TLSv1.2
   SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

   SSLCertificateKeyFile /etc/letsencrypt/live/hogefoo.example.net/privkey.pem
   SSLCertificateFile /etc/letsencrypt/live/hogefoo.example.net/cert.pem
   SSLCertificateChainFile /etc/letsencrypt/live/hogefoo.example.net/chain.pem

   <Directory "/var/www/html/hogefoo">
      Options FollowSymLinks
      AllowOverride None
      Require all granted
   </Directory>

   SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
   ErrorLog /var/log/apache2/error.log
   CustomLog /var/log/apache2/access.log combined env=!nolog
</VirtualHost>

<VirtualHost *:443>
   ServerName foohoge.example.net
   DocumentRoot /var/www/html/foohoge

   SSLEngine on
   SSLHonorCipherOrder on
   Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
   SSLProtocol -all +TLSv1.2
   SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

   SSLCertificateKeyFile /etc/letsencrypt/live/foohoge.example.net/privkey.pem
   SSLCertificateFile /etc/letsencrypt/live/foohoge.example.net/cert.pem
   SSLCertificateChainFile /etc/letsencrypt/live/foohoge.example.net/chain.pem

   <Directory "/var/www/html/foohoge">
      Options FollowSymLinks
      AllowOverride None
      Require all granted
   </Directory>

   SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
   ErrorLog /var/log/apache2/error.log
   CustomLog /var/log/apache2/access.log combined env=!nolog
</VirtualHost>
EOF  
```

# Config 有効化
```bash:command(bash)
if [ ! -L /etc/apache2/sites-enabled/ssl.conf ] ; then ln -s /etc/apache2/sites-available/ssl.conf /etc/apache2/sites-enabled/ssl.conf ; fi
ls -lvAh /etc/apache2/sites-*/ssl.conf
```

```bash:log
~# ls -lvAh /etc/apache2/sites-*/ssl.conf
-rw-r--r-- 1 root root 711 Aug 18 11:43 /etc/apache2/sites-available/ssl.conf
lrwxrwxrwx 1 root root  37 Aug 18 11:43 /etc/apache2/sites-enabled/ssl.conf -> /etc/apache2/sites-available/ssl.conf
~#
```

# Config Test
```bash:command(bash)
apachectl configtest
```

```bash:log
~# apachectl configtest
Syntax OK
~#
```

# Damon restart
```bash:command(bash)
systemctl restart apache2
systemctl enable apache2
```

```bash
~# systemctl restart apache2
~# systemctl enable apache2
Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable apache2
~#
```

# Allow firewall access 
```bash:command(bash)
systemctl is-active ufw
ufw status
ufw allow 443/tcp
ufw status
```

```bash:log
~# systemctl is-active ufw
active
~#
~# ufw status
Status: active

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
80/tcp (v6)                ALLOW       Anywhere (v6)

~#
~# ufw allow 443/tcp
Skipping adding existing rule
Skipping adding existing rule (v6)
~#
~# ufw status
Status: active

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80/tcp (v6)                ALLOW       Anywhere (v6)
443/tcp (v6)               ALLOW       Anywhere (v6)

~#
```

---
# 参考リンク
https://ubuntu-perl-web.com/blog/20200318174004.html

https://blog.bgbgbg.net/archives/4104

https://qiita.com/hana_shin/items/a630871dce209cff04f3