Certbot via cron writes files unreadable by apache (SELinux/CentOS 7)


#1

Hi. I am experiencing a persistent problem trying to get a certbot to automatically renew certificates when run via cron. However, I can renew certificates fine using the same commands from sudo. Via cron, the immediate error is “Error while running apachectl graceful.”

systemctl status httpd.service complains thusly:

Dec 28 11:55:01 opmiwiki.mghpcc.org CROND[718]: (root) CMD (/usr/bin/certbot renew --quiet)
Dec 28 11:55:03 opmiwiki.mghpcc.org httpd[746]: AH00526: Syntax error on line 10 of /etc/httpd/conf.d/le_tls_sni_01_cert_challenge.conf:
Dec 28 11:55:03 opmiwiki.mghpcc.org httpd[746]: SSLCertificateFile: file '/var/lib/letsencrypt/LsNQY6mcFER3HPFz-0D_z6aIWosQq-KDWjCz2V2hOJY.crt' does not exist or is empty
Dec 28 11:55:03 opmiwiki.mghpcc.org systemd[1]: httpd.service: control process exited, code=exited status=1
Dec 28 11:55:03 opmiwiki.mghpcc.org systemd[1]: Reload failed for The Apache HTTP Server.

I installed certbot 0.9.3 using the EPEL package python-certbot-apache.
CentOS Linux release 7.3.1611 (Core) with SELinux enabled.
Apache (httpd) 2.4.6-45.el7.centos
HTTPS host = opmiwiki.mghpcc.org.

crontab lines:
55 11 * * * root /usr/bin/certbot renew --quiet
55 23 * * * root /usr/bin/certbot renew --quiet

When these cron entries run, they generate the following /var/log/letsencrypt/letsencrypt.log:

