initial commit

This commit is contained in:
gwg313 2026-04-15 18:26:05 -04:00
commit ebc1be5217
Signed by: gwg313
GPG key ID: 60FF63B4826B7400
143 changed files with 7721 additions and 0 deletions

View file

@ -0,0 +1,17 @@
{
lib,
config,
...
}: {
config = lib.mkIf config.bluetooth.enable {
services.blueman.enable = true;
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
};
services.upower = {
enable = true;
};
};
}

13
modules/nixos/clamav.nix Normal file
View file

@ -0,0 +1,13 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
clamav
];
services.clamav = {
daemon.enable = true;
updater.enable = true;
scanner.enable = true;
fangfrisch.enable = true;
};
}

5
modules/nixos/comma.nix Normal file
View file

@ -0,0 +1,5 @@
{_}: {
# Disable so comma can be installed
programs.command-not-found.enable = false;
programs.nix-index-database.comma.enable = true;
}

View file

@ -0,0 +1,9 @@
{ pkgs, ... }:
{
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
enableZshIntegration = true;
pinentryPackage = pkgs.pinentry-qt;
};
}

View file

@ -0,0 +1,14 @@
{
config,
pkgs,
...
}: {
services.dbus = {
enable = true;
packages = [pkgs.dconf];
};
programs.dconf = {
enable = true;
};
}

View file

@ -0,0 +1,11 @@
{pkgs, ...}: {
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
pinentryPackage = pkgs.pinentry-qt;
};
environment.sessionVariables = {
SSH_AUTH_SOCK = "/run/user/1000/gnupg/S.gpg-agent.ssh";
};
}

View file

@ -0,0 +1,26 @@
{pkgs, ...}: {
environment.systemPackages = with pkgs; [
wlr-randr
wl-clipboard
];
environment.sessionVariables = {
POLKIT_AUTH_AGENT = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
GSETTINGS_SCHEMA_DIR = "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}/glib-2.0/schemas";
WLR_NO_HARDWARE_CURSORS = "1";
NIXOS_OZONE_WL = "1";
MOZ_ENABLE_WAYLAND = "1";
SDL_VIDEODRIVER = "wayland";
_JAVA_AWT_WM_NONREPARENTING = "1";
CLUTTER_BACKEND = "wayland";
# WLR_RENDERER = "vulkan";
GTK_USE_PORTAL = "1";
#NIXOS_XDG_OPEN_USE_PORTAL = "1"; # Sets the desktop portal to use flatpak
WLR_NO_HARDWARE_CURSOR = "1";
GDK_BACKEND = "wayland";
QT_QPA_PLATFORM = "wayland;xcb";
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
QT_QPA_PLATFORMTHEME = "qt5ct";
};
}

40
modules/nixos/gui/xdg.nix Normal file
View file

@ -0,0 +1,40 @@
{
config,
lib,
pkgs,
...
}:
{
# XDG Portals
xdg = {
autostart.enable = true;
portal = {
enable = true;
wlr.enable = true;
xdgOpenUsePortal = true;
extraPortals = [
# pkgs.xdg-desktop-portal-hyprland
pkgs.xdg-desktop-portal-gtk
];
config = {
common = {
default = [ "gtk" ];
};
};
};
};
environment.pathsToLink = [
"/share/applications"
"/share/xdg-desktop-portal"
];
environment.systemPackages = with pkgs; [
xdg-utils
xdg-desktop-portal
xdg-desktop-portal-gtk
wl-clipboard
];
environment.sessionVariables = {
XDG_SESSION_TYPE = "wayland";
};
}

View file

