# NixOS Sandhole is available as a NixOS module, which runs it as a systemd service. ## Setup You can install the NixOS module for the following pinning solutions (click to expand): Here's an example `configuration.nix` with Sandhole and Agnos. You can find full options in [the NixOS module options page](./nixos_options.md): ```nix { pkgs, ... }: let # Add admin keys to this link farm adminKeys = pkgs.linkFarm "sandhole-admin-keys" [ { name = "example-admin.pub"; path = pkgs.writeText "example-admin.pub" '' ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPH3e5SFdwLOuleypjfgauqEUAmgpm9r8lqfvc6G1o1D example-admin ''; } ]; # Add user keys to this link farm userKeys = pkgs.linkFarm "sandhole-user-keys" [ { name = "example-user.pub"; path = pkgs.writeText "example-user.pub" '' ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtH7kS+q8/8TXWAp4OJvRh/7GNkQ6FR/QBOhGJuEwEC example-user ''; } ]; admin-keys-directory = "/etc/sandhole/admin-keys"; user-keys-directory = "/etc/sandhole/user-keys"; certificates-directory = "/var/lib/sandhole/certificates"; in { # ... # By symlinking the SSH key directories to /etc, # Sandhole doesn't have to restart when modifying keys environment.etc = { "sandhole/admin-keys".source = adminKeys; "sandhole/user-keys".source = userKeys; }; # Configurations for Sandhole services.sandhole = { # Install the Sandhole package and enable the systemd service enable = true; # Let Sandhole manage the firewall and open ports from its configuration. # Note: If `disableTcp` is `false` (default), it will open all ports >= 1024 openFirewall = true; # These are the same CLI options from Sandhole, except without leading hyphens. # See: http://sandhole.com.br/cli.html # Make sure to change at least `domain` and `acme-contact-email` below settings = { domain = "sandhole.com.br"; acme-contact-email = "admin@sandhole.com.br"; disable-tcp = true; force-https = true; inherit admin-keys-directory user-keys-directory certificates-directory ; }; }; security.agnos = { enable = true; temporarilyOpenFirewall = true; user = "sandhole"; generateKeys.enable = true; settings = { dns_listen_addr = "[::]:53"; accounts = [ { # Change this to your e-mail address email = "admin@sandhole.com.br"; private_key_path = "./letsencrypt_key.pem"; certificates = [ { # Change these from `sandhole.com.br` to your domain domains = [ "sandhole.com.br" "*.sandhole.com.br" ]; fullchain_output_file = "${certificates-directory}/sandhole.com.br/fullchain.pem"; key_output_file = "${certificates-directory}/sandhole.com.br/privkey.pem"; } ]; } ]; }; }; } ``` You can then connect services with the provided keys. For example, to use a Vaultwarden NixOS container in the same machine: ```nix { lib, ... }: { # ... networking.nat = { enable = true; internalInterfaces = ["ve-+"]; externalInterface = "eno0"; # Change to the appropriate WAN interface enableIPv6 = true; }; # Example: Setting up Vaultwarden containers.vaultwarden = { autoStart = true; privateNetwork = true; hostAddress = "192.168.102.1"; localAddress = "192.168.102.2"; hostAddress6 = "fc00::2:1"; localAddress6 = "fc00::2:2"; extraFlags = [ "-U" ]; config = { lib, ... }: { services.vaultwarden = { enable = true; config = { DOMAIN = "https://vaultwarden.sandhole.com.br"; SIGNUPS_ALLOWED = false; ROCKET_ADDRESS = "::"; ROCKET_PORT = 8222; ROCKET_LOG = "warning"; }; }; networking = { firewall.allowedTCPPorts = [ 8222 ]; useHostResolvConf = lib.mkForce false; }; services.resolved.enable = true; system.stateVersion = "25.11"; }; }; # Proxy Vaultwarden to the local Sandhole instance services.autossh.sessions = [ { name = "vaultwarden"; user = "root"; # Change the arguments as necessary extraArguments = '' -i /path/to/ssh/key/example-user \ -o StrictHostKeyChecking=accept-new \ -o ServerAliveInterval=30 \ -R vaultwarden.sandhole.com.br:80:192.168.102.2:8222 \ -p 2222 \ 127.0.0.1 ''; } ]; } ``` ## Binary caching In order to avoid re-building Sandhole for each update, you can use Sandhole's binary cache. In `configuration.nix`: ```nix { # ... nix.settings = { substituters = [ # ... "https://cache.eric.dev.br" ]; trusted-public-keys = [ # ... "cache.eric.dev.br-1:szEyq5LCjxDCUHYSRaSFU5HdHmR7QlT+FRG3tB9QtpE=" ]; }; } ```