diff options
author | Linnnus <[email protected]> | 2024-12-21 15:47:33 +0100 |
---|---|---|
committer | Linnnus <[email protected]> | 2024-12-21 16:19:04 +0100 |
commit | 8353554315564b89dfe27d5130080ed04a0a65ad (patch) | |
tree | 896de88b6ea2701692b3ffe977c23947a786318e /shared/nixos | |
parent | 9b7ed17b27157a25e57a6e38be3bcfeaa70ec9e8 (diff) |
Move to a profile-based configuration where common
This patch makes it so common configuration is now located in shared/
and each host basically just becomes a bunch of import statements.
The exception here is host-specific configuration like the `*.linus.onl`
that live inside `hosts/ahmed/`.
Specifically I have:
- moved common configuration `shared/{nixos,home-manager,nix-darwin}`.
- moved `hosts/common.nix` to `shared/nixos/common-{nix,shell}-settings.nix`.
- split `hosts/muhammed/{dev-utils,neovim}` into per-language
configuration.
This patch was done in preparation for the arrival of a new host, which
will need to share a lot of configuration with Muhammed.
Diffstat (limited to 'shared/nixos')
-rw-r--r-- | shared/nixos/cloudflare-proxy/default.nix | 88 | ||||
-rw-r--r-- | shared/nixos/common-hm-settings/default.nix | 27 | ||||
-rw-r--r-- | shared/nixos/common-nix-settings/default.nix | 60 | ||||
-rw-r--r-- | shared/nixos/common-shell-settings/default.nix | 44 |
4 files changed, 219 insertions, 0 deletions
diff --git a/shared/nixos/cloudflare-proxy/default.nix b/shared/nixos/cloudflare-proxy/default.nix new file mode 100644 index 0000000..45ccaa6 --- /dev/null +++ b/shared/nixos/cloudflare-proxy/default.nix @@ -0,0 +1,88 @@ +# This module adds some extra configuration useful when running behid a Cloudflare Proxy. +# Mainly, it blocks all incomming conncections on relevant ports that aren't +# coming from an official CloudFlare domain. +{ + config, + lib, + pkgs, + metadata, + ... +}: let + # TODO: What happens when these get out of date??? Huh??? You little pissbaby + fileToList = x: lib.strings.splitString "\n" (builtins.readFile x); + cfipv4 = fileToList (pkgs.fetchurl { + url = "https://www.cloudflare.com/ips-v4"; + hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns="; + }); + cfipv6 = fileToList (pkgs.fetchurl { + url = "https://www.cloudflare.com/ips-v6"; + hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk="; + }); + + IPv4Whitelist = [metadata.hosts.muhammed.ipAddress]; + IPv6Whitelist = []; +in { + config = { + # Teach NGINX how to extract the proxied IP from proxied requests. + # + # See: https://nixos.wiki/wiki/Nginx#Using_realIP_when_behind_CloudFlare_or_other_CDN + services.nginx.commonHttpConfig = let + realIpsFromList = lib.strings.concatMapStringsSep "\n" (x: "set_real_ip_from ${x};"); + in '' + ${realIpsFromList cfipv4} + ${realIpsFromList cfipv6} + real_ip_header CF-Connecting-IP; + ''; + + # Block non-Cloudflare IP addresses. + networking.firewall = let + chain = "cloudflare-whitelist"; + in { + extraCommands = let + allow-interface = lib.strings.concatMapStringsSep "\n" (i: ''ip46tables --append ${chain} --in-interface ${i} --jump RETURN''); + allow-ip = cmd: lib.strings.concatMapStringsSep "\n" (r: ''${cmd} --append ${chain} --source ${r} --jump RETURN''); + in '' + # Flush the old firewall rules. This behavior mirrors the default firewall service. + # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L59-L66 + ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} 2>/dev/null || true + ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} 2>/dev/null || true + ip46tables --flush ${chain} || true + ip46tables --delete-chain ${chain} || true + + # Create a chain that only allows whitelisted IPs through. + ip46tables --new-chain ${chain} + + # Allow trusted interfaces through. + ${allow-interface config.networking.firewall.trustedInterfaces} + + # Allow local whitelisted IPs through + ${allow-ip "iptables" IPv4Whitelist} + ${allow-ip "ip6tables" IPv6Whitelist} + + # Allow Cloudflare's IP ranges through. + ${allow-ip "iptables" cfipv4} + ${allow-ip "ip6tables" cfipv6} + + # Everything else is dropped. + # + # TODO: I would like to use `nixos-fw-log-refuse` here, but I keep + # running into weird issues when reloading the firewall. + # Something about the table not being deleted properly. + ip46tables --append ${chain} --jump DROP + + # Inject our chain as the first check in INPUT (before nixos-fw). + # We want to capture any new incomming TCP connections. + ip46tables --insert INPUT 1 --protocol tcp --destination-port 80 --syn --jump ${chain} + ip46tables --insert INPUT 1 --protocol tcp --destination-port 443 --syn --jump ${chain} + ''; + extraStopCommands = '' + # Clean up added rulesets (${chain}). This mirrors the behavior of the + # default firewall at the time of writing. + # + # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L218-L219 + ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} 2>/dev/null || true + ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} 2>/dev/null || true + ''; + }; + }; +} diff --git a/shared/nixos/common-hm-settings/default.nix b/shared/nixos/common-hm-settings/default.nix new file mode 100644 index 0000000..9262f51 --- /dev/null +++ b/shared/nixos/common-hm-settings/default.nix @@ -0,0 +1,27 @@ +# This module sets common settings related to home-manager (HM). All hosts that +# I directly interact with should include this module. +# +# NOTE: Even though this lives under `shared/nixos` the configuration in here +# should also be compatible with nix-darwin!! +{ + flakeInputs, + flakeOutputs, + metadata, + ... +}: { + # FIXME: Ideally this module would import flakeInputs.home-manager but that causes an infinite recursion for some reason. + + # Use the flake input pkgs so Home Manager configuration can share overlays + # etc. with the rest of the configuration. + home-manager.useGlobalPkgs = true; + + # Pass special arguments from flake.nix further down the chain. I really hate + # this split module system. + home-manager.extraSpecialArgs = {inherit flakeInputs flakeOutputs metadata;}; + + # All interactive systems (i.e. the ones that would use HM) have a 'linus' user. + home-manager.users.linus = { + imports = builtins.attrValues flakeOutputs.homeModules; + xdg.enable = true; + }; +} diff --git a/shared/nixos/common-nix-settings/default.nix b/shared/nixos/common-nix-settings/default.nix new file mode 100644 index 0000000..b5c0a02 --- /dev/null +++ b/shared/nixos/common-nix-settings/default.nix @@ -0,0 +1,60 @@ +# This module sets common settings related to Nix such as enabling flakes and +# using overlays everywhere.. +# +# NOTE: Even though this lives under `shared/nixos` the configuration in here +# should also be compatible with nix-darwin!! +{ + pkgs, + lib, + config, + flakeInputs, + flakeOutputs, + ... +}: +lib.mkMerge [ + { + # Enable de facto stable features. + nix.settings.experimental-features = ["nix-command" "flakes"]; + + nixpkgs.overlays = [ + # Use local overlays. + flakeOutputs.overlays.additions + flakeOutputs.overlays.modifications + + # Add unstable nixpkgs. + (final: prev: {unstable = flakeInputs.nixpkgs-unstable.legacyPackages.${pkgs.system};}) + ]; + + # I'm not *that* vegan. + nixpkgs.config.allowUnfree = true; + + # This will add each flake input as a registry + # To make nix3 commands consistent with your flake + nix.registry = lib.mapAttrs (_: value: {flake = value;}) flakeInputs; + + nix.nixPath = + [ + # Use overlays from this repo for building system configuration as well as system-wide. + # See: https://nixos.wiki/wiki/Overlays#Using_nixpkgs.overlays_from_configuration.nix_as_.3Cnixpkgs-overlays.3E_in_your_NIX_PATH + "nixpkgs-overlays=${flakeInputs.self}/overlays/compat.nix" + + # This will additionally add out inputs to the system's legacy channels + # Making legacy nix commands consistent as well, awesome! + ] + ++ lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry; + + # Add shell-utilities which are only relevant if Nix is enabled. + environment.systemPackages = with pkgs; [ + # For running programs easily. + nix-index # Also includes nix-locate + flakeInputs.comma.packages.${system}.default + + # For editing secrets. + flakeInputs.agenix.packages.${system}.default + ]; + } + (lib.mkIf pkgs.stdenv.isLinux { + # There is not nix-darwin equivalent to this NixOS option. + nix.enable = true; + }) +] diff --git a/shared/nixos/common-shell-settings/default.nix b/shared/nixos/common-shell-settings/default.nix new file mode 100644 index 0000000..ec71861 --- /dev/null +++ b/shared/nixos/common-shell-settings/default.nix @@ -0,0 +1,44 @@ +# This module sets options to ensure a consistent Baseline Shell Experince™ +# across the entire fleet. This includes e.g. common utilities and aliases. +# +# NOTE: Even though this lives under `shared/nixos` the configuration in here +# should also be compatible with nix-darwin!! +{pkgs, ...}: { + # Set ZSH as the shell. + # https://nixos.wiki/wiki/Command_Shell#Changing_default_shelltrue + programs.zsh.enable = true; + environment.shells = [pkgs.zsh]; + + # Very basic system administration tools. + environment.systemPackages = with pkgs; [ + curl + jq + moreutils + neovim + tree + ]; + + # Aliases that are burned into my muscle memory. + environment.shellAliases = { + "mv" = "mv -i"; + "rm" = "rm -i"; + "cp" = "cp -i"; + "ls" = "ls -F -G -A --color=auto"; + "grep" = "grep --color=auto"; + "file" = "file --no-dereference"; + "tree" = "tree --dirsfirst --gitignore"; + + # See: https://github.com/NixOS/nix/issues/5858 + "nix" = "nix --print-build-logs"; + + ".." = "cd ../"; + "..." = "cd ../../"; + "...." = "cd ../../../"; + "....." = "cd ../../../../"; + "......" = "cd ../../../../../"; + "......." = "cd ../../../../../../"; + "........" = "cd ../../../../../../../"; + "........." = "cd ../../../../../../../../"; + ".........." = "cd ../../../../../../../../../"; + }; +} |