@ -0,0 +1,63 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
# ../../common/nixos/nfs.nix
];
boot.initrd.availableKernelModules = [
"nvme"
"xhci_pci"
"usb_storage"
"sd_mod"
"rtsx_pci_sdmmc"
];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-amd"];
boot.extraModulePackages = [];
boot = {
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
initrd.luks.devices."luks-1dbfdeb6-8537-41b2-abf0-09373af3eeee".device = "/dev/disk/by-uuid/1dbfdeb6-8537-41b2-abf0-09373af3eeee";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/c79b630a-d130-42ed-8cdc-3f8545fe2993";
fsType = "ext4";
};
boot.initrd.luks.devices."luks-96e3b309-ca79-4b42-aca5-3f098b123758".device = "/dev/disk/by-uuid/96e3b309-ca79-4b42-aca5-3f098b123758";
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/1FBA-8B80";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [
{device = "/dev/disk/by-uuid/17eec89e-2381-4a25-8935-63cbcc67d07c";}
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp2s0f0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp5s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,155 @@
{
pkgs,
...
}:
{
programs.git = {
enable = true;
settings = {
user = {
name = "gwg313";
email = "gwg313@pm.me";
};
credential = {
helper = "!pass-git-helper $@";
};
user = {
signingkey = "60FF63B4826B7400";
};
commit = {
gpgsign = true;
verbose = "true";
};
diff = {
algorithm = "histogram";
colorMoved = "plain";
mnemonicPrefix = "true";
renames = "true";
compactionHeuristic = "true";
tool = "nvimdiff";
};
"difftool \"nvimdiff\"" = {
cmd = "nvim -d \"$LOCAL\" \"$REMOTE\" -c \"wincmd w\" -c \"wincmd L\"";
};
merge = {
tool = "nvimdiff4";
prompt = "false";
conflictstyle = "zdiff3";
};
"mergetool \"nvimdiff4\"" = {
cmd = "nvim -d $LOCAL $BASE $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'";
};
mergetool = {
keepBackup = false;
};
init = {
defaultBranch = "main";
};
core = {
pager = "delta";
editor = "nvim";
};
delta = {
features = "line-numbers decorations";
navigate = "true";
whitespace-error-style = "22 reverse";
};
interactive = {
diffFilter = "delta --color-only";
};
push = {
default = "simple";
autoSetupRemote = "true";
followTags = "true";
};
pull = {
rebase = "true";
};
rebase = {
autoSquash = "true";
autoStash = "true";
updateRefs = "true";
};
fetch = {
prune = "true";
pruneTags = "true";
all = "true";
};
tag = {
sort = "version:refname";
};
branch = {
sort = "-committerdate";
};
help = {
autocorrect = "true";
};
rerere = {
enabled = "true";
autoupdate = "true";
};
color.ui = "1";
};
ignores = [
"__pycache__"
".direnv"
"npm-debug.log"
".cache/"
".DS_Store"
".idea/"
"*.swp"
"*.elc"
"auto-save-list"
".direnv/"
"node_modules"
"result"
"result-*"
];
};
programs.zsh = {
shellAliases = {
trackme = "git branch --set-upstream-to=origin/$(git symbolic-ref --short HEAD)";
rebasemain = "git pull origin main --rebase";
hist = ''log --pretty=format:"%Cgreen%h %Creset%cd %Cblue[%cn] %Creset%s%C(yellow)%d%C(reset)" --graph --date=relative --decorate --all'';
llog = ''log --graph --name-status --pretty=format:"%C(red)%h %C(reset)(%cd) %C(green)%an %Creset%s %C(yellow)%d%Creset" --date=relative'';
g = "lazygit";
ga = "git add";
gc = "git commit";
gcu = "git add . && git commit -m 'Update'";
gp = "git push";
gpl = "git pull";
gs = "git status";
gd = "git diff";
gco = "git checkout";
gcb = "git checkout -b";
gbr = "git branch";
grs = "git reset HEAD~1";
grh = "git reset --hard HEAD~1";
gaa = "git add .";
gcm = "git commit -m";
};
};
home.packages = with pkgs; [
cocogitto
delta
lazygit
gh
pre-commit
graphite-cli
tig
pass-git-helper
];
xdg.configFile."pass-git-helper/git-pass-mapping.ini".text = ''
[git.gwg313.xyz*]
target=git/https/git.gwg313.xyz
line_username=1
'';
}

View file

@ -0,0 +1,82 @@
{ config, ... }:
let
user = config.dendritic.current.primaryUser;
secretName = "wireless.env";
in
{
sops.secrets.${secretName} = {
sopsFile = ../../../../secrets/users/${user}.yaml;
};
networking.networkmanager.ensureProfiles = {
environmentFiles = [
config.sops.secrets.${secretName}.path
];
profiles = {
home-wifi = {
connection.id = "home-wifi";
connection.type = "wifi";
wifi.ssid = "$home_uuid";
wifi-security = {
auth-alg = "open";
key-mgmt = "wpa-psk";
psk = "$home_psk";
};
connection.autoconnect-priority = 100;
};
eduroam = {
connection.id = "eduroam";
connection.type = "wifi";
wifi.ssid = "eduroam";
wifi-security = {
key-mgmt = "wpa-eap";
};
"802-1x" = {
eap = "peap;";
identity = "$eduroam_identity";
password = "$school_password";
phase2-auth = "mschapv2";
};
connection.autoconnect = true;
connection.autoconnect-priority = 80;
wifi.powersave = 2;
wifi.mode = "infrastructure";
ipv4.method = "auto";
# ipv4.dns = "8.8.8.8,8.8.4.4.";
# ipv6.dns = "2001:4860:4860::8888";
# wifi.mac-address-randomization = "random";
ipv4.dhcp-send-hostname = false;
# ipv4.dhcp-hostname = "NoName";
# connection.metered = "yes";
};
school = {
connection.id = "School";
connection.type = "wifi";
wifi.ssid = "$school_uuid";
wifi-security = {
key-mgmt = "wpa-eap";
};
"802-1x" = {
eap = "peap;";
identity = "$school_identity";
password = "$school_password";
phase2-auth = "mschapv2";
};
connection.autoconnect = true;
connection.autoconnect-priority = 90;
wifi.powersave = 2;
wifi.mode = "infrastructure";
ipv4.method = "auto";
# ipv4.dns = "8.8.8.8,8.8.4.4.";
# ipv6.dns = "2001:4860:4860::8888";
# wifi.mac-address-randomization = "random";
ipv4.dhcp-send-hostname = false;
# ipv4.dhcp-hostname = "NoName";
# connection.metered = "yes";
};
};
};
}