2016-12-28 16:55:01,845:DEBUG:certbot.main:Root logging level set at 30
2016-12-28 16:55:01,845:INFO:certbot.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-12-28 16:55:01,845:DEBUG:certbot.main:certbot version: 0.9.3
2016-12-28 16:55:01,845:DEBUG:certbot.main:Arguments: ['--quiet']
2016-12-28 16:55:01,845:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2016-12-28 16:55:01,852:DEBUG:certbot.storage:Should renew, less than 30 days before certificate expiry 2017-01-23 12:38:00 UTC.
2016-12-28 16:55:01,852:INFO:certbot.renewal:Cert is due for renewal, auto-renewing...
2016-12-28 16:55:01,853:DEBUG:certbot.plugins.selection:Requested authenticator apache and installer apache
2016-12-28 16:55:02,257:DEBUG:certbot.plugins.selection:Single candidate plugin: * apache
Description: Apache Web Server plugin - Beta
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache.configurator:ApacheConfigurator
Initialized: <certbot_apache.configurator.ApacheConfigurator object at 0x1ac40d0>
Prep: True
2016-12-28 16:55:02,257:DEBUG:certbot.plugins.selection:Single candidate plugin: * apache
Description: Apache Web Server plugin - Beta
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache.configurator:ApacheConfigurator
Initialized: <certbot_apache.configurator.ApacheConfigurator object at 0x1ac40d0>
Prep: True
2016-12-28 16:55:02,258:DEBUG:certbot.plugins.selection:Selected authenticator <certbot_apache.configurator.ApacheConfigurator object at 0x1ac40d0> and installer <certbot_apache.configurator.ApacheConfigurator object at 0x1ac40d0>
2016-12-28 16:55:02,379:DEBUG:certbot.main:Picked account: <Account(6833b58cc8eea8e3697ecb13583d0a46)>
2016-12-28 16:55:02,383:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/directory. args: (), kwargs: {}
2016-12-28 16:55:02,386:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2016-12-28 16:55:02,653:DEBUG:requests.packages.urllib3.connectionpool:"GET /directory HTTP/1.1" 200 352
2016-12-28 16:55:02,654:DEBUG:root:Received <Response [200]>. Headers: {'content-length': '352', 'strict-transport-security': 'max-age=604800', 'boulder-request-id': 'Dhaq-T1kkGKQCjgMsM3w5n1elNW3b3Jc79HJAnCDNq8', 'expires': 'Wed, 28 Dec 2016 16:50:13 GMT', 'server': 'nginx', 'connection': 'keep-alive', 'pragma': 'no-cache', 'cache-control': 'max-age=0, no-cache, no-store', 'date': 'Wed, 28 Dec 2016 16:50:13 GMT', 'x-frame-options': 'DENY', 'content-type': 'application/json', 'replay-nonce': 'ohTeyksorJQR__tSrrRcewK8dkhFybFdbDEih53HHpk'}. Content: '{\n  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",\n  "new-authz": "https://acme-v01.api.letsencrypt.org/acme/new-authz",\n  "new-cert": "https://acme-v01.api.letsencrypt.org/acme/new-cert",\n  "new-reg": "https://acme-v01.api.letsencrypt.org/acme/new-reg",\n  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"\n}'
2016-12-28 16:55:02,654:DEBUG:acme.client:Received response <Response [200]> (headers: {'content-length': '352', 'strict-transport-security': 'max-age=604800', 'boulder-request-id': 'Dhaq-T1kkGKQCjgMsM3w5n1elNW3b3Jc79HJAnCDNq8', 'expires': 'Wed, 28 Dec 2016 16:50:13 GMT', 'server': 'nginx', 'connection': 'keep-alive', 'pragma': 'no-cache', 'cache-control': 'max-age=0, no-cache, no-store', 'date': 'Wed, 28 Dec 2016 16:50:13 GMT', 'x-frame-options': 'DENY', 'content-type': 'application/json', 'replay-nonce': 'ohTeyksorJQR__tSrrRcewK8dkhFybFdbDEih53HHpk'}): '{\n  "key-change": "https://acme-v01.api.letsencrypt.org/acme/key-change",\n  "new-authz": "https://acme-v01.api.letsencrypt.org/acme/new-authz",\n  "new-cert": "https://acme-v01.api.letsencrypt.org/acme/new-cert",\n  "new-reg": "https://acme-v01.api.letsencrypt.org/acme/new-reg",\n  "revoke-cert": "https://acme-v01.api.letsencrypt.org/acme/revoke-cert"\n}'
2016-12-28 16:55:02,654:INFO:certbot.main:Renewing an existing certificate
2016-12-28 16:55:02,654:DEBUG:root:Requesting fresh nonce
2016-12-28 16:55:02,654:DEBUG:root:Sending HEAD request to https://acme-v01.api.letsencrypt.org/acme/new-authz. args: (), kwargs: {}
2016-12-28 16:55:02,738:DEBUG:requests.packages.urllib3.connectionpool:"HEAD /acme/new-authz HTTP/1.1" 405 0
2016-12-28 16:55:02,738:DEBUG:root:Received <Response [405]>. Headers: {'content-length': '91', 'allow': 'POST', 'boulder-request-id': 'dFCr9OqRDdhJwBqg2jLHYPYYMv--Uzo4hWuhlLLz_v8', 'expires': 'Wed, 28 Dec 2016 16:50:13 GMT', 'server': 'nginx', 'connection': 'keep-alive', 'pragma': 'no-cache', 'cache-control': 'max-age=0, no-cache, no-store', 'date': 'Wed, 28 Dec 2016 16:50:13 GMT', 'content-type': 'application/problem+json', 'replay-nonce': 'TrPQSDcBKKe1KrrRU9MLA9aCYP5PO69n2jGC-K3jNxI'}. Content: ''
2016-12-28 16:55:02,738:DEBUG:acme.client:Storing nonce: 'N\xb3\xd0H7\x01(\xa7\xb5*\xba\xd1S\xd3\x0b\x03\xd6\x82`\xfeO;\xafg\xda1\x82\xf8\xad\xe37\x12'
2016-12-28 16:55:02,738:DEBUG:acme.jose.json_util:Omitted empty fields: expires=None, challenges=None, combinations=None, status=None
2016-12-28 16:55:02,738:DEBUG:acme.client:Serialized JSON: {"identifier": {"type": "dns", "value": "opmiwiki.mghpcc.org"}, "resource": "new-authz"}
2016-12-28 16:55:02,739:DEBUG:acme.jose.json_util:Omitted empty fields: x5c=(), crit=(), typ=None, jwk=None, x5u=None, kid=None, alg=None, cty=None, x5tS256=None, jku=None, x5t=None
2016-12-28 16:55:02,741:DEBUG:acme.jose.json_util:Omitted empty fields: x5c=(), crit=(), typ=None, x5u=None, kid=None, cty=None, nonce=None, x5tS256=None, jku=None, x5t=None
2016-12-28 16:55:02,741:DEBUG:root:Sending POST request to https://acme-v01.api.letsencrypt.org/acme/new-authz. args: (), kwargs: {'data': '{"header": {"alg": "RS256", "jwk": {"e": "AQAB", "kty": "RSA", "n": "yFIrwFz0oma-7oNFUIU6Xx0oEO9ZGAlIIDwaxfrD20M3wBOW3sP1PkhY-Fhw7DxPm9LP3y5G63GCLaN24BFjHt92Cc625AmeuODkOZhApkLgYEq2t3oW8hgNAMloMtbckLCh6oejD_XCO6GxR9_n1G2ReMUOWj_VbD9OSIEVcGWZnU2UxICXu9fcDcO_EwWPh2j_B6c6iHTaK0bFuz8rR8d53HeMrbcgbtULJECUr94KgJDmSPAqkyBeEFr6m530SBq3N9m3-75mpO-z_MYjt32guFVtREu1eCtFtpeKeuJU-QQH9MAox96ad-KyAKjrvJZzO8iX6JdMPE5xC-Aj-w"}}, "protected": "eyJub25jZSI6ICJUclBRU0RjQktLZTFLcnJSVTlNTEE5YUNZUDVQTzY5bjJqR0MtSzNqTnhJIn0", "payload": "eyJpZGVudGlmaWVyIjogeyJ0eXBlIjogImRucyIsICJ2YWx1ZSI6ICJvcG1pd2lraS5tZ2hwY2Mub3JnIn0sICJyZXNvdXJjZSI6ICJuZXctYXV0aHoifQ", "signature": "XzE2mA1l2s_1uNYX3Cu-T5D0G45JXzDCE5dqcLDvufP4IiODWcEmHxkijaIP763l0-s6nUO8VPn2kj00llSRC3YyNL6Xp-s6320RLpq1_2qiri8wANdPSfqaPrjkEAU3wq-dvtTYDDfGwEgRU8U2HsHKmUGo-BafCYlSjjXoufUBxI7ijNZ953uyknvvXl3h6o3k_rFHhQN-txtq6NVesgUIdXDi1oG3TErpoE5kZuooifCugmlU3a-q93ndhq_mQoAmDZv14qQuEjNbT7CNCjLTiAOBU9OpvHHo9ShUkBpKP5k43DGJuOHDr9ZZ13D-wC-xc3cVBOlpv-peuy9k1g"}'}
2016-12-28 16:55:02,849:DEBUG:requests.packages.urllib3.connectionpool:"POST /acme/new-authz HTTP/1.1" 201 1004
2016-12-28 16:55:02,850:DEBUG:root:Received <Response [201]>. Headers: {'content-length': '1004', 'strict-transport-security': 'max-age=604800', 'boulder-request-id': 'lgDUzfE5mcEkSxVioiX-x8mp56MRjvA1e4oMEyne__M', 'boulder-requester': '3583115', 'expires': 'Wed, 28 Dec 2016 16:50:13 GMT', 'server': 'nginx', 'connection': 'keep-alive', 'link': '<https://acme-v01.api.letsencrypt.org/acme/new-cert>;rel="next"', 'location': 'https://acme-v01.api.letsencrypt.org/acme/authz/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU', 'pragma': 'no-cache', 'cache-control': 'max-age=0, no-cache, no-store', 'date': 'Wed, 28 Dec 2016 16:50:13 GMT', 'x-frame-options': 'DENY', 'content-type': 'application/json', 'replay-nonce': 'b3tFIXNRBbROozg22wjHd8AN6yHdLkoB6P_J9syvSiY'}. Content: '{\n  "identifier": {\n    "type": "dns",\n    "value": "opmiwiki.mghpcc.org"\n  },\n  "status": "pending",\n  "expires": "2017-01-04T16:50:13.305632065Z",\n  "challenges": [\n    {\n      "type": "tls-sni-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374912",\n      "token": "LsNQY6mcFER3HPFz-0D_z6aIWosQq-KDWjCz2V2hOJY"\n    },\n    {\n      "type": "dns-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374913",\n      "token": "6waUQjjFL0aBB6Cqn9CO-1R8dkb2mKv9RQZB1gz4IfE"\n    },\n    {\n      "type": "http-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374914",\n      "token": "YN7T-Oo4Au2wFHXQBZ0xj53dU70-HbAlyPrI4mkekF4"\n    }\n  ],\n  "combinations": [\n    [\n      1\n    ],\n    [\n      2\n    ],\n    [\n      0\n    ]\n  ]\n}'
2016-12-28 16:55:02,850:DEBUG:acme.client:Storing nonce: 'o{E!sQ\x05\xb4N\xa386\xdb\x08\xc7w\xc0\r\xeb!\xdd.J\x01\xe8\xff\xc9\xf6\xcc\xafJ&'
2016-12-28 16:55:02,850:DEBUG:acme.client:Received response <Response [201]> (headers: {'content-length': '1004', 'strict-transport-security': 'max-age=604800', 'boulder-request-id': 'lgDUzfE5mcEkSxVioiX-x8mp56MRjvA1e4oMEyne__M', 'boulder-requester': '3583115', 'expires': 'Wed, 28 Dec 2016 16:50:13 GMT', 'server': 'nginx', 'connection': 'keep-alive', 'link': '<https://acme-v01.api.letsencrypt.org/acme/new-cert>;rel="next"', 'location': 'https://acme-v01.api.letsencrypt.org/acme/authz/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU', 'pragma': 'no-cache', 'cache-control': 'max-age=0, no-cache, no-store', 'date': 'Wed, 28 Dec 2016 16:50:13 GMT', 'x-frame-options': 'DENY', 'content-type': 'application/json', 'replay-nonce': 'b3tFIXNRBbROozg22wjHd8AN6yHdLkoB6P_J9syvSiY'}): '{\n  "identifier": {\n    "type": "dns",\n    "value": "opmiwiki.mghpcc.org"\n  },\n  "status": "pending",\n  "expires": "2017-01-04T16:50:13.305632065Z",\n  "challenges": [\n    {\n      "type": "tls-sni-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374912",\n      "token": "LsNQY6mcFER3HPFz-0D_z6aIWosQq-KDWjCz2V2hOJY"\n    },\n    {\n      "type": "dns-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374913",\n      "token": "6waUQjjFL0aBB6Cqn9CO-1R8dkb2mKv9RQZB1gz4IfE"\n    },\n    {\n      "type": "http-01",\n      "status": "pending",\n      "uri": "https://acme-v01.api.letsencrypt.org/acme/challenge/3OXjell4ejOBk1qufFllZUd8zVzCbDFncn-ghgQWOJU/452374914",\n      "token": "YN7T-Oo4Au2wFHXQBZ0xj53dU70-HbAlyPrI4mkekF4"\n    }\n  ],\n  "combinations": [\n    [\n      1\n    ],\n    [\n      2\n    ],\n    [\n      0\n    ]\n  ]\n}'
2016-12-28 16:55:02,851:INFO:certbot.auth_handler:Performing the following challenges:
2016-12-28 16:55:02,851:INFO:certbot.auth_handler:tls-sni-01 challenge for opmiwiki.mghpcc.org
2016-12-28 16:55:02,915:DEBUG:certbot_apache.tls_sni_01:Adding Include /etc/httpd/conf.d/le_tls_sni_01_cert_challenge.conf to /files/etc/httpd/conf/httpd.conf
2016-12-28 16:55:02,915:DEBUG:certbot_apache.tls_sni_01:writing a config file with text:
 <IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName 9b62a8509384a78bd731a72eafe3ef09.d0471c2cb9e462b55b55c58e5ac72ec2.acme.invalid
    UseCanonicalName on
    SSLStrictSNIVHostCheck on

    LimitRequestBody 1048576

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /var/lib/letsencrypt/LsNQY6mcFER3HPFz-0D_z6aIWosQq-KDWjCz2V2hOJY.crt
    SSLCertificateKeyFile /var/lib/letsencrypt/LsNQY6mcFER3HPFz-0D_z6aIWosQq-KDWjCz2V2hOJY.pem

    DocumentRoot /var/lib/letsencrypt/tls_sni_01_page/
