Certbot nginx setup fails due to missing certificate files

Ubuntu 20.04 server

Up to now I only did install on 18.04 and had no problems with this scenario. Out of the sudden my certbot handling is not working anymore.

I'm having an nginx configuration, which is like so:

map $http_upgrade $connection_upgrade {
    default         upgrade;
    ''              close;
}


# Servers
server {
  # 'server_name' just for certbot's validation. 
  # SSL certificate is certbot provided
  server_name server1.domain.com server2.domain.com;
  listen 80;
  listen 443 ssl;
  listen [::]:443 ssl;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

Note: I'm explicitly not defining ssl_certificate and ssl_certificate_key since this is supposed to be organized by certbot.

In the past (on 18.04) I ran this command in order to obtain the certificate:

sudo certbot -n --nginx -d server1.domain.com -d server2.domain.com -m <my-email-address> --agree-tos --redirect

I finally got my certificates automatically and also the nginx configuration was updated OK (with entries like certbot managed)

Now this error pops up on the a.m. command. The error is pretty much self-explanatory, but I don't know what to do with it, because I don't have "dummy" certificates which I could enter into the nginx.conf instead:

Error while running nginx -c /etc/nginx/nginx.conf -t.

nginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /etc/nginx/sites-enabled/default:12
nginx: configuration file /etc/nginx/nginx.conf test failed

The nginx plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running nginx -c /etc/nginx/nginx.conf -t.\n\nnginx: [emerg] no "ssl_certificate" is defined for the "listen ... ssl" directive in /etc/nginx/sites-enabled/default:12\nnginx: configuration file /etc/nginx/nginx.conf test failed\n')

Anybody having a pointer how to overcome this?

OK, providing something in the initial configuration (e.g. a self signed cert) helps to overcome this.

Yes, the Certbot --nginx plug-in will make a server block for https (port 443).

But, you have defined your server block for http (port 80) to also listen to port 443. All port 443 (ssl) server blocks must have certs defined and you don't have any.

Remove the two lines for listen 443 and try again.

Also, you are listening to both IPv4 and IPv6 for port 443 but only IPv4 for port 80. You might want to change your listen 80 line if you want to support IPv6

3 Likes

Oh, thanks for the nice pointer. I meanwhile worked around by specifying a self-self signed certificate just for the sake of it. That worked.

You mean an nginx.conf like this would do it?

# Servers
server {
  # 'server_name' just for certbot's validation. 
  # SSL certificate is certbot provided
  server_name server1.domain.com server2.domain.com;
  listen 80;
  listen 80:[::];

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

Generally I don't really want to listen on 80. I just want to have an automatic redirection to 443 in case someone calls me on 80.

Then replace:

with the redirection.

I don't see how any of that could be required to obtain a cert.

In any case, wherever the acme challenge requests will be handled will need a document root statement.

3 Likes

Hmm. I was using nginx as reverse proxy. It is terminating TLS and proxies to 8080 internally. That works.

Certbot btw. added a redirect server section.

The ACME challenge is handled by certbot and the port 80 is open

Where?
[that redirect wasn't shown]

How?
[there was no document root shown for certbot to work from]

2 Likes

No. The Certbot nginx plug-in does not actually use a file so does not need a document root. It adds a specific "return" right in the nginx config

3 Likes

Oh gawd!
I hate that method of authentication.
[wipe it from my mind every time just as soon as I hear it]

But you are right!

3 Likes

I have removed all listener entries from the original config above now and catching two warnings, once if nginx checks the conf and once if certbot gets the certs.

But in the end the configuration is like so:

server {
  server_name server1.domain.com server2.domain.com;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }




    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/server1.domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/server1.domain.com/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 {
    if ($host = server2.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = server1.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  server_name server1.domain.com server2.domain.com;
  listen 80;
    return 404; # managed by Certbot

}

server {
    if ($host = server1.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  server_name server1.domain.com server2.domain.com;
    listen 80;
    return 404; # managed by Certbot


}

Looks a bit weird. I think the confusion comes from the two server entries. But I had a note in my conf, which stated, that this is required for certbot's validation. The certificate is supposed to work for both subdomains.

EDIT: But it works

Yes, you can remove the second port 80 server block. It is a pure subset of the first port 80 server block so would never get chosen by nginx.

3 Likes

Sure. Thanks. But the whole setup is Ansible controlled, I don't want to put my hands on it later on.

I think, if I would remove "server2.domain.com" then I would not have that ambiguity, but I guess I would get in troubles later on with certbot (?, not sure, but I guess I have appeared that in the past).

Are these questions answered with my later post? The first conf was just an Ansible controlled template to start from. In earlier versions of nginx (?) it was seemingly not necessary to specify cert and key, even when there were listeners on 443.

What is wrong with it?

Anyway, thanks for the quick and accurate help.

Regards

1 Like

It leaves much out of the picture.
It comes in and makes temporary changes and then removes them in the blink of an eye.
Now that is all good and fine when things work well.
But when they don't work ... it can hide too much [including the reason why it is failing].

2 Likes

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