Daily Shaarli

All links of one day in a single page.

March 29, 2022

CentOS 8 Configuration Tutorial : Server World

Apache httpd : Configure mod_md
2020/07/14

Install and Configure [mod_md] to automate managing certificates from Let's Encrypt.
It's possbile to configure each VirtualHost.
And it's not need to configure manual SSL/TLS setting like here for the Site with [mod_md].
Also it needs that it's possible to access from the Internet to the Site with [mod_md] because of verification from Let's Encrypt.
[1] Install [mod_md].
[root@www ~]# dnf -y install mod_md

after installing, [mod_md] is enabled

[root@www ~]# cat /etc/httpd/conf.modules.d/01-md.conf

LoadModule md_module modules/mod_md.so
[2] Configure [mod_md].
[root@www ~]# vi /etc/httpd/conf.d/acme.conf

create new

MDBaseServer on
MDCertificateProtocol ACME
MDCAChallenges http-01
MDDriveMode auto
MDPrivateKeys RSA 2048
MDRenewWindow 33%
MDStoreDir md
MDCertificateAuthority https://acme-v02.api.letsencrypt.org/directory
MDCertificateAgreement https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf

<Location "/md-status">
SetHandler md-status
Require ip 127.0.0.1 10.0.0.0/24
</Location>

[MDRenewWindow]

default is [33%] if not specified

if validity of certificates falls specified duration,

[mod_md] will get new certificates

90 days * 33% ≒ 30 days

if you'd like to set with day, specify [d]

30 days ⇒ [30d]

[MDStoreDir]

the directory certificates or other data are stored

if not specified, default is [md]

it is relative path from [ServerRoot] in [httpd.conf]

[md-status]

monitor MD status

[3] If SELinux is enabled, change policy.
[root@www ~]# setsebool -P httpd_can_network_connect on
[root@www ~]# vi httpd-md.te

create new

module httpd-md 1.0;

require {
type httpd_config_t;
type httpd_t;
class dir { add_name create remove_name rename reparent rmdir setattr };
class file { create rename setattr unlink write };
}

============= httpd_t ==============

allow httpd_t httpd_config_t:dir { add_name create remove_name rename reparent rmdir setattr };
allow httpd_t httpd_config_t:file { create rename setattr unlink write };

[root@www ~]# checkmodule -m -M -o httpd-md.mod httpd-md.te

[root@www ~]# semodule_package --outfile httpd-md.pp --module httpd-md.mod

[root@www ~]# semodule -i httpd-md.pp

[4] Configure each VirtualHost you'd like to set [mod_md].
It needs to specify valid email address for each [ServerAdmin] directive because Let's Encrypt will send various notification.

for example, set on the site [www.srv.world] site

[root@www ~]# vi /etc/httpd/conf.d/www.srv.world.conf

MDomain www.srv.world
MDCertificateAgreement accepted
DirectoryIndex index.html
ServerAdmin root@www.srv.world

<VirtualHost *:80>
DocumentRoot /var/www/html
ServerName www.srv.world
</VirtualHost>

<VirtualHost *:443>
SSLEngine on
DocumentRoot /var/www/html
ServerName www.srv.world
</VirtualHost>

for example, set on the site [dlp.srv.world] site

[root@www ~]# vi /etc/httpd/conf.d/dlp.srv.world.conf

MDomain dlp.srv.world
MDCertificateAgreement accepted
DirectoryIndex index.html
ServerAdmin root@dlp.srv.world

<VirtualHost *:80>
DocumentRoot /var/www/dlp.srv.world
ServerName dlp.srv.world
</VirtualHost>

<VirtualHost *:443>
SSLEngine on
DocumentRoot /var/www/dlp.srv.world
ServerName dlp.srv.world
</VirtualHost>

[root@www ~]# systemctl restart httpd

on initial start, some validation ckecks run and

dumy certificate is created under the directory you set for [MDStoreDir]

[root@www ~]# ll /etc/httpd/md/domains/dlp.srv.world

total 12
-rw-------. 1 root root 1115 Jul 13 19:33 fallback-cert.pem
-rw-------. 1 root root 1704 Jul 13 19:33 fallback-privkey.pem
-rw-------. 1 root root 471 Jul 13 19:33 md.json

restart again

[root@www ~]# systemctl restart httpd

if all checks passed, valid certificate is gotten

[root@www ~]# ll /etc/httpd/md/domains/dlp.srv.world

total 16
-rw-------. 1 root root 3899 Jul 13 19:34 job.json
-rw-------. 1 root root 516 Jul 13 19:34 md.json
-rw-------. 1 root root 1704 Jul 13 19:34 privkey.pem
-rw-------. 1 root root 3554 Jul 13 19:34 pubcert.pem

[5] It's possible to confirm expiration date and others of certificate with [openssl] command like follows.
Or it's possbile to see them to access to the URL of [md-status] you set on [2].
[root@www ~]# openssl s_client -connect www.srv.world:443 | openssl x509 -noout -startdate -enddate

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = www.srv.world
verify return:1
notBefore=Jul 14 06:34:02 2020 GMT
notAfter=Oct 12 06:34:02 2020 GMT

[root@www ~]# openssl s_client -connect dlp.srv.world:443 | openssl x509 -noout -startdate -enddate

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = dlp.srv.world
verify return:1
notBefore=Jul 14 06:33:49 2020 GMT
notAfter=Oct 12 06:33:49 2020 GMT