use proper options for the firewall & default to local build

This commit is contained in:
asyncnomi 2025-08-03 04:03:22 +02:00
parent 22f93f23ed
commit f5241119eb
8 changed files with 171 additions and 109 deletions

View file

@ -70,7 +70,7 @@
user = "root"; user = "root";
autoRollback = true; autoRollback = true;
magicRollback = true; magicRollback = true;
remoteBuild = true; remoteBuild = false;
nodes = lib.mapAttrs (name: config: { nodes = lib.mapAttrs (name: config: {
hostname = lib.lists.head (lib.strings.splitString "/" config.ip4); hostname = lib.lists.head (lib.strings.splitString "/" config.ip4);
profilesOrder = [ "system" ]; profilesOrder = [ "system" ];

View file

@ -52,4 +52,7 @@ in
]; ];
}; };
}; };
fwtables.allowedMgmtFwdToMesh = true;
fwtables.allowedUDPPorts = [{ port = 51920; public = true; }];
} }

View file

@ -11,6 +11,8 @@ let
# And mappings # And mappings
mapping = import ./../../mapping.nix; mapping = import ./../../mapping.nix;
meshPort = 51820;
buildSecret = zone: id: { buildSecret = zone: id: {
"wg-private-zone-${toString zone}-id-${toString id}" = { "wg-private-zone-${toString zone}-id-${toString id}" = {
file = ./../../secrets/wireguard + ( "/wg-private-zone-" + toString zone + "-id-" + toString id + ".age" ); file = ./../../secrets/wireguard + ( "/wg-private-zone-" + toString zone + "-id-" + toString id + ".age" );
@ -32,13 +34,13 @@ let
"172.19.${toString (peerConfig.zone + 127)}.0/24" "172.19.${toString (peerConfig.zone + 127)}.0/24"
"fc00:f::${toString (peerConfig.zone + 127)}:0/112" "fc00:f::${toString (peerConfig.zone + 127)}:0/112"
]; ];
Endpoint = "${lib.lists.head (lib.strings.splitString "/" peerConfig.ip4)}:51820"; Endpoint = "${lib.lists.head (lib.strings.splitString "/" peerConfig.ip4)}:${toString meshPort}";
PersistentKeepalive = 25; PersistentKeepalive = 25;
}) peerConfigs; }) peerConfigs;
interfaceConfig = { interfaceConfig = {
PrivateKeyFile = config.age.secrets."wg-private-zone-${toString myZone}-id-${toString myId}".path; PrivateKeyFile = config.age.secrets."wg-private-zone-${toString myZone}-id-${toString myId}".path;
ListenPort = 51820; ListenPort = meshPort;
}; };
# Return route for mgmt traffic # Return route for mgmt traffic
@ -76,4 +78,6 @@ in
routes = rtwg4 ++ rtwg6; routes = rtwg4 ++ rtwg6;
}; };
}; };
fwtables.allowedUDPPorts = [{ port = meshPort; public = true; }];
} }

View file

