summaryrefslogtreecommitdiff
path: root/hosts/poweredge-pro/networking.nix
blob: 6f70ac8d05c6ef232391ad455d9cdb7d510424c3 (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
124
125
126
127
128
129
130
131
132
133
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.lan1 = "50:9a:4c:5d:c3:7a";
      interfaces.lan2 = "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 = "10.255.255.1";  # Read explaination for veth-router-lan below
    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;
    }];
  };

  # 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.ipv4.addresses = [
            # .163 address reserved for remote backup access
            { address = "46.110.173.161"; prefixLength = 29; }  # Gateway
            { address = "46.110.173.162"; prefixLength = 29; }  # Mail
            { address = "46.110.173.164"; prefixLength = 29; }  # Web
            { address = "46.110.173.165"; prefixLength = 29; }  # Wg
            { address = "46.110.173.166"; prefixLength = 29; }  # Spare
          ];
        };
        defaultGateway = {
          address = "46.110.173.161";
          interface = "wan0";
        };
        # NAT (port-forwarding) rules
        nat.forwardPorts =[
          #{  # Filebrowser
          #  sourcePort = 19045;
          #  proto = "tcp";
          #  destination = "192.168.1.45:9000";
          #}
        ];
      };

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

      services.unbound._blocklists = {
        enable = true;
        hageziBlocklists = [ "pro" "nsfw" ];
      };

      system.stateVersion = "26.05";
    };
  };

  # FIXME the following snippet will cause the router container to fail to start:
  #   networking.defaultGateway = {
  #     address = "10.255.255.1";
  #     interface = "veth-router-lan";
  #   };
  # Journalctl will report:
  #   poweredge container router: Bring veth-router-lan up
  #   poweredge container router: RTNETLINK answers: File exists
  #   poweredge systemd: container@router.service: Control process exited, code=exited, status=2/INVALIDARGUMENT
  # So the issue nixos is creating an interface with that same name.
  # As a temporary workaround, the following service is deployed (after the container starts):
  systemd.services.router-default-route = {
    after = [ "container@router.service" ];
    wants = [ "container@router.service" ];
    serviceConfig.Type = "oneshot";
    script = ''
      /run/current-system/sw/bin/ip route replace default via 10.255.255.1 dev veth-router-lan
    '';
    wantedBy = [ "multi-user.target" ];
  };
}