Server Setup Checklist

TODO: set up an ssh sinkhole to waste attackers' time instead of just denying them.

Basic Nginx setup with HTTPS

  1. Fetch a certificate: (as root, without a webserver running) certbot certonly --standalone -d ... -d ... -d ...
  2. Add a root cron job or systemd timer to renew certificates. On systemd machines this is systemctl enable --now certbot-renew.timer. Otherwise, add a root crontab like this one that will run every midnight and restart nginx in order to reload the certificates

    0 0 * * * certbot renew --noninteractive --post-hook 'systemctl restart nginx.service'
    
http {
        server {
                isten 80;
                listen [::]:80;
                server_name example.com;
                location / {
                        return 302 https://$server_name$request_uri;
                }
        }

        server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;
                server_name example.com;
                ssl_certificate /etc/letsencrypt/live/example.com/cert.pem;
                ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

                # root /srv/www/htdocs;

                # location / {
                # 	proxy_pass http://localhost:8080;
                # }
        }
}

If firewalld is running, allow Nginx to be accessed from outside:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

If SELinux is enabled and I'm using Nginx as a reverse proxy, allow Nginx to proxy requests to it:

sudo setsebool -P httpd_can_network_connect true

If I'm serving static files that I want to be accessible to a specific user, the root directory needs to owned by that user and the Nginx group; chown -R user:nginx /my/web/root. Note that in order for Nginx to actually access this folder, every parent directory must have the execute bit set (chmod 644). This means that if you want to serve static files in users' home directories, their home directories will end up readable to other users on the system.

Aside: Perhaps chmod'ing /home/user to 744 and chown'ing it to user:nginx would prevent this, though I think it would come with the downside of the Nginx group (ie, attackers running malicious code in an nginx process via a buffer overflow vulnerability) the ability to list their home directory

Basic PostgreSQL setup

Some systems ship Postgres with the ident authentication policy by default which maps database roles to user accounts. I prefer to have one role per application, so password authentication policy makes more sense. Additionally, it's good to change the password hashing algorithm from md5 to the more secure scram-sha-256. On Linux the config file is /var/lib/pgsql/data/pghba.conf:

host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

System status cron job

To receive reports of cron jobs, add MAILTO=me@example.com at the top of every crontab I'm using.

TODO: systemd workaround.

TODO: set up an address with valid DMARC/SPF so that messages don't get bounced.

TODO: instead of emails about output of each command, it would be nicer to receive daily/weekly digests of everything that happened on the machine.

Backups

TODO: figure out a good, generally applicable backup policy for servers that handles both configs and data and works well with PostgreSQL.

Page last modified on 2024-06-10 Mon 19:31 This site made with <3 in GNU Emacs