forked from mirrors_public/oddlama_nix-config
feat: add zoned nftables firewall
This commit is contained in:
parent
703056a530
commit
deab5b335e
10 changed files with 229 additions and 23 deletions
|
@ -19,6 +19,20 @@
|
||||||
../../../modules/wireguard.nix
|
../../../modules/wireguard.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# IP address math library
|
||||||
|
# https://gist.github.com/duairc/5c9bb3c922e5d501a1edb9e7b3b845ba
|
||||||
|
# Plus some extensions by us
|
||||||
|
lib = let
|
||||||
|
libWithNet = (import "${inputs.lib-net}/net.nix" {inherit lib;}).lib;
|
||||||
|
in
|
||||||
|
lib.recursiveUpdate libWithNet {
|
||||||
|
net.cidr = rec {
|
||||||
|
hostCidr = n: x: "${libWithNet.net.cidr.host n x}/${libWithNet.net.cidr.length x}";
|
||||||
|
ip = x: lib.head (lib.splitString "/" x);
|
||||||
|
canonicalize = x: libWithNet.net.cidr.make (libWithNet.net.cidr.length x) (ip x);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Setup secret rekeying parameters
|
# Setup secret rekeying parameters
|
||||||
rekey = {
|
rekey = {
|
||||||
inherit
|
inherit
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
nodeName,
|
nodeName,
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
inherit
|
inherit
|
||||||
(lib)
|
(lib)
|
||||||
concatStringsSep
|
concatStringsSep
|
||||||
|
head
|
||||||
mapAttrsToList
|
mapAttrsToList
|
||||||
mkDefault
|
mkDefault
|
||||||
mkForce
|
mkForce
|
||||||
|
@ -17,10 +19,59 @@ in {
|
||||||
hostName = mkDefault nodeName;
|
hostName = mkDefault nodeName;
|
||||||
useDHCP = mkForce false;
|
useDHCP = mkForce false;
|
||||||
useNetworkd = true;
|
useNetworkd = true;
|
||||||
wireguard.enable = true;
|
|
||||||
dhcpcd.enable = false;
|
dhcpcd.enable = false;
|
||||||
nftables.enable = true;
|
|
||||||
firewall.enable = true;
|
nftables = {
|
||||||
|
firewall.enable = true;
|
||||||
|
stopRuleset = mkDefault ''
|
||||||
|
table inet filter {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy drop;
|
||||||
|
ct state invalid drop
|
||||||
|
ct state {established, related} accept
|
||||||
|
|
||||||
|
iifname lo accept
|
||||||
|
meta l4proto ipv6-icmp accept
|
||||||
|
meta l4proto icmp accept
|
||||||
|
tcp dport ${toString (head config.services.openssh.ports)} accept
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
}
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority filter; policy accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
nftables.firewall = {
|
||||||
|
zones = lib.mkForce {
|
||||||
|
local.localZone = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
rules = lib.mkForce {
|
||||||
|
icmp = {
|
||||||
|
early = true;
|
||||||
|
after = ["ct"];
|
||||||
|
from = "all";
|
||||||
|
to = ["local"];
|
||||||
|
extraLines = [
|
||||||
|
"ip6 nexthdr icmpv6 icmpv6 type { echo-request, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept"
|
||||||
|
"ip protocol icmp icmp type { echo-request, router-advertisement } accept"
|
||||||
|
#"ip6 saddr fe80::/10 ip6 daddr fe80::/10 udp dport 546 accept"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
ssh = {
|
||||||
|
early = true;
|
||||||
|
after = ["ct"];
|
||||||
|
from = "all";
|
||||||
|
to = ["local"];
|
||||||
|
allowedTCPPorts = config.services.openssh.ports;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Rename known network interfaces
|
# Rename known network interfaces
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{lib, ...}: {
|
{lib, ...}: {
|
||||||
networking = {
|
networking.firewall = {
|
||||||
firewall = {
|
allowedTCPPorts = [5355];
|
||||||
allowedTCPPorts = [5355];
|
allowedUDPPorts = [5353 5355];
|
||||||
allowedUDPPorts = [5353 5355];
|
|
||||||
};
|
|
||||||
networkmanager.dns = "systemd-resolved";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.resolved = {
|
services.resolved = {
|
||||||
|
@ -16,7 +13,7 @@
|
||||||
"8.8.8.8"
|
"8.8.8.8"
|
||||||
"2001:4860:4860::8844"
|
"2001:4860:4860::8844"
|
||||||
];
|
];
|
||||||
llmnr = "true";
|
llmnr = "true"; # Microsoft's version of mDNS
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
Domains=~.
|
Domains=~.
|
||||||
MulticastDNS=true
|
MulticastDNS=true
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
microVmHost = true;
|
microVmHost = true;
|
||||||
physicalConnections = {
|
physicalConnections = {
|
||||||
"10-lan1" = "LAN 1";
|
"10-lan" = "LAN";
|
||||||
"10-lan2" = "LAN 2";
|
"10-wan" = "WAN";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,140 @@
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
lib,
|
lib,
|
||||||
nodeSecrets,
|
nodeSecrets,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
networking.hostId = "49ce3b71";
|
inherit (config.lib.net) cidr;
|
||||||
|
|
||||||
|
net.lan.ipv4cidr = "192.168.100.1/24";
|
||||||
|
net.lan.ipv6cidr = "fd01::1/64";
|
||||||
|
in {
|
||||||
|
networking.hostId = nodeSecrets.networking.hostId;
|
||||||
|
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
"10-lan1" = {
|
"10-lan" = {
|
||||||
DHCP = "yes";
|
address = [net.lan.ipv4cidr net.lan.ipv6cidr];
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan1.mac;
|
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "kernel";
|
networkConfig.IPv6PrivacyExtensions = "kernel";
|
||||||
dhcpV4Config.RouteMetric = 10;
|
dhcpV4Config.RouteMetric = 10;
|
||||||
dhcpV6Config.RouteMetric = 10;
|
dhcpV6Config.RouteMetric = 10;
|
||||||
};
|
};
|
||||||
"10-lan2" = {
|
"10-wan" = {
|
||||||
DHCP = "yes";
|
DHCP = "yes";
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.lan2.mac;
|
#address = [
|
||||||
|
# "192.168.178.2/24"
|
||||||
|
# "fd00::1/64"
|
||||||
|
#];
|
||||||
|
#gateway = [
|
||||||
|
#];
|
||||||
|
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wan.mac;
|
||||||
networkConfig.IPv6PrivacyExtensions = "kernel";
|
networkConfig.IPv6PrivacyExtensions = "kernel";
|
||||||
dhcpV4Config.RouteMetric = 20;
|
dhcpV4Config.RouteMetric = 20;
|
||||||
dhcpV6Config.RouteMetric = 20;
|
dhcpV6Config.RouteMetric = 20;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.nftables.firewall = {
|
||||||
|
zones = lib.mkForce {
|
||||||
|
lan = {
|
||||||
|
interfaces = ["lan"];
|
||||||
|
ipv4Addresses = [(cidr.canonicalize net.lan.ipv4cidr)];
|
||||||
|
ipv6Addresses = [(cidr.canonicalize net.lan.ipv6cidr)];
|
||||||
|
};
|
||||||
|
wan = {
|
||||||
|
interfaces = ["wan"];
|
||||||
|
# TODO ipv4Addresses = [ net.wan.netv4 ];
|
||||||
|
# TODO ipv6Addresses = [ net.wan.netv6 ];
|
||||||
|
ipv4Addresses = ["192.168.1.0/22"];
|
||||||
|
ipv6Addresses = ["fd00::/64"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
rules = lib.mkForce {
|
||||||
|
masquerade-wan = {
|
||||||
|
from = ["lan"];
|
||||||
|
to = ["wan"];
|
||||||
|
masquerade = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
outbound = {
|
||||||
|
from = ["lan"];
|
||||||
|
to = ["lan" "wan"];
|
||||||
|
late = true; # Only accept after any rejects have been processed
|
||||||
|
verdict = "accept";
|
||||||
|
};
|
||||||
|
|
||||||
|
wan-to-local = {
|
||||||
|
from = ["wan"];
|
||||||
|
to = ["local"];
|
||||||
|
};
|
||||||
|
|
||||||
|
lan-to-local = {
|
||||||
|
from = ["lan"];
|
||||||
|
to = ["local"];
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(config.networking.firewall)
|
||||||
|
allowedTCPPorts
|
||||||
|
allowedUDPPorts
|
||||||
|
;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.kea = {
|
||||||
|
dhcp4 = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
lease-database = {
|
||||||
|
name = "/var/lib/kea/dhcp4.leases";
|
||||||
|
persist = true;
|
||||||
|
type = "memfile";
|
||||||
|
};
|
||||||
|
valid-lifetime = 4000;
|
||||||
|
renew-timer = 1000;
|
||||||
|
rebind-timer = 2000;
|
||||||
|
interfaces-config = {
|
||||||
|
interfaces = ["lan"];
|
||||||
|
service-sockets-max-retries = -1;
|
||||||
|
};
|
||||||
|
option-data = [
|
||||||
|
{
|
||||||
|
name = "domain-name-servers";
|
||||||
|
data = "1.1.1.1, 8.8.8.8";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
subnet4 = [
|
||||||
|
{
|
||||||
|
interface = "lan";
|
||||||
|
subnet = cidr.canonicalize net.lan.ipv4cidr;
|
||||||
|
pools = [
|
||||||
|
{pool = "192.168.100.20 - 192.168.100.250";}
|
||||||
|
];
|
||||||
|
option-data = [
|
||||||
|
{
|
||||||
|
name = "routers";
|
||||||
|
data = cidr.ip net.lan.ipv4cidr;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
#reservations = [
|
||||||
|
# {
|
||||||
|
# duid = "aa:bb:cc:dd:ee:ff";
|
||||||
|
# ip-address = cidr.ip net.lan.ipv4cidr;
|
||||||
|
# }
|
||||||
|
#];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#dhcp6 = {
|
||||||
|
# enable = true;
|
||||||
|
#};
|
||||||
|
};
|
||||||
|
systemd.services.kea-dhcp4-server.after = [
|
||||||
|
"sys-subsystem-net-devices-lan.device"
|
||||||
|
];
|
||||||
|
|
||||||
#extra.wireguard.vms = {
|
#extra.wireguard.vms = {
|
||||||
# server = {
|
# server = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
|
|
Binary file not shown.
|
@ -1,4 +1,14 @@
|
||||||
{nodeSecrets, ...}: {
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
nodeSecrets,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (config.lib.net) cidr;
|
||||||
|
|
||||||
|
net.iot.ipv4cidr = "10.90.0.1/24";
|
||||||
|
net.iot.ipv6cidr = "fd90::1/64";
|
||||||
|
in {
|
||||||
networking.hostId = nodeSecrets.networking.hostId;
|
networking.hostId = nodeSecrets.networking.hostId;
|
||||||
|
|
||||||
systemd.network.networks = {
|
systemd.network.networks = {
|
||||||
|
@ -10,9 +20,27 @@
|
||||||
dhcpV6Config.RouteMetric = 10;
|
dhcpV6Config.RouteMetric = 10;
|
||||||
};
|
};
|
||||||
"10-wlan1" = {
|
"10-wlan1" = {
|
||||||
DHCP = "no";
|
address = [net.iot.ipv4cidr net.iot.ipv6cidr];
|
||||||
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wlan1.mac;
|
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wlan1.mac;
|
||||||
address = ["10.90.0.1/24"];
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.nftables.firewall = {
|
||||||
|
zones = lib.mkForce {
|
||||||
|
lan.interfaces = ["lan1"];
|
||||||
|
};
|
||||||
|
|
||||||
|
rules = lib.mkForce {
|
||||||
|
int-to-local = {
|
||||||
|
from = ["lan"];
|
||||||
|
to = ["local"];
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(config.networking.firewall)
|
||||||
|
allowedTCPPorts
|
||||||
|
allowedUDPPorts
|
||||||
|
;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
mkIf
|
mkIf
|
||||||
mkOption
|
mkOption
|
||||||
mkEnableOption
|
mkEnableOption
|
||||||
|
net
|
||||||
optionalAttrs
|
optionalAttrs
|
||||||
optionals
|
optionals
|
||||||
splitString
|
splitString
|
||||||
|
|
|
@ -26,7 +26,6 @@ in
|
||||||
secrets = self.secrets.content;
|
secrets = self.secrets.content;
|
||||||
nodeSecrets = self.secrets.content.nodes.${nodeName};
|
nodeSecrets = self.secrets.content.nodes.${nodeName};
|
||||||
nixos-hardware = nixos-hardware.nixosModules;
|
nixos-hardware = nixos-hardware.nixosModules;
|
||||||
nixos-nftables-firewall = nixos-nftables-firewall.nixosModules;
|
|
||||||
#impermanence = impermanence.nixosModules;
|
#impermanence = impermanence.nixosModules;
|
||||||
};
|
};
|
||||||
imports =
|
imports =
|
||||||
|
@ -36,6 +35,7 @@ in
|
||||||
#impermanence.nixosModules.default
|
#impermanence.nixosModules.default
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
agenix-rekey.nixosModules.default
|
agenix-rekey.nixosModules.default
|
||||||
|
nixos-nftables-firewall.nixosModules.default
|
||||||
]
|
]
|
||||||
++ optionals nodeMeta.microVmHost [
|
++ optionals nodeMeta.microVmHost [
|
||||||
microvm.nixosModules.host
|
microvm.nixosModules.host
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
flatten
|
flatten
|
||||||
foldl'
|
foldl'
|
||||||
genAttrs
|
genAttrs
|
||||||
|
head
|
||||||
mapAttrs'
|
mapAttrs'
|
||||||
mergeAttrs
|
mergeAttrs
|
||||||
nameValuePair
|
nameValuePair
|
||||||
partition
|
partition
|
||||||
removeSuffix
|
removeSuffix
|
||||||
|
splitString
|
||||||
substring
|
substring
|
||||||
unique
|
unique
|
||||||
;
|
;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue