From 4319f5a3ccd4878c2f78a55d6803666885d8cfb2 Mon Sep 17 00:00:00 2001 From: Antoine Viallon Date: Fri, 21 Jan 2022 20:04:40 +0100 Subject: [PATCH] Massive refactoring in configurable modules --- boot.nix | 84 +++++++++++++++++++++++++++++++++++++++++ desktop.nix | 57 ++++++++++++++++++++++++++++ filesystems.nix | 65 ++++++++++++++++++++++++++++++++ general.nix | 92 +++++++++++++++++++++++++++++++++++++++++++++ hardening.nix | 61 ++++++++++++++++++++++++++++++ hardware.nix | 22 +++++++++++ hardware/amd.nix | 8 ++++ hardware/intel.nix | 8 ++++ hardware/nvidia.nix | 8 ++++ laptop.nix | 19 ++++++++++ network.nix | 38 +++++++++++++++++++ packages.nix | 75 ++++++++++++++++++++++++++++++++++++ programs/nano.nix | 17 +++++++++ services.nix | 49 ++++++++++++++++++++++++ 14 files changed, 603 insertions(+) create mode 100644 boot.nix create mode 100644 desktop.nix create mode 100644 filesystems.nix create mode 100644 general.nix create mode 100644 hardening.nix create mode 100644 hardware.nix create mode 100644 hardware/amd.nix create mode 100644 hardware/intel.nix create mode 100644 hardware/nvidia.nix create mode 100644 laptop.nix create mode 100644 network.nix create mode 100644 packages.nix create mode 100644 programs/nano.nix create mode 100644 services.nix diff --git a/boot.nix b/boot.nix new file mode 100644 index 0000000..648b5cf --- /dev/null +++ b/boot.nix @@ -0,0 +1,84 @@ +{ config, pkgs, lib, ... }: +with lib; +let + customKernelPatches = { + enableX32ABI = { + name = "enable-x32"; + patch = null; + extraConfig = '' + X86_X32 y + ''; + }; + grayskyUarches = { + name = "graysky-optimized-5.10"; + patch = pkgs.fetchpatch { + name = "graysky-optimized-5.10.patch"; + url = "https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/master/more-uarches-for-kernel-5.8-5.14.patch"; + #url = "https://raw.githubusercontent.com/graysky2/kernel_compiler_patch/master/more-uarches-for-kernel-5.15%2B.patch" + sha256 = "sha256:079f1gvgj7k1irj25k6bc1dgnihhmxvcwqwbgmvrdn14f7kh8qb3"; + }; + extraConfig = '' + MK10 y + ''; + }; + }; + cfg = config.aviallon.boot; +in +{ + + options.aviallon.boot = { + enable = mkOption { + description = "Enable default boot settings"; + default = true; + example = false; + type = lib.types.bool; + }; + useGrub = mkOption { + description = "Use Grub instead of systemd-boot"; + default = !cfg.efi; + example = cfg.efi; + type = types.bool; + }; + x32abi = { + enable = mkEnableOption "X32 kernel ABI"; + }; + efi = mkOption rec { + description = "Use EFI bootloader"; + default = builtins.pathExists "/sys/firmware/efi"; + example = !default; + type = types.bool; + }; + }; + + config = mkIf cfg.enable { + + hardware.enableAllFirmware = mkOverride 500 true; + + boot = { + initrd.kernelModules = [ ]; + initrd.availableKernelModules = [ "ehci_pci" ]; + + kernelParams = concatLists [ + (optional cfg.x32abi.enable "syscall.x32=y") + ]; + + kernelPatches = concatLists [ + (optional cfg.x32abi.enable customKernelPatches.enableX32ABI) + ]; + + loader.grub.enable = cfg.useGrub || (!cfg.efi); + loader.grub = { + version = 2; + device = (if cfg.efi then "nodev" else null); + efiSupport = true; + }; + + loader.systemd-boot.enable = cfg.efi && (!cfg.useGrub); + + loader = { + efi.efiSysMountPoint = mkDefault "/boot/efi"; + efi.canTouchEfiVariables = mkDefault true; + }; + }; + }; +} diff --git a/desktop.nix b/desktop.nix new file mode 100644 index 0000000..a6f98a4 --- /dev/null +++ b/desktop.nix @@ -0,0 +1,57 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.desktop; +in { + options.aviallon.desktop = { + enable = mkOption { + default = true; + example = false; + type = types.bool; + description = "Enable desktop related configuration"; + }; + layout = mkOption { + type = types.str; + default = "fr"; + example = "us"; + }; + }; + + config = mkIf cfg.enable { + + # Enable the X11 windowing system. + services.xserver.enable = true; + # Configure keymap in X11 + services.xserver.layout = cfg.layout; + services.xserver.xkbOptions = "eurosign:e"; + + + # Enable the Plasma 5 Desktop Environment. + services.xserver.displayManager.sddm.enable = true; + services.xserver.desktopManager.plasma5.enable = true; + + # Enable CUPS to print documents. + services.printing.enable = true; + + # Enable sound. + sound.enable = true; + # hardware.pulseaudio.enable = true; + + # Enable touchpad support (enabled default in most desktopManager). + services.xserver.libinput.enable = true; + + + environment.systemPackages = with pkgs; with libsForQt5; [ + firefox + konsole + kate + yakuake + ]; + + networking.networkmanager = { + packages = [ + pkgs.networkmanager-openvpn + ]; + }; + }; +} diff --git a/filesystems.nix b/filesystems.nix new file mode 100644 index 0000000..da83c07 --- /dev/null +++ b/filesystems.nix @@ -0,0 +1,65 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.filesystems; + ioSchedType = types.enum [ "bfq" "kyber" "mq-deadline" "none" null ]; +in +{ + options.aviallon.filesystems = { + enable = mkOption { + default = true; + example = false; + description = "Enable aviallon's filesystem tuning"; + type = types.bool; + }; + hddScheduler = mkOption { + default = "bfq"; + example = null; + description = "Automatically set HDDs IO queue algorithm"; + type = ioSchedType; + }; + slowFlashScheduler = mkOption { + default = "kyber"; + example = "none"; + description = "Automatically set flash storage IO queue algorithm"; + type = ioSchedType; + }; + nvmeScheduler = mkOption { + default = "none"; + example = "kyber"; + description = "Automatically set NVMe IO queue algorithm"; + type = ioSchedType; + }; + }; + + config = mkIf cfg.enable { + services.udev.extraRules = concatStringsSep "\n" ( + concatLists [ + (optional (!(builtins.isNull cfg.hddScheduler)) + ''ACTION=="add|change" SUBSYSTEM=="block", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}!="none", ATTR{queue/scheduler}="${cfg.hddScheduler}"'' + ) + (optional (!(builtins.isNull cfg.slowFlashScheduler)) + ''ACTION=="add|change" SUBSYSTEM=="block", KERNEL=="sd[a-z]*|nvme[0-9]*n[0-9]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="${cfg.slowFlashScheduler}"'' + ) + (optional (!(builtins.isNull cfg.nvmeScheduler)) + ''ACTION=="add|change" SUBSYSTEM=="block", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="${cfg.nvmeScheduler}"'' + ) + ] + ); + + services.smartd = { + enable = mkDefault true; + autodetect = true; + defaults.autodetected = "-a -o on -s (S/../.././02|L/../../7/04)"; + notifications.mail = { + enable = true; + sender = "admin@${config.networking.hostName}.local"; + recipient = "antoine@lesviallon.fr"; + }; + notifications.x11 = { + enable = true; + display = ":0"; + }; + }; + }; +} diff --git a/general.nix b/general.nix new file mode 100644 index 0000000..866d080 --- /dev/null +++ b/general.nix @@ -0,0 +1,92 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.general; +in +{ + options.aviallon.general = { + enable = mkOption { + default = true; + example = false; + description = "Enable aviallon's general tuning"; + type = types.bool; + }; + cpuArch = mkOption { + default = "x86-64"; + example = "x86-64-v2"; + description = "Set CPU arch used in overlays, ..."; + type = types.str; + }; + cpuTune = mkOption { + default = "generic"; + example = "sandybridge"; + description = "Set CPU tuning for compilers"; + type = types.str; + }; + unsafeOptimizations = mkEnableOption "unsafe system tuning"; + }; + + config = mkIf cfg.enable { + # Set your time zone. + time.timeZone = "Europe/Paris"; + + # Select internationalisation properties. + i18n = { + defaultLocale = "fr_FR.UTF-8"; + }; + + console = { + keyMap = "fr-pc"; + font = "Lat2-Terminus16"; + }; + + boot.kernelParams = concatLists [ + (optional cfg.unsafeOptimizations "mitigations=off") + ]; + + powerManagement.cpuFreqGovernor = mkDefault "schedutil"; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + programs.mtr.enable = true; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + nix.gc.automatic = mkDefault true; + nix.gc.randomizedDelaySec = "30min"; + nix.optimise.automatic = mkDefault true; + + nix.daemonIOSchedPriority = 5; + nix.daemonCPUSchedPolicy = "batch"; + nix.daemonIOSchedClass = "idle"; + + system.autoUpgrade.enable = mkDefault true; + system.autoUpgrade.allowReboot = mkOverride 500 true; + system.autoUpgrade.dates = "00:00"; + + + nixpkgs.localSystem.system = builtins.currentSystem; + nixpkgs.localSystem.platform = lib.systems.platforms.pc // { + gcc.arch = cfg.cpuArch; + gcc.tune = cfg.cpuTune; + }; + + nix.buildMachines = [ + { + hostName = "lesviallon.fr"; + system = "x86_64-linux"; + maxJobs = 2; + speedFactor = 4; + supportedFeatures = [ "kvm" "benchmark" "big-parallel" ]; + } + ]; + nix.distributedBuilds = mkDefault false; + + nix.extraOptions = '' + builders-use-substitutes = true + ''; + }; + +} diff --git a/hardening.nix b/hardening.nix new file mode 100644 index 0000000..e13d5e0 --- /dev/null +++ b/hardening.nix @@ -0,0 +1,61 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.hardening; + desktopCfg = config.aviallon.desktop; +in +{ + options.aviallon.hardening = { + enable = mkOption { + default = !desktopCfg.enable; # It usually conflicts with desktop use. + example = desktopCfg.enable; + description = "Enable aviallon's hardening"; + type = types.bool; + }; + }; + + config = mkIf cfg.enable { + # imports = [ + # (modulesPath + "/profiles/hardened.nix") + # ]; + boot.kernelPackages = pkgs.linuxPackages_hardened; + security.lockKernelModules = mkOverride 500 true; + security.protectKernelImage = mkOverride 500 false; # needed for kexec + + security.apparmor.enable = true; + services.dbus.apparmor = "enabled"; + + boot.kernelParams = [ + # Slab/slub sanity checks, redzoning, and poisoning + "slub_debug=FZP" + + # Overwrite free'd memory + "page_poison=1" + + # Enable page allocator randomization + "page_alloc.shuffle=1" + ]; + + boot.kernel.sysctl = { + "kernel.yama.ptrace_scope" = lib.mkOverride 500 1; + "kernel.kptr_restrict" = lib.mkOverride 500 2; + + "net.core.bpf_jit_enable" = lib.mkOverride 500 false; + + "kernel.ftrace_enabled" = lib.mkOverride 500 false; + }; + + security.allowUserNamespaces = mkDefault true; + boot.blacklistedKernelModules = mkForce [ ]; + + nix.allowedUsers = [ "@wheel" ]; + + security.audit.enable = true; + security.auditd.enable = true; + + security.audit.rules = [ + "-a exit,always -F arch=b64 -S execve" + ]; + # systemd.services.udisks2.confinement.enable = true; + }; +} diff --git a/hardware.nix b/hardware.nix new file mode 100644 index 0000000..a1030a6 --- /dev/null +++ b/hardware.nix @@ -0,0 +1,22 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.hardware; + desktopCfg = config.aviallon.desktop; +in +{ + options.aviallon.hardware = { + gpuVendor = mkOption { + default = null; + example = "amd"; + description = "Enable GPU vendor specific options"; + type = types.enum [ "amd" "nvidia" "intel" ]; + }; + }; + +# imports = [ +# (if (cfg.gpuVendor == "amd") then ./hardware/amd.nix else "") +# (if (cfg.gpuVendor == "nvidia") then ./hardware/nvidia.nix else "") +# (if (cfg.gpuVendor == "intel") then ./hardware/intel.nix else "") +# ]; +} diff --git a/hardware/amd.nix b/hardware/amd.nix new file mode 100644 index 0000000..35a20aa --- /dev/null +++ b/hardware/amd.nix @@ -0,0 +1,8 @@ +{ config, pkgs, lib, ... }: +with lib; +let + inherit (cfg); +in +{ + boot.initrd.kernelModules = [ "amdgpu" ]; +} diff --git a/hardware/intel.nix b/hardware/intel.nix new file mode 100644 index 0000000..ee644e2 --- /dev/null +++ b/hardware/intel.nix @@ -0,0 +1,8 @@ +{ config, pkgs, lib, ... }: +with lib; +#let +# inherit (cfg); +#in +{ + boot.initrd.kernelModules = [ "i915" ]; +} diff --git a/hardware/nvidia.nix b/hardware/nvidia.nix new file mode 100644 index 0000000..261f386 --- /dev/null +++ b/hardware/nvidia.nix @@ -0,0 +1,8 @@ +{ config, pkgs, lib, ... }: +with lib; +let + inherit (cfg); +in +{ + boot.initrd.kernelModules = [ "nouveau" ]; +} diff --git a/laptop.nix b/laptop.nix new file mode 100644 index 0000000..3ba8efe --- /dev/null +++ b/laptop.nix @@ -0,0 +1,19 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.laptop; +in { + options.aviallon.laptop = { + enable = mkOption { + default = false; + example = true; + type = types.bool; + description = "Enable aviallon's laptop configuration"; + }; + }; + + config = mkIf cfg.enable { + networking.networkmanager.wifi.powersave = true; + aviallon.general.unsafeOptimizations = mkOverride 50 true; + }; +} diff --git a/network.nix b/network.nix new file mode 100644 index 0000000..1f8bb94 --- /dev/null +++ b/network.nix @@ -0,0 +1,38 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.network; + desktopCfg = config.aviallon.desktop; +in +{ + options.aviallon.network = { + enable = mkOption { + default = true; + example = false; + description = "Enable aviallon's network tuning"; + type = types.bool; + }; + useNetworkManager = mkOption { + default = desktopCfg.enable; + example = !desktopCfg.enable; + description = "Enable NetworkManager"; + type = types.bool; + }; + }; + + config = mkIf cfg.enable { + networking.useNetworkd = mkOverride 500 true; + networking.networkmanager.enable = cfg.useNetworkManager; + networking.networkmanager.wifi.backend = "iwd"; + + networking.dhcpcd.enable = !config.networking.useNetworkd; + + # Must always be false + networking.useDHCP = false; + + networking.hostId = lib.mkDefault (builtins.abort "Default hostId not changed" null); + networking.hostName = lib.mkDefault (builtins.abort "Default hostname not changed" null); + + networking.firewall.allowPing = !desktopCfg.enable; + }; +} diff --git a/packages.nix b/packages.nix new file mode 100644 index 0000000..f35991e --- /dev/null +++ b/packages.nix @@ -0,0 +1,75 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.programs; + desktopCfg = config.aviallon.desktop; + generalCfg = config.aviallon.general; + + optimizeWithFlag = pkg: flag: + pkg.overrideAttrs (attrs: { + NIX_CFLAGS_COMPILE = (attrs.NIX_CFLAGS_COMPILE or "") + " ${flag}"; + doCheck = false; + }); + optimizeWithFlags = pkg: flags: pkgs.lib.foldl' (pkg: flag: optimizeWithFlag pkg flag) pkg flags; + optimizeForThisHost = pkg: optimizeWithFlags pkg (builtins.trace "${toString config.aviallon.programs.compileFlags}" config.aviallon.programs.compileFlags); +in +{ + imports = [ + ./programs/nano.nix + ]; + + options.aviallon.programs = { + enable = mkOption { + default = true; + example = false; + description = "Enable aviallon's programs"; + type = types.bool; + }; + compileFlags = mkOption { + default = [ "-O3" "-march=${generalCfg.cpuArch}" "-mtune=${generalCfg.cpuTune}" ]; + example = [ "-O2" "-mavx" ]; + description = "Add specific compile flags"; + type = types.listOf types.str; + }; + }; + + config = mkIf cfg.enable { + nixpkgs.config.packageOverrides = pkgs: + let + optimizePackage = optimizeForThisHost pkgs; + in { + nano = optimizeForThisHost pkgs.nano; + rsyncOptimized = optimizeForThisHost pkgs.rsync; + + opensshOptimized = optimizeForThisHost pkgs.openssh; + + nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; + }; + + nixpkgs.config.allowUnfree = true; + + environment.systemPackages = with pkgs; with libsForQt5; [ + vim + wget + nano + opensshOptimized + rsyncOptimized + htop + ]; + + programs.ssh.package = pkgs.opensshOptimized; + + programs.ccache.enable = true; + programs.ccache.packageNames = [ + # config.boot.kernelPackages.kernel + # "opensshOptimized" + # "rsyncOptimized" + ]; + nix.sandboxPaths = [ + (toString config.programs.ccache.cacheDir) + ]; + + }; +} diff --git a/programs/nano.nix b/programs/nano.nix new file mode 100644 index 0000000..0df3dd7 --- /dev/null +++ b/programs/nano.nix @@ -0,0 +1,17 @@ +{config, pkgs, ...}: +{ + environment.systemPackages = [ pkgs.nanorc ]; + programs.nano.syntaxHighlight = false; + programs.nano.nanorc = '' + set tabstospaces + set tabsize 2 + set nowrap + set smarthome + set positionlog + + include "${pkgs.nano}/share/nano/*.nanorc" + include "${pkgs.nanorc}/share/*.nanorc" + + extendsyntax Makefile tabgives " " + ''; +} diff --git a/services.nix b/services.nix new file mode 100644 index 0000000..1f5a8fa --- /dev/null +++ b/services.nix @@ -0,0 +1,49 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.aviallon.services; + desktopCfg = config.aviallon.desktop; +in { + options.aviallon.services = { + enable = mkOption { + default = true; + example = false; + type = types.bool; + description = "Enable aviallon's services configuration"; + }; + }; + + config = mkIf cfg.enable { + # Enable the OpenSSH daemon. + services.openssh.enable = true; + # services.openssh.permitRootLogin = "prohibit-password"; + services.openssh.permitRootLogin = "yes"; + networking.firewall.allowedTCPPorts = [ 22 ]; + networking.firewall.allowedUDPPorts = [ 22 ]; + + services.rsyncd.enable = !desktopCfg.enable; + + services.fstrim.enable = true; + + services.haveged.enable = (builtins.compareVersions config.boot.kernelPackages.kernel.version "5.6" < 0); + + services.irqbalance.enable = true; + + services.printing.enable = desktopCfg.enable; + + services.ananicy.enable = false; + services.ananicy.package = pkgs.ananicy-cpp; + services.ananicy.settings = { + loglevel = "info"; + cgroup_realtime_workaround = false; + }; + services.ananicy.extraRules = '' + {"name": "cp", "type": "BG_CPUIO"} + ''; + + services.avahi.enable = true; # .lan/.local resolution + services.avahi.nssmdns = true; # .lan/.local resolution + services.avahi.publish.enable = true; + services.avahi.publish.hinfo = true; # Whether to register a mDNS HINFO record which contains information about the local operating system and CPU. + }; +}