Configs for our NixOS servers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
nixos-server-configs/configuration.nix

311 lines
9.7 KiB

{ config, pkgs, lib, ... }:
{
imports =
[
./hardware-configuration.nix
./local.nix
./boot.nix
];
# Hardening, partially based on https://madaidans-insecurities.github.io/guides/linux-hardening.html
boot.kernelPackages = pkgs.linuxKernel.packages.linux_hardened;
boot.kernel.sysctl = {
"kernel.kptr_restrict" = 2;
"kernel.dmesg_restrict" = 1;
"kernel.unprivileged_bpf_disabled" = 1;
"kernel.yama.ptrace_scope" = 3;
"kernel.kexec_load_disabled" = 1;
"kernel.sysrq" = 4;
"kernel.perf_event_paranoid" = 3;
"net.core.bpf_jit_harden" = 2;
"net.ipv4.tcp_rfc1337" = 1;
"net.ipv4.tcp_sack" = 0;
"net.ipv4.tcp_dsack" = 0;
"net.ipv4.tcp_fack" = 0;
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.conf.all.rp_filter" = 1;
"net.ipv4.conf.default.rp_filter" = 1;
"dev.tty.ldisc_autoload" = 0;
"vm.swappiness" = 1;
"vm.max_map_count" = 1048576; # For hardened_malloc
"vm.mmap_rnd_bits" = 32;
"vm.mmap_rnd_compat_bits" = 16;
"vm.unprivileged_userfaultfd" = 0;
"fs.protected_symlinks" = 1;
"fs.protected_hardlinks" = 1;
"fs.protected_fifos" = 2;
"fs.protected_regular" = 2;
"kernel.core_pattern" = "|${pkgs.coreutils-full}/bin/false";
"fs.suid_dumpable" = 0;
};
environment.memoryAllocator.provider = "graphene-hardened";
boot = {
kernelParams = [
"slab_nomerge"
"init_on_alloc=1"
"init_on_free=1"
"pages_alloc.shuffle=1"
"pti=on"
"randomize_kstack_offset=on"
"vsyscall=none"
"debugfs=off"
"oops=panic"
"module.sig_enforce=1"
"lockdown=confidentiality"
];
extraModprobeConfig = ''
install vivid ${pkgs.coreutils-full}/bin/false
install dccp ${pkgs.coreutils-full}/bin/false
install sctp ${pkgs.coreutils-full}/bin/false
install rds ${pkgs.coreutils-full}/bin/false
install tipc ${pkgs.coreutils-full}/bin/false
install n-hdlc ${pkgs.coreutils-full}/bin/false
install ax25 ${pkgs.coreutils-full}/bin/false
install netrom ${pkgs.coreutils-full}/bin/false
install x25 ${pkgs.coreutils-full}/bin/false
install rose ${pkgs.coreutils-full}/bin/false
install decnet ${pkgs.coreutils-full}/bin/false
install econet ${pkgs.coreutils-full}/bin/false
install af_802154 ${pkgs.coreutils-full}/bin/false
install ipx ${pkgs.coreutils-full}/bin/false
install appletalk ${pkgs.coreutils-full}/bin/false
install psnap ${pkgs.coreutils-full}/bin/false
install p8023 ${pkgs.coreutils-full}/bin/false
install p8022 ${pkgs.coreutils-full}/bin/false
install can ${pkgs.coreutils-full}/bin/false
install atm ${pkgs.coreutils-full}/bin/false
install bluetooth ${pkgs.coreutils-full}/bin/false}
install btusb ${pkgs.coreutils-full}/bin/false}
'';
tmpOnTmpfs = true;
};
security = {
sudo.enable = false;
polkit.enable = false;
apparmor = {
enable = true;
packages = with pkgs; [ apparmor-profiles ];
killUnconfinedConfinables = true;
};
};
services = {
dbus.apparmor = "enabled";
udisks2.enable = false;
};
# Reduce reboot downtimes and prevent system freezes, also see man systemd-system.conf
boot.loader.timeout = 1;
systemd.watchdog = {
rebootTime = lib.mkDefault "1s";
runtimeTime = "30s";
};
time.timeZone = "Europe/Berlin";
networking = {
useNetworkd = true;
dhcpcd.enable = false;
};
users.users.root = {
shell = pkgs.zsh;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsQfsjibd0vafS30n2cP4vNPtltQsh/7PQKAdVsIQOo yk-5c-nfc"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOUNjIPQUr+3IZ7aLU5oJJrhO3aec1W/q69JIOAoVed2 mba-m1"
];
};
environment = {
variables = {
CLICOLOR = "TRUE";
EDITOR = "kak";
};
defaultPackages = with pkgs; [
kakoune
tealdeer
nmap
bind
croc
killall
smartmontools
];
};
nix = {
gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 4d";
};
settings.auto-optimise-store = true;
};
system.autoUpgrade = {
enable = true;
allowReboot = true;
dates = lib.mkDefault "18:00";
randomizedDelaySec = "45min";
};
hardware.enableRedistributableFirmware = true; # Microcode updates
programs = {
zsh = {
enable = true;
setOptions = [ "extendedglob" "no_beep" ];
syntaxHighlighting.enable = true;
shellAliases = {
la = "ls -a";
ll = "ls -al";
grep = "grep --color=auto";
};
histSize = 50;
interactiveShellInit = lib.mkDefault ''
zstyle ':completion:*' completer _expand _complete _ignored _match _approximate _prefix
zstyle ':completion:*' ignore-parents parent pwd; zstyle ':completion:*' insert-unambiguous true; zstyle ':completion:*' list-colors ""
zstyle ':completion:*' menu select=1
zstyle ':completion:*' original true
zstyle ':completion:*' use-compctl false
bindkey -v
function checkfile {
test -f "$1" && \
test "$(stat -c '%A' $1 | grep $2)" || \
echo "Warning. $1 doesn't exist or has incorrect permissions."
}
test "$USER" '==' 'root' && checkfile /root/.borg-passphrase '\-r--------'
checkfile /etc/borg-ntfy-auth '\-r*-*-----'
'';
};
ssh = {
macs = [
"hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com"
];
ciphers = [
"chacha20-poly1305@openssh.com"
"aes256-gcm@openssh.com"
"aes256-ctr"
];
knownHosts.odroidhc4 = {
extraHostNames = [ "borg.artemislena.eu" "192.168.0.22" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfydibZ7LEgmzwoV9aJx2vUfQvsaa4Gdsew/oiIGFPO";
};
kexAlgorithms = [
"sntrup761x25519-sha512@openssh.com"
"curve25519-sha256"
"curve25519-sha256@libssh.org"
];
};
};
services = {
openssh = {
enable = true;
logLevel = "VERBOSE";
hostKeys = [ {
path = "/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
} ];
passwordAuthentication = false;
kbdInteractiveAuthentication = false;
ciphers = [
"chacha20-poly1305@openssh.com"
"aes256-gcm@openssh.com"
"aes256-ctr"
];
macs = [
"hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com"
];
kexAlgorithms = [
"sntrup761x25519-sha512@openssh.com"
"curve25519-sha256"
"curve25519-sha256@libssh.org"
];
openFirewall = true;
};
# Prevent NTP vulnerabilities by using NTS
# Server list from https://gitea.blesmrt.net/mikaela/shell-things/src/branch/master/etc/chrony/sources.d/nts-servers.sources
timesyncd.enable = false;
chrony = {
enable = true;
enableNTS = true;
servers = [
"ntppool1.time.nl"
"ntppool2.time.nl"
"nts.netnod.se"
"paris.time.system76.com"
];
initstepslew.enabled = false; # Deprecated; makestep is preferred
# System time may be incorrect due to missing RTC battery, preventing lookups, so using router as another NTP server
extraConfig = lib.mkDefault ''
server 192.168.0.1 iburst
makestep 1 3
'';
};
fail2ban.enable = true;
fstrim.enable = lib.mkDefault true;
# Credits to https://xeiaso.net/blog/borg-backup-2021-01-09 for the below
borgbackup.jobs.backup = {
repo = lib.mkDefault "ssh://${config.networking.hostName}@192.168.0.22:2222/./";
paths = [
"/var/lib"
"/etc"
"/root/.ssh"
];
exclude = [
"/var/lib/systemd"
"/var/lib/nixos"
"/var/lib/machines"
"/var/lib/logrotate.status"
"/var/lib/fail2ban"
];
encryption = {
mode = lib.mkDefault "repokey";
passCommand = "cat /root/.borg-passphrase";
};
compression = "none"; # Compressing before encrypting is considered dangerous
startAt = lib.mkDefault "04,12,20:00";
prune.keep = {
within = "1d";
daily = lib.mkDefault 2;
};
persistentTimer = true;
environment.BORG_RELOCATED_REPO_ACCESS_IS_OK = "yes";
postHook = lib.mkDefault ''
test "$exitStatus" '==' '0' && \
${pkgs.curl}/bin/curl -s -u "$(cat /etc/borg-ntfy-auth)" -H 't:${config.networking.hostName}' -H 'p:min' -H 'ta:white_check_mark' -d 'Backup successful.' 'https://ntfy.artemislena.eu/borg' || \
${pkgs.curl}/bin/curl -s -u "$(cat /etc/borg-ntfy-auth)" -H 't:${config.networking.hostName}' -H 'p:high' -H 'ta:warning' -d 'Backup or integrity check failed.' 'https://ntfy.artemislena.eu/borg'
'';
postPrune = ''
# Prune by itself will not free disk space
borg compact $extraArgs
# https://bsd.network/@solene/108900687372607331
borg check $extraArgs --repository-only --max-duration 300
borg check $extraArgs --archives-only
'';
};
journald.extraConfig = ''
Storage=volatile
RuntimeMaxUse=10M
'';
};
systemd = {
services.chronyd.serviceConfig.InaccessiblePaths = "/etc/ld-nix.so.preload"; # Will exit with error otherwise
timers.borgbackup-job-backup.timerConfig.RandomizedDelaySec = lib.mkDefault "45min";
};
}