#tags
- Update system
- Make new user with
sudo
access- Note: If you have an SSH key, remember to copy it over -
ssh-copy-id
- Note: If you have an SSH key, remember to copy it over -
- Harden SSH
- Note: Most if not all of these changes must be applied to the server's SSH configuration file, i.e.
/etc/ssh/sshd_config
and can be applied by restarting the SSH service -sudo systemctl restart <ssh|sshd>
- (Optional, Recommended) Ensure you are using a new SSH key for this server
- Disable root login
- Note: This can be tested by logging in as
root
-ssh root@<ip>
- Note: This can be tested by logging in as
- Disable password authentication
- Disable PAM
- Note: The PAM framework is normally used for password authentication, however, due to it's design, security can be jeoparadised without proper consideration. For those that do not know about this, it is generally faster to disable than to configure in this use case - depending on the project, your mileage may vary
- Note: Disabling password authentication and PAM should be done together, you can test both by preferring passwords when logging in via SSH -
ssh -o PreferredAuthentications=password <user>@<ip>
- (Situational) Disable password authentication in
cloud-init
- Note: This is a file stored in
/etc/ssh/sshd_config.d/*-cloud-init.conf
and may require editing/removing on some VPS providers
- Note: This is a file stored in
- Manually test the above steps work via new, separate SSH session
- Note: Keeping 1 SSH session open and starting another for testing helps to avoid accidental lockout
- Note: Most if not all of these changes must be applied to the server's SSH configuration file, i.e.
- Setup
fail2ban
- Enable the SSH jail via
enabled = true
under the[sshd]
section- Note: Ensure
maxtries
is also set to prevent instant, erroneous bans
- Note: Ensure
- Manually test (you're un-banned automatically based on the default ban time of 10m, which can be changed in
/etc/fail2ban/jail.conf
- the default is 10 minutes)
- Enable the SSH jail via
- Setup firewall (
ufw
)- Note: SSH must be explicitly allowed to avoid shutting yourself out
- Note: If the application is still accessible from ports set using Docker, there are 2 ways to resolve this:
- (Recommended) Use a reverse proxy to expose the desired port (NGINX, Traefik, Caddy)
- Note: This requires no ports for the given service to be set in the Docker command/Docker Compose file
- Note: Ensure the loopback address is used when routing the port -
- 127.0.0.1:7357:7357
, where7357
is the port to be replaced - Prevent ports from being exposed
- Manually test
- (Recommended) Use a reverse proxy to expose the desired port (NGINX, Traefik, Caddy)
- Deny all incoming traffic from
ufw
's default rules -sudo ufw default deny incoming
- Allow all incoming traffic from
ufw
's default rules - Allow SSH
- Enable firewall
- Manually test
- Setup project
- Clone project
- Install dependencies
- Manually test
- Setup automated deployments via pipeline
- Configure firewall
- Allow HTTPS
- Allow HTTP only if it redirects to HTTPS
- Confirm reverse proxy works
- Ensure certificates are automatically validated
- Note: This is unneeded for Caddy/similar tech
- Ensure error reporting works
- Test server and (if setup) local backups
- Monitor up-time via UptimeRobot
- Monitor up-time via UptimeRobot
- Ensure accessibility through availability by scaling the application
- Use Docker Compose in project
- Note: This requires the project having a Docker integration, and can be skipped if the project isn't setup with this
- Use Docker Compose in project