All attempts to renew fail


#1

My domain is: https://www.jefflowy.com

I ran this command: ./certbot-auto renew --dry-run

It produced this output:
Attempting to renew cert (jefflowy.com) from /etc/letsencrypt/renewal/jefflowy.com.conf produced an unexpected error: Problem binding to port 80: Could not bind to IPv4 or IPv6. Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/jefflowy.com/fullchain.pem (failure)

My web server is: | Node.js v9.2.0 | nginx/1.10.3 (Ubuntu)

The operating system my web server runs: Ubuntu 16.04.3 x64

My hosting provider: Digital Ocean

I can login to a root shell on my machine: yes

I’m using a control panel to manage my site: no


#2

Hi @jeffreylowy,

What command did you originally use to obtain the certificate? Did you perhaps use --standalone?


#3

Hi @schoen, thank you for replying. Yes, when I created the certificate I ran ./certbot-auto certonly --standalone


#4

If you created it a couple of months ago, --standalone might have been using port 443, but now it might have switched to port 80 because of a change in permitted authentication methods of the CA side.

When you created the certificate, did you have port 443 free but not port 80? Or is it possible that you weren’t running a web server on this machine at all (but now you are)?


#5

What version of certbot are you using? I had a similar issue with version 0.17 and upgraded to version 0.21 and it was fixed. I used:

sudo apt-get --fix-broken upgrade certbot

Hope this helps.


#6

@rbrisita - thank you! I am running v0.21 :frowning:

@schoen -
Sorry, in advance for my ignorance here and maybe not answering correctly. When I first created the server I was running form port 3000, proxying 80. Once I got the site to a place I was happy, I followed this tutorial, which asked that I add the code below to /etc/nginx/sites-enabled/default (replacing example.com with my domain):

# HTTP — redirect all traffic to HTTPS
server {
    listen 80;
    listen [::]:80 default_server ipv6only=on;
    return 301 https://$host$request_uri;
}

# HTTPS — proxy all requests to the Node app
server {
    # Enable HTTP/2
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name app.example.com;

    # Use the Let’s Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    # Include the SSL configuration from cipherli.st
    include snippets/ssl-params.conf;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass http://localhost:3000/;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
    }
}

#7

So, --standalone conflicts with having nginx listen on port 80, which your nginx configuration is now doing. That’s the root of your renewal problem: when you originally got the certificate, port 80 wasn’t used by nginx, but now it is.

We often say that --standalone is meant for use on machines that aren’t running a web server. However, if a machine starts running a web server after the certificate is issued, --standalone may then stop working.

There are basically two solutions available:

(1) You can temporarily stop and restart nginx when doing certificate renewals. There is a way to get Certbot to remember to do this for you with hooks, so that certbot renew will still work and will temporarily stop nginx for the duration of the renewal authentication. In this case, you can keep using --standalone because port 80 will become free temporarily during the renewal.

(2) You can change the authentication method to something other than --standalone (for example --nginx as of 0.21 should be fine, or --webroot if your configuration serves static files rather than proxying requests to a web app… which it looks like would be a problem for you in this configuration unless you configured an exception to the proxy_pass for the /.well-known/acme-challenge URL path).


#8

Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/...

You are an amazing human, @schoen!!!