Compare commits
No commits in common. "2d8a53db8291beacddfd734c4b70269a86883dd0" and "12221697d20ce3a0994c34b57dafa6da706d0735" have entirely different histories.
2d8a53db82
...
12221697d2
8 changed files with 23 additions and 433 deletions
|
@ -8,7 +8,6 @@
|
||||||
./../../meta/profiles/vm.nix
|
./../../meta/profiles/vm.nix
|
||||||
];
|
];
|
||||||
lyn.sops.secrets."hosts/forgejo-ci/forgejo_ci_token" = {};
|
lyn.sops.secrets."hosts/forgejo-ci/forgejo_ci_token" = {};
|
||||||
lyn.kernel = enable ["latest" "hardened"];
|
|
||||||
# Use UEFI
|
# Use UEFI
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
|
||||||
|
|
|
@ -1,302 +0,0 @@
|
||||||
{lib, pkgs, config, ...}: let
|
|
||||||
ifApparmor = config.l.kernel.lsm.apparmor.enable;
|
|
||||||
in config.l.lib.mkLocalModule ./hardened.nix "custom hardened linux kernel" {
|
|
||||||
boot.kernelPackages = let
|
|
||||||
kernel = pkgs.linux-libre;
|
|
||||||
llvm = pkgs.llvmPackages_latest;
|
|
||||||
|
|
||||||
version = pkgs.kernelPatches.hardened${kernel.meta.branch}.version;
|
|
||||||
major = lib.versions.major version;
|
|
||||||
|
|
||||||
sha256 = pkgs.kernelPatches.hardened.${kernel.meta.branch}.sha256;
|
|
||||||
modDirVer = lib.replaceStrings
|
|
||||||
[ kernel.version ]
|
|
||||||
[ version ]
|
|
||||||
kernel.modDirVersion;
|
|
||||||
in lib.mkDefault (pkgs.linuxPackagesFor (kernel.override {
|
|
||||||
stdenv = llvm.stdenv;
|
|
||||||
extraMakeFlags = [ "LLVM=${llvm.bintools-unwrapped}/bin/" ];
|
|
||||||
kernelPatches = kernel.kernelPatches
|
|
||||||
++ [ pkgs.kernelPatches.hardened.${kernel.meta.branch} ];
|
|
||||||
modDirVersionArg =
|
|
||||||
modDirVer +
|
|
||||||
(pkgs.kernelPatches.hardened.${kernel.meta.branch}).extra;
|
|
||||||
isHardened = true;
|
|
||||||
argsOverride = {
|
|
||||||
inherit version;
|
|
||||||
src = pkgs.fetchurl {
|
|
||||||
url =
|
|
||||||
"mirror://kernel/linux/kernel/v${major}.x/linux-${version}.tar.xz";
|
|
||||||
inherit sha256;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
structuredExtraConfig = with lib.kernel; {
|
|
||||||
# report BUG() conditions and kill the offending process
|
|
||||||
BUG = yes;
|
|
||||||
|
|
||||||
# safer page access permissions to prevent code injection
|
|
||||||
DEBUG_RODATA = yes;
|
|
||||||
SET_MODULE_RONX = yes;
|
|
||||||
|
|
||||||
# validation of commonly targeted structures
|
|
||||||
DEBUG_CREDENTIALS = yes;
|
|
||||||
DEBUG_NOTIFIERS = yes;
|
|
||||||
DEBUG_PLIST = yes;
|
|
||||||
DEBUG_SG = yes;
|
|
||||||
SCHED_STACK_END_CHECK = yes;
|
|
||||||
|
|
||||||
# randomize page allocator when page_alloc.shuffle=1
|
|
||||||
SHUFFLE_PAGE_ALLOCATOR = yes;
|
|
||||||
|
|
||||||
# allow enabling slub/slab free poisoning with slub_debug=P
|
|
||||||
SLUB_DEBUG = yes;
|
|
||||||
|
|
||||||
# wipe higher-level memory allocations on free() with page_poison=1
|
|
||||||
PAGE_POISONING = yes;
|
|
||||||
PAGE_POISONING_NO_SANITY = yes;
|
|
||||||
PAGE_POISONING_ZERO = yes;
|
|
||||||
|
|
||||||
|
|
||||||
# reboot devices immediately when the kernel panics
|
|
||||||
PANIC_TIMEOUT = freeform "-1";
|
|
||||||
|
|
||||||
|
|
||||||
## GCC options (i use LLVM btw) ##
|
|
||||||
|
|
||||||
# GCC_PLUGINS = yes; # Enable gcc plugin options
|
|
||||||
# Gather additional entropy at boot time for systems that may not
|
|
||||||
# have appropriate entropy sources.
|
|
||||||
# GCC_PLUGIN_LATENT_ENTROPY = yes;
|
|
||||||
# GCC_PLUGIN_STRUCTLEAK = yes; # A port of the PaX structleak plugin
|
|
||||||
# GCC_PLUGIN_STRUCTLEAK_BYREF_ALL = yes; # also cover structs passed by address
|
|
||||||
# GCC_PLUGIN_STACKLEAK = yes; # A port of the PaX stackleak plugin
|
|
||||||
# GCC_PLUGIN_RANDSTRUCT = yes; # A port of the PaX randstruct plugin
|
|
||||||
# GCC_PLUGIN_RANDSTRUCT_PERFORMANCE = yes;
|
|
||||||
|
|
||||||
# enable link-time optimisation
|
|
||||||
LTO_CLANG_THIN = yes;
|
|
||||||
|
|
||||||
# clear memory at reboot via EFI
|
|
||||||
# https://trustedcomputinggroup.org/resource/pc-client-work-group-platform-reset-attack-mitigation-specification/
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1532058
|
|
||||||
RESET_ATTACK_MITIGATION = yes;
|
|
||||||
|
|
||||||
# kernel memory permission enforcement
|
|
||||||
STRICT_KERNEL_RWX = yes;
|
|
||||||
STRICT_MODULE_RWX = yes;
|
|
||||||
VMAP_STACK = yes;
|
|
||||||
|
|
||||||
# kernel image and memory ASLR
|
|
||||||
RANDOMIZE_BASE = yes;
|
|
||||||
RANDOMIZE_MEMORY = yes;
|
|
||||||
|
|
||||||
# randomize allocator freelists, harden metadata
|
|
||||||
SLAB_FREELIST_RANDOM = yes;
|
|
||||||
SLAB_FREELIST_HARDENED = yes;
|
|
||||||
SHUFFLE_PAGE_ALLOCATOR = yes;
|
|
||||||
RANDOM_KMALLOC_CACHES = yes;
|
|
||||||
|
|
||||||
# sanity check userspace page table mappings
|
|
||||||
PAGE_TABLE_CHECK = yes;
|
|
||||||
PAGE_TABLE_CHECK_ENFORCED = yes;
|
|
||||||
|
|
||||||
# randomize kernel stack offset on syscall entry
|
|
||||||
RANDOMIZE_KSTACK_OFFSET_DEFAULT = yes;
|
|
||||||
|
|
||||||
# stack frame overflow protection
|
|
||||||
STACKPROTECTOR = yes;
|
|
||||||
STACKPROTECTOR_STRONG = yes;
|
|
||||||
|
|
||||||
# buffer length bounds checking
|
|
||||||
HARDENED_USERCOPY = yes;
|
|
||||||
FORTIFY_SOURCE = yes;
|
|
||||||
|
|
||||||
# array index bounds checking
|
|
||||||
UBSAN = yes;
|
|
||||||
UBSAN_TRAP = yes;
|
|
||||||
UBSAN_BOUNDS = yes;
|
|
||||||
UBSAN_ALIGNMENT = yes;
|
|
||||||
## unaligned memory access is bad and evil!!
|
|
||||||
## sanitizing this will cause lots of reports and warnings though
|
|
||||||
## it works on x86 though i think
|
|
||||||
UBSAN_SHIFT = unset;
|
|
||||||
UBSAN_DIV_ZERO = unset;
|
|
||||||
UBSAN_UNREACHABLE = unset;
|
|
||||||
UBSAN_SIGNED_WRAP = unset;
|
|
||||||
UBSAN_BOOL = unset;
|
|
||||||
UBSAN_ENUM = unset;
|
|
||||||
|
|
||||||
# sampling-based heap out-of-bounds and user-after-free detection
|
|
||||||
KFENCE = yes;
|
|
||||||
|
|
||||||
# linked list integrity checking
|
|
||||||
LIST_HARDENED = yes;
|
|
||||||
|
|
||||||
# zero-initialise heap variables on allocation
|
|
||||||
INIT_ON_ALLOC_DEFAULT =yes;
|
|
||||||
|
|
||||||
# zero-initialise stack variables on function entry
|
|
||||||
INIT_STACK_ALL_ZERO = yes;
|
|
||||||
|
|
||||||
# disable DMA between EFI hand-off and the kernel's IOMMU setup
|
|
||||||
EFI_DISABLE_PCI_DMA = yes;
|
|
||||||
|
|
||||||
# force IOMMU TLB invalidation so devices will never be able to
|
|
||||||
# access stale data content
|
|
||||||
IOMMU_SUPPORT = yes;
|
|
||||||
IOMMU_DEFAULT_DMA_STRICT = yes;
|
|
||||||
|
|
||||||
# do not allow direct physical memory access to non-device memory
|
|
||||||
STRICT_DEVMEM = option no; # depends on DEVMEM
|
|
||||||
IO_STRICT_DEVMEM = option no; # depends on DEVMEM
|
|
||||||
|
|
||||||
# provide userspace with seccomp BPF API
|
|
||||||
# for syscall attack surface reduction
|
|
||||||
SECCOMP = yes;
|
|
||||||
SECCOMP_FILTER = yes;
|
|
||||||
|
|
||||||
# provides some protections against SYN flooding
|
|
||||||
SYN_COOKIES = yes;
|
|
||||||
|
|
||||||
# enable kernel control flow integrity (currently Clang only)
|
|
||||||
CFI_CLANG = yes;
|
|
||||||
# CFI_PERMISSIVE
|
|
||||||
|
|
||||||
# attack surface reduction; do not autoload TTY line disciplines
|
|
||||||
LDISC_AUTOLOAD = no;
|
|
||||||
|
|
||||||
# dangerous; enabling this disables userpace brk ASLR
|
|
||||||
COMPAT_BRK = no;
|
|
||||||
|
|
||||||
# dangerous; exposes kernel text image layout
|
|
||||||
PROC_KCORE = no;
|
|
||||||
|
|
||||||
# dangerous; enabling this disables userspace VDSO ASLR
|
|
||||||
COMPAT_VDSO = no;
|
|
||||||
|
|
||||||
# attack surface reduction: use modern PTY interface (devpts) only
|
|
||||||
LEGACY_PTYS = no;
|
|
||||||
|
|
||||||
# dangerous; allows writing directly to physical memory
|
|
||||||
ACPI_CUSTOM_METHOD = no;
|
|
||||||
|
|
||||||
# attack surface reduction; has been used for heap based attacks
|
|
||||||
INET_DIAG = no;
|
|
||||||
|
|
||||||
# Security modules
|
|
||||||
SECURITY_SELINUX = yes;
|
|
||||||
SECURITY_APPARMOR = yes;
|
|
||||||
SECURITY_SAFESETID = yes;
|
|
||||||
DEFAULT_SECURITY_APPARMOR = lib.mkIf ifApparmor yes;
|
|
||||||
DEFAULT_SECURITY = lib.mkIf ifApparmor (freeform "apparmor");
|
|
||||||
SECURITY_APPARMOR_BOOTPARAM_VALUE = lib.mkIf ifApparmor (freeform "1";)
|
|
||||||
|
|
||||||
# mark LSM hooks read-only after init
|
|
||||||
SECURITY_WRITABLE_HOOKS = no;
|
|
||||||
|
|
||||||
# enable BPF; may expose kernel to spray attacks though
|
|
||||||
BPF_JIT_ALWAYS_ON = yes;
|
|
||||||
|
|
||||||
# Replace menu governour with TEO
|
|
||||||
CPU_IDLE_GOV_MENU = no;
|
|
||||||
CPU_IDLE_GOV_TEO = yes;
|
|
||||||
} // lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 {
|
|
||||||
X86_EXTENDED_PLATFORM = no;
|
|
||||||
|
|
||||||
# don't sanitize unaligned memory access resulting in
|
|
||||||
# undefined behavior because x86 supports unalligned access
|
|
||||||
UBSAN_ALIGNMENT = no;
|
|
||||||
|
|
||||||
# enable chip-specific IOMMU support
|
|
||||||
INTEL_IOMMU = yes;
|
|
||||||
INTEL_IOMMU_DEFAULT_ON = yes;
|
|
||||||
INTEL_IOMMU_SVM = yes;
|
|
||||||
AMD_IOMMU = yes;
|
|
||||||
|
|
||||||
# enforce CET Indirect Branch Tracking in the kernel
|
|
||||||
X86_KERNEL_IBT = yes;
|
|
||||||
|
|
||||||
# enable CET shadow stack for userspace
|
|
||||||
X86_USER_SHADOW_STACK = yes;
|
|
||||||
|
|
||||||
# disable legacy x86 interfaces
|
|
||||||
STRICT_SIGALTSTACK_SIZE = yes;
|
|
||||||
LEGACY_VSYSCALL_XONLY = no;
|
|
||||||
|
|
||||||
# modern libc no longer needs a fixed-position mapping in userspace,
|
|
||||||
# remove it as a possible target
|
|
||||||
LEGACY_VSYSCALL_NONE = yes;
|
|
||||||
|
|
||||||
# disable IO delay
|
|
||||||
IO_DELAY_NONE = yes;
|
|
||||||
};
|
|
||||||
}))
|
|
||||||
boot.kernelParams = [
|
|
||||||
# set apparmor as the default security module
|
|
||||||
(lib.mkIf ifApparmor "security=apparmor")
|
|
||||||
|
|
||||||
# zero-fill page and slab allocations
|
|
||||||
"init_on_free=1"
|
|
||||||
|
|
||||||
# disable IO delay
|
|
||||||
"io_delay=none"
|
|
||||||
|
|
||||||
# enable page allocator free list randomization
|
|
||||||
"page_alloc.shuffle=1"
|
|
||||||
|
|
||||||
# overwrite free()'d pages
|
|
||||||
"page_poison=1"
|
|
||||||
|
|
||||||
# disable slab merging
|
|
||||||
"slab_nomerge"
|
|
||||||
|
|
||||||
# disable vsyscall mechanism
|
|
||||||
"vsyscall=none"
|
|
||||||
|
|
||||||
# enable transparent hugepages
|
|
||||||
"transparent_hugepage=always"
|
|
||||||
|
|
||||||
# disable debugfs
|
|
||||||
"debugfs=off"
|
|
||||||
|
|
||||||
# clear mlocked memory in case the program crashes
|
|
||||||
"init_mlocked_on_free=1"
|
|
||||||
];
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
# disable automatic loading of TTY line disciplines
|
|
||||||
"dev.tty.ldisc_autoload" = 0;
|
|
||||||
|
|
||||||
"kernel.ftrace_enabled" = lib.mkDefault false;
|
|
||||||
|
|
||||||
# disable first 64 KiB of virtual memory for allocation
|
|
||||||
"vm.mmap_min_addr" = 65536;
|
|
||||||
|
|
||||||
# increase ASLR randomisation
|
|
||||||
"vm.mmap_rnd_bits" = 32;
|
|
||||||
"vm.mmap_rnd_compat_bits" = 16;
|
|
||||||
|
|
||||||
# restrict ptrace()
|
|
||||||
"kernel.yama.ptrace_scope" = 1;
|
|
||||||
|
|
||||||
# hide kernel memory addresses
|
|
||||||
"kernel.kptr_restrict" = 2;
|
|
||||||
|
|
||||||
# enable hardened eBPF JIT
|
|
||||||
"net.core.bpf_jit_enable" = 1;
|
|
||||||
"net.core.bpf_jit_harden" = 1;
|
|
||||||
|
|
||||||
# Dirty page cache ratio
|
|
||||||
"vm.dirty_background_ratio" = 3;
|
|
||||||
"vm.dirty_ratio" = 6;
|
|
||||||
|
|
||||||
# Hide kptrs even for processes with CAP_SYSLOG
|
|
||||||
"kernel.kptr_restrict" = lib.mkOverride 500 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
# references:
|
|
||||||
# - https://github.com/NixOS/nixpkgs/blob/e6db435973160591fe7348876a5567c729495175/pkgs/os-specific/linux/kernel/hardened/config.nix
|
|
||||||
# - https://nixos.wiki/wiki/Linux_kernel#Custom_configuration
|
|
||||||
# - https://kspp.github.io/
|
|
||||||
# - linux src/arch/x86/configs/hardening.config and src/kernel/configs/hardening.config
|
|
||||||
# - trial and error
|
|
||||||
# - illdef
|
|
|
@ -1,3 +0,0 @@
|
||||||
{lib, config, pkgs, ...}: config.lyn.lib.mkLocalModule ./latest.nix "latest linux kernel" {
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
|
||||||
}
|
|
|
@ -1,71 +1,23 @@
|
||||||
{lib, ...}: { config.lyn.lib = rec {
|
{lib, config, ...}: {
|
||||||
/**
|
lib.mkLocalModule = pathInterpolation: optDesc: config: let
|
||||||
Split a string, and return all elements after a marker.
|
#example_input = ./some/subdir/MARKER/a/b/c/d/e/f/g;
|
||||||
|
marker = "local-modules";
|
||||||
# Example
|
splitAfterMarker = marker: input: builtins.foldl' (acc: new:
|
||||||
|
if acc == false then # marker not found yet
|
||||||
```
|
if new == marker then [] else acc
|
||||||
splitAfterMarker "/" "modules" /home/user/flake/modules/abc/def
|
else # marker found
|
||||||
== ["abc" "def"]
|
if builtins.typeOf new == "string"
|
||||||
```
|
then acc ++ [new]
|
||||||
*/
|
else acc
|
||||||
splitAfterMarker = splitter: marker: input: builtins.foldl' (acc: new:
|
) false (builtins.split "/" (builtins.toString input));
|
||||||
if acc == false then # marker not found yet
|
path = splitAfterMarker marker pathInterpolation;
|
||||||
if new == marker then [] /* marker found */ else false
|
inputs = {
|
||||||
else acc ++ [new] # marker already found, add to output list
|
#optDesc = "enable this";
|
||||||
) false (lib.splitString splitter input);
|
inherit optDesc: config;
|
||||||
/**
|
};
|
||||||
Make a Nix module, with its attrpath being the local path
|
mod = {config, ...}: {
|
||||||
relative to a marker directory. Accepts a prefix, and removes `.nix` file endings.
|
options = lib.setAttrsByPath path (lib.mkEnableOption inputs.optDesc);
|
||||||
|
config = lib.mkIf (lib.getAttrByPath path config) inputs.config;
|
||||||
# Example
|
};
|
||||||
|
in mod;
|
||||||
```
|
}
|
||||||
mkLocalModuleMarker "modules" ["myModules" "abc"] ./current-file.nix "enable something" {}
|
|
||||||
{ myModules.abc.current.file.path.current-file.enable = true; }
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
mkLocalModuleMarker = marker: prefix: currentPath: optDesc: moduleConfig: let
|
|
||||||
normalizedPath = removeSuffix ".nix" (builtins.toString currentPath);
|
|
||||||
attrPath = prefix ++ (splitAfterMarker "/" marker normalizedPath);
|
|
||||||
mod = {config, ...}: {
|
|
||||||
options = lib.setAttrsByPath attrPath (lib.mkEnableOption optDesc);
|
|
||||||
config = lib.mkIf (lib.getAttrByPath attrPath config) moduleConfig;
|
|
||||||
};
|
|
||||||
in mod;
|
|
||||||
/**
|
|
||||||
Find a folder or a parent folder containing a file.
|
|
||||||
|
|
||||||
# Example
|
|
||||||
|
|
||||||
```
|
|
||||||
findFolderWithFile "flake.nix" ./.
|
|
||||||
== /home/user/flake/
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
findFolderWithFile = file: arg:
|
|
||||||
if builtins.pathExists (arg + "/" + file) then arg
|
|
||||||
else if arg == /. then throw "could not find folder containing ${file}"
|
|
||||||
else findRoot file (arg + "/..");
|
|
||||||
/**
|
|
||||||
Shorthand for mkLocalModuleMarker, setting marker to your flake and prefix to l.
|
|
||||||
*/
|
|
||||||
mkLocalModule = path: mkLocalModuleMarker (findFolderWithFile "flake.nix" path) ["lyn"] path;
|
|
||||||
};}
|
|
||||||
|
|
||||||
# foldl' op nul [x0 x1 x2 ...] = op (op (op nul x0) x1) x2) .... For example, foldl' (x: y: x + y) 0 [1 2 3]
|
|
||||||
|
|
||||||
|
|
||||||
# input = /home/alina/flake/desktop/common
|
|
||||||
# options.desktop.common
|
|
||||||
# input' = /nix/store/aaa-flake/desktop/common
|
|
||||||
# foldl' (split "/" input)
|
|
||||||
# marker = flake
|
|
||||||
# foldl' ([home alina flake modules audio.nix ])
|
|
||||||
# acc = false false [] [modules] [modules audio.nix]
|
|
||||||
# | ^ marker found
|
|
||||||
# | marker not found yet
|
|
||||||
|
|
||||||
|
|
||||||
# $ echo "abc\ndef" > readme
|
|
||||||
# readPathsFromFile "readme" == [./abc ./def]
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
{lib, config, pkgs, ...}: {
|
|
||||||
users.users.lyn.packages = with pkgs; [
|
|
||||||
p7zip
|
|
||||||
zstd
|
|
||||||
unzip
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
{lib, config, pkgs, ...}: {
|
|
||||||
users.users.lyn.packages = with pkgs; [
|
|
||||||
pinentry
|
|
||||||
gnupg
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{lib, config, pkgs, ...}: {
|
|
||||||
users.users.lyn.packages = with pkgs; [
|
|
||||||
magic-wormhole-rs
|
|
||||||
inetutils
|
|
||||||
tcpdump
|
|
||||||
tor
|
|
||||||
wireguard-tools
|
|
||||||
openvpn
|
|
||||||
nmap
|
|
||||||
netcat
|
|
||||||
sabnzbd
|
|
||||||
sshfs
|
|
||||||
subfinder
|
|
||||||
tshark
|
|
||||||
dnsutils
|
|
||||||
yt-dlp
|
|
||||||
yggdrasil
|
|
||||||
traceroute
|
|
||||||
wget
|
|
||||||
curl
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
{lib, config, pkgs, ...}: {
|
|
||||||
users.users.lyn.packages = with pkgs; [
|
|
||||||
checksec
|
|
||||||
mitmproxy
|
|
||||||
mitmproxy2swagger
|
|
||||||
websploit
|
|
||||||
bettercap
|
|
||||||
cantoolz
|
|
||||||
ssh-mitm
|
|
||||||
jadx
|
|
||||||
frida-tools
|
|
||||||
apktool
|
|
||||||
thc-hydra
|
|
||||||
john
|
|
||||||
metasploit
|
|
||||||
sherlock
|
|
||||||
radare2
|
|
||||||
subfinder
|
|
||||||
seclists
|
|
||||||
];
|
|
||||||
}
|
|
Loading…
Reference in a new issue