Nginx-Certbot-Debians 2. Setbacks
This setup can go wrong…
I ran Certbot too early!
On an empty config file? No worries. For installation, you can run it again and again,
sudo certbot --nginx
When challenged, say to Certbot you will reuse the original certificates.
Certbot install likes working Port 80 server blocks
Certbot likes to work with an existing, running, server. On Port 80, as HTTP. The Vertbot instructions for every system start like this,
To use Certbot, you’ll need…
an HTTP website
that is already online
with an open port 80
The reason Certbot likes this is because it can then scan the file, identify server configuration, then inject something useful. If there is no configuration, Certbot install does nothing.
How do I add a subdomain?
Everyone asks this. Certbot is guessy. It wants to supplement existing certificates. So asks you about that, even if you type something else in. It has an ‘–expand’ command, that guesses. I’m not keen on that command. I prefer facts. I follow an idea from a post listed in the references. List your existing certificates,
sudo certbot certificates
All certificates have a name. Get the name, then target certificates. Add all domains to this command, because Certbot will erase current contents,
sudo certbot certonly --cert-name zerohour.com -d zerohour.com,www.zerohour.com
As for Certbot install, this is where it goes pickle‐shaped. See, Certbot will handle installing into an existing block, say you want to add ‘www.zerohour.com’ to ‘zerohour.com’.
But let’s say you want some other functionality, so want a separate block for your ‘smokingwreakage.zerohour.com’ domain name. Certbot will be confused. Won’t do anything bad, but will refuse to write. This is where people end with multiple certificates for the same domain, or blocks that won’t authenticate. Maybe you’d be best abandoning the Certbot installer and handwriting the block. You should have the certificate list on the original route, so copy and paste over, then can write in the redirect,
# New block for new subdomain
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name smokingwreakage.zerohour.co.uk;
root /usr/share/nginx/wreakagezerohour;
access_log /var/log/nginx/wreakagezerohour/access.log;
error_log /var/log/nginx/wreakagezerohourerror.log;
location / {
limit_except GET { deny all; }
}
#########################
# Certbot certificates
#########################
ssl_certificate /etc/letsencrypt/live/zerohour.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/zerohour.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 {
# Add new subdomain here
if ($host = smokingwreakage.zerohour.com) {
return 301 https://$host$request_uri;
}
if ($host = zerohour.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
# Add new subdomain here
server_name zerohour.com smokingwreakage.zerohour.com;
return 404; # managed by Certbot
}
Check also the post in References.
How do I add a new domain?
You need a working server block. It needs to be symlimked into ‘sites‐enabled,
sudo ln -s /etc/nginx/sites-available/com.hourone.conf /etc/nginx/sites-enabled/
And needs to be passed by,
nginx -t
Otherwise Certbot will fail.
If you’ve run a Certbot install on a non‐working config—easy to do—despite dire warnings and abrupt behaviour, Certbot will make the certificate. You can get in a big tangle with this, generating multiple certificates. You can get out by listing the certificates, tidy up surplus files, then run this as install instead,
certbot install --cert-name hourone.com
Which only runs the install routine.
An /etc/nginx/nginx.conf
As of 2022,
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
Debianess
Debian packaging is rigourous. If code can’t be placed in as Debain approves, and fit with Debian ethos, it will be hacked intil it does. But there are reasons for the packaging decisions in Debian.
This is about two directories in ‘/etc/nginx/’, ‘sites‐available’, and ‘sites‐enabled’,
├── sites-enabled
│ └── default
└── sites-available
└── default
Which is a Debian reconfiguration, and true for, as well as Nginx, Debian packaging of Apache. First, you are supposed to write one config file per route/server. On a remote terminal editor, this makes life easier. Second, it means you can drop or raise a server segment by pulling the configuration in and out of the directory—which is neat.
But that is not enough. First, if you’re writing or moving files, it means the whole server is down while you do that. Second, if something goes wrong in the editing, it can cause temp files to appear—‐if those temp files can be interpreted as configuration by the server, you are in trouble. So Debian provide the second directory, ‘sites‐enabled’. What you do is, when you have finished the configuration, or want to enable/diable a site, you make a symlink into ‘sites enabled’. That is a very fast thing to do. If the config works, it is near‐seamless. With bo danger of leaving junk about. For Apache, Debian provide a script for this action called ‘a2ensite’. No script for Nginx. But the intent is the same.
Should I use the Debian structure?
There’s downsides. Unless you’ve found this information somewhere, you’ll never know about it. And the structure is an over‐abstraction for a small server. Will you remember all this in one year’s time? However, I give you one reason why you should, even if Debian are near forcing you into this. Let’s say you ignore them, then write config straight into ‘/etc/nginx/nginx.conf’. You will, if you spot them, get code riddled with errors,
nginx: [warn] conflicting server name "zerohour.com" on 0.0.0.0:443, ignored
The Nginx test command,
nginx -t
returns,
...
conflicting server name "zerohour.com" on 0.0.0.0:80, ignored
If you go online, you’ll find other coders have run into this problem.
Here is the problem… these lines in ‘nginx.conf,
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
They are importing live configuration from other files. Thus, there are many declarations of the same server in different blocks—thus the conflicts. If you want your hacky stab at one‐file configuration to work, you need to comment those two out.
All good? See Part Three Maintaining Certbot to check this will stay running.
Refs
Nano shortcuts, always useful here,
Certbot, my site is running on… instructions,
Debian on some aspects on their packaging,
The How Do I Add A Subdomain To Certbot question,