View file

@ -0,0 +1,53 @@
{
config,
lib,
inputs,
...
}:
{
fileSystems = {
"/books" = {
device = inputs.secrets.nfs.devices.books;
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.after=network-online.target"
"x-systemd.mount-timeout=90"
];
};
"/music" = {
device = inputs.secrets.nfs.devices.music;
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.after=network-online.target"
"x-systemd.mount-timeout=90"
];
};
"/personal" = {
device = inputs.secrets.nfs.devices.personal;
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.after=network-online.target"
"x-systemd.mount-timeout=90"
];
};
"/backups" = {
device = inputs.secrets.nfs.devices.backups;
fsType = "nfs";
options = [
"x-systemd.automount"
"noauto"
"x-systemd.after=network-online.target"
"x-systemd.mount-timeout=90"
];
};
};
}

View file

@ -0,0 +1,106 @@
{ ... }:
{
programs.ssh = {
enable = true;
hashKnownHosts = true;
matchBlocks = {
"router" = {
hostname = "router.local.gwg313.xyz";
user = "glen";
identityFile = "/home/gwg313/.ssh/home/id_ed25519";
};
"github.com" = {
hostname = "github.com";
identityFile = "/home/gwg313/.ssh/github/id_ed25519";
};
"candlekeep" = {
hostname = "candlekeep.local.gwg313.xyz";
user = "gwg313";
identityFile = "/home/gwg313/.ssh/home/id_ed25519";
};
"candlekeep.zt" = {
hostname = "candlekeep.zt"; # added to hosts in zerotier config
user = "gwg313";
identityFile = "/home/gwg313/.ssh/home/id_ed25519";
};
"grymforge" = {
hostname = "grymforge.local.gwg313.xyz";
user = "gwg313";
identityFile = "/home/gwg313/.ssh/home/id_ed25519";
};
"grymforge.zt" = {
hostname = "grymforge.zt"; # added to hosts in zerotier config
user = "gwg313";
identityFile = "/home/gwg313/.ssh/home/id_ed25519";
extraOptions = {
"VisualHostKey" = "no";
};
};
"waypoint" = {
hostname = "waypoint.local.gwg313.xyz";
user = "root";
identityFile = "/home/gwg313/.ssh/colmena/id_ed25519";
};
"seikan" = {
hostname = "147.182.147.32";
user = "root";
identityFile = "/home/gwg313/.ssh/digital_ocean/id_ed25519";
};
"panopticon" = {
hostname = "10.1.10.9";
user = "root";
identityFile = "/home/gwg313/.ssh/colmena/id_ed25519";
};
"vault-tec" = {
hostname = "10.1.10.13";
user = "root";
identityFile = "/home/gwg313/.ssh/colmena/id_ed25519";
};
"qnx" = {
hostname = "10.1.40.32";
user = "qnxuser";
identitiesOnly = true;
identityFile = "/home/gwg313/.ssh/qnxuser";
extraOptions = {
"Ciphers" = "aes256-ctr";
};
};
"qnxzt" = {
hostname = "10.1.40.32";
user = "qnxuser";
identitiesOnly = true;
identityFile = "/home/gwg313/.ssh/qnxuser";
proxyJump = "grymforge.zt";
extraOptions = {
"Ciphers" = "aes256-ctr";
"VisualHostKey" = "no";
};
};
"qnxproj" = {
hostname = "10.1.10.66";
user = "qnxuser";
identitiesOnly = true;
identityFile = "/home/gwg313/.ssh/qnxuser";
proxyJump = "bastion";
extraOptions = {
"Ciphers" = "aes256-ctr";
"VisualHostKey" = "no";
};
};
"bastion" = {
hostname = "10.1.10.9";
user = "bastion";
identitiesOnly = true;
identityFile = "/home/gwg313/.ssh/qnxuser";
};
};
};
}

