Certbot writes subdomain SSL config to nginx’s default config than the specific subdomain config

I created a LetsEncrypt SSL config for my domain (hrishib.com). Prior to this, I created an nginx configuration for my domain under /etc/nginx/sites-available and symlinked it in /etc/nginx/sites-enabled . When certbot created the certificates for this domain, it modified the hrishib.com configuration under sites-available.

I then installed phpmyadmin and wanted it to be available at phpmyadmin.hrishib.com However, certbot wrote the SSL config for this subdomain in default under /sites-available/ even when there is a subdomain configuration file called phpmyadmin.hrishib.com under /sites-available/. Why did it not write the configuration to the subdomain configuration file as with the top-level domain?

My domain is: hrishib.com

I ran this command: certbot —nginx -d phpmyadmin.hrishib.com

It produced this output:

My web server is (include version): nginx 1.18

The operating system my web server runs on is (include version): Ubuntu 20.04

My hosting provider, if applicable, is: AWS EC2

I can log in to a root shell on my machine (yes or no, or I don't know): Yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): No

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): certbot 0.40.0

Welcome to the community!

The files in the /sites-available/ must be enabled to be in use.
[only files seen in /sites-enabled/ will be used by nginx and thus by certbot]
Was the phpmyadmin.hrishib.com site enabled before running certbot —nginx -d phpmyadmin.hrishib.com ?

Hi, thanks!

Yes it was. Which is why this was strange. Also, if I now remove the config from default and add it to phpmyadmin.hrishib.com config, would it work? And more importantly, when certbot renews it would it add to default again?

If you disable the default.conf neither nginx nor certbot should use it again.
If you add the server_name to the phpmyadmin config, then certbot should find it there.

My recommendation for Ubuntu 20 with nginx is to remove the certbot that was added with apt.
sudo apt remove certbot
and then install certbot via snapd:

Hi @electrotwelve,

That does sound strange!

Does the default.conf virtualhost happen to also have server_name phpmyadmin.hrishib.com?

That's the only reason I can think that this would have happened.

If you are able to share the full output of:

sudo nginx -T

that would help get to the bottom of things.

Hi,

The output is visible here. The default has no server_name and is pointing to /var/www/html. As you can see the configuration added by certbot also points to the same root. The sites-enabled has phpmyadmin.hrishib.com in it.

Thanks! I think I see what's happened here. I will try to explain, excuse me if I do it poorly.

When Certbot's nginx plugin is asked to secure a domain, it searches for a virtualhost with a matching server_name for the domain that was requested.

If it doesn't find an exact or wildcard match, then it searches for the default nginx virtualhost, and clones it in order to create a virtualhost for the requested domain.

The latter is what happened in this case.

So, you may ask, why was there no virtualhost which matched the requested domain?

The answer lies in the configuration you just pasted, on line 452:

server_name phpmadmin.hrishib.com;

phpmadmin vs phpmyadmin

1 Like

Right you are!!! What a rookie mistake :expressionless:

# configuration file /etc/nginx/sites-enabled/phpmyadmin.hrishib.com:
server {
  server_name phpmadmin.hrishib.com;
  root /usr/share/phpmyadmin;
  index index.php index.html index.htm index.nginx-debian.html;

  access_log /var/log/nginx/phpmyadmin_access.log;
  error_log /var/log/nginx/phpmyadmin_error.log;

  location / {
    try_files $uri $uri/ /index.php;
  }

  location ~ ^/(doc|sql|setup)/ {
    deny all;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
  }

  location ~ /\.ht {
    deny all;
  }
}

In addition to the TYPO already mentioned, I fail to see a listen statement in that server block.

1 Like

Nice catch. It might not matter due to the default value of listen: https://nginx.org/en/docs/http/ngx_http_core_module.html#listen, but I've never tried omitting it myself.

1 Like