Dry run of renew works but the actual renew does not

My domain is: fef.michalzajac.me

I ran this command: sudo certbot certonly --nginx -d fef.michalzajac.me

It produced this output:

$ sudo certbot certonly -d fef.michalzajac.me          
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Nginx Web Server plugin (nginx)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator nginx, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for fef.michalzajac.me
nginx: [warn] conflicting server name "frelia.org" on 0.0.0.0:80, ignored
Waiting for verification...
Cleaning up challenges
nginx: [warn] conflicting server name "frelia.org" on 0.0.0.0:80, ignored
Failed authorization procedure. fef.michalzajac.me (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://fef.michalzajac.me/.well-known/acme-challenge/du3rhFoJvN81y97e4yfyRsMQHzagpaIoP6tHk6Ai3ZQ [188.226.239.107]: 404

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: fef.michalzajac.me
   Type:   unauthorized
   Detail: Invalid response from
   https://fef.michalzajac.me/.well-known/acme-challenge/du3rhFoJvN81y97e4yfyRsMQHzagpaIoP6tHk6Ai3ZQ
   [188.226.239.107]: 404

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

My web server is: nginx/1.16.1

The operating system my web server runs on is: Ubuntu 18.04.4 LTS

My hosting provider, if applicable, is: DigitalOcean

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

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

The version of my client is: certbot 0.31.0

Dry run for the same domain:

$ sudo certbot certonly -d fef.michalzajac.me --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Nginx Web Server plugin (nginx)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 1
Plugins selected: Authenticator nginx, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate

IMPORTANT NOTES:
 - The dry run was successful.

nginx configuration block:

upstream thin {
  server 127.0.0.1:4567;
}

server {
  server_name fef.michalzajac.me;

  location / {
    proxy_pass http://thin/;
    proxy_redirect     off;
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $server_name;
  }

  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/fef.michalzajac.me/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/fef.michalzajac.me/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
  listen 80;
  server_name fef.michalzajac.me;
  return 301 https://$host$request_uri;
}
1 Like

I figured it out myself. There was a problem with the location block - it passes EVERY request to the upstream which of course errors out.

I fixed it by altering my configuration to look like

upstream thin {
  server 127.0.0.1:4567;
}

server {
  server_name fef.michalzajac.me;

  location / {
    try_files $uri @sinatra;
  }

  location @sinatra {
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $http_host;
    proxy_redirect     off;
    proxy_pass http://thin;
  }

  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/fef.michalzajac.me/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/fef.michalzajac.me/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
  listen fef.michalzajac.me:80;
  server_name fef.michalzajac.me;
  return 301 https://$host$request_uri;
}
1 Like

Or not. I still have problems with renewing my other domain which I adjusted to have the following block:

upstream docker {
  server localhost:2137;
}

server {
    server_name git.frelia.org;

    location / {
      try_files $uri @upstream;
    }

    location @upstream {
      proxy_pass http://docker;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/git.frelia.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/git.frelia.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    listen 80;
    server_name git.frelia.org;
    return 301 https://$host$request_uri;
}
1 Like

Which was fixed only by making the @upstream block look like the following

    location @upstream {
      proxy_set_header   Host $host;
      proxy_set_header   X-Real-IP $remote_addr;
      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header   X-Forwarded-Host $http_host;
      proxy_redirect     off;
      proxy_pass http://docker;
    }

Where I copied headers one-by-one and it didn’t work only after

proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

was added.

It would be awesome if someone could tell me why that particular header made it work.

1 Like