vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / libreswan.nix
bloba66ff30652241c2c2db643da707716a20b2b5b47
1 { config, lib, pkgs, ... }:
2 let
4   cfg = config.services.libreswan;
6   libexec = "${pkgs.libreswan}/libexec/ipsec";
7   ipsec = "${pkgs.libreswan}/sbin/ipsec";
9   trim = chars: str:
10   let
11     nonchars = lib.filter (x : !(lib.elem x.value chars))
12                (lib.imap0 (i: v: {ind = i; value = v;}) (lib.stringToCharacters str));
13   in
14     lib.optionalString (nonchars != [ ])
15       (lib.substring (lib.head nonchars).ind (lib.add 1 (lib.sub (lib.last nonchars).ind (lib.head nonchars).ind)) str);
16   indent = str: lib.concatStrings (lib.concatMap (s: ["  " (trim [" " "\t"] s) "\n"]) (lib.splitString "\n" str));
17   configText = indent (toString cfg.configSetup);
18   connectionText = lib.concatStrings (lib.mapAttrsToList (n: v:
19     ''
20       conn ${n}
21       ${indent v}
22     '') cfg.connections);
24   configFile = pkgs.writeText "ipsec-nixos.conf"
25     ''
26       config setup
27       ${configText}
29       ${connectionText}
30     '';
32   policyFiles = lib.mapAttrs' (name: text:
33     { name = "ipsec.d/policies/${name}";
34       value.source = pkgs.writeText "ipsec-policy-${name}" text;
35     }) cfg.policies;
41   ###### interface
43   options = {
45     services.libreswan = {
47       enable = lib.mkEnableOption "Libreswan IPsec service";
49       configSetup = lib.mkOption {
50         type = lib.types.lines;
51         default = ''
52             protostack=netkey
53             virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10
54         '';
55         example = ''
56             secretsfile=/root/ipsec.secrets
57             protostack=netkey
58             virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10
59         '';
60         description = "Options to go in the 'config setup' section of the Libreswan IPsec configuration";
61       };
63       connections = lib.mkOption {
64         type = lib.types.attrsOf lib.types.lines;
65         default = {};
66         example = lib.literalExpression ''
67           { myconnection = '''
68               auto=add
69               left=%defaultroute
70               leftid=@user
72               right=my.vpn.com
74               ikev2=no
75               ikelifetime=8h
76             ''';
77           }
78         '';
79         description = "A set of connections to define for the Libreswan IPsec service";
80       };
82       policies = lib.mkOption {
83         type = lib.types.attrsOf lib.types.lines;
84         default = {};
85         example = lib.literalExpression ''
86           { private-or-clear = '''
87               # Attempt opportunistic IPsec for the entire Internet
88               0.0.0.0/0
89               ::/0
90             ''';
91           }
92         '';
93         description = ''
94           A set of policies to apply to the IPsec connections.
96           ::: {.note}
97           The policy name must match the one of connection it needs to apply to.
98           :::
99         '';
100       };
102       disableRedirects = lib.mkOption {
103         type = lib.types.bool;
104         default = true;
105         description = ''
106           Whether to disable send and accept redirects for all network interfaces.
107           See the Libreswan [
108           FAQ](https://libreswan.org/wiki/FAQ#Why_is_it_recommended_to_disable_send_redirects_in_.2Fproc.2Fsys.2Fnet_.3F) page for why this is recommended.
109         '';
110       };
112     };
114   };
117   ###### implementation
119   config = lib.mkIf cfg.enable {
121     # Install package, systemd units, etc.
122     environment.systemPackages = [ pkgs.libreswan pkgs.iproute2 ];
123     systemd.packages = [ pkgs.libreswan ];
124     systemd.tmpfiles.packages = [ pkgs.libreswan ];
126     # Install configuration files
127     environment.etc = {
128       "ipsec.secrets".source = "${pkgs.libreswan}/etc/ipsec.secrets";
129       "ipsec.conf".source = "${pkgs.libreswan}/etc/ipsec.conf";
130       "ipsec.d/01-nixos.conf".source = configFile;
131     } // policyFiles;
133     systemd.services.ipsec = {
134       description = "Internet Key Exchange (IKE) Protocol Daemon for IPsec";
135       wantedBy = [ "multi-user.target" ];
136       restartTriggers = [ configFile ] ++ lib.mapAttrsToList (n: v: v.source) policyFiles;
137       path = with pkgs; [
138         libreswan
139         iproute2
140         procps
141         nssTools
142         iptables
143         nettools
144       ];
145       preStart = lib.optionalString cfg.disableRedirects ''
146         # Disable send/receive redirects
147         echo 0 | tee /proc/sys/net/ipv4/conf/*/send_redirects
148         echo 0 | tee /proc/sys/net/ipv{4,6}/conf/*/accept_redirects
149       '';
150       serviceConfig = {
151         StateDirectory = "ipsec/nss";
152         StateDirectoryMode = 0700;
153       };
154     };
156   };