</VirtualHost>

</IfModule>

2016-12-28 16:55:02,931:DEBUG:certbot.reverter:Creating backup of /etc/httpd/conf/httpd.conf
2016-12-28 16:55:03,172:ERROR:certbot.util:Error while running apachectl graceful.

Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

2016-12-28 16:55:03,173:DEBUG:certbot.error_handler:Encountered exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 112, in _solve_challenges
    resp = self.auth.perform(self.achalls)
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1755, in perform
    self.restart()
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1665, in restart
    self._reload()
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1676, in _reload
    raise errors.MisconfigurationError(str(err))
MisconfigurationError: Error while running apachectl graceful.

Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.


2016-12-28 16:55:03,174:DEBUG:certbot.error_handler:Calling registered functions
2016-12-28 16:55:03,174:INFO:certbot.auth_handler:Cleaning up challenges
2016-12-28 16:55:03,511:WARNING:certbot.renewal:Attempting to renew cert from /etc/letsencrypt/renewal/opmiwiki.mghpcc.org.conf produced an unexpected error: Error while running apachectl graceful.

Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
. Skipping.
2016-12-28 16:55:03,512:DEBUG:certbot.renewal:Traceback was:
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 348, in renew_all_lineages
    main.obtain_cert(lineage_config, plugins, renewal_candidate)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 563, in obtain_cert
    action, _ = _auth_from_domains(le_client, config, domains, lineage)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 96, in _auth_from_domains
    renewal.renew_cert(config, domains, le_client, lineage)
  File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 238, in renew_cert
    new_certr, new_chain, new_key, _ = le_client.obtain_certificate(domains)
  File "/usr/lib/python2.7/site-packages/certbot/client.py", line 253, in obtain_certificate
    self.config.allow_subset_of_names)
  File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 74, in get_authorizations
    resp = self._solve_challenges()
  File "/usr/lib/python2.7/site-packages/certbot/auth_handler.py", line 112, in _solve_challenges
    resp = self.auth.perform(self.achalls)
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1755, in perform
    self.restart()
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1665, in restart
    self._reload()
  File "/usr/lib/python2.7/site-packages/certbot_apache/configurator.py", line 1676, in _reload
    raise errors.MisconfigurationError(str(err))