@ -7,8 +7,72 @@ let
# Import mapping # Import mapping
mapping = import ./../../mapping.nix; mapping = import ./../../mapping.nix;
generatePortRules = protocol: ports: let
publicPorts = lib.filter (p: p.public) ports;
privatePorts = lib.filter (p: !p.public) ports;
publicRules = map (p: "${protocol} dport ${toString p.port} accept") publicPorts;
privateRules = map (p: "iifname mesh ${protocol} dport ${toString p.port} accept") privatePorts;
in
publicRules ++ privateRules;
cfg = config.fwtables;
in in
{ {
options.fwtables = with lib; {
allowedTCPPorts = mkOption {
type = types.listOf (types.submodule {
options = {
port = mkOption {
type = types.port;
description = "The TCP port number";
};
public = mkOption {
type = types.bool;
default = false;
description = "Whether the port should be accessible from public internet (true) or only from mesh network (false)";
};
};
});
default = [];
description = "List of allowed TCP ports with their accessibility settings";
example = [
{ port = 80; public = true; }
{ port = 8080; public = false; }
];
};
allowedUDPPorts = mkOption {
type = types.listOf (types.submodule {
options = {
port = mkOption {
type = types.port;
description = "The UDP port number";
};
public = mkOption {
type = types.bool;
default = false;
description = "Whether the port should be accessible from public internet (true) or only from mesh network (false)";
};
};
});
default = [];
description = "List of allowed UDP ports with their accessibility settings";
example = [
{ port = 53; public = true; }
{ port = 1234; public = false; }
];
};
allowedMgmtFwdToMesh = mkOption {
type = types.bool;
default = false;
description = "Allow traffic to jump from mgmt if to mesh if";
};
};
config = {
networking = { networking = {
nat.enable = false; nat.enable = false;
firewall.enable = false; firewall.enable = false;
@ -42,41 +106,11 @@ in
ip protocol icmp accept ip protocol icmp accept
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
# SSH # Temporary SSH access for convenience during early stages
tcp dport 22 accept tcp dport 22 accept
# Mesh ${lib.concatStringsSep "\n" (generatePortRules "tcp" cfg.allowedTCPPorts)}
udp dport 51820 accept ${lib.concatStringsSep "\n" (generatePortRules "udp" cfg.allowedUDPPorts)}
${if lib.elem myName mapping.bastion.hosts then ''
# Mgmt
udp dport 51920 accept
'' else ""}
${if myName == mapping.dns.master then ''
# DNS Master
iifname mesh tcp dport 53 accept
iifname mesh udp dport 53 accept
'' else ""}
${if lib.elem myName mapping.dns.secondary then ''
# DNS Secondary
tcp dport 53 accept
udp dport 53 accept
'' else ""}
${if lib.elem myName mapping.mail.hosts then ''
# Mail server (without IMAP)
# With support for both SSL & STARTTLS
tcp dport 25 accept
tcp dport 465 accept
tcp dport 587 accept
'' else ""}
${if lib.elem myName mapping.db.hosts then ''
# DNS Secondary
iifname mesh tcp dport 5432 accept
'' else ""}
# Log anything else # Log anything else
ip protocol tcp counter log prefix "tcp.in.dropped: " ip protocol tcp counter log prefix "tcp.in.dropped: "
@ -86,12 +120,12 @@ in
chain forward { chain forward {
type filter hook forward priority 0; policy drop; type filter hook forward priority 0; policy drop;
${lib.optionalString cfg.allowedMgmtFwdToMesh ''
ct state related,established accept ct state related,established accept
ct state invalid counter drop ct state invalid counter drop
${if lib.elem myName mapping.bastion.hosts then ''
iifname mgmt oifname mesh accept iifname mgmt oifname mesh accept
'' else ""} ''}
} }
chain output { chain output {
type filter hook output priority 0; policy accept; type filter hook output priority 0; policy accept;
@ -120,4 +154,5 @@ in
}; };
}; };
}; };
};
} }

View file

@ -84,4 +84,8 @@ in
echo "PostgreSQL dataDir not empty, skipping initial master to slave replication" echo "PostgreSQL dataDir not empty, skipping initial master to slave replication"
fi fi
''); '');
fwtables.allowedTCPPorts = [
{ port = cfg.settings.port; public = false; }
];
} }

View file

@ -285,4 +285,7 @@ in
]; ];
}; };
}; };
fwtables.allowedTCPPorts = [{ port = 53; public = true; }];
fwtables.allowedUDPPorts = [{ port = 53; public = true; }];
} }

View file

@ -223,4 +223,10 @@ in
}; };
}; };
}; };
fwtables.allowedTCPPorts = [
{ port = 25; public = true; }
{ port = 465; public = true; }
{ port = 587; public = true; }
];
} }

View file

@ -3,6 +3,13 @@
{ {
# Users # Users
# Uid 1000 - 1999 are reserved for specific system users that need uid > 999 # Uid 1000 - 1999 are reserved for specific system users that need uid > 999
nix.settings.trusted-users = [
"asyncnomi"
"gamma"
"jeltz"
"soyouzpanda"
"raito"
];
# Wheeler # Wheeler
users.users.asyncnomi = { users.users.asyncnomi = {