diff --git a/common/nixos/sysctl/default.nix b/common/nixos/sysctl/default.nix new file mode 100644 index 0000000..afb70c3 --- /dev/null +++ b/common/nixos/sysctl/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./kernel.nix + ./file_system.nix + ./virtualization.nix + ./networking/default.nix + ]; +} diff --git a/common/nixos/sysctl/file_system.nix b/common/nixos/sysctl/file_system.nix new file mode 100644 index 0000000..2cc0586 --- /dev/null +++ b/common/nixos/sysctl/file_system.nix @@ -0,0 +1,41 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # disallow core dumping by SUID/SGID programs + "fs.suid_dumpable" = 0; + + # protect the creation of hard links + # one of the following conditions must be fulfilled + # - the user can only link to files that he or she owns + # - the user must first have read and write access to a file, that he/she wants to link to + "fs.protected_hardlinks" = 1; + + # protect the creation of symbolic links + # one of the following conditions must be fulfilled + # - the process following the symbolic link is the owner of the symbolic link + # - the owner of the directory is also the owner of the symbolic link + "fs.protected_symlinks" = 1; + + # enable extended FIFO protection + "fs.protected_fifos" = 2; + + # similar to protected_fifos, but it avoids writes to an attacker-controlled regular file + "fs.protected_regular" = 2; + + # increase system file descriptor limit + # this value can be up to: + # - 2147483647 (0x7fffffff) on a 32-bit system + # - 9223372036854775807 (0x7fffffffffffffff) on a 64-bit system + # be aware that the Linux kernel documentation suggests that inode-max should be 3-4 times + # larger than this value + "fs.file-max" = 9223372036854775807; + + # increase the amount of files that can be watched + # each file watch handle takes 1080 bytes + # up to 540 MiB of memory will be consumed if all 524288 handles are used + "fs.inotify.max_user_watches" = 524288; + }; +} diff --git a/common/nixos/sysctl/kernel.nix b/common/nixos/sysctl/kernel.nix new file mode 100644 index 0000000..a5d6535 --- /dev/null +++ b/common/nixos/sysctl/kernel.nix @@ -0,0 +1,70 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # enable ExecShield protection + # 2 enables ExecShield by default unless applications bits are set to disabled + # uncomment on systems without NX/XD protections + # check with: dmesg | grep --color '[NX|DX]*protection' + #kernel.exec-shield = 2 + + # enable ASLR + # turn on protection and randomize stack, vdso page and mmap + randomize brk base address + "kernel.randomize_va_space" = 2; + + # controls the System Request debugging functionality of the kernel + "kernel.sysrq" = 0; + + # controls whether core dumps will append the PID to the core filename + # useful for debugging multi-threaded applications + "kernel.core_uses_pid" = 1; + + # restrict access to kernel address + # kernel pointers printed using %pK will be replaced with 0’s regardless of privileges + "kernel.kptr_restrict" = 2; + + # Ptrace protection using Yama + # - 1: only a parent process can be debugged + # - 2: only admins can use ptrace (CAP_SYS_PTRACE capability required) + # - 3: disables ptrace completely, reboot is required to re-enable ptrace + "kernel.yama.ptrace_scope" = 3; + + # restrict kernel logs to root only + "kernel.dmesg_restrict" = 1; + + # restrict BPF JIT compiler to root only + "kernel.unprivileged_bpf_disabled" = 1; + + # disables kexec as it can be used to livepatch the running kernel + "kernel.kexec_load_disabled" = 1; + + # disable unprivileged user namespaces to decrease attack surface + "kernel.unprivileged_userns_clone" = 0; + + # disable the loading of kernel modules + # this can be used to prevent runtime insertion of malicious modules + # could break the system if enabled within sysctl.conf + # consider setting this manually after system is up + # sudo sysctl -w kernel.modules_disabled=1 + #kernel.modules_disabled = 1 + + # allow for more PIDs + # this value can be up to: + # - 32768 (2^15) on a 32-bit system + # - 4194304 (2^22) on a 64-bit system + "kernel.pid_max" = 4194304; + + # reboot machine after kernel panic + #kernel.panic = 10 + + # restrict perf subsystem usage + "kernel.perf_event_paranoid" = 3; + "kernel.perf_cpu_time_max_percent" = 1; + "kernel.perf_event_max_sample_rate" = 1; + + # prevent unprivileged attackers from loading vulnerable line disciplines with the TIOCSETD ioctl + "dev.tty.ldisc_autoload" = 0; + }; +} diff --git a/common/nixos/sysctl/network.nix b/common/nixos/sysctl/network.nix new file mode 100644 index 0000000..1f13683 --- /dev/null +++ b/common/nixos/sysctl/network.nix @@ -0,0 +1,8 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + }; +} diff --git a/common/nixos/sysctl/networking/default.nix b/common/nixos/sysctl/networking/default.nix new file mode 100644 index 0000000..edb4ce2 --- /dev/null +++ b/common/nixos/sysctl/networking/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./ipv4.nix + ./ipv6.nix + ./net.nix + ]; +} diff --git a/common/nixos/sysctl/networking/ipv4.nix b/common/nixos/sysctl/networking/ipv4.nix new file mode 100644 index 0000000..7f50248 --- /dev/null +++ b/common/nixos/sysctl/networking/ipv4.nix @@ -0,0 +1,114 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # enable BBR congestion control + "net.ipv4.tcp_congestion_control" = "bbr"; + + # disallow IPv4 packet forwarding + "net.ipv4.ip_forward" = 0; + + # enable SYN cookies for SYN flooding protection + "net.ipv4.tcp_syncookies" = 1; + + # number of times SYNACKs for a passive TCP connection attempt will be retransmitted + "net.ipv4.tcp_synack_retries" = 5; + + # do not send redirects + "net.ipv4.conf.default.send_redirects" = 0; + "net.ipv4.conf.all.send_redirects" = 0; + + # do not accept packets with SRR option + "net.ipv4.conf.default.accept_source_route" = 0; + "net.ipv4.conf.all.accept_source_route" = 0; + + # enable reverse path source validation (BCP38) + # refer to RFC1812, RFC2827, and BCP38 (http://www.bcp38.info) + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + + # log packets with impossible addresses to kernel log + "net.ipv4.conf.default.log_martians" = 1; + "net.ipv4.conf.all.log_martians" = 1; + + # do not accept ICMP redirect messages + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + + # disable sending and receiving of shared media redirects + # this setting overwrites net.ipv4.conf.all.secure_redirects + # refer to RFC1620 + "net.ipv4.conf.default.shared_media" = 0; + "net.ipv4.conf.all.shared_media" = 0; + + # always use the best local address for announcing local IP via ARP + "net.ipv4.conf.default.arp_announce" = 2; + "net.ipv4.conf.all.arp_announce" = 2; + + # reply only if the target IP address is local address configured on the incoming interface + "net.ipv4.conf.default.arp_ignore" = 1; + "net.ipv4.conf.all.arp_ignore" = 1; + + # drop Gratuitous ARP frames to prevent ARP poisoning + # this can cause issues when ARP proxies are used in the network + "net.ipv4.conf.default.drop_gratuitous_arp" = 1; + "net.ipv4.conf.all.drop_gratuitous_arp" = 1; + + # ignore all ICMP echo requests + #net.ipv4.icmp_echo_ignore_all = 1 + + # ignore all ICMP echo and timestamp requests sent to broadcast/multicast + "net.ipv4.icmp_echo_ignore_broadcasts" = 1; + + # ignore bad ICMP errors + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + + # mitigate TIME-WAIT Assassination hazards in TCP + # refer to RFC1337 + "net.ipv4.tcp_rfc1337" = 1; + + # disable TCP window scaling + # this makes the host less susceptible to TCP RST DoS attacks + # could drastically reduce throughput if latency is high + #net.ipv4.tcp_window_scaling = 0 + + # increase system IP port limits + "net.ipv4.ip_local_port_range" = "1024 65535"; + + # TCP timestamps could provide protection against wrapped sequence numbers, + # but the host's uptime can be calculated precisely from its timestamps + # it is also possible to differentiate operating systems based on their use of timestamps + # - 0: disable TCP timestamps + # - 1: enable timestamps as defined in RFC1323 and use random offset for + # each connection rather than only using the current time + # - 2: enable timestamps without random offsets + "net.ipv4.tcp_timestamps" = 0; + + # enabling SACK can increase the throughput + # but SACK is commonly exploited and rarely used + "net.ipv4.tcp_sack" = 0; + "net.ipv4.tcp_dsack" = 0; + "net.ipv4.tcp_fack" = 0; + + # divide socket buffer evenly between TCP window size and application + "net.ipv4.tcp_adv_win_scale" = 1; + + # SSR could impact TCP's performance on a fixed-speed network (e.g., wired) + # but it could be helpful on a variable-speed network (e.g., LTE) + # uncomment this if you are on a fixed-speed network + "net.ipv4.tcp_slow_start_after_idle" = 0; + + # enabling MTU probing helps mitigating PMTU blackhole issues + # this may not be desirable on congested networks + "net.ipv4.tcp_mtu_probing" = 1; + "net.ipv4.tcp_base_mss" = 1024; + + # increase memory thresholds to prevent packet dropping + "net.ipv4.tcp_rmem" = "4096 87380 8388608"; + "net.ipv4.tcp_wmem" = "4096 87380 8388608"; + }; +} diff --git a/common/nixos/sysctl/networking/ipv6.nix b/common/nixos/sysctl/networking/ipv6.nix new file mode 100644 index 0000000..693f774 --- /dev/null +++ b/common/nixos/sysctl/networking/ipv6.nix @@ -0,0 +1,56 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # disallow IPv6 packet forwarding + "net.ipv6.conf.default.forwarding" = 0; + "net.ipv6.conf.all.forwarding" = 0; + + # number of Router Solicitations to send until assuming no routers are present + "net.ipv6.conf.default.router_solicitations" = 0; + "net.ipv6.conf.all.router_solicitations" = 0; + + # do not accept Router Preference from RA + "net.ipv6.conf.default.accept_ra_rtr_pref" = 0; + "net.ipv6.conf.all.accept_ra_rtr_pref" = 0; + + # learn prefix information in router advertisement + "net.ipv6.conf.default.accept_ra_pinfo" = 0; + "net.ipv6.conf.all.accept_ra_pinfo" = 0; + + # setting controls whether the system will accept Hop Limit settings from a router advertisement + "net.ipv6.conf.default.accept_ra_defrtr" = 0; + "net.ipv6.conf.all.accept_ra_defrtr" = 0; + + # router advertisements can cause the system to assign a global unicast address to an interface + "net.ipv6.conf.default.autoconf" = 0; + "net.ipv6.conf.all.autoconf" = 0; + + # number of neighbor solicitations to send out per address + "net.ipv6.conf.default.dad_transmits" = 0; + "net.ipv6.conf.all.dad_transmits" = 0; + + # number of global unicast IPv6 addresses can be assigned to each interface + "net.ipv6.conf.default.max_addresses" = 1; + "net.ipv6.conf.all.max_addresses" = 1; + + # enable IPv6 Privacy Extensions (RFC30;41) and prefer the temporary address + #"net.ipv6.conf.default.use_tempaddr" = 2; # Nix sets by default + "net.ipv6.conf.all.use_tempaddr" = 2; + + # ignore IPv6 ICMP redirect messages + "net.ipv6.conf.default.accept_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + + # do not accept packets with SRR option + "net.ipv6.conf.default.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + + # ignore all ICMPv6 echo requests + #net.ipv6.icmp.echo_ignore_all = 1 + #net.ipv6.icmp.echo_ignore_anycast = 1 + #net.ipv6.icmp.echo_ignore_multicast = 1 + }; +} diff --git a/common/nixos/sysctl/networking/net.nix b/common/nixos/sysctl/networking/net.nix new file mode 100644 index 0000000..fe281dd --- /dev/null +++ b/common/nixos/sysctl/networking/net.nix @@ -0,0 +1,21 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # increase the maximum length of processor input queues + "net.core.netdev_max_backlog" = 250000; + + # enable BPF JIT hardening for all users + # this trades off performance, but can mitigate JIT spraying + "net.core.bpf_jit_harden" = 2; + + # increase TCP max buffer size setable using setsockopt() + "net.core.rmem_max" = 8388608; + "net.core.wmem_max" = 8388608; + "net.core.rmem_default" = 8388608; + "net.core.wmem_default" = 8388608; + #net.core.optmem_max = 40960 + }; +} diff --git a/common/nixos/sysctl/virtualization.nix b/common/nixos/sysctl/virtualization.nix new file mode 100644 index 0000000..073ca9b --- /dev/null +++ b/common/nixos/sysctl/virtualization.nix @@ -0,0 +1,18 @@ +{ + config, + pkgs, + ... +}: { + boot.kernel.sysctl = { + # do not allow mmap in lower addresses + "vm.mmap_min_addr" = 65536; + + # improve mmap ASLR effectiveness + "vm.mmap_rnd_bits" = 32; + "vm.mmap_rnd_compat_bits" = 16; + + # prevent unprivileged users from accessing userfaultfd + # restricts syscall to the privileged users or the CAP_SYS_PTRACE capability + "vm.unprivileged_userfaultfd" = 0; + }; +} diff --git a/hosts/candlekeep/configuration.nix b/hosts/candlekeep/configuration.nix index 039db28..24da624 100644 --- a/hosts/candlekeep/configuration.nix +++ b/hosts/candlekeep/configuration.nix @@ -15,7 +15,7 @@ # outputs.nixosModules.example ../../common/nixos/common.nix ../../common/nixos/laptop.nix - #../../common/networking/zerotier.nix + ../../common/networking/zerotier.nix ../../common/nixos/bluetooth.nix ../../common/nixos/restic.nix ../../common/nixos/ssh.nix @@ -26,10 +26,10 @@ ../../common/virtualization/podman.nix ../../common/virtualization/kubernetes.nix ../../common/virtualization/libvirt.nix + ../../common/nixos/sysctl/default.nix ./auditd.nix ./kernel.nix - ./sysctl.nix ./earlyoom.nix # Or modules from other flakes (such as nixos-hardware): diff --git a/hosts/candlekeep/sysctl.nix b/hosts/candlekeep/sysctl.nix deleted file mode 100644 index 33ed331..0000000 --- a/hosts/candlekeep/sysctl.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - config, - pkgs, - ... -}: { - boot.kernel.sysctl = { - # Restrict kernel pointers - "kernel.kptr_restrict" = 2; - - "kernel.dmesg_restrict" = 1; - - # Restrict eBPF - "kernel.unprivileged_bpf_disabled" = 1; - - # Harden JIT - "net.core.bpf_jit_harden" = 2; - - "dev.tty.ldisc_autoload" = 0; - "vm.unprivileged_userfaultfd" = 0; - - # Disable loading other kernels at runtime - "kernel.kexec_load_disabled" = 1; - - # Disable SysRq key for non-users (can be used in remote exploits) - "kernel.sysrq" = 4; - - "kernel.perf_event_paranoid" = 3; - "kernel.unprivileged_userns_clone" = 1; - - ## NETWORK - - # SYN flood attack prevention - "net.ipv4.tcp_syncookies" = 1; - - # Prevent IP spoofing - "net.ipv4.conf.all.rp_filter" = 1; - "net.ipv4.conf.default.rp_filter" = 1; - - # MITM attack prevention (disable redirect acceptance) - "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; - "net.ipv4.conf.all.send_redirects" = 0; - "net.ipv4.conf.default.send_redirects" = 0; - - # Clock fingerprinting prevention (disabled ICMP requests) - "net.ipv4.icmp_echo_ignore_all" = 1; - - # Restrict ptrace usage - "kernel.yama.ptrace_scope" = 2; - - # ASLR exploit mitigation - "vm.mmap_rnd_bits" = 32; - "vm.mmap_rnd_compat_bits" = 16; - - "fs.protected_fifos" = 2; - "fs.protected_regular" = 2; - }; -} diff --git a/hosts/grymforge/configuration.nix b/hosts/grymforge/configuration.nix index 694380e..974b72a 100644 --- a/hosts/grymforge/configuration.nix +++ b/hosts/grymforge/configuration.nix @@ -25,10 +25,10 @@ ../../common/virtualization/podman.nix ../../common/virtualization/kubernetes.nix ../../common/virtualization/libvirt.nix + ../../common/nixos/sysctl/default.nix ./auditd.nix ./kernel.nix - ./sysctl.nix ./earlyoom.nix # Or modules from other flakes (such as nixos-hardware): diff --git a/hosts/grymforge/sysctl.nix b/hosts/grymforge/sysctl.nix deleted file mode 100644 index 33ed331..0000000 --- a/hosts/grymforge/sysctl.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - config, - pkgs, - ... -}: { - boot.kernel.sysctl = { - # Restrict kernel pointers - "kernel.kptr_restrict" = 2; - - "kernel.dmesg_restrict" = 1; - - # Restrict eBPF - "kernel.unprivileged_bpf_disabled" = 1; - - # Harden JIT - "net.core.bpf_jit_harden" = 2; - - "dev.tty.ldisc_autoload" = 0; - "vm.unprivileged_userfaultfd" = 0; - - # Disable loading other kernels at runtime - "kernel.kexec_load_disabled" = 1; - - # Disable SysRq key for non-users (can be used in remote exploits) - "kernel.sysrq" = 4; - - "kernel.perf_event_paranoid" = 3; - "kernel.unprivileged_userns_clone" = 1; - - ## NETWORK - - # SYN flood attack prevention - "net.ipv4.tcp_syncookies" = 1; - - # Prevent IP spoofing - "net.ipv4.conf.all.rp_filter" = 1; - "net.ipv4.conf.default.rp_filter" = 1; - - # MITM attack prevention (disable redirect acceptance) - "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; - "net.ipv4.conf.all.send_redirects" = 0; - "net.ipv4.conf.default.send_redirects" = 0; - - # Clock fingerprinting prevention (disabled ICMP requests) - "net.ipv4.icmp_echo_ignore_all" = 1; - - # Restrict ptrace usage - "kernel.yama.ptrace_scope" = 2; - - # ASLR exploit mitigation - "vm.mmap_rnd_bits" = 32; - "vm.mmap_rnd_compat_bits" = 16; - - "fs.protected_fifos" = 2; - "fs.protected_regular" = 2; - }; -}