View file

@ -0,0 +1,19 @@
{ config, ... }:
let
user = config.dendritic.current.primaryUser;
in
{
services.openssh = {
enable = true;
settings = {
AllowUsers = [ user ];
};
};
users.users.${user}.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILq54YrM3BbhBs0oDLOrc1bkg6FCCmkV4E3pWLZp0ejN gwg313@pm.me"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPZK7127ict2+Urhi1cbD6EIU85mD4lkQ9/ihaif0jsX" # Phone
];
}

View file

@ -0,0 +1,78 @@
{
inputs,
...
}:
{
services.syncthing = {
enable = true;
dataDir = "/home/gwg313";
openDefaultPorts = true;
configDir = "/home/gwg313/.config/syncthing";
user = "gwg313";
group = "users";
guiAddress = "127.0.0.1:8384";
overrideDevices = true;
overrideFolders = true;
settings = {
gui = {
user = inputs.secrets.syncthing.gui_user;
password = inputs.secrets.syncthing.gui_password;
};
devices = {
"grymforge" = {
id = inputs.secrets.syncthing.grymforge_id;
};
};
folders = {
"repos" = {
path = "/home/gwg313/repos";
devices = [ "grymforge" ];
versioning = {
type = "staggered";
params = {
cleanInterval = "3600";
maxAge = "15768000";
};
};
};
"documents" = {
path = "/home/gwg313/Documents";
devices = [ "grymforge" ];
versioning = {
type = "staggered";
params = {
cleanInterval = "3600";
maxAge = "15768000";
};
};
};
"password-store" = {
path = "/home/gwg313/.local/share/password-store";
devices = [ "grymforge" ];
versioning = {
type = "staggered";
params = {
cleanInterval = "3600";
maxAge = "15768000";
};
};
};
"zettelkasten" = {
path = "/home/gwg313/zettelkasten/";
devices = [ "grymforge" ];
versioning = {
type = "staggered";
params = {
cleanInterval = "3600";
maxAge = "15768000";
};
};
};
};
};
};
}

View file

@ -0,0 +1,4 @@
{ lib, ... }:
{
services.usbguard.rules = lib.mkAfter "";
}

19
modules/nixos/locale.nix Normal file
View file

@ -0,0 +1,19 @@
{_}: {
# Set your time zone.
time.timeZone = "America/Toronto";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
LC_IDENTIFICATION = "en_US.UTF-8";
LC_MEASUREMENT = "en_US.UTF-8";
LC_MONETARY = "en_US.UTF-8";
LC_NAME = "en_US.UTF-8";
LC_NUMERIC = "en_US.UTF-8";
LC_PAPER = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
}

View file

@ -0,0 +1,15 @@
{...}: {
services.logrotate = {
settings = {
header = {
dateext = true;
};
"var/log/audit/audit.log" = {
frequency = "daily";
rotate = 3;
size = "100k";
};
};
};
}

View file

@ -0,0 +1,7 @@
{ ... }:
{
networking.nftables.enable = true;
networking.firewall = {
enable = true;
};
}

View file

@ -0,0 +1,34 @@
{pkgs, ...}: {
# Enable sound with pipewire.
hardware.pulseaudio.enable = false;
# hardware.alsa.enablePersistence = true;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
# If you want to use JACK applications, uncomment this
#jack.enable = true;
# use the example session manager (no others are packaged yet so this is enabled by default,
# no need to redefine it in your config for now)
#media-session.enable = true;
extraConfig.pipewire.adjust-sample-rate = {
"context.properties" = {
"default.clock.rate" = 192000;
#"defautlt.allowed-rates" = [ 192000 48000 44100 ];
"defautlt.allowed-rates" = [192000];
#"default.clock.quantum" = 32;
#"default.clock.min-quantum" = 32;
#"default.clock.max-quantum" = 32;
};
};
};
environment.systemPackages = with pkgs; [
pipewire
wireplumber
easyeffects
];
}

View file

@ -0,0 +1,12 @@
{ lib, ... }:
{
imports = [
./ssh.nix
./ssh_client.nix
./ssh_guard.nix
];
ssh_client.enable = lib.mkDefault true;
ssh.enable = lib.mkDefault false;
ssh_guard.enable = lib.mkDefault false;
}

146
modules/nixos/ssh/ssh.nix Normal file
View file

