This document covers using the Server role.
- System Maintenance
- Bind Mounts and External Disks
- Services
- Service Virtual Machines
- WireGuard
- Further Reading
Routine tasks such as updating the flake, switching configurations,
garbage-collecting, and editing variables & secrets are handled through the
bespoke unified nixos(1) wrapper CLI.
Manpage:
man nixosSee CLI Documentation for the full command reference and workflow examples.
The flake uses variables for device-specific configuration.
For example, server services can be configured and external drives can be mounted via the variables file. To edit the variables file:
nixos edit varsThe flake uses secrets (via sops) for sensitive information.
For example, the hashed user password, the network PSK, the DuckDNS API key,
etc. are configured via sops. To edit the sops file:
nixos edit sopsThe variables file can be used to create bind mounts, which can be used to put files in expected data directories from external disks.
See Additional Disks and Mounts for more information.
The following services are available:
OpenSSH secure shell daemon with a hardened configuration. SSH is also required for seeding the current machine.
OpenSSH runs on the Host.
Enabled using vars.services.ssh.enable.
Open on LAN to the private CIDR defined by vars.services.ssh.allow:
vars.services.ssh.port
Trusted public keys are defined in vars.services.ssh.trusted-keys.
Host keys are generated and stored under /etc/ssh.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.services.ssh.allow, for nftables filtering on LAN - public key in
vars.services.ssh.trusted-keys, for OpenSSH authorization
For vars.services.ssh
{
enable = true;
allow = "10.0.0.4/31"; # allow 10.0.0.4 and 10.0.0.5
trusted-keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM4BfT6bp+fl83TyrSFAerXpAq6AVmVlfUnfnPU3jHHY example@example"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH+iL2MFXNyxd3Hu6akfdOBeI6HYWE4R0LTBScTHCoyH example@example"
];
}Unbound caching forwarding validating DNS server with a hardened configuration.
Unbound runs in a Virtual Machine. See Service Virtual Machines for more information.
Queries are forwarded to Cloudflare with DoT.
Enabled using vars.services.unbound.enable
Open on WireGuard to the private CIDR defined by vars.services.unbound.allow:
53/tcpdns53/udpdns
Additional entries can be added using vars.services.unbound.local-data.
Data is stored under /var/lib/unbound.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.unbound.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.unbound.allow, for Unbound's access control
Web server and reverse proxy.
NGINX runs in a Virtual Machine. See Service Virtual Machines for more information.
Enabled using vars.services.nginx.enable.
Open on WireGuard to private CIDR defined by vars.services.nginx.allow:
443https
The nginx web server is hosted at https://<your-duckdns-domain>.
The DuckDNS domain is declared using vars.services.nginx.domain.
It attempts to fetch a Let's Encrypt HTTPS certificate with a DNS-01 challenge using your duckdns domain.
Certificates are renewed using ACME, which stores them in /var/lib/acme.
The root of the web server returns a homepage with links to all the enabled services' reverse proxy pages. There are additional locations as well. All possible locations are listed below:
| Location | Name | Description | Allowed private CIDR |
|---|---|---|---|
/searxng/ |
SearXNG | Search engine | vars.services.searxng.allow |
/vaultwarden/ |
Vaultwarden web vault | Password manager | vars.services.vaultwarden.allow |
/i2pd/ |
I2PD web console | Invisible Internet Protocol | vars.services.i2pd.allow |
/qbt/ |
qBittorrent webui | Bittorrent client | vars.services.qbt.allow |
/torrents/ |
qBittorrent torrents | Torrents in /srv/torrents |
vars.services.qbt.allow |
/static/ |
Static serve | /srv/static |
- |
Note that NGINX itself is open to vars.services.nginx.allow only.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.nginx.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.<name>.allowfor specific locations, for NGINX allow rules
Fast, private metasearch engine.
Enabled using vars.services.searxng.enable.
SearXNG runs in a Virtual Machine. See Service Virtual Machines for more information.
The following search engines are enabled by default on the general tab:
- Bing
- DuckDuckGo
- Startpage
- Wikipedia
The following search engines are enabled by default on the images tab:
- DuckDuckGo
- Startpage
Requires a secret key which is stored using sops-nix.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.nginx.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.searxng.allow, for NGINX allow rules
Password manager.
Enabled using vars.services.vaultwarden.enable.
Vaultwarden runs in a Virtual Machine. See Service Virtual Machines for more information.
The vault is stored at /var/lib/bitwarden_rs.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.nginx.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.vaultwarden.allow, for NGINX allow rules
Router for the I2P network.
Enabled using vars.services.i2pd.enable.
I2PD runs in a Virtual Machine. See Service Virtual Machines for more information.
Open on WireGuard to the private CIDR defined by vars.services.i2pd.allow:
4444HTTP proxy
Data is stored under /var/lib/i2pd.
Access control is enforced in the following places:
For webconsole:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.nginx.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.i2pd.allow, for NGINX allow rules
For HTTP proxy:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.i2pd.allow, for nftables filtering on WireGuard
Web interface for the qBittorrent bittorrent client.
qBittorrent runs in a Virtual Machine. See Service Virtual Machines for more information.
Enabled using vars.services.qbt.enable.
Data is stored under /var/lib/qbt.
Default torrent download directory is /srv/torrents/downloads.
Additionally, two categories are created: Movies and TV.
Default download directory for Movies is: /srv/torrents/movies.
Default download directory for TV is: /srv/torrents/tv.
The entirety of /srv/torrents can be viewed at the NGINX location
/torrents/.
qBittorrent will initially start with username admin and a random password.
Check the service status for the password. Since qBittorrent runs in a Virtual
Machine, ssh into the Virtual Machine first.
svcvm ssh qbt
systemctl status qbtThen, in the web ui https://<your-duckdns-domain>/qbt/ under
Tools > Options > WebUI > Authentication set a username and password.
Access control is enforced in the following places:
Clients must satisfy ALL of:
- in the private LAN CIDR defined by
vars.wireguard.allow, for nftables filtering on LAN - declared as a peer with public key in
vars.wireguard.peers, for WireGuard tunnelling - in the private WireGuard CIDR defined by
vars.services.nginx.allow, for nftables filtering on WireGuard - in the private WireGuard CIDR defined by
vars.services.qbt.allow, for NGINX allow rules
Several services run in svcvm QEMU microvm
machines. Each svcvm guest uses its own interface and runs behind a NAT. Rather
than being bridged, the VMs use a
routed network model
with TAP interfaces and nftables for NAT.
The nftables firewall is used to allow restricted access to required regions. See Firewall for more information.
| svcvm Guest | (internal) IP Address | Interface | Gateway |
|---|---|---|---|
unbound |
10.204.3.2 |
svcvm3 |
10.204.3.1 |
nginx |
10.204.4.2 |
svcvm4 |
10.204.4.1 |
searxng |
10.204.5.2 |
svcvm5 |
10.204.5.1 |
vaultwarden |
10.204.6.2 |
svcvm6 |
10.204.6.1 |
i2pd |
10.204.7.2 |
svcvm7 |
10.204.7.1 |
qbt |
10.204.8.2 |
svcvm8 |
10.204.8.1 |
Each svcvm guest can be manually started/stopped/restarted using the svcvm
CLI. For example:
svcvm start i2pd
svcvm stop qbt
svcvm restart searxngIt is possible to SSH into the svcvm guests using VSOCK from the host with the
root password toor if the corresponding vars.services.<name>.debug is set to
true. For example, if vars.services.nginx.debug is set to true:
svcvm ssh nginxServices are exposed using WireGuard over LAN. WireGuard is configured in the
variables file under vars.wireguard.
Example configuration for Server (10.20.0.1 on wireguard) with a single peer
Workstation (10.20.0.2 on wireguard, 10.0.0.2 on LAN):
{
# wireguard vpn
wireguard = {
# wireguard address
address = "10.20.0.1";
# wireguard port
port = 51820;
# wireguard peers
peers = [
{
PublicKey = "F3625gAtaFYmIl8Od3DaR+FWZYukzlkHNHZCuNAR0A4=";
AllowedIPs = "10.20.0.2/32";
PersistentKeepalive = 25;
}
];
# private CIDR (LAN) to allow
# used by nftables only
allow = "10.0.0.2/32";
};
}Multiple peers can be added like this. The individual
vars.services.<name>.allow CIDRs can then be set to WireGuard peer CIDRs.
The Server has to be declared as a peer on the Workstation as well.