summaryrefslogtreecommitdiff
path: root/shared/nixos
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-12-21 15:47:33 +0100
committerLinnnus <[email protected]>2024-12-21 16:19:04 +0100
commit8353554315564b89dfe27d5130080ed04a0a65ad (patch)
tree896de88b6ea2701692b3ffe977c23947a786318e /shared/nixos
parent9b7ed17b27157a25e57a6e38be3bcfeaa70ec9e8 (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.nix88
-rw-r--r--shared/nixos/common-hm-settings/default.nix27
-rw-r--r--shared/nixos/common-nix-settings/default.nix60
-rw-r--r--shared/nixos/common-shell-settings/default.nix44
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 ../../../../../../../../../";
+ };
+}