declared network.nix
This commit is contained in:
145
hosts/vps/network.nix
Normal file
145
hosts/vps/network.nix
Normal file
@@ -0,0 +1,145 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
externalInterface = config.my.interfaces.${config.networking.hostName};
|
||||
wgInterface = "wg0";
|
||||
ips = {
|
||||
homeServer = config.my.ips.wg-server;
|
||||
wgWorkstation = config.my.ips.wg-workstation;
|
||||
wgFriend1 = config.my.ips.wg-friend1;
|
||||
wgFriend6 = config.my.ips.wg-friend6;
|
||||
};
|
||||
subnets = {
|
||||
wgFriends = config.my.subnets.wg-friends;
|
||||
wgGuests = config.my.subnets.wg-guests;
|
||||
wgHomelab = config.my.subnets.wg-homelab;
|
||||
};
|
||||
ports = {
|
||||
inherit (config.my.ports)
|
||||
giteaSsh
|
||||
qbittorrent
|
||||
ssh
|
||||
wg
|
||||
;
|
||||
web = [
|
||||
80
|
||||
443
|
||||
];
|
||||
syncthing = config.my.ports.syncthingRelay;
|
||||
synapseFederation = config.my.ports.synapseSsl;
|
||||
};
|
||||
portsStr = {
|
||||
syncthing = toString config.my.ports.syncthingRelay;
|
||||
synapseFederation = toString config.my.ports.synapseSsl;
|
||||
synapseClient = toString config.my.servers.synapse.port;
|
||||
syncplay = toString config.my.servers.syncplay.port;
|
||||
synctube = toString config.my.servers.synctube.port;
|
||||
stash = toString config.my.servers.stash.port;
|
||||
jellyfin = toString config.my.servers.jellyfin.port;
|
||||
audiobookshelf = toString config.my.servers.audiobookshelf.port;
|
||||
kavita = toString config.my.servers.kavita.port;
|
||||
openWebui = toString config.my.ports.openWebui;
|
||||
sillytavern = toString config.my.ports.sillytavern;
|
||||
ollama = toString config.my.ports.ollama;
|
||||
comfyui = toString config.my.ports.comfyui;
|
||||
};
|
||||
forwardedPorts = [
|
||||
{
|
||||
comment = "snat ssh forward";
|
||||
port = ports.giteaSsh;
|
||||
proto = "tcp";
|
||||
}
|
||||
{
|
||||
comment = "snat qbittorrent tcp forward";
|
||||
port = ports.qbittorrent;
|
||||
proto = "tcp";
|
||||
}
|
||||
{
|
||||
comment = "snat qbittorrent udp forward";
|
||||
port = ports.qbittorrent;
|
||||
proto = "udp";
|
||||
}
|
||||
];
|
||||
mkForwardPort =
|
||||
{ port, proto, ... }:
|
||||
{
|
||||
sourcePort = port;
|
||||
inherit proto;
|
||||
destination = "${ips.homeServer}:${toString port}";
|
||||
};
|
||||
mkSnatRule =
|
||||
{
|
||||
comment,
|
||||
port,
|
||||
proto,
|
||||
...
|
||||
}:
|
||||
''iifname "${externalInterface}" oifname "${wgInterface}" ip daddr ${ips.homeServer}/32 ${proto} dport ${toString port} masquerade comment "${comment}"'';
|
||||
in
|
||||
{
|
||||
networking = {
|
||||
nat = {
|
||||
inherit externalInterface;
|
||||
enable = true;
|
||||
internalInterfaces = [ wgInterface ];
|
||||
forwardPorts = map mkForwardPort forwardedPorts;
|
||||
};
|
||||
nftables = {
|
||||
enable = true;
|
||||
tables.vps-snat = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority srcnat;
|
||||
iifname "${wgInterface}" oifname "${externalInterface}" ip saddr ${subnets.wgHomelab} masquerade comment "snat homelab egress"
|
||||
${lib.concatStringsSep "\n " (map mkSnatRule forwardedPorts)}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
firewall = {
|
||||
enable = true;
|
||||
filterForward = true;
|
||||
checkReversePath = "loose";
|
||||
allowedTCPPorts = [
|
||||
ports.ssh
|
||||
ports.qbittorrent
|
||||
]
|
||||
++ ports.web;
|
||||
allowedUDPPorts = [
|
||||
ports.wg
|
||||
ports.qbittorrent
|
||||
];
|
||||
extraForwardRules = ''
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.syncthing} accept
|
||||
iifname "${wgInterface}" ip saddr ${ips.homeServer}/32 ip daddr ${subnets.wgFriends} tcp dport ${portsStr.syncthing} accept
|
||||
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 tcp dport { ${portsStr.synapseClient}, ${portsStr.synapseFederation}, ${portsStr.syncplay}, ${portsStr.synctube} } accept
|
||||
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
||||
iifname "${wgInterface}" ip saddr ${ips.wgFriend1}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept
|
||||
iifname "${wgInterface}" ip saddr ${ips.wgFriend6}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} ip daddr ${ips.homeServer}/32 tcp dport { ${portsStr.stash}, ${portsStr.jellyfin}, ${portsStr.audiobookshelf}, ${portsStr.kavita} } accept
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
||||
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgHomelab} ip daddr ${ips.homeServer}/32 accept
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgHomelab} ip daddr ${ips.wgWorkstation}/32 tcp dport { ${portsStr.openWebui}, ${portsStr.sillytavern}, ${portsStr.ollama}, ${portsStr.comfyui} } accept
|
||||
iifname "${wgInterface}" ip saddr ${ips.wgWorkstation}/32 ip daddr ${subnets.wgHomelab} tcp sport { ${portsStr.openWebui}, ${portsStr.sillytavern}, ${portsStr.ollama}, ${portsStr.comfyui} } accept
|
||||
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgHomelab} oifname "${externalInterface}" accept
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} oifname "${externalInterface}" accept
|
||||
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} oifname "${externalInterface}" accept
|
||||
|
||||
ip saddr ${subnets.wgFriends} ip daddr ${subnets.wgHomelab} drop
|
||||
ip saddr ${subnets.wgHomelab} ip daddr ${subnets.wgFriends} drop
|
||||
ip saddr ${subnets.wgGuests} ip daddr ${subnets.wgHomelab} drop
|
||||
ip saddr ${subnets.wgHomelab} ip daddr ${subnets.wgGuests} drop
|
||||
ip saddr ${subnets.wgGuests} ip daddr ${subnets.wgFriends} drop
|
||||
ip saddr ${subnets.wgFriends} ip daddr ${subnets.wgGuests} drop
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user