1 { config, pkgs, lib, ... }:
3 inherit (lib) mkEnableOption mkPackageOption mkOption types;
5 cfg = config.services.wg-access-server;
7 settingsFormat = pkgs.formats.yaml { };
8 configFile = settingsFormat.generate "config.yaml" cfg.settings;
12 options.services.wg-access-server = {
13 enable = mkEnableOption "wg-access-server";
15 package = mkPackageOption pkgs "wg-access-server" { };
18 type = lib.types.submodule {
19 freeformType = settingsFormat.type;
21 dns.enable = mkOption {
25 Enable/disable the embedded DNS proxy server.
26 This is enabled by default and allows VPN clients to avoid DNS leaks by sending all DNS requests to wg-access-server itself.
31 default = "sqlite3://db.sqlite";
32 description = "A storage backend connection string. See [storage docs](https://www.freie-netze.org/wg-access-server/3-storage/)";
36 description = "See https://www.freie-netze.org/wg-access-server/2-configuration/ for possible options";
39 secretsFile = mkOption {
42 yaml file containing all secrets. this needs to be in the same structure as the configuration.
44 This must to contain the admin password and wireguard private key.
45 As well as the secrets for your auth backend.
49 adminPassword: <admin password>
51 privateKey: <wireguard private key>
54 clientSecret: <client secret>
60 config = lib.mkIf cfg.enable {
65 assertion = !lib.hasAttrByPath attrPath config.services.wg-access-server.settings;
67 {option}`services.wg-access-server.settings.${lib.concatStringsSep "." attrPath}` must definded
68 in {option}`services.wg-access-server.secretsFile`.
73 [ "wireguard" "privateKey" ]
74 [ "auth" "sessionStore" ]
75 [ "auth" "oidc" "clientSecret" ]
76 [ "auth" "gitlab" "clientSecret" ]
79 boot.kernel.sysctl = {
80 "net.ipv4.conf.all.forwarding" = "1";
81 "net.ipv6.conf.all.forwarding" = "1";
84 systemd.services.wg-access-server = {
85 description = "WG access server";
86 wantedBy = [ "multi-user.target" ];
87 requires = [ "network-online.target" ];
88 after = [ "network-online.target" ];
90 # merge secrets into main config
91 yq eval-all "select(fileIndex == 0) * select(fileIndex == 1)" ${configFile} $CREDENTIALS_DIRECTORY/SECRETS_FILE \
92 > "$STATE_DIRECTORY/config.yml"
94 ${lib.getExe cfg.package} serve --config "$STATE_DIRECTORY/config.yml"
99 # needed by startup script
107 ] ++ lib.optional cfg.settings.dns.enabled "CAP_NET_BIND_SERVICE";
110 WorkingDirectory = "/var/lib/wg-access-server";
111 StateDirectory = "wg-access-server";
114 "SECRETS_FILE:${cfg.secretsFile}"
119 AmbientCapabilities = capabilities;
120 CapabilityBoundingSet = capabilities;