From 7e642c7dfeb3c6702d214a07a4b3c2f762ac65e8 Mon Sep 17 00:00:00 2001 From: Greg Hellings Date: Fri, 5 May 2023 15:59:59 -0500 Subject: [PATCH] Add router module and dhcp config --- hosts/mm/default.nix | 180 ++++++++++++++++++++++++-------------- modules-linux/default.nix | 1 + modules-linux/router.nix | 76 ++++++++++++++++ 3 files changed, 190 insertions(+), 67 deletions(-) create mode 100644 modules-linux/router.nix diff --git a/hosts/mm/default.nix b/hosts/mm/default.nix index 6faf43b..e9d947b 100644 --- a/hosts/mm/default.nix +++ b/hosts/mm/default.nix @@ -1,84 +1,130 @@ # Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page +# your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running ‘nixos-help’). { config, pkgs, ... }: +let + wanInterface = "enp2s0"; + lanInterface = "enp1s0"; + lanIpAddress = "10.177.1.1"; +in { - imports = - [ # Include the results of the hardware scan. - ./hardware-configuration.nix - ]; + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; - greg.home = false; + greg.home = false; - # Bootloader. - boot.loader.systemd-boot.enable = true; - boot.loader.efi.canTouchEfiVariables = true; - boot.loader.efi.efiSysMountPoint = "/boot/efi"; + # Bootloader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.efi.efiSysMountPoint = "/boot/efi"; - networking.hostName = "mm"; # Define your hostname. - networking.domain = "mindmazeroom.com"; - # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. + networking = { + hostName = "mm"; + domain = "mindmazeroom.lan"; + nameservers = [ "127.0.0.1" ]; + networkmanager.enable = true; + interfaces = { + "${wanInterface}".useDHCP = true; + "${lanInterface}" = { + useDHCP = false; + ipv4.addresses = [{ + address = lanIpAddress; + prefixLength = 24; + }]; + }; + }; + firewall = { # Might not strictly be necessary? + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ 53 67 ]; + }; + }; - # Configure network proxy if necessary - # networking.proxy.default = "http://user:password@proxy:port/"; - # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + # Serves as the router, DHCP, and DNS for the site + greg.router = { + enable = true; + wan = wanInterface; + lan = [ lanInterface ]; + }; + services = { + dnsmasq = { + enable = true; + settings = { + expand-hosts = true; + log-queries = true; + server = [ + "1.1.1.1" + "8.8.4.4" + ]; + }; + }; + create_ap = { + enable = false; + settings = { + INTERNET_IFACE = ""; + WIFI_IFACE = "wlan0"; + SSID = "MM_Test"; + PASSPHRASE = "MindMaze2023"; + }; + }; + kea.dhcp4 = { + enable = true; + settings = { + interfaces-config = { + interfaces = [ lanInterface ]; + }; + lease-database = { + name = "/var/lib/kea/dhcp4.leases"; + persist = true; + type = "memfile"; + }; + renew-timer = 1000; + rebind-timer = 2000; + valid-lifetime = 4000; + option-data = [{ + name = "domain-name-servers"; + data = "${lanIpAddress}"; + } { + name = "routers"; + data = "10.177.1.1"; + }]; + subnet4 = [{ + subnet = "10.177.1.0/24"; + pools = [{ + pool = "10.177.1.10-10.177.1.250"; + }]; + }]; + }; + }; - # Enable networking - networking.networkmanager.enable = true; + # Configure keymap in X11 + xserver = { + layout = "us"; + xkbVariant = ""; + }; + }; - # Set your time zone. - time.timeZone = "America/Chicago"; + # Set your time zone. + time.timeZone = "America/Chicago"; - # Configure keymap in X11 - services.xserver = { - layout = "us"; - xkbVariant = ""; - }; + # Define a user account. Don't forget to set a password with ‘passwd’. + users.users.greg = { + isNormalUser = true; + description = "Greg Hellings"; + extraGroups = [ "networkmanager" "wheel" ]; + packages = with pkgs; []; + }; - # Define a user account. Don't forget to set a password with ‘passwd’. - users.users.greg = { - isNormalUser = true; - description = "Greg Hellings"; - extraGroups = [ "networkmanager" "wheel" ]; - packages = with pkgs; []; - }; - - # Allow unfree packages - nixpkgs.config.allowUnfree = true; - - environment.systemPackages = with pkgs; [ - vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. - wget - ]; - - # 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; - # }; - - # List services that you want to enable: - - # Enable the OpenSSH daemon. - # services.openssh.enable = true; - - # Open ports in the firewall. - # networking.firewall.allowedTCPPorts = [ ... ]; - # networking.firewall.allowedUDPPorts = [ ... ]; - # Or disable the firewall altogether. - # networking.firewall.enable = false; - - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It‘s perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). - system.stateVersion = "22.05"; # Did you read the comment? + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + environment.systemPackages = with pkgs; [ + vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + wget + ]; + system.stateVersion = "22.05"; } diff --git a/modules-linux/default.nix b/modules-linux/default.nix index d4be972..8b59f36 100644 --- a/modules-linux/default.nix +++ b/modules-linux/default.nix @@ -10,6 +10,7 @@ ./linode.nix ./linux.nix ./proxy.nix + ./router.nix ./rpi4.nix ./tailscale.nix ]; diff --git a/modules-linux/router.nix b/modules-linux/router.nix new file mode 100644 index 0000000..875494f --- /dev/null +++ b/modules-linux/router.nix @@ -0,0 +1,76 @@ +{ config, lib, pkgs, ... }: + +let + names = mylist: (lib.strings.concatMapStringsSep "," (x: ''"${x}"'') mylist); + # Pass the names of the wan/lan ports + nftConfig = { wan, lan, limitedLan ? [] }: + let + lanList = names lan; + allLan = names (lan ++ limitedLan); + wanName = ''"${wan}"''; + in +'' +table ip filter { + chain input { + type filter hook input priority 0; policy drop; + + iifname { ${lanList} } accept comment "Allows LAN traffic and outgoing" + iifname ${wanName} ct state { established, related } accept comment "Allows existing connections" + iifname ${wanName} icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow some ICMP traffic" + iifname ${wanName} counter drop comment "Drop other incoming traffic, and count how much" + } + chain forward { + type filter hook forward priority 0; policy drop; + iifname { ${allLan} } oifname { ${wanName} } accept comment "Forward LAN to WAN" + iifname { ${wanName} } oifname { ${allLan} } ct state established, related accept comment "Allow incoming established traffic" + } +} + +table ip nat { + chain postrouting { + type nat hook postrouting priority 100; policy accept; + oifname "${wan}" masquerade + } +} + +table ip6 filter { + chain input { + type filter hook input priority 0; policy drop; + } + chain forward { + type filter hook forward priority 0; policy drop; + } +} +''; + cfg = config.greg.router; + +in with lib; { + options.greg.router = { + enable = mkEnableOption "Enable NFTables and routing"; + wan = mkOption { + type = types.str; + description = "The name of the network interface that is the WAN connection"; + }; + lan = mkOption { + type = (types.listOf types.str); + description = "A list of all network interfaces that are considered LAN connections"; + }; + limited = mkOption { + type = (types.listOf types.str); + description = "A list of limited access LAN connections - such as IOT connections and similar."; + default = []; + }; + }; + + config = mkIf cfg.enable { + networking.nftables = { + enable = true; + ruleset = (nftConfig { lan = cfg.lan; wan = cfg.wan; }); + }; + + environment.systemPackages = [ + pkgs.pciutils + pkgs.tcpdump + ]; + }; +}