MisconfigurationError: Error while running apachectl graceful.

Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.


2016-12-28 16:55:03,514:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/certbot", line 9, in <module>
    load_entry_point('certbot==0.9.3', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 776, in main
    return config.func(config, plugins)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 592, in renew
    renewal.renew_all_lineages(config)
  File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 365, in renew_all_lineages
    len(renew_failures), len(parse_failures)))
Error: 1 renew failure(s), 0 parse failure(s)

Two months ago, I ran the exact same command from sudo, and renewal worked. This time, sudo /usr/bin/certbot renew --dry-run succeeded, but I have otherwise left my environment alone for testing.


First renewal not successful. HTTP service stopped
#2

The following RedHat bug describes the same situation: https://bugzilla.redhat.com/show_bug.cgi?id=1385167

I still can’t auto-renew. Is there a “right” / supported way to allow cron and httpd to share access to certificate files using SELinux?


Using the name of the challenge certificate from previous errors, I first determined was not that certbot was failing to write the challenge certificate, but that httpd lacked read access to /var/lib/letsencrypt:

$ sudo fgrep /var/lib/letsencrypt/qaRIb9XSxNqIUpMU8Yl /var/log/audit/audit.log
type=AVC msg=audit(1482987304.635:990145): avc:  denied  { getattr } for  pid=2289 comm="httpd" path="/var/lib/letsencrypt/qaRIb9XSxNqIUpMU8Yl-u0EwBil6LzxTbWkkMIabZ_Q.crt" dev="dm-0" ino=546102 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:cron_var_lib_t:s0 tclass=file

