1{ config, lib, pkgs, ... }:
2let
3 cfg = config.services.mullvad-vpn;
4in
5with lib;
6{
7 options.services.mullvad-vpn = {
8 enable = mkOption {
9 type = types.bool;
10 default = false;
11 description = lib.mdDoc ''
12 This option enables Mullvad VPN daemon.
13 This sets {option}`networking.firewall.checkReversePath` to "loose", which might be undesirable for security.
14 '';
15 };
16
17 enableExcludeWrapper = mkOption {
18 type = types.bool;
19 default = true;
20 description = lib.mdDoc ''
21 This option activates the wrapper that allows the use of mullvad-exclude.
22 Might have minor security impact, so consider disabling if you do not use the feature.
23 '';
24 };
25
26 package = mkOption {
27 type = types.package;
28 default = pkgs.mullvad;
29 defaultText = literalExpression "pkgs.mullvad";
30 description = lib.mdDoc ''
31 The Mullvad package to use. `pkgs.mullvad` only provides the CLI tool, `pkgs.mullvad-vpn` provides both the CLI and the GUI.
32 '';
33 };
34 };
35
36 config = mkIf cfg.enable {
37 boot.kernelModules = [ "tun" ];
38
39 environment.systemPackages = [ cfg.package ];
40
41 # mullvad-daemon writes to /etc/iproute2/rt_tables
42 networking.iproute2.enable = true;
43
44 # See https://github.com/NixOS/nixpkgs/issues/113589
45 networking.firewall.checkReversePath = "loose";
46
47 # See https://github.com/NixOS/nixpkgs/issues/176603
48 security.wrappers.mullvad-exclude = mkIf cfg.enableExcludeWrapper {
49 setuid = true;
50 owner = "root";
51 group = "root";
52 source = "${cfg.package}/bin/mullvad-exclude";
53 };
54
55 systemd.services.mullvad-daemon = {
56 description = "Mullvad VPN daemon";
57 wantedBy = [ "multi-user.target" ];
58 wants = [ "network.target" ];
59 after = [
60 "network-online.target"
61 "NetworkManager.service"
62 "systemd-resolved.service"
63 ];
64 path = [
65 pkgs.iproute2
66 # Needed for ping
67 "/run/wrappers"
68 ];
69 startLimitBurst = 5;
70 startLimitIntervalSec = 20;
71 serviceConfig = {
72 ExecStart = "${cfg.package}/bin/mullvad-daemon -v --disable-stdout-timestamps";
73 Restart = "always";
74 RestartSec = 1;
75 };
76 };
77 };
78
79 meta.maintainers = with maintainers; [ patricksjackson ymarkus ];
80}