summaryrefslogtreecommitdiff
path: root/modules/xnet/net/vpn-gateway.nix
blob: d26ced1f46e416a6aaabdc9bc559279a6000834b (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
{ config, lib, pkgs, ... }:
let
  cfg = config.xnet.net.vpnGateway;
  inherit (lib) mkOption mkIf types;

  iface = "enp2s0";
  fwmark = "0x1";
  ip = "192.168.2.113";
  vpn = {
    iface = "wg0";
    endpoint = "149.88.22.129:51820";
    addr = "10.69.70.71/32";
    peers = [

    ];
  };
in

{
  # options.xnet.net.vpnGateway = {
  #   interface = mkOption {
  #     type = types.str;
  #     description = "Interface to forward VPN routed packets to internet";
  #   };
  #
  #   vpn = types.subModule {
  #     interface = mkOption {
  #       type = types.str;
  #       default = "wg0";
  #       description = "Name of VPN interface.";
  #     };
  #
  #     endpoint = mkOption {
  #       type = types.str;
  #       description = "ip:port of the VPN endpoint.";
  #     };
  #
  #     addr = mkOption {
  #       type = types.str;
  #       description = "Address of the VPN interface.";
  #     };
  #
  #     privateKeyFile = mkOption {
  #       type = types.str;
  #       description = "Path to private key.";
  #     };
  #
  #     peers = types.listOf types.subModule {
  #
  #     };
  #   };

  boot.kernel.sysctl = {
    "net.ipv4.ip_forward" = 1;
    "net.ipv6.conf.all.forwarding" = 1;
  };

  networking = {
    wg-quick.interfaces."${vpn.iface}" = {
      address = [ vpn.addr ];
      privateKeyFile = "/certs/wg/private.key";

      peers = [{
        publicKey = "yxyntWsANEwxeR0pOPNAcfWY7zEVICZe9G+GxortzEY=";
        allowedIPs = [ "0.0.0.0/0" ];
        endpoint = "149.88.22.129:51820";
        persistentKeepalive = 25;
      }];
    };

    nat = {
      enable = true;
      externalInterface = "wg0";
      internalInterfaces = [ "enp2s0" ];
    };

    firewall = {
      extraCommands = ''
        # Create a new routing table for forwarded traffic
        echo "200 vpn" >> /etc/iproute2/rt_tables

        # Mark packets from other hosts
        iptables -t mangle -A PREROUTING -i enp2s0 ! -s 192.168.1.113 -j MARK --set-mark 0x1

        # Route marked packets through WireGuard
        ip rule add fwmark 0x1 table vpn
        ip route add default dev wg0 table vpn

        # Allow forwarding
        iptables -A FORWARD -i enp2s0 -o wg0 -j ACCEPT
        iptables -A FORWARD -i wg0 -o enp2s0 -m state --state RELATED,ESTABLISHED -j ACCEPT

        # NAT only forwarded traffic
        iptables -t nat -A POSTROUTING -o wg0 ! -s 192.168.1.113 -j MASQUERADE
      '';

      extraStopCommands = ''
        ip rule del fwmark 0x1 table vpn 2>/dev/null || true
        ip route flush table vpn 2>/dev/null || true
      '';
    };
  };
}