config/configuration.nix

392 lines
11 KiB
Nix
Raw Normal View History

2023-01-03 12:31:37 +02:00
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
2023-01-17 15:43:21 +02:00
{ config, pkgs, lib, ... }:
2023-01-03 12:31:37 +02:00
2023-01-17 15:43:21 +02:00
let
tailscale_subnet4 = "100.89.176.0/20";
2023-01-17 15:43:21 +02:00
ssh_pubkeys = {
2023-01-03 12:31:37 +02:00
motiejus = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+qpaaD+FCYPcUU1ONbw/ff5j0xXu5DNvp/4qZH/vOYwG13uDdfI5ISYPs8zNaVcFuEDgNxWorVPwDw4p6+1JwRLlhO4J/5tE1w8Gt6C7y76LRWnp0rCdva5vL3xMozxYIWVOAiN131eyirV2FdOaqTwPy4ouNMmBFbibLQwBna89tbFMG/jwR7Cxt1I6UiYOuCXIocI5YUbXlsXoK9gr5yBRoTjl2OfH2itGYHz9xQCswvatmqrnteubAbkb6IUFYz184rnlVntuZLwzM99ezcG4v8/485gWkotTkOgQIrGNKgOA7UNKpQNbrwdPAMugqfSTo6g8fEvy0Q+6OXdxw5X7en2TJE+BLVaXp4pVMdOAzKF0nnssn64sRhsrUtFIjNGmOWBOR2gGokaJcM6x9R72qxucuG5054pSibs32BkPEg6Qzp+Bh77C3vUmC94YLVg6pazHhLroYSP1xQjfOvXyLxXB1s9rwJcO+s4kqmInft2weyhfaFE0Bjcoc+1/dKuQYfPCPSB//4zvktxTXud80zwWzMy91Q4ucRrHTBz3PrhO8ys74aSGnKOiG3ccD3HbaT0Ff4qmtIwHcAjrnNlINAcH/A2mpi0/2xA7T8WpFnvgtkQbcMF0kEKGnNS5ULZXP/LC8BlLXxwPdqTzvKikkTb661j4PhJhinhVwnQ==";
vno1_root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMiWb7yeSeuFCMZWarKJD6ZSxIlpEHbU++MfpOIy/2kh";
2023-01-26 19:05:59 +02:00
};
mountLatest = ({mountpoint, zfs_name}:
''
set -euo pipefail
${pkgs.util-linux}/bin/umount ${mountpoint}/.snapshot-latest || : &>/dev/null
mkdir -p ${mountpoint}/.snapshot-latest
${pkgs.util-linux}/bin/mount -t zfs $(${pkgs.zfs}/bin/zfs list -H -t snapshot -o name ${zfs_name} | sort | tail -1) ${mountpoint}/.snapshot-latest
''
);
umountLatest = ({mountpoint, ...}:
''set -euo pipefail
2023-01-26 20:26:58 +02:00
${pkgs.util-linux}/bin/umount ${mountpoint}/.snapshot-latest
2023-01-26 19:05:59 +02:00
''
);
backup_paths = {
var_lib = {
mountpoint = "/var/lib";
zfs_name = "rpool/nixos/var/lib";
paths = [
"/var/lib/.snapshot-latest/gitea"
"/var/lib/.snapshot-latest/headscale"
];
2023-01-26 20:57:45 +02:00
backup_at = "*-*-* *:01:00";
2023-01-26 19:05:59 +02:00
};
var_log = {
mountpoint = "/var/log";
zfs_name = "rpool/nixos/var/log";
2023-01-31 18:32:51 +02:00
paths = [ "/var/log/.snapshot-latest/caddy/" ];
2023-01-26 20:57:45 +02:00
patterns = [
2023-01-31 18:32:51 +02:00
"+ /var/log/.snapshot-latest/caddy/access-beta.jakstys.lt.log-*.zst"
2023-01-26 20:57:45 +02:00
"- *"
];
2023-01-26 19:05:59 +02:00
backup_at = "*-*-* 00:10:00";
};
};
in {
2023-01-03 12:31:37 +02:00
imports =
[
/etc/nixos/hardware-configuration.nix /etc/nixos/zfs.nix
];
2023-01-04 10:06:52 +02:00
boot.initrd.network = {
2023-01-03 12:31:37 +02:00
enable = true;
2023-01-04 10:06:52 +02:00
ssh = {
enable = true;
port = 22;
authorizedKeys = builtins.attrValues ssh_pubkeys;
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
};
2023-01-03 12:31:37 +02:00
};
2023-01-04 10:06:52 +02:00
security.sudo = {
wheelNeedsPassword = false;
execWheelOnly = true;
2023-01-03 12:31:37 +02:00
};
time.timeZone = "UTC";
2023-01-04 10:06:52 +02:00
users = {
mutableUsers = false;
2023-01-03 12:31:37 +02:00
2023-01-04 10:06:52 +02:00
users = {
git = {
description = "Gitea Service";
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
};
motiejus = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [ ssh_pubkeys.motiejus ];
};
};
};
2023-01-03 12:31:37 +02:00
environment.systemPackages = with pkgs; [
jq
vim
git
tmux
tree
wget
lsof
file
htop
#ncdu
2023-01-03 15:36:48 +02:00
sqlite
2023-01-03 12:31:37 +02:00
ripgrep
binutils
pciutils
headscale
mailutils
2023-01-03 12:31:37 +02:00
nixos-option
];
programs.mtr.enable = true;
2023-01-26 19:11:13 +02:00
programs.mosh.enable = true;
2023-01-11 09:47:50 +02:00
programs.ssh.knownHosts = {
"vno1-oh2.servers.jakst" = {
extraHostNames = ["dl.jakstys.lt" "vno1-oh2.jakstys.lt"];
2023-02-19 22:08:28 +02:00
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHtYsaht57g2sp6UmLHqsCK+fHjiiZ0rmGceFmFt88pY";
2023-01-11 09:47:50 +02:00
};
"hel1-a.servers.jakst" = {
extraHostNames = ["hel1-a.jakstys.lt" "git.jakstys.lt" "vpn.jakstys.lt"];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF6Wd2lKrpP2Gqul10obMo2dc1xKaaLv0I4FAnfIaFKu";
};
"hel1-b.servers.jakst" = {
extraHostNames = ["hel1-b.jakstys.lt" "jakstys.lt"];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINCJxdEkgQ3U0XxqDibk0g3iV+FG423Yk8hj6VAIOpT5";
};
"mtwork.motiejus.jakst" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOvNuABV5KXmh6rmS+R50XeJ9/V+Sgpuc1DrlYXW2bQb";
};
"zh2769.rsync.net" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJtclizeBy1Uo3D86HpgD3LONGVH0CJ0NT+YfZlldAJd";
};
"github.com" = {
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
};
};
2023-01-03 12:31:37 +02:00
2023-01-04 10:06:52 +02:00
services = {
zfs = {
autoScrub.enable = true;
trim.enable = true;
expandOnBoot = "all";
};
2023-01-03 12:31:37 +02:00
sanoid = {
enable = true;
templates.prod = {
hourly = 24;
daily = 7;
autosnap = true;
autoprune = true;
};
2023-01-26 19:05:59 +02:00
datasets = lib.mapAttrs' (name: value: {
name = value.zfs_name;
value = { use_template = ["prod"]; };
}) backup_paths;
2023-01-15 18:54:39 +02:00
extraArgs = [ "--verbose" ];
};
2023-01-26 19:05:59 +02:00
borgbackup.jobs = lib.mapAttrs' (name: value:
let
snapshot = { mountpoint = value.mountpoint; zfs_name = value.zfs_name; };
rwpath = value.mountpoint + "/.snapshot-latest";
in {
name = name;
value = {
doInit = true;
2023-01-26 20:57:45 +02:00
repo = "zh2769@zh2769.rsync.net:borg";
2023-01-26 19:05:59 +02:00
encryption = {
mode = "repokey-blake2";
passCommand = "cat /var/src/secrets/borgbackup/password";
};
paths = value.paths;
2023-01-26 20:26:58 +02:00
extraArgs = "--remote-path=borg1";
2023-01-26 19:05:59 +02:00
compression = "auto,lzma";
2023-01-26 20:57:45 +02:00
startAt = value.backup_at;
2023-01-26 19:05:59 +02:00
readWritePaths = [ rwpath ];
preHook = mountLatest snapshot;
postHook = umountLatest snapshot;
2023-01-26 20:57:45 +02:00
prune.keep = {
within = "1d";
daily = 7;
weekly = 4;
monthly = 3;
};
2023-01-26 19:05:59 +02:00
} // lib.optionalAttrs (value ? patterns) {
patterns = value.patterns;
2023-01-15 18:54:39 +02:00
};
2023-01-26 19:05:59 +02:00
}) backup_paths;
2023-01-04 10:06:52 +02:00
openssh = {
enable = true;
passwordAuthentication = false;
permitRootLogin = "no";
extraConfig = ''
AcceptEnv GIT_PROTOCOL
'';
};
locate = {
enable = true;
locate = pkgs.plocate;
localuser = null;
2023-01-03 12:31:37 +02:00
};
2023-01-04 10:06:52 +02:00
headscale = {
enable = true;
serverUrl = "https://vpn.jakstys.lt";
openIdConnect = {
issuer = "https://git.jakstys.lt/";
clientId = "1c5fe796-452c-458d-b295-71a9967642fc";
clientSecretFile = "/var/lib/headscale/oidc_client_secret"; # https://github.com/juanfont/headscale/pull/1127
2023-01-04 10:06:52 +02:00
};
settings = {
ip_prefixes = [
tailscale_subnet4
"fd7a:115c:a1e0:59b0::/64"
];
2023-01-04 10:06:52 +02:00
dns_config = {
nameservers = [ "1.1.1.1" "8.8.4.4" ];
magic_dns = true;
base_domain = "jakst";
};
2023-01-03 12:31:37 +02:00
};
};
2023-01-04 10:06:52 +02:00
tailscale.enable = true;
gitea = {
enable = true;
user = "git";
database.user = "git";
domain = "git.jakstys.lt";
rootUrl = "https://git.jakstys.lt";
httpAddress = "127.0.0.1";
httpPort = 3000;
settings = {
admin.DISABLE_REGULAR_ORG_CREATION = true;
api.ENABLE_SWAGGER = false;
mirror.ENABLED = false;
other.SHOW_FOOTER_VERSION = false;
packages.ENABLED = false;
repository.DEFAULT_REPO_UNITS = "repo.code,repo.releases";
repository.DISABLE_MIGRATIONS = true;
repository.DISABLE_STARS = true;
repository.ENABLE_PUSH_CREATE_USER = true;
security.LOGIN_REMEMBER_DAYS = 30;
server.ENABLE_GZIP = true;
server.LANDING_PAGE = "/motiejus";
service.DISABLE_REGISTRATION = true;
service.ENABLE_TIMETRACKING = false;
service.ENABLE_USER_HEATMAP = false;
service.SHOW_MILESTONES_DASHBOARD_PAGE = false;
session.COOKIE_SECURE = true;
"service.explore".DISABLE_USERS_PAGE = true;
};
};
2023-01-03 18:23:12 +02:00
2023-01-04 10:06:52 +02:00
caddy = {
enable = true;
email = "motiejus+acme@jakstys.lt";
virtualHosts."vpn.jakstys.lt".extraConfig = ''
reverse_proxy 127.0.0.1:8080
'';
virtualHosts."git.jakstys.lt".extraConfig = ''
reverse_proxy 127.0.0.1:3000
'';
2023-01-17 15:12:08 +02:00
virtualHosts."beta.jakstys.lt" = {
logFormat = ''
output file ${config.services.caddy.logDir}/access-beta.jakstys.lt.log {
roll_disabled
}
'';
extraConfig = ''
header /_/* Cache-Control "public, max-age=31536000, immutable"
root * /var/www/jakstys.lt
file_server {
precompressed br gzip
}
2023-01-17 15:12:08 +02:00
@matrixMatch {
path /.well-known/matrix/client
path /.well-known/matrix/server
}
header @matrixMatch Content-Type application/json
header @matrixMatch Access-Control-Allow-Origin *
header @matrixMatch Cache-Control "public, max-age=3600, immutable"
2023-01-17 15:12:08 +02:00
handle /.well-known/matrix/client {
respond "{\"m.homeserver\": {\"base_url\": \"https://jakstys.lt\"}}" 200
}
handle /.well-known/matrix/server {
respond "{\"m.server\": \"jakstys.lt:443\"}" 200
}
2023-01-17 15:12:08 +02:00
handle /_matrix/* {
reverse_proxy http://hel1-b.servers.jakst:8088
}
'';
};
2023-01-03 18:39:41 +02:00
};
postfix = {
enable = true;
enableSmtp = true;
networks = [ "127.0.0.1/8" "[::ffff:127.0.0.0]/104" "[::1]/128" tailscale_subnet4 ];
hostname = "hel1-a.jakstys.lt";
relayHost = "smtp.sendgrid.net";
relayPort = 587;
mapFiles = {
sasl_passwd = "/var/src/secrets/postfix/sasl_passwd";
};
extraConfig = ''
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_tls_security_level = encrypt
header_size_limit = 4096000
'';
};
logrotate = {
settings = {
"/var/log/caddy/access-beta.jakstys.lt.log" = {
rotate = 60;
frequency = "daily";
dateext = true;
dateyesterday = true;
compress = true;
compresscmd = "${pkgs.zstd}/bin/zstd";
compressext = ".zst";
compressoptions = "--long -19";
uncompresscmd = "${pkgs.zstd}/bin/unzstd";
2023-01-17 15:12:08 +02:00
postrotate = "${pkgs.systemd}/bin/systemctl restart caddy";
};
};
};
2023-01-03 12:31:37 +02:00
};
# TODO: compress static stuff
#${pkgs.findutils}/bin/find ${pkgs.gitea.data} -name '*.css' -exec ${pkgs.brotli}/bin/brotli {} \+
2023-01-04 10:06:52 +02:00
networking = {
hostName = "hel1-a";
firewall = {
allowedTCPPorts = [ 80 443 ];
allowedUDPPorts = [ 443 ];
checkReversePath = "loose"; # tailscale insists on this
};
2023-01-03 12:31:37 +02:00
};
2023-01-04 10:06:52 +02:00
system = {
copySystemConfiguration = true;
autoUpgrade.enable = true;
autoUpgrade = {
allowReboot = true;
rebootWindow = {
2023-01-17 16:00:41 +02:00
lower = "01:00";
upper = "01:30";
2023-01-04 10:06:52 +02:00
};
2023-01-03 12:31:37 +02:00
};
};
2023-02-19 19:23:55 +02:00
nix.gc = {
automatic = true;
2023-02-19 22:21:14 +02:00
dates = "daily";
options = "--delete-older-than 14d";
2023-02-19 19:23:55 +02:00
};
2023-01-26 20:08:41 +02:00
systemd.services."make-snapshot-dirs" = let
vals = builtins.attrValues backup_paths;
mountpoints = builtins.catAttrs "mountpoint" vals;
unique_mountpoints = lib.unique mountpoints;
in {
description = "prepare snapshot directories for backups";
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
ExecStart = builtins.map (d: "${pkgs.coreutils}/bin/mkdir -p ${d}/.snapshot-latest") unique_mountpoints;
RemainAfterExit = true;
};
};
2023-01-26 19:05:59 +02:00
2023-01-04 10:06:52 +02:00
# Do not change
system.stateVersion = "22.11";
2023-01-03 12:31:37 +02:00
}