summaryrefslogtreecommitdiff
path: root/hosts/poweredge/networking.nix
blob: 859bc932a4e42867517b2226f06373a3a58f9b6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
let
	hostIp = "192.168.1.10";
in { config, ... }: {
	networking = {
		# Label lan and wan interfaces
		_interfaceLabels = {
			enable = true;
			interfaces.lan0 = "50:9a:4c:5d:c3:7a";
			interfaces.wan0 = "50:9a:4c:5d:c3:7b";
		};
		# Create bridged lan interface for all containers
		bridges.br-lan0.interfaces = [ "lan0" ];
		# Disable dhcp on router interfaces
		interfaces = {
			veth-router-lan.useDHCP = false;
			vb-router-lan0.useDHCP = false;
		};
		# Configure network
		defaultGateway = {
			# Read explaination for veth-router-lan below
			address = "10.255.255.1";
			interface = "veth-router-lan";
		};
		nameservers = [ "192.168.1.1" ];  # DNS will only be available from this ip address THROUGH the default gateway
		# br-lan0 will be the interface used for networking on poweredge host
		interfaces.br-lan0.ipv4.addresses = [{
			address = hostIp;
			prefixLength = 24;
		}];
	};

	# Wireguard office tunnel secret
	sops.secrets.wg0-router.sopsFile = ./resources/secrets/wg0-router.yaml;

	# Router container
	containers.router = {
		autoStart = true;
		ephemeral = true;
		privateNetwork = true;
		# Pass wan0 directly into container since it isn't needed elsewhere
		interfaces = [ "wan0" ];
		# Setup router lan0
		# NOTE: Host/container communication is not possible through a hostBridge interface
		extraVeths.vb-router-lan0.hostBridge = "br-lan0";
		# Setup virtual host-router bridge interface.
		# This is the default gateway for host/container communication since
		# communication isn't possible through hostBridge interfaces.
		# This is essentially equivalent to connecting the host to the
		# container with a virtual ethernet cable on a separate interface.
		extraVeths.veth-router-lan = {
			hostAddress  = "10.255.255.2";
			localAddress = "10.255.255.1";
		};
		# Bind wg0-router secret to container
		bindMounts."/run/secrets/wg0" = {
			hostPath = config.sops.secrets.wg0-router.path;
			isReadOnly = true;
		};

		config = { lib, config, ... }: {
			imports = [
				../../nixos/services/router
				./router-hosts.nix  # Contains dhcp config + static leases + overrides
			];

			networking = {
				# Set ip addresses
				enableIPv6 = false;
				interfaces = {
					vb-router-lan0.ipv4.addresses = [{
						address = "192.168.1.1";
						prefixLength = 24;
					}];
					wan0.useDHCP = true;
				};
				# Setup wireguard
				wg-quick.interfaces = {
					wg0.configFile = "/run/secrets/wg0";
				};
				# Firewall (port-forwarding) rules
				firewall = {
					#interfaces.wan0 = {
					#	allowedTCPPorts = [ 8333 ];  # bitcoin
					#	allowedUDPPorts = [ 51820 ];  # wg
					#};
				};
				# Additional advanced rules
				# TODO add multi NAT feature to router service (this is just a normal nat rule)
				nftables = {
					enable = true;
					tables = {
						# NAT/masquerade wg0 allowing vb-router-lan0 clients to access wg0
						wg-nat = {
							family = "ip";
							content = ''
								chain post {
									type nat hook postrouting priority srcnat; policy accept;
									iifname "vb-router-lan0" oifname "wg0" masquerade comment "vb-router-lan0 => wg0"
									iifname "veth-router-lan" oifname "wg0" masquerade comment "veth-router-lan => wg0"
								}
						'';
						};
					};
				};
			};

			# Setup router
			services._router = {
				dnsDhcpConfig.enable = true;
				routing = {
					enable = true;
					interfaces = {
						lan = [ "vb-router-lan0" "veth-router-lan" ];
						wan = "wan0";
					};
				};
			};

			system.stateVersion = "25.11";
		};
	};

}