業務用エアコン関連の技術情報、エラーコード、環境問題対策に関する別サイト「エアコンの安全な修理・適切なフロン回収」

Debian13.6 : Let's Encrypt, WEB/Mail Server SSL

1. Obtain a certificate (Let's Encrypt)

1.1 advance preparation

1.Enable mod_ssl

# a2enmod ssl

2.Package management system Snappy installed
Since the SSL certificate issuing tool "certbot" of Let's Encrypt is recommended to be installed using "snap" after 2021, install Snapd first

# apt -y install snapd

Bring snapd version up to date

# snap install core
core 16-2.61.4-20260225 from Canonical✓ installed

# snap refresh core
snap "core" has no updates available

Version Check

# snap --version
snap    2.68.3-3+deb13u1+b6
snapd   2.68.3-3+deb13u1+b6
series  16
debian  13
kernel  6.12.96+deb13-amd64

1.2.certbot package install

# snap install --classic certbot
certbot 5.7.0 from Certbot Project (certbot-eff✓) installed

Create symbolic link to /snap/bin/certbot

# ln -s /snap/bin/certbot /usr/bin/certbot

Confirmation

# ls -la /usr/bin/certbot
lrwxrwxrwx 1 root root 17 May 20 10:34 /usr/bin/certbot -> /snap/bin/certbot

# ls -la /snap/bin/certbot
lrwxrwxrwx 1 root root 13 May 20 10:33 /snap/bin/certbot -> /usr/bin/snap

1.3 Obtain a Let's Encrypt Certificate

It is assumed that a web server such as Apache httpd or Nginx is running.
It is also assumed that the server on which the work is to be performed (the server with the FQDN of the server from which you want to obtain the certificate) is accessible from the Internet at port 80.

# certbot certonly --webroot -w /var/www/html/[FQDN] -d [FQDN]

# First time only, you must register your e-mail address and agree to the Terms of Use Specify an e-mail address that can receive your messages.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address or hit Enter to skip.
 (Enter 'c' to cancel): [mail address] 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at:
https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf
You must agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, 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: y
Account registered.
Requesting a certificate for [FQDN]

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/[FQDN]/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/[FQDN]/privkey.pem
This certificate expires on 2026-10-21.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

「Successfully received certificate.」
The following certificate is obtained under [/etc/letsencrypt/live/[FQDN]/] as described in the message
# cert.pem
# chain.pem
# fullchain.pem
# privkey.pem

Obtaining a Let's Encrypt certificate when the web server is not running
It is a prerequisite that the server on which the work is to be performed is accessible from the Internet at port 80.
#Use the simple Web server function by specifying [--standalone].
# -d [FQDN from which you want to obtain a certificate]
 FQDN (Fully Qualified Domain Name) : Hostname. Domain name without abbreviation
# If there are multiple FQDNs for which you want to obtain certificates, specify multiple -d [FQDNs for which you want to obtain certificates]

# certbot certonly --standalone -d [FQDN]

1.4 Automatic renewal of certificates (Let's Encrypt)

①Pre-registration testing
First, test the automatic renewal using the following --dry-run option. With this option, the certificate is not renewed, but only the operation is tested, so there is no need to worry about being caught by the limit on the number of times a certificate can be obtained.

# certbot renew --dry-run

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/[FQDN].conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for [FQDN]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/[FQDN]/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

When you install the snap version of certbot, the automatic certificate renewal function is also installed.

# systemctl list-timers | less

NEXT                            LEFT LAST                             PASSED UNIT                         ACTIVATES    
Thu 2026-07-23 10:09:00 JST     8min Thu 2026-07-23 09:39:44 JST   20min ago phpsessionclean.timer        phpsessionclean.service
Thu 2026-07-23 10:48:32 JST    48min Wed 2026-07-22 11:09:40 JST           - man-db.timer                 man-db.service
Thu 2026-07-23 11:35:00 JST 1h 34min -                                     - snap.certbot.renew.timer     snap.certbot.renew.service
Thu 2026-07-23 22:06:57 JST      12h Thu 2026-07-23 09:23:14 JST   37min ago apt-daily.timer              apt-daily.service
Fri 2026-07-24 00:00:00 JST      13h Thu 2026-07-23 08:57:13 JST 1h 3min ago dpkg-db-backup.timer         dpkg-db-backup.service
Fri 2026-07-24 00:00:00 JST      13h Thu 2026-07-23 08:57:13 JST 1h 3min ago locate.timer                 locate.service
Fri 2026-07-24 00:15:23 JST      14h Thu 2026-07-23 09:11:03 JST   49min ago logrotate.timer              logrotate.service
Fri 2026-07-24 06:14:53 JST      20h Thu 2026-07-23 09:11:03 JST   49min ago apt-daily-upgrade.timer      apt-daily-upgrade.service
Fri 2026-07-24 09:12:13 JST      23h Thu 2026-07-23 09:12:13 JST   48min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Sun 2026-07-26 03:10:17 JST   2 days Wed 2026-07-22 11:09:40 JST           - e2scrub_all.timer            e2scrub_all.service
Mon 2026-07-27 01:20:54 JST   3 days Wed 2026-07-22 11:09:40 JST           - fstrim.timer                 fstrim.service

11 timers listed.
Pass --all to see loaded but inactive timers, too.

snap.certbot.renew.timer is registered
Check the unit file for snap.certbot.renew.timer

# vi /etc/systemd/system/snap.certbot.renew.timer

[Unit]
# Auto-generated, DO NOT EDIT
Description=Timer renew for snap application certbot.renew
Requires=snap-certbot-5781.mount
After=snap-certbot-5781.mount
X-Snappy=yes

[Timer]
Unit=snap.certbot.renew.service
OnCalendar=*-*-* 01:59
OnCalendar=*-*-* 21:56

[Install]
WantedBy=timers.target

According to the above settings, it will attempt to update at 1:59 and 21:56 every day as specified in the OnCalender parameter (however, the set time will change randomly for each update).

Check the unit file snap.certbot.renew.service

# vi /etc/systemd/system/snap.certbot.renew.service

[Unit]
# Auto-generated, DO NOT EDIT
Description=Service for snap application certbot.renew
Requires=snap-certbot-5781.mount
Wants=network.target
After=snap-certbot-5781.mount network.target snapd.apparmor.service
X-Snappy=yes

[Service]
EnvironmentFile=-/etc/environment
ExecStart=/usr/bin/snap run --timer="00:00~24:00/2" certbot.renew
SyslogIdentifier=certbot.renew
Restart=no
WorkingDirectory=/var/snap/certbot/5781
TimeoutStopSec=30s
Type=oneshot

However, the web server that uses the certificate will not be restarted, so set up a script that will run automatically after the update

# vi /etc/letsencrypt/renewal-hooks/post/web_restart.sh

Describe the following
#!/bin/bash
systemctl restart apache2
# chmod 755 /etc/letsencrypt/renewal-hooks/post/web_restart.sh

2. SSL/TLS (Let's Encrypt) configuration for Apache2

Edit Apache2 SSL-related configuration files

# cd /etc/apache2/sites-available/
# cp default-ssl.conf vhost-ssl.conf ← vhost-ssl can be any name

# vi vhost-ssl.conf
Line 2:Administrator address change
ServerAdmin <Email Address>>
Line 4:change
DocumentRoot /var/www/html/<FQDN>/
Line 12,13:change
ErrorLog ${APACHE_LOG_DIR}/<FQDN>.error.log
CustomLog ${APACHE_LOG_DIR}/<FQDN>.access.log combined
Line 31,32:Change to the certificate obtained in [1]
SSLCertificateFile /etc/letsencrypt/live/<FQDN>/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/<FQDN>/privkey.pem
Per Line 43:Add to the chain file obtained in [1]
SSLCertificateChainFile /etc/letsencrypt/live/<FQDN>/chain.pem

Reflecting and activating the configuration file

# a2ensite vhost-ssl.conf
Enabling site vhost-ssl.
To activate the new configuration, you need to run:
  systemctl reload apache2

Default Disable
# a2dissite default-ssl.conf

# systemctl restart apache2

http to https redirect

# a2enmod rewrite

Add to the virtual host configuration file "vhost.conf"

# cd /etc/apache2/sites-available/
# vi vhost.conf

<VirtualHost *:80>
RewriteEngine on ←Add
RewriteCond %{HTTPS} off ←Add
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] ←Add
~omission~
ServerName <FQDN>
ServerAdmin <administrator E-mail address>
DocumentRoot /var/www/html/<FQDN>/
~omission~
ErrorLog ${APACHE_LOG_DIR}/<FQDN>.error.log
CustomLog ${APACHE_LOG_DIR}/<FQDN>.access.log combined
~omission~
</VirtualHost>

Reflection of settings and startup

Restart Apache

# systemctl restart apache2

https port open with ufw

# ufw allow https
# ufw reload

3. SSL/TLS (Let's Encrypt) settings on the mail server

3.1 Obtaining a certificate for the mail server

Do this after stopping the web server first

# systemctl stop apache2.service

# certbot certonly --standalone -d mail.<domain>
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for mail.<domain>

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mail.<domain>/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/mail.<domain>/privkey.pem
This certificate expires on 2026-10-21.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

3.2 Postfix Configuration

# vi /etc/postfix/main.cf

Add to the last line
smtpd_use_tls = yes
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.<domain>/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.<domain>/privkey.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# vi /etc/postfix/master.cf

Per Line 19-23 : Some comments removed
submission inet n - y - - smtpd
    -o syslog_name=postfix/submission
#   -o smtpd_forbid_unauth_pipelining=no
#   -o smtpd_tls_security_level=encrypt
    -o smtpd_sasl_auth_enable=yes

Add to last line
smtps     inet  n       -       y       -       -       smtpd
    -o syslog_name=postfix/smtps
    -o smtpd_tls_wrappermode=yes
    -o smtpd_sasl_auth_enable=yes

3.3 Dovecot Configuration

# vi /etc/dovecot/conf.d/10-ssl.conf

Line 6:confirmation
ssl = yes
Line 18,20:Change (certificate/key file specification)
ssl_server_cert_file = /etc/letsencrypt/live/mail.[domain]/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.[domain]/privkey.pem

※Please note that starting with Dovecot 2.4.1, the format for specifying certificate paths has changed, and the previous "<" symbol is no longer used.

Allow Port 587

# ufw allow 587/tcp
# ufw reload
# systemctl restart postfix dovecot

3.4 Thunderbird Settings

Incoming server
Port  :  143
Connection security   :  STARTTLS
Authentication method  :  Normal password

Sending server
Port   :  587
Connection security   :  STARTTLS
Authentication method  :  Normal password