I then created a security module like the reporter of the RedHat bug did, with help from audit2allow and some trial and error, resulting in:

module certbot_renew_via_cron 1.1;

require {
        type cron_var_lib_t;
        type httpd_t;
        class file { getattr read };
}

allow httpd_t cron_var_lib_t:file { getattr read };

then piping that file through

$ sudo checkmodule -M -m -o certbot_renew_via_cron certbot_renew_via_cron.te
$ sudo semodule_package -o certbot_renew_via_cron.pp -m certbot_renew_via_cron
$ sudo semodule -i certbot_renew_via_cron.pp

However, I’m still getting read errors, which are now killing apache during apachectl graceful. certbot describes this as MisconfigurationError: Error while running apachectl graceful., /var/log/messages complains httpd.service: main process exited, code=exited, status=1/FAILURE, and /var/log/httpd/error_log says

[Thu Dec 29 14:11:03.793435 2016] [ssl:emerg] [pid 4317] (13)Permission denied: AH02201: Init: Can't open server certificate file /var/lib/letsencrypt/9AP12j-6tXRZ5iJXEOf8EwVHcNiN-DU2GeNuyRI7UNU.crt
[Thu Dec 29 14:11:03.793445 2016] [ssl:emerg] [pid 4317] AH02312: Fatal error initialising mod_ssl, exiting.

#3

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.