@ -0,0 +1,146 @@
{ user, ... }:
{
# https://www.ssh-audit.com/hardening_guides.html
# https://github.com/jtesta/ssh-audit
services.openssh = {
enable = true;
settings = {
########## Features ##########
# disallow ssh-agent forwarding to prevent lateral movement
AllowAgentForwarding = false;
# prevent TCP ports from being forwarded over SSH tunnels
# **please be aware that disabling TCP forwarding does not prevent port forwarding**
# any user with an interactive login shell can spin up his/her own instance of sshd
AllowTcpForwarding = true;
# prevent StreamLocal (Unix-domain socket) forwarding
AllowStreamLocalForwarding = false;
# disables all forwarding features
# overrides all other forwarding switches
DisableForwarding = false;
# disallow remote hosts from connecting to forwarded ports
# i.e. forwarded ports are forced to bind to 127.0.0.1 instad of 0.0.0.0
GatewayPorts = "no";
# prevent tun device forwarding
PermitTunnel = false;
# suppress MOTD
PrintMotd = false;
# disable X11 forwarding since it is not necessary
X11Forwarding = false;
########## Authentication ##########
# AllowUsers = ["${user}"];
# Use keys only. Remove if you want to SSH using password (not recommended)
PasswordAuthentication = false;
HostbasedAuthentication = false;
# enable pubkey authentication
PubkeyAuthentication = true;
# Forbid root login through SSH.
PermitRootLogin = "no";
# nix enables pam by default
# UsePAM = false;
# challenge-response authentication backend it not configured by default
# therefore, it is set to "no" by default to avoid the use of an unconfigured backend
ChallengeResponseAuthentication = false;
# set maximum authentication retries to prevent brute force attacks
MaxAuthTries = 3;
# disallow connecting using empty passwords
PermitEmptyPasswords = false;
########## Cryptography ##########
# explicitly define cryptography algorithms to avoid the use of weak algorithms
# AES CTR modes have been removed to mitigate the Terrapin attack
# https://terrapin-attack.com/
Ciphers = [
"aes256-gcm@openssh.com"
"aes128-gcm@openssh.com"
];
Macs = [
"hmac-sha2-256-etm@openssh.com"
"hmac-sha2-512-etm@openssh.com"
"umac-128-etm@openssh.com"
];
KexAlgorithms = [
"sntrup761x25519-sha512@openssh.com"
"curve25519-sha256"
"curve25519-sha256@libssh.org"
"diffie-hellman-group16-sha512"
"diffie-hellman-group18-sha512"
];
# hostKeyAlgorithms = [
# "rsa-sha2-512"
# "rsa-sha2-256"
# "ssh-ed25519"
# ];
########## Connection Preferences ##########
# enforce SSH server to only use SSH protocol version 2
# SSHv1 contains security issues and should be avoided at all costs
# SSHv1 is disabled by default after OpenSSH 7.0, but this option is
# specified anyways to ensure this configuration file's compatibility
# with older versions of OpenSSH server
Protocol = 2;
# number of client alive messages sent without client responding
ClientAliveCountMax = 2;
# send a keepalive message to the client when the session has been idle for 300 seconds
# this prevents/detects connection timeouts
ClientAliveInterval = 300;
# compression before encryption might cause security issues
Compression = false;
# prevent SSH trust relationships from allowing lateral movements
IgnoreRhosts = true;
# log verbosely for addtional information
LogLevel = "VERBOSE";
# allow a maximum of two multiplexed sessions over a single TCP connection
MaxSessions = 2;
# let ClientAliveInterval handle keepalive
TCPKeepAlive = false;
# disable reverse DNS lookups
# UseDNS = false;
};
extraConfig = ''
########## Features ##########
# accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
########## Connection Preferences ##########
# disable reverse DNS lookups
UseDNS no
########## Disable GSS ##########
GSSAPIAuthentication no
'';
};
}

View file

