added stuff
This commit is contained in:
parent
e8d9044d2b
commit
9d0ebdfbd0
907 changed files with 70990 additions and 0 deletions
39
nyx/modules/core/common/system/os/activation/default.nix
Normal file
39
nyx/modules/core/common/system/os/activation/default.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
system.activationScripts = {
|
||||
# if system declares that it wants closure diffs, then run the diff script on activation
|
||||
# this is useless if you are using nh, which does this for you in a different way
|
||||
diff = lib.mkIf config.modules.system.activation.diffGenerations {
|
||||
supportsDryActivation = true;
|
||||
text = ''
|
||||
if [[ -e /run/current-system ]]; then
|
||||
echo "=== diff to current-system ==="
|
||||
${pkgs.nvd}/bin/nvd --nix-bin-dir='${config.nix.package}/bin' diff /run/current-system "$systemConfig"
|
||||
echo "=== end of the system diff ==="
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# <https://github.com/colemickens/nixcfg/blob/main/mixins/ssh.nix>
|
||||
# symlink root's ssh config to ours
|
||||
# to fix nix-daemon's ability to remote build since it sshs from the root account
|
||||
root_ssh_config = let
|
||||
sshDir = "/home/notashelf/.ssh";
|
||||
in {
|
||||
text = ''
|
||||
(
|
||||
# symlink root ssh config to ours so daemon can use our agent/keys/etc...
|
||||
mkdir -p /root/.ssh
|
||||
ln -sf ${sshDir}/config /root/.ssh/config
|
||||
ln -sf ${sshDir}/known_hosts /root/.ssh/known_hosts
|
||||
ln -sf ${sshDir}/known_hosts /root/.ssh/known_hosts
|
||||
)
|
||||
'';
|
||||
deps = [];
|
||||
};
|
||||
};
|
||||
}
|
8
nyx/modules/core/common/system/os/boot/default.nix
Normal file
8
nyx/modules/core/common/system/os/boot/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
imports = [
|
||||
./loaders # per-bootloader configurations
|
||||
./secure-boot.nix # secure boot module
|
||||
./generic.nix # generic configuration, such as kernel and tmpfs setup
|
||||
./plymouth.nix # plymouth boot splash
|
||||
];
|
||||
}
|
180
nyx/modules/core/common/system/os/boot/generic.nix
Normal file
180
nyx/modules/core/common/system/os/boot/generic.nix
Normal file
|
@ -0,0 +1,180 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkDefault mkForce mkOverride mkMerge mkIf optionals;
|
||||
|
||||
sys = config.modules.system;
|
||||
in {
|
||||
config.boot = {
|
||||
# kernel console loglevel
|
||||
consoleLogLevel = 3;
|
||||
|
||||
# always use the latest kernel instead of the old-ass lts one
|
||||
kernelPackages = mkOverride 500 sys.boot.kernel;
|
||||
|
||||
# additional packages supplying kernel modules
|
||||
extraModulePackages = mkDefault sys.boot.extraModulePackages;
|
||||
|
||||
# configuration to be appended to the generated modprobe.conf
|
||||
extraModprobeConfig = mkDefault sys.boot.extraModprobeConfig;
|
||||
|
||||
# whether to enable support for Linux MD RAID arrays
|
||||
# I don't know why this defaults to true, how many people use RAID anyway?
|
||||
# also on > 23.11, this will throw a warning if neither MAILADDR nor PROGRAM are set
|
||||
swraid.enable = mkDefault false;
|
||||
|
||||
# settings shared between bootloaders
|
||||
# they are set unless system.boot.loader != none
|
||||
loader = {
|
||||
# if set to 0, space needs to be held to get the boot menu to appear
|
||||
timeout = mkForce 2;
|
||||
|
||||
# whether to copy the necessary boot files into /boot
|
||||
# so that /nix/store is not needed by the boot loader.
|
||||
generationsDir.copyKernels = true;
|
||||
|
||||
# allow installation to modify EFI variables
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
# instructions on how /tmp should be handled
|
||||
# if your system is low on ram, you should avoid tmpfs to prevent hangups while compiling
|
||||
tmp = {
|
||||
# /tmp on tmpfs, lets it live on your ram
|
||||
# it defaults to FALSE, which means you will use disk space instead of ram
|
||||
# enable tmpfs tmp on anything except servers and builders
|
||||
useTmpfs = sys.boot.tmpOnTmpfs;
|
||||
|
||||
# If not using tmpfs, which is naturally purged on reboot, we must clean
|
||||
# /tmp ourselves. /tmp should be volatile storage!
|
||||
cleanOnBoot = mkDefault (!config.boot.tmp.useTmpfs);
|
||||
|
||||
# The size of the tmpfs, in percentage form
|
||||
# this defaults to 50% of your ram, which is a good default
|
||||
# but should be tweaked based on your systems capabilities
|
||||
tmpfsSize = mkDefault "75%";
|
||||
};
|
||||
|
||||
# initrd and kernel tweaks
|
||||
# if you intend to copy paste this section, read what each parameter or module does before doing so
|
||||
# or perish, I am not responsible for your broken system. if you copy paste this section without reading
|
||||
# and later realise your mistake, you are a moron.
|
||||
initrd = mkMerge [
|
||||
(mkIf sys.boot.initrd.enableTweaks {
|
||||
# Verbosity of the initrd
|
||||
# disabling verbosity removes only the mandatory messages generated by the NixOS
|
||||
verbose = false;
|
||||
|
||||
systemd = {
|
||||
# enable systemd in initrd
|
||||
# extremely experimental, just the way I like it on a production machine
|
||||
enable = true;
|
||||
|
||||
# strip copied binaries and libraries from inframs
|
||||
# saves 30~ mb space according to the nix derivation
|
||||
strip = true;
|
||||
|
||||
# packages that will be added to the PATH in initrd
|
||||
# this is useful for debugging if the host provides
|
||||
# emergency access
|
||||
storePaths = with pkgs; [util-linux pciutils];
|
||||
extraBin = {
|
||||
fdisk = "${pkgs.util-linux}/bin/fdisk";
|
||||
lsblk = "${pkgs.util-linux}/bin/lsblk";
|
||||
lspci = "${pkgs.pciutils}/bin/lspci";
|
||||
};
|
||||
};
|
||||
|
||||
# List of modules that are always loaded by the initrd
|
||||
kernelModules = [
|
||||
"ahci"
|
||||
"nvme"
|
||||
"xhci_pci"
|
||||
"btrfs"
|
||||
"sd_mod"
|
||||
"dm_mod"
|
||||
"tpm"
|
||||
];
|
||||
|
||||
# the set of kernel modules in the initial ramdisk used during the boot process
|
||||
availableKernelModules = [
|
||||
"usbhid"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
"dm_mod"
|
||||
"uas"
|
||||
"usb_storage"
|
||||
"rtsx_usb_sdmmc"
|
||||
"rtsx_pci_sdmmc" # Realtek PCI-Express SD/MMC Card Interface driver
|
||||
"ata_piix"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"ehci_pci"
|
||||
];
|
||||
})
|
||||
|
||||
(mkIf sys.boot.initrd.optimizeCompressor
|
||||
{
|
||||
compressor = "zstd";
|
||||
compressorArgs = ["-19" "-T0"];
|
||||
})
|
||||
];
|
||||
|
||||
# https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html
|
||||
kernelParams =
|
||||
(optionals sys.boot.enableKernelTweaks [
|
||||
# https://en.wikipedia.org/wiki/Kernel_page-table_isolation
|
||||
# auto means kernel will automatically decide the pti state
|
||||
"pti=auto" # on | off
|
||||
|
||||
# CPU idle behaviour
|
||||
# poll: slightly improve performance at cost of a hotter system (not recommended)
|
||||
# halt: halt is forced to be used for CPU idle
|
||||
# nomwait: Disable mwait for CPU C-states
|
||||
"idle=nomwait" # poll | halt | nomwait
|
||||
|
||||
# enable IOMMU for devices used in passthrough
|
||||
# and provide better host performance in virtualization
|
||||
"iommu=pt"
|
||||
|
||||
# disable usb autosuspend
|
||||
"usbcore.autosuspend=-1"
|
||||
|
||||
# disables resume and restores original swap space
|
||||
"noresume"
|
||||
|
||||
# allows systemd to set and save the backlight state
|
||||
"acpi_backlight=native" # none | vendor | video | native
|
||||
|
||||
# prevent the kernel from blanking plymouth out of the fb
|
||||
"fbcon=nodefer"
|
||||
|
||||
# disable the cursor in vt to get a black screen during intermissions
|
||||
"vt.global_cursor_default=0"
|
||||
|
||||
# disable displaying of the built-in Linux logo
|
||||
"logo.nologo"
|
||||
])
|
||||
++ (optionals sys.boot.silentBoot [
|
||||
# tell the kernel to not be verbose
|
||||
"quiet"
|
||||
|
||||
# kernel log message level
|
||||
"loglevel=3" # 1: sustem is unusable | 3: error condition | 7: very verbose
|
||||
|
||||
# udev log message level
|
||||
"udev.log_level=3"
|
||||
|
||||
# lower the udev log level to show only errors or worse
|
||||
"rd.udev.log_level=3"
|
||||
|
||||
# disable systemd status messages
|
||||
# rd prefix means systemd-udev will be used instead of initrd
|
||||
"systemd.show_status=auto"
|
||||
"rd.systemd.show_status=auto"
|
||||
]);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
_: {
|
||||
imports = [
|
||||
./grub
|
||||
./systemd-boot
|
||||
];
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkDefault mkIf;
|
||||
|
||||
cfg = config.modules.system;
|
||||
in {
|
||||
config = mkIf (cfg.boot.loader == "grub") {
|
||||
boot.loader = {
|
||||
grub = {
|
||||
enable = mkDefault true;
|
||||
useOSProber = true;
|
||||
efiSupport = true;
|
||||
enableCryptodisk = mkDefault false;
|
||||
device = cfg.boot.grub.device;
|
||||
theme = null;
|
||||
backgroundColor = null;
|
||||
splashImage = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkForce;
|
||||
|
||||
cfg = config.modules.system;
|
||||
in {
|
||||
config = mkIf (cfg.boot.loader == "none") {
|
||||
boot.loader = {
|
||||
grub.enable = mkForce false;
|
||||
systemd-boot.enable = mkForce false;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkDefault mkIf optionalAttrs;
|
||||
|
||||
cfg = config.modules.system;
|
||||
in {
|
||||
config = mkIf (cfg.boot.loader == "systemd-boot") {
|
||||
boot.loader = {
|
||||
systemd-boot =
|
||||
{
|
||||
enable = mkDefault true;
|
||||
configurationLimit = null; # unlimited
|
||||
consoleMode = mkDefault "max"; # the default is "keep", can be overriden per host if need be
|
||||
|
||||
# Fix a security hole in place for backwards compatibility. See desc in
|
||||
# nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
|
||||
editor = false;
|
||||
}
|
||||
// optionalAttrs cfg.boot.memtest.enable {
|
||||
# https://matrix.to/#/!sgkZKRutwatDMkYBHU:nixos.org/$iKnJUt1L_7E5bq7hStDPwv6_2HTBvNjwfcWxlKlF-k8?via=nixos.org&via=matrix.org&via=nixos.dev
|
||||
extraFiles."efi/memtest86plus/memtest.efi" = "${cfg.boot.memtest.package}/memtest.efi";
|
||||
extraEntries."memtest86plus.conf" = ''
|
||||
title MemTest86+
|
||||
efi /efi/memtest86plus/memtest.efi
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
39
nyx/modules/core/common/system/os/boot/plymouth.nix
Normal file
39
nyx/modules/core/common/system/os/boot/plymouth.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
self',
|
||||
...
|
||||
}: let
|
||||
inherit (pkgs) plymouth;
|
||||
inherit (lib) mkIf;
|
||||
|
||||
cfg = config.modules.system.boot.plymouth;
|
||||
in {
|
||||
config = mkIf cfg.enable {
|
||||
# configure plymouth theme
|
||||
# <https://github.com/adi1090x/plymouth-themes>
|
||||
boot.plymouth = let
|
||||
pack = cfg.pack;
|
||||
theme = cfg.theme;
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
}
|
||||
// lib.optionalAttrs cfg.withThemes {
|
||||
themePackages = [(self'.packages.plymouth-themes.override {inherit pack theme;})];
|
||||
|
||||
inherit theme;
|
||||
};
|
||||
|
||||
# make plymouth work with sleep
|
||||
powerManagement = {
|
||||
powerDownCommands = ''
|
||||
${plymouth} --show-splash
|
||||
'';
|
||||
resumeCommands = ''
|
||||
${plymouth} --quit
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
36
nyx/modules/core/common/system/os/boot/secure-boot.nix
Normal file
36
nyx/modules/core/common/system/os/boot/secure-boot.nix
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
sys = config.modules.system.boot;
|
||||
in {
|
||||
imports = [
|
||||
inputs.lanzaboote.nixosModules.lanzaboote
|
||||
];
|
||||
|
||||
config = mkIf sys.secureBoot {
|
||||
environment.systemPackages = [
|
||||
# For debugging and troubleshooting Secure Boot.
|
||||
pkgs.sbctl
|
||||
];
|
||||
|
||||
# Lanzaboote currently replaces the systemd-boot module.
|
||||
# This setting is usually set to true in configuration.nix
|
||||
# generated at installation time. So we force it to false
|
||||
# for now.
|
||||
boot.loader.systemd-boot.enable = lib.mkForce false;
|
||||
|
||||
boot = {
|
||||
bootspec.enable = true;
|
||||
lanzaboote = {
|
||||
enable = true;
|
||||
pkiBundle = "/etc/secureboot";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
15
nyx/modules/core/common/system/os/default.nix
Normal file
15
nyx/modules/core/common/system/os/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
imports = [
|
||||
./activation # activation system for nixos-rebuild
|
||||
./boot # boot and bootloader configurations
|
||||
./display # display protocol (wayland/xorg)
|
||||
./environment # system environment e.g. locale, timezone, packages
|
||||
./fs # filesystem support options
|
||||
./misc # things that don't fit anywhere else
|
||||
./networking # network configuration & tcp optimizations
|
||||
./programs # general programs
|
||||
./services # gemeral services
|
||||
./theme # theming for desktop toolkits e.g. gtk, qt
|
||||
./users # per user configurations
|
||||
];
|
||||
}
|
6
nyx/modules/core/common/system/os/display/default.nix
Normal file
6
nyx/modules/core/common/system/os/display/default.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./wayland
|
||||
./xorg
|
||||
];
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
imports = [
|
||||
./wms
|
||||
|
||||
./environment.nix
|
||||
./xdg-portals.nix
|
||||
./services.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
sys = config.modules.system.video;
|
||||
env = config.modules.usrEnv;
|
||||
in {
|
||||
config = mkIf (sys.enable && env.isWayland) {
|
||||
environment.etc."greetd/environments".text = ''
|
||||
${lib.optionalString (env.desktop == "Hyprland") "Hyprland"}
|
||||
zsh
|
||||
'';
|
||||
|
||||
environment = {
|
||||
variables = {
|
||||
NIXOS_OZONE_WL = "1";
|
||||
_JAVA_AWT_WM_NONEREPARENTING = "1";
|
||||
GDK_BACKEND = "wayland,x11";
|
||||
ANKI_WAYLAND = "1";
|
||||
MOZ_ENABLE_WAYLAND = "1";
|
||||
XDG_SESSION_TYPE = "wayland";
|
||||
SDL_VIDEODRIVER = "wayland";
|
||||
CLUTTER_BACKEND = "wayland";
|
||||
#WLR_DRM_NO_ATOMIC = "1";
|
||||
#WLR_BACKEND = "vulkan";
|
||||
#__GL_GSYNC_ALLOWED = "0";
|
||||
#__GL_VRR_ALLOWED = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf getExe;
|
||||
|
||||
cfg = config.modules.system.video;
|
||||
env = config.modules.usrEnv;
|
||||
in {
|
||||
config = mkIf (cfg.enable && env.isWayland) {
|
||||
systemd.services = {
|
||||
seatd = {
|
||||
enable = true;
|
||||
description = "Seat management daemon";
|
||||
script = "${getExe pkgs.seatd} -g wheel";
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
RestartSec = "1";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
imports = [
|
||||
./hyprland
|
||||
];
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs',
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
sys = config.modules.system;
|
||||
env = config.modules.usrEnv;
|
||||
in {
|
||||
# disables Nixpkgs Hyprland module to avoid conflicts
|
||||
disabledModules = ["programs/hyprland.nix"];
|
||||
|
||||
config = mkIf (sys.video.enable && (env.desktop == "Hyprland" && env.isWayland)) {
|
||||
services.xserver.displayManager.sessionPackages = [inputs'.hyprland.packages.default];
|
||||
|
||||
xdg.portal = {
|
||||
extraPortals = [
|
||||
inputs'.xdg-portal-hyprland.packages.xdg-desktop-portal-hyprland
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
sys = config.modules.system;
|
||||
env = config.modules.usrEnv;
|
||||
inherit (lib) mkForce mkIf;
|
||||
in {
|
||||
config = mkIf sys.video.enable {
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
|
||||
extraPortals = [pkgs.xdg-desktop-portal-gtk];
|
||||
|
||||
config = {
|
||||
common = let
|
||||
portal =
|
||||
if env.desktop == "Hyprland"
|
||||
then "hyprland"
|
||||
else if env.desktop == "sway"
|
||||
then "wlr"
|
||||
else "gtk"; # FIXME: does this actually implement what we need?
|
||||
in {
|
||||
default = [
|
||||
"hyprland"
|
||||
"gtk"
|
||||
];
|
||||
|
||||
# for flameshot to work
|
||||
# https://github.com/flameshot-org/flameshot/issues/3363#issuecomment-1753771427
|
||||
"org.freedesktop.impl.portal.Screencast" = "${portal}";
|
||||
"org.freedesktop.impl.portal.Screenshot" = "${portal}";
|
||||
};
|
||||
};
|
||||
|
||||
# xdg-desktop-wlr (this section) is no longer needed, xdg-desktop-portal-hyprland
|
||||
# will (and should) override this one
|
||||
# however in case I run a different compositor on a Wayland host, it can be enabled
|
||||
wlr = {
|
||||
enable = mkForce (env.isWayland && env.desktop != "Hyprland");
|
||||
settings = {
|
||||
screencast = {
|
||||
max_fps = 60;
|
||||
chooser_type = "simple";
|
||||
chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./environment.nix
|
||||
./xserver.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
sys = config.modules.system.video;
|
||||
env = config.modules.usrEnv;
|
||||
in {
|
||||
config = mkIf (sys.enable && !env.isWayland) {
|
||||
environment.etc."greetd/environments".text = ''
|
||||
${lib.optionalString (env.desktop == "i3") "i3"}
|
||||
${lib.optionalString (env.desktop == "awesome") "awesome"}
|
||||
zsh
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{pkgs, ...}: {
|
||||
services.xserver.excludePackages = [
|
||||
pkgs.xterm
|
||||
];
|
||||
}
|
19
nyx/modules/core/common/system/os/environment/aliases.nix
Normal file
19
nyx/modules/core/common/system/os/environment/aliases.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
environment.shellAliases = let
|
||||
nr = "${pkgs.nixos-rebuild}/bin/nixos-rebuild";
|
||||
in {
|
||||
# nix aliases
|
||||
rebuild = "nix-store --verify; pushd ~dotfiles ; ${nr} switch --flake .#$1 --use-remote-sudo && notify-send \"Done\" ; popd";
|
||||
deploy = "${nr} switch --flake .#$1 --target-host $1 --use-remote-sudo -Lv";
|
||||
|
||||
# things I do to keep my home directory clean
|
||||
wget = "wget --hsts-file='\${XDG_DATA_HOME}/wget-hsts'";
|
||||
|
||||
# init a LICENSE file with my go-to gpl3 license
|
||||
"gpl" = "${lib.getExe pkgs.curl} https://www.gnu.org/licenses/gpl-3.0.txt -o LICENSE";
|
||||
};
|
||||
}
|
10
nyx/modules/core/common/system/os/environment/default.nix
Normal file
10
nyx/modules/core/common/system/os/environment/default.nix
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
imports = [
|
||||
./aliases.nix
|
||||
./etc.nix
|
||||
./locale.nix
|
||||
./packages.nix
|
||||
./paths.nix
|
||||
./variables.nix
|
||||
];
|
||||
}
|
8
nyx/modules/core/common/system/os/environment/etc.nix
Normal file
8
nyx/modules/core/common/system/os/environment/etc.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
# https://github.com/NixOS/nixpkgs/issues/72394#issuecomment-549110501
|
||||
# the service is enabled by default, but this is not set. so by default, you will seee the error
|
||||
# why?
|
||||
environment.etc."mdadm.conf".text = ''
|
||||
MAILADDR root
|
||||
'';
|
||||
}
|
59
nyx/modules/core/common/system/os/environment/locale.nix
Normal file
59
nyx/modules/core/common/system/os/environment/locale.nix
Normal file
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkDefault;
|
||||
in {
|
||||
time = {
|
||||
timeZone = "Europe/Istanbul";
|
||||
hardwareClockInLocalTime = true;
|
||||
};
|
||||
|
||||
services.xserver.xkb = {
|
||||
layout = "tr";
|
||||
variant = "";
|
||||
};
|
||||
|
||||
i18n = let
|
||||
defaultLocale = "en_US.UTF-8";
|
||||
tr = "tr_TR.UTF-8";
|
||||
in {
|
||||
inherit defaultLocale;
|
||||
|
||||
extraLocaleSettings = {
|
||||
LANG = defaultLocale;
|
||||
LC_COLLATE = defaultLocale;
|
||||
LC_CTYPE = defaultLocale;
|
||||
LC_MESSAGES = defaultLocale;
|
||||
|
||||
LC_ADDRESS = tr;
|
||||
LC_IDENTIFICATION = tr;
|
||||
LC_MEASUREMENT = tr;
|
||||
LC_MONETARY = tr;
|
||||
LC_NAME = tr;
|
||||
LC_NUMERIC = tr;
|
||||
LC_PAPER = tr;
|
||||
LC_TELEPHONE = tr;
|
||||
LC_TIME = tr;
|
||||
};
|
||||
|
||||
supportedLocales = mkDefault [
|
||||
"en_US.UTF-8/UTF-8"
|
||||
"tr_TR.UTF-8/UTF-8"
|
||||
];
|
||||
|
||||
# ime configuration
|
||||
inputMethod = {
|
||||
enabled = "fcitx5"; # Needed for fcitx5 to work in qt6
|
||||
fcitx5.addons = with pkgs; [
|
||||
fcitx5-gtk
|
||||
fcitx5-lua
|
||||
libsForQt5.fcitx5-qt
|
||||
|
||||
# themes
|
||||
fcitx5-material-color
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
27
nyx/modules/core/common/system/os/environment/packages.nix
Normal file
27
nyx/modules/core/common/system/os/environment/packages.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
environment = {
|
||||
# nixos ships a bunch of packages by default under environment.defaultPackages
|
||||
# those do not add much to the system closure, but for a little added extra security
|
||||
# and in an attempt to reduce my system closure size, I would like those to be
|
||||
# removed from my packages
|
||||
defaultPackages = lib.mkForce [];
|
||||
|
||||
# packages that will be shared across all users and and all systems
|
||||
# this should generally include tools used for debugging
|
||||
# or system administration
|
||||
systemPackages = with pkgs; [
|
||||
git
|
||||
curl
|
||||
wget
|
||||
pciutils
|
||||
lshw
|
||||
man-pages
|
||||
rsync
|
||||
bind.dnsutils
|
||||
];
|
||||
};
|
||||
}
|
9
nyx/modules/core/common/system/os/environment/paths.nix
Normal file
9
nyx/modules/core/common/system/os/environment/paths.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
# enable completions for system packages
|
||||
# and other stuff
|
||||
environment.pathsToLink = [
|
||||
"/share/zsh" # zsh completions
|
||||
"/share/bash-completion" # bash completions
|
||||
"/share/nix-direnv" # direnv completions
|
||||
];
|
||||
}
|
18
nyx/modules/core/common/system/os/environment/variables.nix
Normal file
18
nyx/modules/core/common/system/os/environment/variables.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
_: {
|
||||
# variables that I want to set globally on all systems
|
||||
|
||||
environment.variables = {
|
||||
FLAKE = "/home/notashelf/.config/nyx";
|
||||
SSH_AUTH_SOCK = "/run/user/\${UID}/keyring/ssh";
|
||||
|
||||
# editors
|
||||
EDITOR = "nvim";
|
||||
VISUAL = "nvim";
|
||||
SUDO_EDITOR = "nvim";
|
||||
|
||||
# pager stuff
|
||||
SYSTEMD_PAGERSECURE = "true";
|
||||
PAGER = "less -FR";
|
||||
MANPAGER = "nvim +Man!";
|
||||
};
|
||||
}
|
52
nyx/modules/core/common/system/os/fs/default.nix
Normal file
52
nyx/modules/core/common/system/os/fs/default.nix
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkMerge;
|
||||
|
||||
sys = config.modules.system;
|
||||
in {
|
||||
config = mkMerge [
|
||||
(mkIf (builtins.elem "btrfs" sys.fs) {
|
||||
# scrub btrfs devices
|
||||
services.btrfs.autoScrub = {
|
||||
enable = true;
|
||||
fileSystems = ["/"];
|
||||
};
|
||||
|
||||
# this fixes initrd.systemd.enable for whatever reason
|
||||
boot = {
|
||||
supportedFilesystems = ["btrfs"];
|
||||
initrd = {
|
||||
supportedFilesystems = ["btrfs"];
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (builtins.elem "ext4" sys.fs) {
|
||||
boot = {
|
||||
supportedFilesystems = ["ext4"];
|
||||
initrd = {
|
||||
supportedFilesystems = ["ext4"];
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (builtins.elem "exfat" sys.fs) {
|
||||
boot = {
|
||||
supportedFilesystems = ["exfat"];
|
||||
initrd = {
|
||||
supportedFilesystems = ["exfat"];
|
||||
};
|
||||
};
|
||||
})
|
||||
|
||||
# accept both ntfs and ntfs3 as valid values
|
||||
(mkIf ((builtins.elem "ntfs" sys.fs) || (builtins.elem "ntfs3" sys.fs)) {
|
||||
boot = {
|
||||
supportedFilesystems = ["ntfs"];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
41
nyx/modules/core/common/system/os/misc/console.nix
Normal file
41
nyx/modules/core/common/system/os/misc/console.nix
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) attrValues mkDefault;
|
||||
in {
|
||||
console = let
|
||||
variant = "v18n";
|
||||
in {
|
||||
enable = mkDefault true;
|
||||
earlySetup = true;
|
||||
keyMap = "trq";
|
||||
|
||||
font = "ter-powerline-${variant}";
|
||||
packages = attrValues {inherit (pkgs) terminus_font powerline-fonts;};
|
||||
};
|
||||
|
||||
# FIXME: kmscon, in my testing, is working as advertised and a performance difference
|
||||
# is observable. However, enabling kmscon seems to *completely* ignore silent boot
|
||||
# parameters. Not sure if this is a potential conflict with earlySetup (probably not)
|
||||
# or kmscon not respecting the kernel parameters (more likely). Either way, I will
|
||||
# revisit this in the future.
|
||||
services.kmscon = {
|
||||
enable = false;
|
||||
hwRender = true;
|
||||
fonts = [
|
||||
{
|
||||
name = "Source Code Pro";
|
||||
package = pkgs.source-code-pro;
|
||||
}
|
||||
];
|
||||
|
||||
extraOptions = "--term xterm-256color";
|
||||
extraConfig = ''
|
||||
font-size=14
|
||||
xkb-layout=${config.console.layout}
|
||||
'';
|
||||
};
|
||||
}
|
12
nyx/modules/core/common/system/os/misc/crash.nix
Normal file
12
nyx/modules/core/common/system/os/misc/crash.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
systemd = {
|
||||
# TODO: those tend to include sensitie information, maybe we want to disable this?
|
||||
# it could be an override in the security module
|
||||
tmpfiles.rules = [
|
||||
# Enables storing of the kernel log (including stack trace) into pstore upon a panic or crash.
|
||||
"w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y"
|
||||
# Enables storing of the kernel log upon a normal shutdown (shutdown, reboot, halt).
|
||||
"w /sys/module/printk/parameters/always_kmsg_dump - - - - N"
|
||||
];
|
||||
};
|
||||
}
|
9
nyx/modules/core/common/system/os/misc/default.nix
Normal file
9
nyx/modules/core/common/system/os/misc/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
imports = [
|
||||
./realtime.nix
|
||||
./crash.nix
|
||||
./journald.nix
|
||||
./console.nix
|
||||
./xdg-portals.nix
|
||||
];
|
||||
}
|
20
nyx/modules/core/common/system/os/misc/journald.nix
Normal file
20
nyx/modules/core/common/system/os/misc/journald.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
dev = config.modules.device;
|
||||
in {
|
||||
# https://wiki.archlinux.org/title/Systemd/Journal#Persistent_journals
|
||||
# limit systemd journal size
|
||||
# journals get big really fasti and on desktops they are not audited often
|
||||
# on servers, however, they are important for both security and stability
|
||||
# thus, persisting them as is remains a good idea
|
||||
services.journald.extraConfig = mkIf (dev.type != "server") ''
|
||||
SystemMaxUse=100M
|
||||
RuntimeMaxUse=50M
|
||||
SystemMaxFileSize=50M
|
||||
'';
|
||||
}
|
35
nyx/modules/core/common/system/os/misc/realtime.nix
Normal file
35
nyx/modules/core/common/system/os/misc/realtime.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{config, ...}: {
|
||||
# port of https://gitlab.archlinux.org/archlinux/packaging/packages/realtime-privileges
|
||||
# see https://wiki.archlinux.org/title/Realtime_process_management
|
||||
# tldr: realtime processes have higher priority than normal processes
|
||||
# and that's a good thing
|
||||
users = {
|
||||
users."${config.modules.system.mainUser}".extraGroups = ["realtime"];
|
||||
groups.realtime = {};
|
||||
};
|
||||
|
||||
services.udev.extraRules = ''
|
||||
KERNEL=="cpu_dma_latency", GROUP="realtime"
|
||||
'';
|
||||
|
||||
security.pam.loginLimits = [
|
||||
{
|
||||
domain = "@realtime";
|
||||
type = "-";
|
||||
item = "rtprio";
|
||||
value = 98;
|
||||
}
|
||||
{
|
||||
domain = "@realtime";
|
||||
type = "-";
|
||||
item = "memlock";
|
||||
value = "unlimited";
|
||||
}
|
||||
{
|
||||
domain = "@realtime";
|
||||
type = "-";
|
||||
item = "nice";
|
||||
value = -11;
|
||||
}
|
||||
];
|
||||
}
|
18
nyx/modules/core/common/system/os/misc/xdg-portals.nix
Normal file
18
nyx/modules/core/common/system/os/misc/xdg-portals.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
sys = config.modules.system;
|
||||
inherit (lib) mkIf;
|
||||
in {
|
||||
config = mkIf sys.video.enable {
|
||||
xdg.portal.config = {
|
||||
common = {
|
||||
"org.freedesktop.impl.portal.Secret" = [
|
||||
"gnome-keyring"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
16
nyx/modules/core/common/system/os/networking/blocker.nix
Normal file
16
nyx/modules/core/common/system/os/networking/blocker.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{config, ...}: let
|
||||
dev = config.modules.device;
|
||||
in {
|
||||
# this should block *most* junk sites
|
||||
networking = {
|
||||
stevenblack = {
|
||||
enable = dev.type != "server"; # don't touch hosts file on a server
|
||||
block = [
|
||||
"fakenews"
|
||||
"gambling"
|
||||
"porn"
|
||||
#"social" # blocks stuff like reddit, which I occasionally visit
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
108
nyx/modules/core/common/system/os/networking/default.nix
Normal file
108
nyx/modules/core/common/system/os/networking/default.nix
Normal file
|
@ -0,0 +1,108 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce mkDefault;
|
||||
in {
|
||||
imports = [
|
||||
./firewall
|
||||
|
||||
./blocker.nix
|
||||
./network-manager.nix
|
||||
./optimize.nix
|
||||
./resolved.nix
|
||||
./ssh.nix
|
||||
./tailscale.nix
|
||||
./tcpcrypt.nix
|
||||
./wireless.nix
|
||||
];
|
||||
|
||||
# network tools that are helpful and nice to have
|
||||
boot.kernelModules = ["af_packet"];
|
||||
environment.systemPackages = with pkgs; [
|
||||
mtr
|
||||
tcpdump
|
||||
traceroute
|
||||
];
|
||||
|
||||
networking = {
|
||||
# generate a unique hostname by hashing the hostname
|
||||
# with md5 and taking the first 8 characters of the hash
|
||||
# this is especially helpful while using zfs but still
|
||||
# ensures that there will be a unique hostId even when
|
||||
# we are not using zfs
|
||||
hostId = builtins.substring 0 8 (builtins.hashString "md5" config.networking.hostName);
|
||||
|
||||
# global dhcp has been deprecated upstream
|
||||
# use the new networkd service instead of the legacy
|
||||
# "script-based" network setups. Host may contain individual
|
||||
# dhcp interfaces or systemd-networkd configurations in host
|
||||
# specific directories
|
||||
useDHCP = mkForce false;
|
||||
useNetworkd = mkForce true;
|
||||
|
||||
# interfaces are assigned names that contain topology information (e.g. wlp3s0)
|
||||
# and thus should be consistent across reboots
|
||||
# this already defaults to true, we set it in case it changes upstream
|
||||
usePredictableInterfaceNames = mkDefault true;
|
||||
|
||||
# dns
|
||||
nameservers = [
|
||||
# cloudflare, yuck
|
||||
# shares data
|
||||
"1.1.1.1"
|
||||
"1.0.0.1"
|
||||
"2606:4700:4700::1111"
|
||||
"2606:4700:4700::1001"
|
||||
|
||||
# quad9, said to be the best
|
||||
# shares *less* data
|
||||
"9.9.9.9"
|
||||
"149.112.112.112"
|
||||
"2620:fe::fe"
|
||||
"2620:fe::9"
|
||||
];
|
||||
|
||||
# search paths used when resolving domain names
|
||||
# this can allow us to find hosts on private networks
|
||||
# e.g. wireguard, tailscale and headscale
|
||||
search = [
|
||||
"notashelf.dev" # referss to the server itself
|
||||
"notashelf.notashelf.dev" # headscale network
|
||||
];
|
||||
};
|
||||
|
||||
# enable wireless database, it helps with finding the right channels
|
||||
hardware.wirelessRegulatoryDatabase = true;
|
||||
|
||||
# allow for the system to boot without waiting for the network interfaces are online
|
||||
# speeds up boot times
|
||||
systemd = let
|
||||
# TODO: allow for the hosts to define those interfaces
|
||||
ethernetDevices = [
|
||||
"wlp1s0f0u8" # wifi dongle
|
||||
];
|
||||
in {
|
||||
# according to 23.11 release notes, wait-online target has long been fixed
|
||||
# spoiler: no it's not.
|
||||
network.wait-online.enable = false;
|
||||
services =
|
||||
{
|
||||
NetworkManager-wait-online.enable = false;
|
||||
|
||||
# disable networkd and resolved from being restarted on configuration changes
|
||||
# lets me avoid a short network outage when I change the configuration
|
||||
# also means that I **must** reboot to make sure my network changes are
|
||||
# are properly propagated
|
||||
systemd-networkd.stopIfChanged = false;
|
||||
systemd-resolved.stopIfChanged = false;
|
||||
}
|
||||
// lib.concatMapAttrs (_: v: v) (lib.genAttrs ethernetDevices (device: {
|
||||
# Assign an IP address when the device is plugged in rather than on startup. Needed to prevent
|
||||
# blocking the boot sequence when the device is unavailable, as it is hotpluggable.
|
||||
"network-addresses-${device}".wantedBy = lib.mkForce ["sys-subsystem-net-devices-${device}.device"];
|
||||
}));
|
||||
};
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkForce;
|
||||
dev = config.modules.device;
|
||||
cfg = config.networking.nftables;
|
||||
in {
|
||||
imports = [
|
||||
./nftables
|
||||
|
||||
./fail2ban.nix
|
||||
./tarpit.nix
|
||||
];
|
||||
|
||||
config = {
|
||||
# enable opensnitch firewall
|
||||
# inactive until opensnitch UI is opened
|
||||
# since the UI cannot be opened on servers, we
|
||||
# disable it if dev.type is server
|
||||
services.opensnitch.enable = dev.type != "server";
|
||||
|
||||
networking.firewall = {
|
||||
enable = !cfg.enable;
|
||||
package =
|
||||
if cfg.enable
|
||||
then pkgs.iptables-nftables-compat
|
||||
else pkgs.iptables;
|
||||
allowedTCPPorts = [443 8080];
|
||||
allowedUDPPorts = [];
|
||||
allowPing = dev.type == "server";
|
||||
logReversePathDrops = true;
|
||||
logRefusedConnections = false; # avoid log spam
|
||||
# Leaks IPv6 route table entries due to kernel bug. This leads to degraded
|
||||
# IPv6 performance in some situations.
|
||||
# checkReversePath = config.boot.kernelPackages.kernelAtLeast "5.16";
|
||||
checkReversePath = mkForce false; # Don't filter DHCP packets, according to nixops-libvirtd
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkMerge mkForce;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
|
||||
sys = config.modules.system;
|
||||
in {
|
||||
# fail2ban firewall jail
|
||||
services.fail2ban = {
|
||||
enable = true;
|
||||
extraPackages = [pkgs.nftables]; # make nftables accessible to fail2ban service
|
||||
|
||||
ignoreIP = [
|
||||
"127.0.0.0/8" # localhost
|
||||
"10.0.0.0/8" # wireguard
|
||||
"100.64.0.0/16" # tailscale
|
||||
"192.168.0.0/16" # local network
|
||||
];
|
||||
|
||||
maxretry = 7;
|
||||
bantime-increment = {
|
||||
enable = true;
|
||||
rndtime = "12m";
|
||||
overalljails = true;
|
||||
multipliers = "4 8 16 32 64 128 256 512 1024 2048";
|
||||
maxtime = "5000h"; # get banned for 5000 hours idiot
|
||||
};
|
||||
|
||||
jails = mkMerge [
|
||||
{
|
||||
# sshd jail
|
||||
sshd = mkForce ''
|
||||
enabled = true
|
||||
port = ${concatStringsSep "," (map toString config.services.openssh.ports)}
|
||||
mode = aggressive
|
||||
'';
|
||||
}
|
||||
{
|
||||
# nftables jail
|
||||
nftables-common = mkForce ''
|
||||
enabled = true
|
||||
banaction = nftables-multiport
|
||||
chain = input
|
||||
'';
|
||||
}
|
||||
|
||||
(mkIf sys.services.vaultwarden.enable {
|
||||
# vaultwarden and vaultwarden admin interface jails
|
||||
vaultwarden = ''
|
||||
enabled = true
|
||||
port = 80,443,8822
|
||||
filter = vaultwarden
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = /var/log/vaultwarden.log
|
||||
maxretry = 3
|
||||
bantime = 14400
|
||||
findtime = 14400
|
||||
'';
|
||||
|
||||
vaultwarden-admin = ''
|
||||
enabled = true
|
||||
port = 80,443
|
||||
filter = vaultwarden-admin
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = /var/log/vaultwarden.log
|
||||
maxretry = 3
|
||||
bantime = 14400
|
||||
findtime = 14400
|
||||
'';
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkRuleset;
|
||||
|
||||
sys = config.modules.system;
|
||||
cfg = config.networking.nftables;
|
||||
|
||||
check-results =
|
||||
pkgs.runCommand "check-nft-ruleset" {
|
||||
ruleset = pkgs.writeText "nft-ruleset" cfg.ruleset;
|
||||
} ''
|
||||
mkdir -p $out
|
||||
${pkgs.nftables}/bin/nft -c -f $ruleset 2>&1 > $out/message \
|
||||
&& echo false > $out/assertion \
|
||||
|| echo true > $out/assertion
|
||||
'';
|
||||
in {
|
||||
imports = [./rules.nix];
|
||||
config = mkIf sys.networking.nftables.enable {
|
||||
networking.nftables = {
|
||||
enable = true;
|
||||
|
||||
# flush ruleset on each reload
|
||||
flushRuleset = true;
|
||||
|
||||
# nftables.tables is semi-verbatim configuration
|
||||
# that is inserted **before** nftables.ruleset
|
||||
# as per the nftables module.
|
||||
tables = {
|
||||
"fail2ban" = {
|
||||
name = "fail2ban-nftables";
|
||||
family = "ip";
|
||||
content = ''
|
||||
# <https://wiki.gbe0.com/en/linux/firewalling-and-filtering/nftables/fail2ban>
|
||||
chain input {
|
||||
type filter hook input priority 100;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# our ruleset, built with our local ruleset builder from lib/network/firewall.nix
|
||||
# I prefer using this to the nftables.tables.* and verbatim nftables.ruleset = ""
|
||||
# kinds of configs, as it allows me to programmatically approach to my ruleset
|
||||
# instead of structuring it inside a multiline string. nftables.rules, which is
|
||||
# located in ./rules.nix, is easily parsable and modifiable with the help of Nix.
|
||||
ruleset = mkRuleset cfg.rules;
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion = import "${check-results}/assertion";
|
||||
message = ''
|
||||
Bad config:
|
||||
${builtins.readFile "${check-results}/message"}
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
# pin IFD as a system dependency
|
||||
# this makes sure the IFD result is realised in time
|
||||
# without making the IFD a part of the system
|
||||
# unlike system.extraDependencies
|
||||
system.checks = [check-results];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) entryBefore entryBetween entryAfter entryAnywhere;
|
||||
in {
|
||||
networking.nftables.rules = {
|
||||
inet = {
|
||||
filter = {
|
||||
input = {
|
||||
loopback = entryAnywhere {
|
||||
field = "iifname";
|
||||
value = "lo";
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
established-locally = entryAfter ["loopback"] {
|
||||
protocol = "ct";
|
||||
field = "state";
|
||||
value = ["established" "related"];
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
basic-icmp6 = entryAfter ["loopback" "established-locally"] {
|
||||
protocol = "ip6 nexthdr icmpv6 icmpv6";
|
||||
field = "type";
|
||||
value = [
|
||||
"destination-unreachable"
|
||||
"packet-too-big"
|
||||
"time-exceeded"
|
||||
"parameter-problem"
|
||||
"nd-router-advert"
|
||||
"nd-neighbor-solicit"
|
||||
"nd-neighbor-advert"
|
||||
#"mld-listener-query" "nd-router-solicit" # for routers
|
||||
];
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
basic-icmp = entryAfter ["loopback" "established-locally"] {
|
||||
protocol = "ip protocol icmp icmp";
|
||||
field = "type";
|
||||
value = [
|
||||
"destination-unreachable"
|
||||
"router-advertisement"
|
||||
"time-exceeded"
|
||||
"parameter-problem"
|
||||
];
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
ping6 = entryBefore ["basic-icmp6"] {
|
||||
protocol = "ip6 nexthdr icmpv6 icmpv6";
|
||||
field = "type";
|
||||
value = "echo-request";
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
ping = entryBefore ["basic-icmp"] {
|
||||
protocol = "ip protocol icmp icmp";
|
||||
field = "type";
|
||||
value = "echo-request";
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
ssh = entryBetween ["basic-icmp6" "basic-icmp" "ping6" "ping"] ["default"] {
|
||||
protocol = "tcp";
|
||||
field = "dport";
|
||||
value = config.services.openssh.ports;
|
||||
policy = "accept";
|
||||
};
|
||||
|
||||
default = entryAfter ["loopback" "established-locally" "basic-icmp6" "basic-icmp" "ping6" "ping"] {
|
||||
policy = lib.mkDefault "drop";
|
||||
};
|
||||
};
|
||||
|
||||
# accept all outgoing traffic
|
||||
output = {
|
||||
default = entryAnywhere {
|
||||
policy = "accept";
|
||||
};
|
||||
};
|
||||
|
||||
# let nftables forward traffic
|
||||
# we decide whether the host can forward traffic
|
||||
# via sysctl settings elsewhere
|
||||
forward = {
|
||||
default = entryAnywhere {
|
||||
policy = "accept";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
# jebait agressive port scanners by wasting their time with connection that'll never make it in
|
||||
# this *does* have performance implications, however, so be careful which hosts you enable it for
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
sys = config.modules.system;
|
||||
cfg = sys.networking.tarpit;
|
||||
in {
|
||||
config = mkIf cfg.enable {
|
||||
services.endlessh-go = {
|
||||
enable = true;
|
||||
port = 22;
|
||||
openFirewall = true;
|
||||
|
||||
extraOptions = [
|
||||
"-alsologtostderr"
|
||||
"-geoip_supplier max-mind-db"
|
||||
"-max_mind_db ${pkgs.clash-geoip}/etc/clash/Country.mmdb"
|
||||
];
|
||||
|
||||
prometheus = {
|
||||
enable = true;
|
||||
port = 9105;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf mkForce;
|
||||
|
||||
dev = config.modules.device;
|
||||
sys = config.modules.system;
|
||||
|
||||
inherit (sys.networking) wireless;
|
||||
in {
|
||||
# we use networkmanager manage network devices locally
|
||||
networking.networkmanager = {
|
||||
enable = true;
|
||||
plugins = mkForce []; # disable all plugins, we don't need them
|
||||
dns = "systemd-resolved"; # use systemd-resolved as dns backend
|
||||
unmanaged = [
|
||||
"interface-name:tailscale*"
|
||||
"interface-name:br-*"
|
||||
"interface-name:rndis*"
|
||||
"interface-name:docker*"
|
||||
"interface-name:virbr*"
|
||||
];
|
||||
|
||||
wifi = {
|
||||
inherit (wireless) backend; # this can be iwd or wpa_supplicant, use wpa_supp. until iwd support is stable
|
||||
macAddress = "random"; # use a random mac address on every boot
|
||||
powersave = true; # enable wifi powersaving
|
||||
scanRandMacAddress = true; # MAC address randomization of a Wi-Fi device during scanning
|
||||
};
|
||||
|
||||
ethernet.macAddress = mkIf (dev.type != "server") "random"; # causes server to be unreachable over SSH
|
||||
};
|
||||
}
|
78
nyx/modules/core/common/system/os/networking/optimize.nix
Normal file
78
nyx/modules/core/common/system/os/networking/optimize.nix
Normal file
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
sys = config.modules.system.networking;
|
||||
inherit (lib) mkIf;
|
||||
in {
|
||||
config = mkIf sys.optimizeTcp {
|
||||
boot = {
|
||||
kernelModules = ["tls" "tcp_bbr"];
|
||||
kernel.sysctl = {
|
||||
# TCP hardening
|
||||
# Prevent bogus ICMP errors from filling up logs.
|
||||
"net.ipv4.icmp_ignore_bogus_error_responses" = 1;
|
||||
# Reverse path filtering causes the kernel to do source validation of
|
||||
# packets received from all interfaces. This can mitigate IP spoofing.
|
||||
"net.ipv4.conf.default.rp_filter" = 1;
|
||||
"net.ipv4.conf.all.rp_filter" = 1;
|
||||
# Do not accept IP source route packets (we're not a router)
|
||||
"net.ipv4.conf.all.accept_source_route" = 0;
|
||||
"net.ipv6.conf.all.accept_source_route" = 0;
|
||||
# Don't send ICMP redirects (again, we're on a router)
|
||||
"net.ipv4.conf.all.send_redirects" = 0;
|
||||
"net.ipv4.conf.default.send_redirects" = 0;
|
||||
# Refuse ICMP redirects (MITM mitigations)
|
||||
"net.ipv4.conf.all.accept_redirects" = 0;
|
||||
"net.ipv4.conf.default.accept_redirects" = 0;
|
||||
"net.ipv4.conf.all.secure_redirects" = 0;
|
||||
"net.ipv4.conf.default.secure_redirects" = 0;
|
||||
"net.ipv6.conf.all.accept_redirects" = 0;
|
||||
"net.ipv6.conf.default.accept_redirects" = 0;
|
||||
# Protects against SYN flood attacks
|
||||
"net.ipv4.tcp_syncookies" = 1;
|
||||
# Incomplete protection again TIME-WAIT assassination
|
||||
"net.ipv4.tcp_rfc1337" = 1;
|
||||
# And other stuff
|
||||
"net.ipv4.conf.all.log_martians" = true;
|
||||
"net.ipv4.conf.default.log_martians" = true;
|
||||
"net.ipv4.icmp_echo_ignore_broadcasts" = true;
|
||||
"net.ipv6.conf.default.accept_ra" = 0;
|
||||
"net.ipv6.conf.all.accept_ra" = 0;
|
||||
"net.ipv4.tcp_timestamps" = 0;
|
||||
|
||||
# TCP optimization
|
||||
# TCP Fast Open is a TCP extension that reduces network latency by packing
|
||||
# data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for
|
||||
# both incoming and outgoing connections:
|
||||
"net.ipv4.tcp_fastopen" = 3;
|
||||
# Bufferbloat mitigations + slight improvement in throughput & latency
|
||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
"net.core.default_qdisc" = "cake";
|
||||
|
||||
# Other stuff that I am too lazy to document
|
||||
"net.core.optmem_max" = 65536;
|
||||
"net.core.rmem_default" = 1048576;
|
||||
"net.core.rmem_max" = 16777216;
|
||||
"net.core.somaxconn" = 8192;
|
||||
"net.core.wmem_default" = 1048576;
|
||||
"net.core.wmem_max" = 16777216;
|
||||
"net.ipv4.ip_local_port_range" = "16384 65535";
|
||||
"net.ipv4.tcp_max_syn_backlog" = 8192;
|
||||
"net.ipv4.tcp_max_tw_buckets" = 2000000;
|
||||
"net.ipv4.tcp_mtu_probing" = 1;
|
||||
"net.ipv4.tcp_rmem" = "4096 1048576 2097152";
|
||||
"net.ipv4.tcp_slow_start_after_idle" = 0;
|
||||
"net.ipv4.tcp_tw_reuse" = 1;
|
||||
"net.ipv4.tcp_wmem" = "4096 65536 16777216";
|
||||
"net.ipv4.udp_rmem_min" = 8192;
|
||||
"net.ipv4.udp_wmem_min" = 8192;
|
||||
"net.netfilter.nf_conntrack_generic_timeout" = 60;
|
||||
"net.netfilter.nf_conntrack_max" = 1048576;
|
||||
"net.netfilter.nf_conntrack_tcp_timeout_established" = 600;
|
||||
"net.netfilter.nf_conntrack_tcp_timeout_time_wait" = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
34
nyx/modules/core/common/system/os/networking/resolved.nix
Normal file
34
nyx/modules/core/common/system/os/networking/resolved.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
services = {
|
||||
resolved = {
|
||||
# enable systemd DNS resolver daemon
|
||||
enable = true;
|
||||
|
||||
# this is necessary to get tailscale picking up your headscale instance
|
||||
# and allows you to ping connected hosts by hostname
|
||||
domains = ["~."];
|
||||
|
||||
# DNSSEC provides to DNS clients (resolvers) origin authentication of DNS data, authenticated denial of existence
|
||||
# and data integrity but not availability or confidentiality.
|
||||
# this is considered EXPERIMENTAL and UNSTABLE according to upstream
|
||||
# PLEASE SEE <https://github.com/systemd/systemd/issues/25676#issuecomment-1634810897>
|
||||
# before you decide to set this. I have it set to false as the issue
|
||||
# does not inspire confidence in systemd's ability to manage this
|
||||
dnssec = "false";
|
||||
|
||||
# additional configuration to be appeneded to systemd-resolved configuration
|
||||
extraConfig = ''
|
||||
# <https://wiki.archlinux.org/title/Systemd-resolved#DNS_over_TLS>
|
||||
# apparently upstream (systemd) recommends this to be false
|
||||
# `allow-downgrade` is vulnerable to downgrade attacks
|
||||
DNSOverTLS=yes # or allow-downgrade
|
||||
'';
|
||||
|
||||
# ideally our fallbackDns should be something more widely available
|
||||
# but I do not want my last resort to sell my data to every company available
|
||||
# NOTE: DNS fallback is not a recovery DNS
|
||||
# See <https://github.com/systemd/systemd/issues/5771#issuecomment-296673115>
|
||||
fallbackDns = ["9.9.9.9"];
|
||||
};
|
||||
};
|
||||
}
|
131
nyx/modules/core/common/system/os/networking/ssh.nix
Normal file
131
nyx/modules/core/common/system/os/networking/ssh.nix
Normal file
|
@ -0,0 +1,131 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce mkDefault;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
inherit (lib.lists) elemAt;
|
||||
in {
|
||||
services.openssh = {
|
||||
# enable openssh
|
||||
enable = true;
|
||||
openFirewall = true; # the ssh port(s) should be automatically passed to the firewall's allowedTCPports
|
||||
ports = [30]; # the port(s) openssh daemon should listen on
|
||||
startWhenNeeded = true; # automatically start the ssh daemon when it's required
|
||||
settings = {
|
||||
# no root login
|
||||
PermitRootLogin = mkForce "no";
|
||||
|
||||
# no password auth
|
||||
# force publickey authentication only
|
||||
PasswordAuthentication = false;
|
||||
AuthenticationMethods = "publickey";
|
||||
PubkeyAuthentication = "yes";
|
||||
ChallengeResponseAuthentication = "no";
|
||||
UsePAM = "no";
|
||||
|
||||
# remove sockets as they get stale
|
||||
# this will unbind gnupg sockets if they exists
|
||||
StreamLocalBindUnlink = "yes";
|
||||
|
||||
KbdInteractiveAuthentication = mkDefault false;
|
||||
UseDns = false; # no
|
||||
X11Forwarding = false; # ew xorg
|
||||
|
||||
# key exchange algorithms recommended by `nixpkgs#ssh-audit`
|
||||
KexAlgorithms = [
|
||||
"curve25519-sha256"
|
||||
"curve25519-sha256@libssh.org"
|
||||
"diffie-hellman-group16-sha512"
|
||||
"diffie-hellman-group18-sha512"
|
||||
"diffie-hellman-group-exchange-sha256"
|
||||
"sntrup761x25519-sha512@openssh.com"
|
||||
];
|
||||
|
||||
# message authentication code algorithms recommended by `nixpkgs#ssh-audit`
|
||||
Macs = [
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
"umac-128-etm@openssh.com"
|
||||
];
|
||||
|
||||
# kick out inactive sessions
|
||||
ClientAliveCountMax = 5;
|
||||
ClientAliveInterval = 60;
|
||||
|
||||
# max auth attempts
|
||||
MaxAuthTries = 3;
|
||||
};
|
||||
|
||||
hostKeys = mkDefault [
|
||||
{
|
||||
bits = 4096;
|
||||
path = "/etc/ssh/ssh_host_rsa_key";
|
||||
type = "rsa";
|
||||
}
|
||||
{
|
||||
bits = 4096;
|
||||
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||
type = "ed25519";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
programs.ssh = let
|
||||
# a list of hosts that are connected over Tailscale
|
||||
# it would be better to construct this list dynamically
|
||||
# but we hardcode it because we cannot check if a host is
|
||||
# authenticated - that needs manual intervention
|
||||
hosts = ["helios" "enyo" "hermes"];
|
||||
|
||||
# generate the ssh config for the hosts
|
||||
mkHostConfig = hostname: ''
|
||||
# Configuration for ${hostname}
|
||||
Host ${hostname}
|
||||
HostName ${hostname}
|
||||
Port ${toString (elemAt config.services.openssh.ports 0)}
|
||||
StrictHostKeyChecking=accept-new
|
||||
'';
|
||||
|
||||
hostConfig = concatStringsSep "\n" (map mkHostConfig hosts);
|
||||
in {
|
||||
startAgent = !config.modules.system.yubikeySupport.enable;
|
||||
extraConfig = ''
|
||||
${hostConfig}
|
||||
'';
|
||||
|
||||
# ship github/gitlab/sourcehut host keys to avoid MiM (man in the middle) attacks
|
||||
knownHosts = mapAttrs (_: mkForce) {
|
||||
github-rsa = {
|
||||
hostNames = ["github.com"];
|
||||
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
|
||||
};
|
||||
|
||||
github-ed25519 = {
|
||||
hostNames = ["github.com"];
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||
};
|
||||
|
||||
gitlab-rsa = {
|
||||
hostNames = ["gitlab.com"];
|
||||
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9";
|
||||
};
|
||||
gitlab-ed25519 = {
|
||||
hostNames = ["gitlab.com"];
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
|
||||
};
|
||||
|
||||
sourcehut-rsa = {
|
||||
hostNames = ["git.sr.ht"];
|
||||
publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ+l/lvYmaeOAPeijHL8d4794Am0MOvmXPyvHTtrqvgmvCJB8pen/qkQX2S1fgl9VkMGSNxbp7NF7HmKgs5ajTGV9mB5A5zq+161lcp5+f1qmn3Dp1MWKp/AzejWXKW+dwPBd3kkudDBA1fa3uK6g1gK5nLw3qcuv/V4emX9zv3P2ZNlq9XRvBxGY2KzaCyCXVkL48RVTTJJnYbVdRuq8/jQkDRA8lHvGvKI+jqnljmZi2aIrK9OGT2gkCtfyTw2GvNDV6aZ0bEza7nDLU/I+xmByAOO79R1Uk4EYCvSc1WXDZqhiuO2sZRmVxa0pQSBDn1DB3rpvqPYW+UvKB3SOz";
|
||||
};
|
||||
|
||||
sourcehut-ed25519 = {
|
||||
hostNames = ["git.sr.ht"];
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
96
nyx/modules/core/common/system/os/networking/tailscale.nix
Normal file
96
nyx/modules/core/common/system/os/networking/tailscale.nix
Normal file
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf mkDefault optionals mkBefore;
|
||||
inherit (config.services) tailscale;
|
||||
|
||||
sys = config.modules.system.networking;
|
||||
cfg = sys.tailscale;
|
||||
|
||||
upFlags =
|
||||
cfg.flags.default
|
||||
++ ["--authkey file:${config.age.secrets.tailscale-client.path}"]
|
||||
++ optionals cfg.isServer ["--advertise-exit-node"]
|
||||
++ optionals (cfg.endpoint != null) ["--login-server ${cfg.endpoint}"]
|
||||
# TODO: test if specifying an operator messes with the autologin service
|
||||
# which, as you expect, does not run as the operator user
|
||||
++ optionals (cfg.operator != null) ["--operator" cfg.operator];
|
||||
in {
|
||||
config = mkIf cfg.enable {
|
||||
# make the tailscale command usable to users
|
||||
environment.systemPackages = [pkgs.tailscale];
|
||||
|
||||
networking.firewall = {
|
||||
# always allow traffic from the designated tailscale interface
|
||||
trustedInterfaces = ["${tailscale.interfaceName}"];
|
||||
checkReversePath = "loose";
|
||||
|
||||
# allow
|
||||
allowedUDPPorts = [tailscale.port];
|
||||
};
|
||||
|
||||
boot.kernel = {
|
||||
sysctl = {
|
||||
# # Enable IP forwarding
|
||||
# required for Wireguard & Tailscale/Headscale subnet feature
|
||||
# See <https://tailscale.com/kb/1019/subnets/?tab=linux#step-1-install-the-tailscale-client>
|
||||
"net.ipv4.ip_forward" = true;
|
||||
"net.ipv6.conf.all.forwarding" = true;
|
||||
};
|
||||
};
|
||||
|
||||
# enable tailscale, inter-machine VPN service
|
||||
services.tailscale = {
|
||||
enable = true;
|
||||
permitCertUid = "root";
|
||||
useRoutingFeatures = mkDefault "both";
|
||||
# TODO: these flags still need to be specified with `tailscale up`
|
||||
# for some reason
|
||||
extraUpFlags = upFlags;
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services = {
|
||||
# lets not send our logs to log.tailscale.io
|
||||
# unless I get to know what they do with the logs
|
||||
tailscaled.serviceConfig.Environment = mkBefore ["TS_NO_LOGS_NO_SUPPORT=true"];
|
||||
|
||||
# oneshot tailscale authentication servcie
|
||||
# TODO: this implies tailscale has been authenticated before with our own login server
|
||||
# ideally we should have a way to authenticate tailscale with our own login server in
|
||||
# this service, likely through an option in the system module
|
||||
tailscale-autoconnect = {
|
||||
description = "Automatic connection to Tailscale";
|
||||
|
||||
# make sure tailscale is running before trying to connect to tailscale
|
||||
after = ["network-pre.target" "tailscale.service"];
|
||||
wants = ["network-pre.target" "tailscale.service"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
# set this service as a oneshot job
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
# have the job run this shell script
|
||||
script = ''
|
||||
# wait for tailscaled to settle
|
||||
sleep 2
|
||||
|
||||
# check if we are already authenticated to tailscale
|
||||
status="$(${pkgs.tailscale}/bin/tailscale status -json | ${pkgs.jq}/bin/jq -r .BackendState)"
|
||||
if [ $status = "Running" ]; then # if so, then do nothing
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# otherwise authenticate with tailscale
|
||||
${pkgs.tailscale}/bin/tailscale up ${toString upFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
network.wait-online.ignoredInterfaces = ["${tailscale.interfaceName}"];
|
||||
};
|
||||
};
|
||||
}
|
101
nyx/modules/core/common/system/os/networking/tcpcrypt.nix
Normal file
101
nyx/modules/core/common/system/os/networking/tcpcrypt.nix
Normal file
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
dev = config.modules.device;
|
||||
in {
|
||||
# get rid of the tcpcrypt module provided by nixpkgs
|
||||
# it is unmaintained and I cannot be arsed to PR a fix
|
||||
disabledModules = ["services/networking/tcpcrypt.nix"];
|
||||
config = mkIf (dev.type != "server") {
|
||||
# FIXME: the upstream tcpcrypd service is unmaintained and poorly designed
|
||||
# networking.tcpcrypt.enable = true;
|
||||
|
||||
# create a system user for the tcpcrypt service
|
||||
# this is the user we will use the systemd service as
|
||||
users = {
|
||||
groups.tcpcryptd = {};
|
||||
users.tcpcryptd = {
|
||||
description = "tcpcrypt daemon user";
|
||||
group = "tcpcryptd";
|
||||
uid = config.ids.uids.tcpcryptd; # nixpkgs already defines a hardcoded uid, use it
|
||||
};
|
||||
};
|
||||
|
||||
# enable opportunistic TCP encryption
|
||||
# this is NOT a pancea, however, if the receiver supports encryption and the attacker is passive
|
||||
# privacy will be more plausible (but not guaranteed, unlike what the option docs suggest)
|
||||
# NOTE: the systemd service below is rewritten to be an alternative to networking.tcpcrypt.enable
|
||||
# it lacks hardening and SHOULD NOT BE USED until further notice.
|
||||
systemd.services.tcpcrypt = let
|
||||
# borrowed from fedora's tcpcrypt rpm spec
|
||||
# <https://src.fedoraproject.org/rpms/tcpcrypt/blob/rawhide/f/tcpcryptd-firewall>
|
||||
tcpcryptd-firewall = pkgs.writeShellApplication {
|
||||
name = "tcpcryptd-firewall";
|
||||
runtimeInputs = [pkgs.iptables];
|
||||
text = ''
|
||||
|
||||
# use iptables manually
|
||||
if [ "$1" = "start" ]; then
|
||||
iptables -t raw -N nixos-tcpcrypt
|
||||
iptables -t raw -A nixos-tcpcrypt -p tcp -m mark --mark 0x0/0x10 -j NFQUEUE --queue-num 666
|
||||
iptables -t raw -I PREROUTING -j nixos-tcpcrypt
|
||||
|
||||
iptables -t mangle -N nixos-tcpcrypt
|
||||
iptables -t mangle -A nixos-tcpcrypt -p tcp -m mark --mark 0x0/0x10 -j NFQUEUE --queue-num 666
|
||||
iptables -t mangle -I POSTROUTING -j nixos-tcpcrypt
|
||||
fi
|
||||
|
||||
if [ "$1" = "stop" ]; then
|
||||
iptables -t mangle -D POSTROUTING -j nixos-tcpcrypt || true
|
||||
iptables -t raw -D PREROUTING -j nixos-tcpcrypt || true
|
||||
|
||||
iptables -t raw -F nixos-tcpcrypt || true
|
||||
iptables -t raw -X nixos-tcpcrypt || true
|
||||
|
||||
iptables -t mangle -F nixos-tcpcrypt || true
|
||||
iptables -t mangle -X nixos-tcpcrypt || true
|
||||
fi
|
||||
'';
|
||||
};
|
||||
in {
|
||||
description = "tcpcrypt, opportunistic tcp encryption";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target" "syslog.target"];
|
||||
|
||||
serviceConfig = {
|
||||
Restart = "on-failure";
|
||||
RestartSec = 10;
|
||||
|
||||
RuntimeDirectory = "tcpcryptd";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
echo -en "Starting tcpcryptd\n"
|
||||
${pkgs.procps}/bin/sysctl -n net.ipv4.tcp_ecn > /run/tcpcryptd/pre-tcpcrypt-ecn-state
|
||||
${pkgs.procps}/bin/sysctl -w net.ipv4.tcp_ecn=0
|
||||
|
||||
# start the firewall
|
||||
${tcpcryptd-firewall}/bin/tcpcryptd-firewall start
|
||||
'';
|
||||
|
||||
# -f disables network test
|
||||
script = "${pkgs.tcpcrypt}/bin/tcpcryptd -v -f -x 0x10 ";
|
||||
|
||||
postStop = ''
|
||||
echo -en "Stopped tcpcrypd, restoring tcp_enc state\n"
|
||||
if [ -f /run/tcpcryptd/pre-tcpcrypt-ecn-state ]; then
|
||||
${pkgs.procps}/bin/sysctl -w net.ipv4.tcp_ecn=$(cat /run/tcpcryptd/pre-tcpcrypt-ecn-state)
|
||||
fi
|
||||
|
||||
# stop the firewall
|
||||
${tcpcryptd-firewall}/bin/tcpcryptd-firewall stop
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
71
nyx/modules/core/common/system/os/networking/wireless.nix
Normal file
71
nyx/modules/core/common/system/os/networking/wireless.nix
Normal file
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.lists) optionals;
|
||||
inherit (lib.attrsets) optionalAttrs;
|
||||
inherit (lib.meta) getExe;
|
||||
|
||||
sys = config.modules.system;
|
||||
|
||||
inherit (sys.networking) wireless;
|
||||
in {
|
||||
config = {
|
||||
environment.systemPackages = optionals (wireless.backend == "iwd") pkgs.iwgtk;
|
||||
networking.wireless =
|
||||
{
|
||||
enable = wireless.backend == "wpa_supplicant";
|
||||
|
||||
# configure iwd
|
||||
iwd = {
|
||||
enable = wireless.backend == "iwd";
|
||||
settings = {
|
||||
#Rank.BandModifier5Ghz = 2.0;
|
||||
#Scan.DisablePeriodicScan = true;
|
||||
Settings.AutoConnect = true;
|
||||
|
||||
General = {
|
||||
AddressRandomization = "network";
|
||||
AddressRandomizationRange = "full";
|
||||
EnableNetworkConfiguration = true;
|
||||
RoamRetryInterval = 15;
|
||||
};
|
||||
|
||||
Network = {
|
||||
EnableIPv6 = true;
|
||||
RoutePriorityOffset = 300;
|
||||
# NameResolvingService = "resolvconf";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
// optionalAttrs wireless.allowImperative {
|
||||
# Imperative Configuration
|
||||
userControlled.enable = true;
|
||||
allowAuxiliaryImperativeNetworks = true; # patches wpa_supplicant
|
||||
|
||||
extraConfig = ''
|
||||
update_config=1
|
||||
'';
|
||||
};
|
||||
|
||||
# launch indicator as a daemon on login if wireless backend
|
||||
# is defined as iwd
|
||||
systemd = {
|
||||
# make sure we ensure the existence of wpa_supplicant config
|
||||
# before we run the wpa_supplicant service
|
||||
services.wpa_supplicant.preStart = ''
|
||||
touch /etc/wpa_supplicant.conf
|
||||
'';
|
||||
|
||||
user.services.iwgtk = mkIf (wireless.backend == "iwd") {
|
||||
serviceConfig.ExecStart = "${getExe pkgs.iwgtk} -i";
|
||||
wantedBy = ["graphical-session.target"];
|
||||
partOf = ["graphical-session.target"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
39
nyx/modules/core/common/system/os/programs/default.nix
Normal file
39
nyx/modules/core/common/system/os/programs/default.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./direnv.nix
|
||||
./nano.nix
|
||||
];
|
||||
|
||||
programs = {
|
||||
bash = {
|
||||
# when entering the interactive shell, set the history file to
|
||||
# the config directory to avoid cluttering the $HOME directory
|
||||
interactiveShellInit = ''
|
||||
export HISTFILE="$XDG_STATE_HOME"/bash_history
|
||||
'';
|
||||
|
||||
# initialize starship in impromptu bash sessions
|
||||
# (e.g. when running a command without entering a shell)
|
||||
promptInit = ''
|
||||
eval "$(${lib.getExe pkgs.starship} init bash)"
|
||||
'';
|
||||
};
|
||||
|
||||
# less pager
|
||||
less.enable = true;
|
||||
|
||||
# home-manager is quirky as ever, and wants this to be set in system config
|
||||
# instead of just home-manager
|
||||
zsh.enable = true;
|
||||
|
||||
# run commands without installing the programs
|
||||
comma.enable = true;
|
||||
|
||||
# type "fuck" to fix the last command that made you go "fuck"
|
||||
thefuck.enable = true;
|
||||
};
|
||||
}
|
103
nyx/modules/core/common/system/os/programs/direnv.nix
Normal file
103
nyx/modules/core/common/system/os/programs/direnv.nix
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
|
||||
# shut up. SHUT UP
|
||||
silent = true;
|
||||
|
||||
# faster, persistent implementation of use_nix and use_flake
|
||||
nix-direnv = {
|
||||
enable = true;
|
||||
package = pkgs.nix-direnv.override {
|
||||
nix = config.nix.package;
|
||||
};
|
||||
};
|
||||
|
||||
# enable loading direnv in nix-shell nix shell or nix develop
|
||||
loadInNixShell = true;
|
||||
|
||||
direnvrcExtra = ''
|
||||
: ''${XDG_CACHE_HOME:=$HOME/.cache}
|
||||
declare -A direnv_layout_dirs
|
||||
|
||||
# https://github.com/direnv/direnv/wiki/Customizing-cache-location#hashed-directories
|
||||
direnv_layout_dir() {
|
||||
echo "''${direnv_layout_dirs[$PWD]:=$(
|
||||
echo -n "$XDG_CACHE_HOME"/direnv/layouts/
|
||||
echo -n "$PWD" | ${pkgs.perl}/bin/shasum | cut -d ' ' -f 1
|
||||
)}"
|
||||
}
|
||||
|
||||
# Usage: daemonize <name> [<command> [...<args>]]
|
||||
#
|
||||
# Starts the command in the background with an exclusive lock on $name.
|
||||
#
|
||||
# If no command is passed, it uses the name as the command.
|
||||
#
|
||||
# Logs are in .direnv/$name.log
|
||||
#
|
||||
# To kill the process, run `kill $(< .direnv/$name.pid)`.
|
||||
daemonize() {
|
||||
local name=$1
|
||||
shift
|
||||
local pid_file=$(direnv_layout_dir)/$name.pid
|
||||
local log_file=$(direnv_layout_dir)/$name.log
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
cmd=$name
|
||||
else
|
||||
cmd=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
if ! has "$cmd"; then
|
||||
echo "ERROR: $cmd not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(direnv_layout_dir)"
|
||||
|
||||
# Open pid_file on file descriptor 200
|
||||
exec 200>"$pid_file"
|
||||
|
||||
# Check that we have exclusive access
|
||||
if ! flock --nonblock 200; then
|
||||
echo "daemonize[$name] is already running as pid $(< "$pid_file")"
|
||||
return
|
||||
fi
|
||||
|
||||
# Start the process in the background. This requires two forks to escape the
|
||||
# control of bash.
|
||||
|
||||
# First fork
|
||||
(
|
||||
# Second fork
|
||||
(
|
||||
echo "daemonize[$name:$BASHPID]: starting $cmd $*" >&2
|
||||
|
||||
# Record the PID for good measure
|
||||
echo "$BASHPID" >&200
|
||||
|
||||
# Redirect standard file descriptors
|
||||
exec 0</dev/null
|
||||
exec 1>"$log_file"
|
||||
exec 2>&1
|
||||
# Used by direnv
|
||||
exec 3>&-
|
||||
exec 4>&-
|
||||
|
||||
# Run command
|
||||
exec "$cmd" "$@"
|
||||
) &
|
||||
) &
|
||||
|
||||
# Release that file descriptor
|
||||
exec 200>&-
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
48
nyx/modules/core/common/system/os/programs/nano.nix
Normal file
48
nyx/modules/core/common/system/os/programs/nano.nix
Normal file
|
@ -0,0 +1,48 @@
|
|||
{pkgs, ...}: {
|
||||
programs.nano = {
|
||||
# enabled by default anyway, we can keep it in case my neovim config breaks
|
||||
enable = true;
|
||||
nanorc = ''
|
||||
include ${pkgs.nanorc}/share/*.nanorc # extended syntax highlighting
|
||||
|
||||
# Options
|
||||
# https://github.com/davidhcefx/Modern-Nano-Keybindings
|
||||
set tabsize 4
|
||||
set tabstospaces
|
||||
set linenumbers
|
||||
set numbercolor yellow,normal
|
||||
set indicator # side-bar for indicating cur position
|
||||
set smarthome # `Home` jumps to line start first
|
||||
set afterends # `Ctrl+Right` move to word ends instead of word starts
|
||||
set wordchars "_" # recognize '_' as part of a word
|
||||
set zap # delete selected text as a whole
|
||||
set historylog # remember search history
|
||||
set multibuffer # read files into multibuffer instead of insert
|
||||
set mouse # enable mouse support
|
||||
bind M-R redo main
|
||||
bind ^C copy main
|
||||
bind ^X cut main
|
||||
bind ^V paste main
|
||||
bind ^K zap main
|
||||
bind ^H chopwordleft all
|
||||
bind ^Q exit all
|
||||
bind ^Z suspend main
|
||||
bind M-/ comment main
|
||||
bind ^Space complete main
|
||||
|
||||
bind M-C location main
|
||||
bind ^E wherewas all
|
||||
bind M-E findprevious all
|
||||
bind ^R replace main
|
||||
bind ^B pageup all # vim-like support
|
||||
bind ^F pagedown all
|
||||
bind ^G firstline all
|
||||
bind M-G lastline all
|
||||
|
||||
bind M-1 help all # fix ^G been used
|
||||
bind Sh-M-C constantshow main # fix M-C, M-F and M-b been used
|
||||
bind Sh-M-F formatter main
|
||||
bind Sh-M-B linter main
|
||||
'';
|
||||
};
|
||||
}
|
12
nyx/modules/core/common/system/os/services/default.nix
Normal file
12
nyx/modules/core/common/system/os/services/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
imports = [
|
||||
./systemd
|
||||
|
||||
./fstrim.nix
|
||||
./fwupd.nix
|
||||
./logrotate.nix
|
||||
./lvm.nix
|
||||
./thermald.nix
|
||||
./zram.nix
|
||||
];
|
||||
}
|
39
nyx/modules/core/common/system/os/services/fstrim.nix
Normal file
39
nyx/modules/core/common/system/os/services/fstrim.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
in {
|
||||
# if lvm is enabled, then tell it to issue discards
|
||||
# (this is good for SSDs and has almost no downsides on HDDs, so
|
||||
# it's a good idea to enable it unconditionally)
|
||||
environment.etc."lvm/lvm.conf".text = mkIf config.services.lvm.enable ''
|
||||
devices {
|
||||
issue_discards = 1
|
||||
}
|
||||
'';
|
||||
|
||||
# discard blocks that are not in use by the filesystem, good for SSDs
|
||||
services.fstrim = {
|
||||
# we may enable this unconditionally across all systems becuase it's performance
|
||||
# impact is negligible on systems without a SSD - which means it's a no-op with
|
||||
# almost no downsides aside from the service firing once per week
|
||||
enable = true;
|
||||
|
||||
# the default value, good enough for average-load systems
|
||||
interval = "weekly";
|
||||
};
|
||||
|
||||
# tweak fstim service to run only when on AC power
|
||||
# and to be nice to other processes
|
||||
# (this is a good idea for any service that runs periodically)
|
||||
systemd.services.fstrim = {
|
||||
unitConfig.ConditionACPower = true;
|
||||
|
||||
serviceConfig = {
|
||||
Nice = 19;
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
};
|
||||
}
|
13
nyx/modules/core/common/system/os/services/fwupd.nix
Normal file
13
nyx/modules/core/common/system/os/services/fwupd.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
{config, ...}: {
|
||||
# firmware updater for machine hardware
|
||||
services.fwupd = {
|
||||
enable = true;
|
||||
daemonSettings.EspLocation = config.boot.loader.efi.efiSysMountPoint;
|
||||
|
||||
# newer hardware may have their firmware in testing
|
||||
# e.g. Framework devices don't have their firmware in stable yet
|
||||
# TODO: make a system-level option that sets this value for hosts
|
||||
# that have testing firmware
|
||||
# extraRemotes = [ "lvfs-testing" ];
|
||||
};
|
||||
}
|
28
nyx/modules/core/common/system/os/services/logrotate.nix
Normal file
28
nyx/modules/core/common/system/os/services/logrotate.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
services.logrotate.settings.header = {
|
||||
# general
|
||||
global = true;
|
||||
dateext = true;
|
||||
dateformat = "-%Y-%m-%d";
|
||||
nomail = true;
|
||||
missingok = true;
|
||||
copytruncate = true;
|
||||
|
||||
# rotation frequency
|
||||
priority = 1;
|
||||
frequency = "weekly";
|
||||
rotate = 7; # special value, means every 7 days
|
||||
minage = 7; # avoid removing logs that are less than 7 days old
|
||||
|
||||
# compression
|
||||
compress = true; # lets compress logs to save space
|
||||
compresscmd = "${lib.getExe' pkgs.zstd "zstd"}";
|
||||
compressoptions = " -Xcompression-level 10";
|
||||
compressext = "zst";
|
||||
uncompresscmd = "${lib.getExe' pkgs.zstd "unzstd"}";
|
||||
};
|
||||
}
|
6
nyx/modules/core/common/system/os/services/lvm.nix
Normal file
6
nyx/modules/core/common/system/os/services/lvm.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{lib, ...}: let
|
||||
inherit (lib) mkDefault;
|
||||
in {
|
||||
# I don't use lvm, can be disabled
|
||||
services.lvm.enable = mkDefault false;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
inherit (config) modules;
|
||||
env = modules.usrEnv;
|
||||
|
||||
cfg = env.brightness;
|
||||
in {
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services."system-brightnessd" = {
|
||||
description = "Automatic backlight management with systemd";
|
||||
|
||||
# TODO: maybe this needs to be a part of graphical-session.target?
|
||||
# I am not very sure how wantedBy and partOf really work
|
||||
wantedBy = ["default.target"];
|
||||
partOf = ["graphical-session.target"];
|
||||
|
||||
# TODO: this needs to be hardened
|
||||
# not that a backlight service is a security risk, but it's a good habit
|
||||
# to keep our systemd services as secure as possible
|
||||
serviceConfig = {
|
||||
Type = "${cfg.serviceType}";
|
||||
ExecStart = "${lib.getExe cfg.package}";
|
||||
Restart = "never";
|
||||
RestartSec = "5s";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
imports = [
|
||||
./brightnessd.nix
|
||||
./oomd.nix
|
||||
];
|
||||
}
|
31
nyx/modules/core/common/system/os/services/systemd/oomd.nix
Normal file
31
nyx/modules/core/common/system/os/services/systemd/oomd.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
systemd = {
|
||||
# Systemd OOMd
|
||||
# Fedora enables these options by default. See the 10-oomd-* files here:
|
||||
# https://src.fedoraproject.org/rpms/systemd/tree/3211e4adfcca38dfe24188e28a65b1cf385ecfd6
|
||||
# by default it only kills cgroups. So either systemd services marked for killing under OOM
|
||||
# or (disabled by default, enabled by us) the entire user slice. Fedora used to kill root
|
||||
# and system slices, but their oomd configuration has since changed.
|
||||
# TODO: maybe disable user slice by default?
|
||||
oomd = {
|
||||
enable = !config.systemd.enableUnifiedCgroupHierarchy;
|
||||
enableRootSlice = true;
|
||||
enableSystemSlice = true;
|
||||
enableUserSlices = true;
|
||||
extraConfig = {
|
||||
"DefaultMemoryPressureDurationSec" = "20s";
|
||||
};
|
||||
};
|
||||
|
||||
# make it that nix builds are more likely killed than important services.
|
||||
# 100 is the default for user slices and 500 is systemd-coredumpd@
|
||||
# this is important because as my system got huge, nix flake check started
|
||||
# causing OOMs and killing my desktop environment - which I do not like
|
||||
# nuke nix-daemon if it gets too memory hungry
|
||||
services.nix-daemon.serviceConfig.OOMScoreAdjust = lib.mkDefault 350;
|
||||
};
|
||||
}
|
4
nyx/modules/core/common/system/os/services/thermald.nix
Normal file
4
nyx/modules/core/common/system/os/services/thermald.nix
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
# monitor and control temparature
|
||||
services.thermald.enable = true;
|
||||
}
|
34
nyx/modules/core/common/system/os/services/zram.nix
Normal file
34
nyx/modules/core/common/system/os/services/zram.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkIf;
|
||||
in {
|
||||
# compress half of the ram to use as swap
|
||||
# basically, get more memory per memory
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
algorithm = "zstd";
|
||||
memoryPercent = 90; # defaults to 50
|
||||
};
|
||||
|
||||
# <https://www.kernel.org/doc/html/latest/admin-guide/sysctl/vm.html>
|
||||
boot.kernel.sysctl = mkIf config.zramSwap.enable {
|
||||
# zram is relatively cheap, prefer swap
|
||||
# swappiness refers to the kernel's willingness prefer swap
|
||||
# over memory. higher values mean that we'll utilize swap more often
|
||||
# which preserves memory, but will cause performance issues as well
|
||||
# as wear on the drive
|
||||
"vm.swappiness" = 180; # 0-200
|
||||
# level of reclaim when memory is being fragmented
|
||||
"vm.watermark_boost_factor" = 0; # 0 to disable
|
||||
# aggressiveness of kswapd
|
||||
# it defines the amount of memory left in a node/system before kswapd is woken up
|
||||
"vm.watermark_scale_factor" = 125; # 0-300
|
||||
# zram is in memory, no need to readahead
|
||||
# page-cluster refers to the number of pages up to which
|
||||
# consecutive pages are read in from swap in a single attempt
|
||||
"vm.page-cluster" = 0;
|
||||
};
|
||||
}
|
5
nyx/modules/core/common/system/os/theme/default.nix
Normal file
5
nyx/modules/core/common/system/os/theme/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
imports = [
|
||||
./qt.nix
|
||||
];
|
||||
}
|
16
nyx/modules/core/common/system/os/theme/qt.nix
Normal file
16
nyx/modules/core/common/system/os/theme/qt.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
environment.variables = let
|
||||
qmlPackages = with pkgs; [
|
||||
plasma5Packages.qqc2-desktop-style
|
||||
plasma5Packages.kirigami2
|
||||
];
|
||||
|
||||
qtVersion = pkgs.qt515.qtbase.version;
|
||||
in {
|
||||
"QML2_IMPORT_PATH" = "${lib.concatStringsSep ":" (builtins.map (p: "${p}/lib/qt-${qtVersion}/qml") qmlPackages)}";
|
||||
};
|
||||
}
|
9
nyx/modules/core/common/system/os/users/default.nix
Normal file
9
nyx/modules/core/common/system/os/users/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
# we want to handle user configurations on a per-file basis
|
||||
# users that are not in users/<username>.nix don't get to be a real user
|
||||
imports = [
|
||||
./notashelf.nix
|
||||
./nix-builder.nix
|
||||
./root.nix
|
||||
];
|
||||
}
|
17
nyx/modules/core/common/system/os/users/nix-builder.nix
Normal file
17
nyx/modules/core/common/system/os/users/nix-builder.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
users = {
|
||||
groups.nix = {};
|
||||
|
||||
users.nix-builder = {
|
||||
useDefaultShell = true;
|
||||
isSystemUser = true;
|
||||
createHome = true;
|
||||
group = "nix";
|
||||
home = "/var/tmp/nix-builder";
|
||||
openssh.authorizedKeys = {
|
||||
keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK3Oglg7aVYQJzGa4JhnvDhRYx0jkLHwDT/9IyiLUNS2 notashelf@enyo"];
|
||||
# keyFiles = []; # TODO: can this be used with agenix?
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
42
nyx/modules/core/common/system/os/users/notashelf.nix
Normal file
42
nyx/modules/core/common/system/os/users/notashelf.nix
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIABG2T60uEoq4qTZtAZfSBPtlqWs2b4V4O+EptQ6S/ru notashelf@prometheus"
|
||||
];
|
||||
in {
|
||||
boot.initrd.network.ssh.authorizedKeys = keys;
|
||||
|
||||
users.users.notashelf = {
|
||||
isNormalUser = true;
|
||||
shell = pkgs.zsh;
|
||||
initialPassword = "changeme";
|
||||
openssh.authorizedKeys.keys = keys;
|
||||
extraGroups =
|
||||
[
|
||||
"wheel"
|
||||
"systemd-journal"
|
||||
"audio"
|
||||
"video"
|
||||
"input"
|
||||
"plugdev"
|
||||
"lp"
|
||||
"tss"
|
||||
"power"
|
||||
"nix"
|
||||
]
|
||||
++ lib.ifTheyExist config [
|
||||
"network"
|
||||
"networkmanager"
|
||||
"wireshark"
|
||||
"mysql"
|
||||
"docker"
|
||||
"podman"
|
||||
"git"
|
||||
"libvirtd"
|
||||
];
|
||||
};
|
||||
}
|
3
nyx/modules/core/common/system/os/users/root.nix
Normal file
3
nyx/modules/core/common/system/os/users/root.nix
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
users.users.root.hashedPassword = "*"; # lock root account
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue