From 76381b19c5b59daa233ffc53a99b09eae9f143c1 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Wed, 2 Apr 2025 16:16:10 +0800 Subject: [PATCH] refactor(networking): harden networkmanager systemd services --- README.md | 53 +++++++++++++++++++++++++++++++++--------- modules/networking.nix | 28 ++++++++++++++++++++++ 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5408853..f086565 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,23 @@ -> "This is fucking brilliant. Nobody needs this, nobody has a real use for this and this definitely does not attract girls. Still, I'll try this and probably love it. -Tim Goeree" +> "This is fucking brilliant. Nobody needs this, nobody has a real use for this +> and this definitely does not attract girls. Still, I'll try this and probably +> love it. -Tim Goeree" # As Yet Unreproducible -- [x] ~User passwords~ -> _Managed with sops-nix_ +- [x] ~~User passwords~~ -> _Managed with sops-nix_ - [ ] Spotify login - [ ] Firefox login # Adding Secrets with sops-nix -Secrets are stored in configs/secrets/secrets.yaml. You can edit these secrets with `sops secrets.yaml` given you have an age private key stored at `~/.config/sops/age/keys.txt`. +Secrets are stored in configs/secrets/secrets.yaml. You can edit these secrets +with `sops secrets.yaml` given you have an age private key stored at +`~/.config/sops/age/keys.txt`. -To decrypt these secrets with sops-nix during a rebuild, you must add your host public key to the `.sops.yaml` file. Generate it with `cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age`, add it to the file, then run `sops updatekeys secrets.yaml`. +To decrypt these secrets with sops-nix during a rebuild, you must add your host +public key to the `.sops.yaml` file. Generate it with +`cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age`, add it to the file, then +run `sops updatekeys secrets.yaml`. # Provisioning A New Machine @@ -33,7 +40,8 @@ wpa_cli ip addr ``` -On the host machine, run the following command to build the new system configuration and copy it over SSH along with the sops age key and ssh keys. +On the host machine, run the following command to build the new system +configuration and copy it over SSH along with the sops age key and ssh keys. ```bash # WARNING: You must use the IP address of the machine. @@ -41,7 +49,8 @@ On the host machine, run the following command to build the new system configura deploy --flake .# --target-host @ ``` -Complete the setup by running the following on the target system once it is booted into the new install. +Complete the setup by running the following on the target system once it is +booted into the new install. ```bash # On the target machine: @@ -52,12 +61,34 @@ cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age # On the host machine: # Add the host age public key to .sops.yaml sops updatekeys secrets.yaml - ``` +# Hardening + +[!NOTE] Thanks to +https://blog.notashelf.dev/posts/2025-03-03-insecurities-remedies-i.html for +this section! + +Systemd services where appropriate are hardened using +`systemd.services..serviceConfig`: + +- Protected from modifying the system clock +- Protected from modifying kernel parameters, modules or logs +- Whitelists syscalls +- Restricts namespaces the service is allowed to use, or changing its user or + group +- Restricts realtime access +- Restricts setting memory as writable and executable + # Acknowledgements -- https://www.youtube.com/watch?v=CwfKlX3rA6E for piquing my interest in this OS in the first place -- https://nixos-and-flakes.thiscute.world/ for teaching me about nix, nixos, flakes, and home-manager in an extremely easy to follow and well-documented fashion -- https://blog.notashelf.dev/posts/2025-02-24-ssh-signing-commits.html for teaching me how to trivially sign my commits -- https://www.reddit.com/r/NixOS/comments/fsummx/comment/fm3jbcm/ for an easy way to list all installed packages (`nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq`) +- https://www.youtube.com/watch?v=CwfKlX3rA6E for piquing my interest in this OS + in the first place +- https://nixos-and-flakes.thiscute.world/ for teaching me about nix, nixos, + flakes, and home-manager in an extremely easy to follow and well-documented + fashion +- https://blog.notashelf.dev/posts/2025-02-24-ssh-signing-commits.html for + teaching me how to trivially sign my commits +- https://www.reddit.com/r/NixOS/comments/fsummx/comment/fm3jbcm/ for an easy + way to list all installed packages + (`nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq`) diff --git a/modules/networking.nix b/modules/networking.nix index 52a8e58..8a3776d 100644 --- a/modules/networking.nix +++ b/modules/networking.nix @@ -5,6 +5,34 @@ ... }: { + systemd.services.NetworkManager-dispatcher.serviceConfig = { + ProtectClock = true; # Prevents the service from changing the system time or timezone. + ProtectKernelTunables = true; # Restricts the service's ability to modify kernel parameters via sysctl. + ProtectKernelModules = true; # Prevents the service from loading or unloading kernel modules. + ProtectKernelLogs = true; # Prevents the service from reading kernel logs directly. + SystemCallFilter = "~@clock @cpu-emulation @debug @obsolete @module @mount @raw-io @reboot @swap"; # Whitelists system calls, blocking all others based on specified groups. + ProtectControlGroups = true; # Prevents the service from joining or modifying control groups other than its own. + RestrictNamespaces = true; # Enforces stricter namespace isolation, preventing user namespace creation/joining. + LockPersonality = true; # Disables the `personality()` system call, preventing execution domain changes. + MemoryDenyWriteExecute = true; # Prevents the service from mapping memory pages as both writable and executable (W^X). + RestrictRealtime = true; # Prevents the service from using real-time scheduling policies. + RestrictSUIDSGID = true; # Prevents the service from utilizing setuid/setgid functionality. + }; + + systemd.services.NetworkManager.serviceConfig = { + ProtectClock = true; # Prevents the service from changing the system time or timezone. + ProtectKernelTunables = true; # Restricts the service's ability to modify kernel parameters via sysctl. + ProtectKernelModules = true; # Prevents the service from loading or unloading kernel modules. + ProtectKernelLogs = true; # Prevents the service from reading kernel logs directly. + SystemCallFilter = "~@clock @cpu-emulation @debug @obsolete @module @mount @raw-io @reboot @swap"; # Whitelists system calls, blocking all others based on specified groups. + ProtectControlGroups = true; # Prevents the service from joining or modifying control groups other than its own. + RestrictNamespaces = true; # Enforces stricter namespace isolation, preventing user namespace creation/joining. + LockPersonality = true; # Disables the `personality()` system call, preventing execution domain changes. + MemoryDenyWriteExecute = true; # Prevents the service from mapping memory pages as both writable and executable (W^X). + RestrictRealtime = true; # Prevents the service from using real-time scheduling policies. + RestrictSUIDSGID = true; # Prevents the service from utilizing setuid/setgid functionality. + }; + networking = { hostName = hostname; useDHCP = lib.mkDefault true;