@ -0,0 +1,79 @@
{
...
}:
{
programs.ssh = {
# disable unnecessary forwardings
forwardX11 = false;
# explicitly define cryptography algorithms to avoid the use of weak algorithms
# AES CTR modes have been removed to mitigate the Terrapin attack
# https://terrapin-attack.com/
ciphers = [
"aes256-gcm@openssh.com"
"aes128-gcm@openssh.com"
];
hostKeyAlgorithms = [
"ssh-ed25519"
"ssh-ed25519-cert-v01@openssh.com"
"sk-ssh-ed25519@openssh.com"
"sk-ssh-ed25519-cert-v01@openssh.com"
"rsa-sha2-256"
"rsa-sha2-256-cert-v01@openssh.com"
"rsa-sha2-512"
"rsa-sha2-512-cert-v01@openssh.com"
];
macs = [
"hmac-sha2-256-etm@openssh.com"
"hmac-sha2-512-etm@openssh.com"
"umac-128-etm@openssh.com"
];
kexAlgorithms = [
"sntrup761x25519-sha512@openssh.com"
"curve25519-sha256"
"curve25519-sha256@libssh.org"
"diffie-hellman-group16-sha512"
"diffie-hellman-group18-sha512"
];
extraConfig = "
# disable unnecessary forwardings
ForwardAgent no
ForwardX11Trusted no
GatewayPorts no
Tunnel no
# disable unnecessary authentication methods
ChallengeResponseAuthentication no
HostbasedAuthentication no
# define authentication methods to be used
PasswordAuthentication yes
PubkeyAuthentication yes
PreferredAuthentications publickey,password
# disable pre-connection compression as it could cause security issues
Compression no
# in addition to checking a host's hostname, also check the host's IP address
# this provides extra safety against DNS spoofing attacks
CheckHostIP yes
# ask the user if the user wants to accept the new host's host key
StrictHostKeyChecking ask
# hash the entries in the known_hosts file to prevent disclosure
# of the file's content
HashKnownHosts yes
# send a keepalive message to the server when the session has been idle for 60 seconds
# this prevents/detects connection timeouts
ServerAliveInterval 60
# increase the number of password retries
NumberOfPasswordPrompts 5
# display an ASCII art of the server's host key
VisualHostKey yes
";
};
}

View file

@ -0,0 +1,16 @@
{
config,
lib,
...
}: {
services.sshguard = {
enable = true;
services = [
"sshd"
];
blocktime = 120;
detection_time = 1800;
blacklist_threshold = 120;
blacklist_file = "/var/lib/sshguard/blacklist.db";
};
}

View file

@ -0,0 +1,41 @@
{
config,
pkgs,
...
}: {
boot.kernel.sysctl = {
# disallow core dumping by SUID/SGID programs
"fs.suid_dumpable" = 0;
# protect the creation of hard links
# one of the following conditions must be fulfilled
# - the user can only link to files that he or she owns
# - the user must first have read and write access to a file, that he/she wants to link to
"fs.protected_hardlinks" = 1;
# protect the creation of symbolic links
# one of the following conditions must be fulfilled
# - the process following the symbolic link is the owner of the symbolic link
# - the owner of the directory is also the owner of the symbolic link
"fs.protected_symlinks" = 1;
# enable extended FIFO protection
"fs.protected_fifos" = 2;
# similar to protected_fifos, but it avoids writes to an attacker-controlled regular file
"fs.protected_regular" = 2;
# increase system file descriptor limit
# this value can be up to:
# - 2147483647 (0x7fffffff) on a 32-bit system
# - 9223372036854775807 (0x7fffffffffffffff) on a 64-bit system
# be aware that the Linux kernel documentation suggests that inode-max should be 3-4 times
# larger than this value
"fs.file-max" = 9223372036854775807;
# increase the amount of files that can be watched
# each file watch handle takes 1080 bytes
# up to 540 MiB of memory will be consumed if all 524288 handles are used
"fs.inotify.max_user_watches" = 524288;
};
}

View file

@ -0,0 +1,70 @@
{
config,
pkgs,
...
}:
{
boot.kernel.sysctl = {
# enable ExecShield protection
# 2 enables ExecShield by default unless applications bits are set to disabled
# uncomment on systems without NX/XD protections
# check with: dmesg | grep --color '[NX|DX]*protection'
#kernel.exec-shield = 2
# enable ASLR
# turn on protection and randomize stack, vdso page and mmap + randomize brk base address
"kernel.randomize_va_space" = 2;
# controls the System Request debugging functionality of the kernel
"kernel.sysrq" = 0;
# controls whether core dumps will append the PID to the core filename
# useful for debugging multi-threaded applications
"kernel.core_uses_pid" = 1;
# restrict access to kernel address
# kernel pointers printed using %pK will be replaced with 0s regardless of privileges
"kernel.kptr_restrict" = 2;
# Ptrace protection using Yama
# - 1: only a parent process can be debugged
# - 2: only admins can use ptrace (CAP_SYS_PTRACE capability required)
# - 3: disables ptrace completely, reboot is required to re-enable ptrace
# If you need ptrace to work, then avoid non-ancestor ptrace access to running processes and their credentials, and use value "1".
# # breaks debuggers
# "kernel.yama.ptrace_scope" = 3;
# restrict kernel logs to root only
"kernel.dmesg_restrict" = 1;
# restrict BPF JIT compiler to root only
"kernel.unprivileged_bpf_disabled" = 1;
# disables kexec as it can be used to livepatch the running kernel
"kernel.kexec_load_disabled" = 1;
# disable the loading of kernel modules
# this can be used to prevent runtime insertion of malicious modules
# could break the system if enabled within sysctl.conf
# consider setting this manually after system is up
# sudo sysctl -w kernel.modules_disabled=1
#kernel.modules_disabled = 1
# allow for more PIDs
# this value can be up to:
# - 32768 (2^15) on a 32-bit system
# - 4194304 (2^22) on a 64-bit system
"kernel.pid_max" = 4194304;
# reboot machine after kernel panic
#kernel.panic = 10
# restrict perf subsystem usage
"kernel.perf_event_paranoid" = 3;
"kernel.perf_cpu_time_max_percent" = 1;
"kernel.perf_event_max_sample_rate" = 1;
# prevent unprivileged attackers from loading vulnerable line disciplines with the TIOCSETD ioctl
"dev.tty.ldisc_autoload" = 0;
};
}

