nixos-config/hosts/plover/default.nix

185 lines
5.3 KiB
Nix
Raw Normal View History

{ config, options, lib, pkgs, modulesPath, ... }:
2022-11-23 05:27:01 +00:00
let
2022-11-25 13:27:23 +00:00
inherit (builtins) toString;
inherit (import ./modules/hardware/networks.nix) interfaces;
2022-12-12 12:34:23 +00:00
2022-12-16 14:25:50 +00:00
# The head of the Borgbase hostname.
hetzner-boxes-user = "u332477";
hetzner-boxes-server = "${hetzner-boxes-user}.your-storagebox.de";
2022-11-23 05:27:01 +00:00
in
{
imports = [
# Since this will be rarely configured, make sure to import the appropriate
# hardware modules depending on the hosting provider (and even just the
# server).
./modules/hardware/hetzner-cloud-cx21.nix
2022-11-26 06:13:17 +00:00
# The users for this host.
(lib.getUser "nixos" "admin")
2022-11-26 06:13:17 +00:00
(lib.getUser "nixos" "plover")
# Hardened profile from nixpkgs.
"${modulesPath}/profiles/hardened.nix"
2023-01-12 13:22:55 +00:00
# The primary DNS server that is completely hidden.
./modules/services/bind.nix
# The reverse proxy of choice.
2023-01-12 13:22:55 +00:00
./modules/services/nginx.nix
# The database of choice which is used by most self-managed services on
# this server.
./modules/services/postgresql.nix
2023-01-12 13:22:55 +00:00
# The application services for this server. They are modularized since
# configuring it here will make it too big.
./modules/services/atuin.nix
./modules/services/gitea.nix
./modules/services/kanidm.nix
2023-01-12 13:22:55 +00:00
./modules/services/vaultwarden.nix
./modules/services/wireguard.nix
./modules/services/wezterm-mux-server.nix
2022-11-23 05:27:01 +00:00
];
2023-06-30 05:38:38 +00:00
# Automatic format and partitioning.
disko.devices = import ./disko.nix {
disks = [ "/dev/sda" ];
};
networking = {
2023-01-06 12:26:57 +00:00
nftables.enable = true;
domain = "foodogsquared.one";
firewall = {
2023-02-06 08:09:09 +00:00
enable = true;
allowedTCPPorts = [
22 # Secure Shells.
];
};
};
2023-02-09 06:17:59 +00:00
services.fail2ban = {
ignoreIP = [
# VPN clients.
"${interfaces.wireguard0.IPv4.address}/13"
"${interfaces.wireguard0.IPv6.address}/64"
];
2023-02-09 06:17:59 +00:00
# We're going to be unforgiving with this one since we only have key
# authentication and password authentication is disabled anyways.
jails.sshd.settings = {
enabled = true;
maxretry = 1;
};
2023-02-09 06:17:59 +00:00
};
2023-07-05 03:38:58 +00:00
sops.secrets = lib.getSecrets ./secrets/secrets.yaml {
"ssh-key" = { };
"lego/env" = { };
2023-07-05 03:38:58 +00:00
"borg/repos/host/patterns/keys" = { };
"borg/repos/host/password" = { };
"borg/repos/services/password" = { };
"borg/ssh-key" = { };
2023-07-05 03:38:58 +00:00
};
2022-11-23 05:27:01 +00:00
2023-01-12 13:22:55 +00:00
# All of the keys required to deploy the secrets.
2022-11-23 05:27:01 +00:00
sops.age.keyFile = "/var/lib/sops-nix/key.txt";
2022-12-02 04:33:51 +00:00
profiles.server = {
enable = true;
headless.enable = true;
hardened-config.enable = true;
cleanup.enable = true;
};
2023-01-12 13:22:55 +00:00
# DNS-related settings. We're settling by configuring the ACME setup with a
# self-hosted DNS server.
security.acme.defaults = {
email = "admin+acme@foodogsquared.one";
dnsProvider = "rfc2136";
dnsResolver = "1.1.1.1";
credentialsFile = config.sops.secrets."lego/env".path;
2022-12-03 00:09:26 +00:00
};
# Enable generating new DH params.
security.dhparams.enable = true;
# !!! The keys should be rotated at an interval here.
2022-12-02 04:33:51 +00:00
services.openssh.hostKeys = [{
path = config.sops.secrets."ssh-key".path;
2022-12-02 04:33:51 +00:00
type = "ed25519";
}];
2022-12-02 23:40:21 +00:00
# Of course, what is a server without a backup? A professionally-handled
2022-12-16 14:25:50 +00:00
# production system. However, we're not professionals so we do have backups.
services.borgbackup.jobs =
let
jobCommonSettings = { patternFiles ? [ ], patterns ? [ ], paths ? [ ], repo, passCommand }: {
inherit paths repo;
compression = "zstd,11";
dateFormat = "+%F-%H-%M-%S-%z";
doInit = true;
encryption = {
inherit passCommand;
mode = "repokey-blake2";
};
extraCreateArgs =
let
args = lib.flatten [
(builtins.map
(patternFile: "--patterns-from ${lib.escapeShellArg patternFile}")
patternFiles)
(builtins.map
(pattern: "--pattern ${lib.escapeShellArg pattern}")
patterns)
];
in
lib.concatStringsSep " " args;
extraInitArgs = "--make-parent-dirs";
persistentTimer = true;
preHook = ''
extraCreateArgs="$extraCreateArgs --stats"
'';
prune.keep = {
weekly = 4;
monthly = 12;
yearly = 6;
};
startAt = "monthly";
environment.BORG_RSH = "ssh -i ${config.sops.secrets."borg/ssh-key".path}";
2022-12-02 23:40:21 +00:00
};
borgRepo = path: "ssh://${hetzner-boxes-user}@${hetzner-boxes-server}:23/./borg/plover/${path}";
in
{
# Backup for host-specific files. They don't change much so it is
# acceptable for it to be backed up monthly.
host-backup = jobCommonSettings {
patternFiles = [
config.sops.secrets."borg/repos/host/patterns/keys".path
];
repo = borgRepo "host";
passCommand = "cat ${config.sops.secrets."borg/repos/host/password".path}";
};
# Backups for various services.
services-backup = jobCommonSettings
{
paths = [
# ACME accounts and TLS certificates
"/var/lib/acme"
];
repo = borgRepo "services";
passCommand = "cat ${config.sops.secrets."borg/repos/services/password".path}";
} // { startAt = "weekly"; };
2022-12-02 23:40:21 +00:00
};
programs.ssh.extraConfig = ''
Host ${hetzner-boxes-server}
IdentityFile ${config.sops.secrets."borg/ssh-key".path}
2022-12-02 23:40:21 +00:00
'';
system.stateVersion = "23.11";
2022-11-23 05:27:01 +00:00
}