infrastructure

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

wireguard-server.nix (3086B)


      1 {
      2   config,
      3   pkgs,
      4   lib,
      5   ...
      6 }:
      7 
      8 let
      9   cfg = config.services.local.wireguard-server;
     10 in
     11 {
     12   options.services.local.wireguard-server = {
     13     enable = lib.mkEnableOption "WireGuard VPN server";
     14 
     15     address = lib.mkOption {
     16       type = lib.types.str;
     17       default = "10.100.0.1/24";
     18       description = "VPN server address with CIDR";
     19     };
     20 
     21     privateKeySecretName = lib.mkOption {
     22       type = lib.types.str;
     23       description = "Name of the sops secret containing the private key";
     24     };
     25 
     26     listenPort = lib.mkOption {
     27       type = lib.types.port;
     28       default = 51820;
     29       description = "WireGuard listen port";
     30     };
     31 
     32     externalInterface = lib.mkOption {
     33       type = lib.types.str;
     34       default = "eth0";
     35       description = "External network interface for NAT";
     36     };
     37 
     38     peers = lib.mkOption {
     39       type = lib.types.listOf (lib.types.submodule {
     40         options = {
     41           name = lib.mkOption {
     42             type = lib.types.str;
     43             description = "Peer name (for comments)";
     44           };
     45           publicKey = lib.mkOption {
     46             type = lib.types.str;
     47             description = "Peer's public key";
     48           };
     49           allowedIPs = lib.mkOption {
     50             type = lib.types.listOf lib.types.str;
     51             description = "Allowed IPs for this peer";
     52           };
     53         };
     54       });
     55       default = [];
     56       description = "List of VPN peers";
     57     };
     58 
     59     enableDnsmasq = lib.mkOption {
     60       type = lib.types.bool;
     61       default = true;
     62       description = "Enable dnsmasq for VPN DNS";
     63     };
     64   };
     65 
     66   config = lib.mkIf cfg.enable {
     67     sops.secrets.${cfg.privateKeySecretName} = {
     68       restartUnits = [ "wg-quick-wg0.service" ];
     69     };
     70 
     71     networking.nat = {
     72       enable = true;
     73       externalInterface = cfg.externalInterface;
     74       internalInterfaces = [ "wg0" ];
     75     };
     76 
     77     networking.firewall.allowedUDPPorts = [ cfg.listenPort ] ++ lib.optionals cfg.enableDnsmasq [ 53 ];
     78     networking.firewall.allowedTCPPorts = lib.optionals cfg.enableDnsmasq [ 53 ];
     79 
     80     services.dnsmasq = lib.mkIf cfg.enableDnsmasq {
     81       enable = true;
     82       settings = {
     83         interface = "wg0";
     84       };
     85     };
     86 
     87     networking.wg-quick.interfaces.wg0 = {
     88       address = [ cfg.address ];
     89       listenPort = cfg.listenPort;
     90       privateKeyFile = "/run/secrets/${cfg.privateKeySecretName}";
     91 
     92       postUp = ''
     93         ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -o ${cfg.externalInterface} -j ACCEPT
     94         ${pkgs.iptables}/bin/iptables -A FORWARD -o wg0 -i ${cfg.externalInterface} -j ACCEPT
     95         ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s ${cfg.address} -j MASQUERADE
     96       '';
     97       preDown = ''
     98         ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -o ${cfg.externalInterface} -j ACCEPT
     99         ${pkgs.iptables}/bin/iptables -D FORWARD -o wg0 -i ${cfg.externalInterface} -j ACCEPT
    100         ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s ${cfg.address} -j MASQUERADE
    101       '';
    102 
    103       peers = map (peer: {
    104         publicKey = peer.publicKey;
    105         allowedIPs = peer.allowedIPs;
    106       }) cfg.peers;
    107     };
    108   };
    109 }