View file

@ -0,0 +1,8 @@
{
config,
pkgs,
...
}: {
boot.kernel.sysctl = {
};
}

View file

@ -0,0 +1,7 @@
{
imports = [
./ipv4.nix
./ipv6.nix
./net.nix
];
}

View file

@ -0,0 +1,114 @@
{
config,
pkgs,
...
}: {
boot.kernel.sysctl = {
# enable BBR congestion control
"net.ipv4.tcp_congestion_control" = "bbr";
# disallow IPv4 packet forwarding
"net.ipv4.ip_forward" = 0;
# enable SYN cookies for SYN flooding protection
"net.ipv4.tcp_syncookies" = 1;
# number of times SYNACKs for a passive TCP connection attempt will be retransmitted
"net.ipv4.tcp_synack_retries" = 5;
# do not send redirects
"net.ipv4.conf.default.send_redirects" = 0;
"net.ipv4.conf.all.send_redirects" = 0;
# do not accept packets with SRR option
"net.ipv4.conf.default.accept_source_route" = 0;
"net.ipv4.conf.all.accept_source_route" = 0;
# enable reverse path source validation (BCP38)
# refer to RFC1812, RFC2827, and BCP38 (http://www.bcp38.info)
"net.ipv4.conf.default.rp_filter" = 1;
"net.ipv4.conf.all.rp_filter" = 1;
# log packets with impossible addresses to kernel log
"net.ipv4.conf.default.log_martians" = 1;
"net.ipv4.conf.all.log_martians" = 1;
# do not accept ICMP redirect messages
"net.ipv4.conf.default.accept_redirects" = 0;
"net.ipv4.conf.default.secure_redirects" = 0;
"net.ipv4.conf.all.accept_redirects" = 0;
"net.ipv4.conf.all.secure_redirects" = 0;
# disable sending and receiving of shared media redirects
# this setting overwrites net.ipv4.conf.all.secure_redirects
# refer to RFC1620
"net.ipv4.conf.default.shared_media" = 0;
"net.ipv4.conf.all.shared_media" = 0;
# always use the best local address for announcing local IP via ARP
"net.ipv4.conf.default.arp_announce" = 2;
"net.ipv4.conf.all.arp_announce" = 2;
# reply only if the target IP address is local address configured on the incoming interface
"net.ipv4.conf.default.arp_ignore" = 1;
"net.ipv4.conf.all.arp_ignore" = 1;
# drop Gratuitous ARP frames to prevent ARP poisoning
# this can cause issues when ARP proxies are used in the network
"net.ipv4.conf.default.drop_gratuitous_arp" = 1;
"net.ipv4.conf.all.drop_gratuitous_arp" = 1;
# ignore all ICMP echo requests
#net.ipv4.icmp_echo_ignore_all = 1
# ignore all ICMP echo and timestamp requests sent to broadcast/multicast
"net.ipv4.icmp_echo_ignore_broadcasts" = 1;
# ignore bad ICMP errors
"net.ipv4.icmp_ignore_bogus_error_responses" = 1;
# mitigate TIME-WAIT Assassination hazards in TCP
# refer to RFC1337
"net.ipv4.tcp_rfc1337" = 1;
# disable TCP window scaling
# this makes the host less susceptible to TCP RST DoS attacks
# could drastically reduce throughput if latency is high
#net.ipv4.tcp_window_scaling = 0
# increase system IP port limits
"net.ipv4.ip_local_port_range" = "1024 65535";
# TCP timestamps could provide protection against wrapped sequence numbers,
# but the host's uptime can be calculated precisely from its timestamps
# it is also possible to differentiate operating systems based on their use of timestamps
# - 0: disable TCP timestamps
# - 1: enable timestamps as defined in RFC1323 and use random offset for
# each connection rather than only using the current time
# - 2: enable timestamps without random offsets
"net.ipv4.tcp_timestamps" = 0;
# enabling SACK can increase the throughput
# but SACK is commonly exploited and rarely used
"net.ipv4.tcp_sack" = 0;
"net.ipv4.tcp_dsack" = 0;
"net.ipv4.tcp_fack" = 0;
# divide socket buffer evenly between TCP window size and application
"net.ipv4.tcp_adv_win_scale" = 1;
# SSR could impact TCP's performance on a fixed-speed network (e.g., wired)
# but it could be helpful on a variable-speed network (e.g., LTE)
# uncomment this if you are on a fixed-speed network
"net.ipv4.tcp_slow_start_after_idle" = 0;
# enabling MTU probing helps mitigating PMTU blackhole issues
# this may not be desirable on congested networks
"net.ipv4.tcp_mtu_probing" = 1;
"net.ipv4.tcp_base_mss" = 1024;
# increase memory thresholds to prevent packet dropping
"net.ipv4.tcp_rmem" = "4096 87380 8388608";
"net.ipv4.tcp_wmem" = "4096 87380 8388608";
};
}

