Server Setup Checklist
[ ]
Set root password.[ ]
Create admin user in groupwheel
.[ ]
Allow admin user to use sudo or doas, installing one or the other if not present.[ ]
Install and enable sshd if it's not already present.[ ]
SetAllowRootLogin
tono
in sshd config.[ ]
Enable pubkey ssh authentication (ssh-copy-id(1)
on the local machine).[ ]
Set system hostname (/etc/hostname) if not already set, then reboot.
TODO: set up an ssh sinkhole to waste attackers' time instead of just denying them.
Basic Nginx setup with HTTPS
- Fetch a certificate: (as root, without a webserver running)
certbot certonly --standalone -d ... -d ... -d ...
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 certificates0 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.