Certbot fails renewal with http-01 challenge on NGINX: Connection refused
The problem
This has been bothering me for more than half of a year. You might be unable to automatically renew certificates if the following conditions are true:
- You're using the python-certbot-nginx plugin to install certificates and handle their renewal on your webserver.
- You're using different location for acme-challenge than the actual folder inside installation root - this is most likely if you're using NGINX as a proxy for a different service.
During the renewal process you will most likely receive the following error:
Attempting to renew cert (example.com) from /etc/letsencrypt/renewal/example.com.conf produced an unexpected error: Failed authorization procedure. example.com (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching https://www.example.com/.well-known/acme-challenge/1hDMJJfjSOPJENxVmuXdDiphrVlEgRGXfHWB7Z8: Connection refused
However testing the connection with curl or wget from any location predictably gives just a 404 error. To fix it, I had to delete the old certificate configuration and reinstall it with the certbot-nginx plugin each time. This would allow http-01 challenge to pass successfully.
After pulling my hair for a while and playing with the --dry-run
option, I've finally noticed the following message:
Plugins selected: Authenticator webroot, Installer nginx
This is wrong. It should be:
Plugins selected: Authenticator nginx, Installer nginx
The reason for the failure appears to be the alternate acme-challenge folder location. Webroot authenticator doesn't handle it and it will attempt to verify using regular sub-folder in webroot.
The solution
Open /etc/cron.d/certbot
file and add --nginx
option to the renew command, the python-certbot-nginx should be adding it automatically but it doesn't.