diff --git a/custom/linux-bench/package.nix b/custom/linux-bench/package.nix new file mode 100644 index 0000000..c54aa73 --- /dev/null +++ b/custom/linux-bench/package.nix @@ -0,0 +1,48 @@ +{ + lib, + buildGoModule, + fetchFromGitea, + makeWrapper, + gnugrep, + iptables, +}: + +buildGoModule rec { + pname = "linux-bench"; + version = "0-unstable-2025-01-31"; + +# src = fetchFromGitHub { +# owner = "aquasecurity"; +# repo = "linux-bench"; +# rev = "ce039756a6211beca47a23220c31998a9a891ad0"; +# hash = "sha256-wprsaIe6hgH28yHkSqdHQdFyQMvObQY6hChsfBTviTA="; +# }; + + src = fetchFromGitea { + owner = "grimmauld"; + repo = "linux-bench"; + rev = "a936791cd0f4b4c02eb6294a3156ee784bf23c6a"; + hash = "sha256-8V0PUZJgNYPM81EH14nw4JpNH4StR1u1PbM+6GVpXVk="; + domain = "git.grimmauld.de"; + }; + + nativeBuildInputs = [ + makeWrapper + ]; + + vendorHash = "sha256-dlynz7mOiN+5ndYkmCUQu/Z31AwmJ+J2S3EBjQG5nWI="; + + postInstall = '' + wrapProgram $out/bin/linux-bench \ + --add-flags "--config-dir ${src}/cfg" \ + --prefix PATH : ${lib.makeBinPath [ gnugrep iptables ]} + ''; + + meta = { + description = "Checks whether a Linux server according to security best practices as defined in the CIS Distribution-Independent Linux Benchmark"; + homepage = "https://github.com/aquasecurity/linux-bench"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ grimmauld ]; + mainProgram = "linux-bench"; + }; +} diff --git a/hardening/default.nix b/hardening/default.nix index 01d8179..09f54a8 100644 --- a/hardening/default.nix +++ b/hardening/default.nix @@ -1,6 +1,7 @@ { lib, pkgs, + config, ... }: { @@ -11,13 +12,58 @@ ./opensnitch ./security.nix ./encrypt-dns.nix + ./filesystem-deny-mount.nix ]; specialisation.unhardened.configuration = { services.opensnitch.enable = lib.mkForce false; security.apparmor.enable = lib.mkForce false; }; - # + + systemd.oomd.enable = false; + + boot.kernel.sysctl = { + "net.ipv6.conf.all.accept_ra" = 0; + "net.ipv6.conf.default.accept_ra" = 0; + "net.ipv4.conf.all.send_redirects"=0; + "net.ipv4.conf.default.accept_source_route"=0; + "net.ipv4.conf.all.accept_redirects"=0; + "net.ipv4.conf.default.accept_redirects"=0; + "net.ipv6.conf.all.accept_redirects"=0; + "net.ipv6.conf.default.accept_redirects"=0; + "net.ipv4.conf.all.secure_redirects"=0; + "net.ipv4.conf.default.secure_redirects"=0; + "net.ipv4.conf.all.log_martians"=1; + "net.ipv4.conf.default.log_martians"=1; + "net.ipv4.icmp_echo_ignore_broadcasts"=1; + "net.ipv4.conf.all.rp_filter"=1; + "net.ipv4.conf.default.rp_filter"=1; + + "fs.suid_dumpable" = 0; + }; + + environment.etc."motd" = { text = config.users.motd; mode = "644"; }; + environment.etc."limits.conf".text = "* hard core 0"; + environment.etc."hosts.allow" = { text = "ALL: LOCAL"; mode = "644"; }; + environment.etc."hosts.deny" = { text = ""; mode = "644"; }; + environment.etc."issue" = { text = "Authorized uses only. All activity may be monitored and reported."; mode = "644"; }; + environment.etc."issue.net" = { text = "Authorized uses only. All activity may be monitored and reported."; mode = "644"; }; + +# systemd.tmpfiles.rules = [ +# "L+ /etc/passwd- 0644 root root - /etc/passwd" +# "L+ /etc/shadow- 0644 root root - /etc/shadow" +# "L+ /etc/group- 0644 root root - /etc/group" +# "L+ /etc/gshadow- 0644 root root - /etc/gshadow" +# ]; + + users.motd = "welcome to grimms paranoid box"; + + security.loginDefs.settings = { + # PASS_MAX_DAYS = 365; + PASS_MIN_DAYS = 7; + PASS_WARN_AGE = 14; + ENCRYPT_METHOD = "SHA512"; + }; systemd.tpm2.enable = false; systemd.enableEmergencyMode = false; @@ -27,5 +73,5 @@ security.apparmor.enable = true; security.allowSimultaneousMultithreading = true; environment.defaultPackages = lib.mkForce [ ]; - environment.systemPackages = with pkgs; [ nano ]; + environment.systemPackages = with pkgs; [ nano clamav linux-bench ]; } diff --git a/hardening/filesystem-deny-mount.nix b/hardening/filesystem-deny-mount.nix new file mode 100644 index 0000000..c169e4d --- /dev/null +++ b/hardening/filesystem-deny-mount.nix @@ -0,0 +1,46 @@ +{ pkgs,... }: +{ + # copied from https://github.com/NixOS/nixpkgs/issues/11790#issuecomment-2409053332 + + # Create a symlink from /bin/true to the Nix-managed true binary. + environment.etc."bin/true".source = "${pkgs.coreutils}/bin/true"; + # CIS 1.1.1.1.a Ensure mounting of cramfs filesystems is disabled + environment.etc."modprobe.d/cramfs.conf".text = '' + install cramfs /bin/true + ''; + # CIS 1.1.1.2.a Ensure mounting of freevxfs filesystems is disabled + environment.etc."modprobe.d/freevxfs.conf".text = '' + install freevxfs /bin/true + ''; + # CIS 1.1.1.3.a Ensure mounting of jffs2 filesystems is disabled + environment.etc."modprobe.d/jffs2.conf".text = '' + install jffs2 /bin/true + ''; + # CIS 1.1.1.4.a Ensure mounting of hfs filesystems is disabled + environment.etc."modprobe.d/hfs.conf".text = '' + install hfs /bin/true + ''; + # CIS 1.1.1.5.a Ensure mounting of hfsplus filesystems is disabled + environment.etc."modprobe.d/hfsplus.conf".text = '' + install hfsplus /bin/true + ''; + # CIS 1.1.1.6.a Ensure mounting of squashfs filesystems is disabled + environment.etc."modprobe.d/squashfs.conf".text = '' + install squashfs /bin/true + ''; + # CIS 1.1.1.7.a Ensure mounting of udf filesystems is disabled + environment.etc."modprobe.d/udf.conf".text = '' + install udf /bin/true + ''; + + # CIS 1.1.1.8.a Ensure mounting of FAT filesystems is disabled +# environment.etc."modprobe.d/fat.conf".text = '' +# install fat /bin/true +# ''; + environment.etc."modprobe.d/CIS.conf".text = '' + install dccp /bin/true + install sctp /bin/true + install rds /bin/true + install tipc /bin/true + ''; +} diff --git a/hardening/ssh-as-sudo.nix b/hardening/ssh-as-sudo.nix index 3743775..dcd7cb3 100644 --- a/hardening/ssh-as-sudo.nix +++ b/hardening/ssh-as-sudo.nix @@ -2,18 +2,34 @@ { services.openssh = { enable = true; - settings.PasswordAuthentication = false; - settings.challengeResponseAuthentication = false; + settings = { + PasswordAuthentication = false; + challengeResponseAuthentication = false; + # PermitRootLogin = "no"; + KbdInteractiveAuthentication = false; + }; # settings.UsePAM = false; openFirewall = lib.mkDefault false; allowSFTP = lib.mkDefault false; # startWhenNeeded = true; extraConfig = '' - AllowTcpForwarding yes + allowtcpforwarding no X11Forwarding no AllowAgentForwarding no AllowStreamLocalForwarding no AuthenticationMethods publickey + Protocol 2 + MaxAuthTries 4 + PermitEmptyPasswords no + PermitUserEnvironment no + MaxSessions 4 + LoginGraceTime 60 + ClientAliveCountMax 3 + ClientAliveInterval 15 + HostbasedAuthentication no + IgnoreRhosts yes + banner /etc/issue.net + maxstartups 10:30:60 ''; }; diff --git a/hardening/systemd/global/default.nix b/hardening/systemd/global/default.nix index 1a2348d..e314f21 100644 --- a/hardening/systemd/global/default.nix +++ b/hardening/systemd/global/default.nix @@ -4,5 +4,6 @@ ./clock.nix ./realtime.nix ./syscall_arch.nix + ./suidsgid.nix ]; } diff --git a/hardening/systemd/global/suidsgid.nix b/hardening/systemd/global/suidsgid.nix new file mode 100644 index 0000000..6c65d56 --- /dev/null +++ b/hardening/systemd/global/suidsgid.nix @@ -0,0 +1,26 @@ +{ lib, config, ... }: +let + inherit (lib) types mkIf mkDefault; +in +{ + options.systemd.services = lib.mkOption { + type = + let + osConfig = config; + in + types.attrsOf ( + lib.types.submodule { + config.serviceConfig = mkIf (osConfig.specialisation != { }) { + RestrictSUIDSGID = mkDefault true; + }; + } + + ); + }; + + config = mkIf (config.specialisation != { }) { + systemd.services = { + suid-sgid-wrappers.serviceConfig.RestrictSUIDSGID = false; + }; + }; +} diff --git a/hardening/systemd/nscd.nix b/hardening/systemd/nscd.nix index 1079d21..0fa94dd 100644 --- a/hardening/systemd/nscd.nix +++ b/hardening/systemd/nscd.nix @@ -15,15 +15,7 @@ "AF_INET" "AF_INET6" ]; - RestrictNamespaces = [ - "~pid" - "~user" - "~net" - "~uts" - "~mnt" - "~cgroup" - "~ipc" - ]; + RestrictNamespaces = true; SystemCallFilter = "@system-service"; LockPersonality = true; diff --git a/overlays/default.nix b/overlays/default.nix index 65c2b5c..96325d8 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -40,6 +40,7 @@ ./factorio.nix ./ranger.nix ./vesktop.nix + ./linux-bench.nix # ./grpcio-tools.nix ]; } diff --git a/overlays/linux-bench.nix b/overlays/linux-bench.nix new file mode 100644 index 0000000..f032726 --- /dev/null +++ b/overlays/linux-bench.nix @@ -0,0 +1,4 @@ +{ prev, ... }: +{ + linux-bench = prev.callPackage ../custom/linux-bench/package.nix { }; +} diff --git a/specific/grimm-nixos-ssd/filesystems.nix b/specific/grimm-nixos-ssd/filesystems.nix index 4c72d69..986a3bd 100644 --- a/specific/grimm-nixos-ssd/filesystems.nix +++ b/specific/grimm-nixos-ssd/filesystems.nix @@ -39,6 +39,20 @@ in "nodev" ]; }; + + fileSystems."/tmp" = { + device = "none"; + fsType = "tmpfs"; + options = [ + "defaults" + "rw" + "relatime" + "mode=1777" + "noexec" + "nosuid" + "nodev" + ]; + }; fileSystems."${persist}" = { device = "zpool/persistent"; diff --git a/specific/grimm-nixos-ssd/tmpfiles.nix b/specific/grimm-nixos-ssd/tmpfiles.nix index 18bf573..3f07118 100644 --- a/specific/grimm-nixos-ssd/tmpfiles.nix +++ b/specific/grimm-nixos-ssd/tmpfiles.nix @@ -17,6 +17,8 @@ "D! /var/cache 0755 root root 7d" "e! /var/.Trash-0 0755 root root 14d" "D! /var/tmp 0755 root root 14d" + "d /nix/profile/bin 0755 root root" + "d /nix/var/nix/profiles/default/bin 0755 root root" # "D! /root 0700 root root" ]; @@ -39,6 +41,8 @@ "e ${user.home}/.sane - - - 7d" "e ${user.home}/.dotnet - - - 7d" "e ${user.home}/.nuget - - - 7d" + "L+ ${user.home}/.nix-profile - - - - ${user.home}/.local/state/nix/profiles/profile" + "L+ ${user.home}/.local/state/nix/profiles - - - - /nix/var/nix/profiles" # "d /home/${user}/.local/state/mpv/watch_later - - - 14d" ]; } diff --git a/sway/default.nix b/sway/default.nix index 244c1bc..27fb5e0 100644 --- a/sway/default.nix +++ b/sway/default.nix @@ -195,7 +195,7 @@ ''${getExe' pkgs.coreutils-full "sleep"} 3 && ${getExe' pkgs.blueman "blueman-applet"}'' (getExe' pkgs.lxqt.lxqt-policykit "lxqt-policykit-agent") # (getExe' config.hardware.opentabletdriver.package "otd-daemon") - pkgs.swaynotificationcenter + # pkgs.swaynotificationcenter pkgs.networkmanagerapplet aw-bundle # (pkgs.writeShellScriptBin "rmenu-cache-clear" "rm -r $HOME/.cache/rmenu") # invalidate rmenu cache on sway restart diff --git a/users.nix b/users.nix index 941441e..4a0adca 100644 --- a/users.nix +++ b/users.nix @@ -38,7 +38,7 @@ # { remote = "Videos"; } # ]; - hashedPassword = "$y$j9T$HmVEEG6w96IUWynzJsLjT/$MCNKOTOUkku4ybBJiXPIHasXEkNVe6Ouu5gRTl2ab00"; + hashedPassword = "$6$m8sCUb3SlDQvcbh1$Nf0vyO4qFq75He9Qrxmsz82RlHqpZatKKXlRKhfAZb9gHHaE.EM3MMinNjlKhFBYQnrZTbP46sSc4nWZv8sFZ/"; packages = lib.optionals config.grimmShared.graphical ( with pkgs;