summaryrefslogtreecommitdiff
path: root/modules/router.nix
blob: 359832e390f051a01023d5b5827b409fce820c45 (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
{ config, lib, pkgs, ... }:
with lib;
let
  cfg = config.orbekk.router;

  devices = ["eno1" "eno2"];

  router-netns-up = pkgs.writeScript "router-netns-up" ''
    #!${pkgs.bash}/bin/bash
    ip netns add router
    ip netns exec router ip link set lo up
    ${lib.concatMapStrings (device: ''
      ip link set ${device} netns router
    '')
    devices}
    ip link add router-vport type veth peer name dragon-vport netns router
  '';

  router-netns-down = pkgs.writeScript "router-netns-down" ''
    #!${pkgs.bash}/bin/bash
    ip link del main
    ip netns del router
  '';

  router-config = { config, lib, pkgs, ... }: {
    system.stateVersion = "22.05";

    virtualisation.vswitch.enable = true;
    virtualisation.vswitch.resetOnStart = true;
    networking.vswitches.kjlan = {
      interfaces.wan-vport = { vlan = 10; type = "internal"; };
      interfaces.lan-vport = { vlan = 100; type = "internal"; };
      interfaces.admin-vport = { vlan = 255; type = "internal"; };
      interfaces.dragon-vport = { vlan = 100; };

      extraOvsctlCmds = ''
        add bond kjlan bond0 eno1 eno2 lacp=active miimon=5000
        set interface wan-vport mac=\"3c:97:0e:19:7e:5c\"
      '';
    };

    networking.interfaces.lan-vport = {
      ipv4.addresses = [{address = "172.20.100.1"; prefixLength = 23;}];
    };
    networking.interfaces.admin-vport = {
      ipv4.addresses = [{address = "10.10.255.18"; prefixLength = 24;}];
      ipv4.routes = [{address = "10.10.255.0"; prefixLength = 24;}];
    };

    services.dnsmasq = {
      enable = true;
      servers = [ "1.1.1.1" "8.8.8.8" "8.8.4.4" ];
      resolveLocalQueries = false;

      extraConfig = ''
        no-resolv
        no-hosts

        address=/localhost/::1
        address=/localhost/127.0.0.1

        dhcp-range=lan-vport,172.20.100.1,172.20.101.254,5m
        dhcp-option=net:lan,option:router,172.20.100.1
        dhcp-option=net:lan,option:dns-server,172.20.100.1
      '';
    };

    networking.dhcpcd = {
      extraConfig = ''
        interface wan-vport
          dhcp
      '';
    };
  };
in {
  options = {
    orbekk.router = {
      enable = mkEnableOption "Enable router config";
    };
  };

  config = mkIf cfg.enable {
    systemd.services."router-netns" = {
      description = "router network namespace";
      before = ["network.target"];
      after = ["network-interfaces.target"];
      path = with pkgs; [bash iproute];
      serviceConfig = {
        Type = "oneshot";
        RemainAfterExit = "yes";
        ExecStart = "${router-netns-up}";
        ExecStop = "${router-netns-down}";
      };
    };

    networking.wireguard.interfaces.vpn.interfaceNamespace = "router";

    systemd.services."container@router" = {
      after = ["router-netns.service"];
      wantedBy = ["network.target"];
    };

    containers.router = {
      autoStart = true;
      extraFlags = ["--network-namespace-path" "/var/run/netns/router"];
      privateNetwork = false;
      config = router-config;
      additionalCapabilities = ["CAP_NET_ADMIN"];
    };
  };
}