#+title: Server Setup #+author: Emmet These are basic instructions for how I have configured the OS and auxiliary packages for my home server. This sets up: - Sane security defaults - At-rest encryption for all important data - Remote and local backups For information on how to setup the various Docker containers for services, visit each of the subdirectories here: - [[./homelab][homelab]] - [[./network][network]] - [[./gameservers][gameservers]] ** Installation I use NixOS btw, so I have a NixOS setup for servers. All I need are my dotfiles ([[https://gitlab.com/librephoenix/nixos-config][GitLab]], [[https://github.com/librephoenix/nixos-config][GitHub]]) with =profile= set to "homelab" inside my =flake.nix=. What this essentially does is: - Activate a firewall that doesn't let anything through by default (except SSH) - Activates ssh with my public ssh key authorized - Disallows root login via ssh - Disallows password-based login via ssh - Replaces =sudo= with =doas=, since sudo is overkill for a system managed by one person - Installs necessary packages for server management: - =docker=, along with docker utilities =docker-compose= and =lazydocker= - =gocryptfs= for easy at-rest encryption of all important data - =rdiff-backup= for quick reverse-incremental backups - =rclone= for connecting to cloud storage for off-site backups Again, since I use NixOS, my configuration does all of this for me, since I told it to. All of these can be done on other Linux distros (i.e. Ubuntu, Debian, Arch), but require you to remember a set of steps. A quick look through the [[https://wiki.archlinux.org/][Arch wiki]] should tell you how to set any of these up yourself on a different system if you would like. ** At-rest Encryption Most of the time, when you encrypt a Linux desktop or laptop, you use =block encryption=, which encrypts /literally everything/ (except the bootloader). What this means is, if the computer shuts down unexpectedly, when turning it back on, you must either: - Input the keyphrase manually - Store a keyfile on the disk to decrypt it In the first case, you /can/ set it up to allow you to input the keyphrase remotely, but that's a bit annoying to setup, which means you can only input the keyphrase when you have physical access to the server. In the second case, any moderately skilled hacker who steals your hard drive can decrypt the entire thing, which means the encryption isn't doing its job. In any case, while more secure, this block encryption is inconvenient for homelab usage. *** Stacked Filesystem Encryption The other solution is =stacked filesystem encryption=, in which you encrypt only a single directory (we'll call it =crypt=), and then virtually mount it for usage inside a decrypted directory (I usually call this directory =plain=). Benefits to this for are: - You can decrypt it remotely a lot easier (as long as the server is physically on), since you will still always have access to ssh in the case of an interruption - It's /really/ easy to backup everything to the cloud /encrypted/, since all you need to do is sync the =crypt= folder instead of the =plain= folder With respect to block-level encryption: - It may be easier for an attacker with physical access to tamper with your system-level files to install a rootkit or other nasty hack, since those files remain unencrypted on the system - With most stacked encryption solutions, attackers can still see the directory structure and relative file sizes of encrypted files, which can allow them to guess what kind of files you have (even if the file names and contents are encrypted) For my use I'm going with =stacked filesystem encryption= using a package called [[https://nuetzlich.net/gocryptfs/][gocryptfs]] *** Gocryptfs Setup First create two directories: =crypt= and =plain=. =crypt= is the encrypted directory, while =plain= is where it will be mounted in the clear. #+BEGIN_SRC sh :noexec mkdir crypt plain #+END_SRC Then, you must initialize the encrypted directory, providing it with a passphrase: #+BEGIN_SRC sh :noexec gocryptfs -init crypt #+END_SRC It will give you a master key, which gives you /complete access to the encrypted directory/. As they explain, save it in a secure place and /only use it in emergencies/! Finally, to mount it, you merely run: #+BEGIN_SRC sh :noexec gocryptfs crypt plain #+END_SRC The only problem with this setup, is that /only the user that called the command can view the unencrypted contents/. If you call this as your normal user /not even root can see inside the decrypted mount/. This is a feature, not a bug. However, since many docker containers rely on multiple users, this means that running most docker containers inside a gocryptfs mount won't work by default. Fortunately, we can allow other users into the mount with the =-allow_others= flag: #+BEGIN_SRC sh :noexec gocryptfs -allow_others crypt plain #+END_SRC which allows normal filesystem access inside the gocryptfs mount based on *nix permissions. ** Container Setup With gocryptfs setup and mounted, the =docker-compose= examples from this repo can be copied into the =plain= directory and setup. Most examples require you to change defaults, such as database passwords, domain name(s), email, time zones, etc.. More info can be found in each subdirectory (i.e. [[./homelab][homelab]], [[./network][network]], [[./gameservers][gameservers]], etc...) Once such defaults are properly configured, you can =cd= into each directory and run: #+BEGIN_SRC sh :noexec sudo docker-compose up -d #+END_SRC to start the containers. ** Backup Setup If data does not exist in at least 3 physical drives, and at least 2 geographically separated locations, it does not exist. It is a good idea to set up: - A local backup on a separate SSD or flash drive - This protects against your main hard drive failing - Additionally, if it is disconnected, this protects against ransomware and/or other hacks where access to data is compromised by an attacker - A remote backup in the cloud (or someone else's computer) - This protects you against a home disaster such as fire, flooding, theft More information can be found in [[./homelab/maintenance.org][maintenance.org]] within the homelab directory.