Merge: zmap: 4.2.0 -> 4.3.1 (#364578)
[NixPkgs.git] / nixos / modules / services / networking / pppd.nix
blobb4ea3e213f889d17a55567fffeaea16d7ef1c105
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 with lib;
10 let
11   cfg = config.services.pppd;
14   meta = {
15     maintainers = [ ];
16   };
18   options = {
19     services.pppd = {
20       enable = mkEnableOption "pppd";
22       package = mkPackageOption pkgs "ppp" { };
24       peers = mkOption {
25         default = { };
26         description = "pppd peers.";
27         type = types.attrsOf (
28           types.submodule (
29             { name, ... }:
30             {
31               options = {
32                 name = mkOption {
33                   type = types.str;
34                   default = name;
35                   example = "dialup";
36                   description = "Name of the PPP peer.";
37                 };
39                 enable = mkOption {
40                   type = types.bool;
41                   default = true;
42                   example = false;
43                   description = "Whether to enable this PPP peer.";
44                 };
46                 autostart = mkOption {
47                   type = types.bool;
48                   default = true;
49                   example = false;
50                   description = "Whether the PPP session is automatically started at boot time.";
51                 };
53                 config = mkOption {
54                   type = types.lines;
55                   default = "";
56                   description = "pppd configuration for this peer, see the pppd(8) man page.";
57                 };
58               };
59             }
60           )
61         );
62       };
63     };
64   };
66   config =
67     let
68       enabledConfigs = filter (f: f.enable) (attrValues cfg.peers);
70       mkEtc = peerCfg: {
71         name = "ppp/peers/${peerCfg.name}";
72         value.text = peerCfg.config;
73       };
75       mkSystemd = peerCfg: {
76         name = "pppd-${peerCfg.name}";
77         value = {
78           restartTriggers = [ config.environment.etc."ppp/peers/${peerCfg.name}".source ];
79           before = [ "network.target" ];
80           wants = [ "network.target" ];
81           after = [ "network-pre.target" ];
82           environment = {
83             # pppd likes to write directly into /var/run. This is rude
84             # on a modern system, so we use libredirect to transparently
85             # move those files into /run/pppd.
86             LD_PRELOAD = "${pkgs.libredirect}/lib/libredirect.so";
87             NIX_REDIRECTS = "/var/run=/run/pppd";
88           };
89           serviceConfig =
90             let
91               capabilities = [
92                 "CAP_BPF"
93                 "CAP_SYS_TTY_CONFIG"
94                 "CAP_NET_ADMIN"
95                 "CAP_NET_RAW"
96               ];
97             in
98             {
99               ExecStart = "${getBin cfg.package}/sbin/pppd call ${peerCfg.name} nodetach nolog";
100               Restart = "always";
101               RestartSec = 5;
103               AmbientCapabilities = capabilities;
104               CapabilityBoundingSet = capabilities;
105               KeyringMode = "private";
106               LockPersonality = true;
107               MemoryDenyWriteExecute = true;
108               NoNewPrivileges = true;
109               PrivateMounts = true;
110               PrivateTmp = true;
111               ProtectControlGroups = true;
112               ProtectHome = true;
113               ProtectHostname = true;
114               ProtectKernelModules = true;
115               # pppd can be configured to tweak kernel settings.
116               ProtectKernelTunables = false;
117               ProtectSystem = "strict";
118               RemoveIPC = true;
119               RestrictAddressFamilies = [
120                 "AF_ATMPVC"
121                 "AF_ATMSVC"
122                 "AF_INET"
123                 "AF_INET6"
124                 "AF_IPX"
125                 "AF_NETLINK"
126                 "AF_PACKET"
127                 "AF_PPPOX"
128                 "AF_UNIX"
129               ];
130               RestrictNamespaces = true;
131               RestrictRealtime = true;
132               RestrictSUIDSGID = true;
133               SecureBits = "no-setuid-fixup-locked noroot-locked";
134               SystemCallFilter = "@system-service";
135               SystemCallArchitectures = "native";
137               # All pppd instances on a system must share a runtime
138               # directory in order for PPP multilink to work correctly. So
139               # we give all instances the same /run/pppd directory to store
140               # things in.
141               #
142               # For the same reason, we can't set PrivateUsers=true, because
143               # all instances need to run as the same user to access the
144               # multilink database.
145               RuntimeDirectory = "pppd";
146               RuntimeDirectoryPreserve = true;
147             };
148           wantedBy = mkIf peerCfg.autostart [ "multi-user.target" ];
149         };
150       };
152       etcFiles = listToAttrs (map mkEtc enabledConfigs);
153       systemdConfigs = listToAttrs (map mkSystemd enabledConfigs);
155     in
156     mkIf cfg.enable {
157       environment.etc = etcFiles;
158       systemd.services = systemdConfigs;
159     };