View file

@ -0,0 +1,56 @@
{
config,
pkgs,
...
}: {
boot.kernel.sysctl = {
# disallow IPv6 packet forwarding
"net.ipv6.conf.default.forwarding" = 0;
"net.ipv6.conf.all.forwarding" = 0;
# number of Router Solicitations to send until assuming no routers are present
"net.ipv6.conf.default.router_solicitations" = 0;
"net.ipv6.conf.all.router_solicitations" = 0;
# do not accept Router Preference from RA
"net.ipv6.conf.default.accept_ra_rtr_pref" = 0;
"net.ipv6.conf.all.accept_ra_rtr_pref" = 0;
# learn prefix information in router advertisement
"net.ipv6.conf.default.accept_ra_pinfo" = 0;
"net.ipv6.conf.all.accept_ra_pinfo" = 0;
# setting controls whether the system will accept Hop Limit settings from a router advertisement
"net.ipv6.conf.default.accept_ra_defrtr" = 0;
"net.ipv6.conf.all.accept_ra_defrtr" = 0;
# router advertisements can cause the system to assign a global unicast address to an interface
"net.ipv6.conf.default.autoconf" = 0;
"net.ipv6.conf.all.autoconf" = 0;
# number of neighbor solicitations to send out per address
"net.ipv6.conf.default.dad_transmits" = 0;
"net.ipv6.conf.all.dad_transmits" = 0;
# number of global unicast IPv6 addresses can be assigned to each interface
"net.ipv6.conf.default.max_addresses" = 1;
"net.ipv6.conf.all.max_addresses" = 1;
# enable IPv6 Privacy Extensions (RFC30;41) and prefer the temporary address
#"net.ipv6.conf.default.use_tempaddr" = 2; # Nix sets by default
"net.ipv6.conf.all.use_tempaddr" = 2;
# ignore IPv6 ICMP redirect messages
"net.ipv6.conf.default.accept_redirects" = 0;
"net.ipv6.conf.all.accept_redirects" = 0;
# do not accept packets with SRR option
"net.ipv6.conf.default.accept_source_route" = 0;
"net.ipv6.conf.all.accept_source_route" = 0;
# ignore all ICMPv6 echo requests
#net.ipv6.icmp.echo_ignore_all = 1
#net.ipv6.icmp.echo_ignore_anycast = 1
#net.ipv6.icmp.echo_ignore_multicast = 1
};
}

View file

@ -0,0 +1,17 @@
_: {
boot.kernel.sysctl = {
# increase the maximum length of processor input queues
"net.core.netdev_max_backlog" = 250000;
# enable BPF JIT hardening for all users
# this trades off performance, but can mitigate JIT spraying
"net.core.bpf_jit_harden" = 2;
# increase TCP max buffer size setable using setsockopt()
"net.core.rmem_max" = 8388608;
"net.core.wmem_max" = 8388608;
"net.core.rmem_default" = 8388608;
"net.core.wmem_default" = 8388608;
#net.core.optmem_max = 40960
};
}

View file

@ -0,0 +1,18 @@
{
config,
pkgs,
...
}: {
boot.kernel.sysctl = {
# do not allow mmap in lower addresses
"vm.mmap_min_addr" = 65536;
# improve mmap ASLR effectiveness
"vm.mmap_rnd_bits" = 32;
"vm.mmap_rnd_compat_bits" = 16;
# prevent unprivileged users from accessing userfaultfd
# restricts syscall to the privileged users or the CAP_SYS_PTRACE capability
"vm.unprivileged_userfaultfd" = 0;
};
}