11 cfg = config.services.pppd;
20 enable = mkEnableOption "pppd";
22 package = mkPackageOption pkgs "ppp" { };
26 description = "pppd peers.";
27 type = types.attrsOf (
36 description = "Name of the PPP peer.";
43 description = "Whether to enable this PPP peer.";
46 autostart = mkOption {
50 description = "Whether the PPP session is automatically started at boot time.";
56 description = "pppd configuration for this peer, see the pppd(8) man page.";
68 enabledConfigs = filter (f: f.enable) (attrValues cfg.peers);
71 name = "ppp/peers/${peerCfg.name}";
72 value.text = peerCfg.config;
75 mkSystemd = peerCfg: {
76 name = "pppd-${peerCfg.name}";
78 restartTriggers = [ config.environment.etc."ppp/peers/${peerCfg.name}".source ];
79 before = [ "network.target" ];
80 wants = [ "network.target" ];
81 after = [ "network-pre.target" ];
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";
99 ExecStart = "${getBin cfg.package}/sbin/pppd call ${peerCfg.name} nodetach nolog";
103 AmbientCapabilities = capabilities;
104 CapabilityBoundingSet = capabilities;
105 KeyringMode = "private";
106 LockPersonality = true;
107 MemoryDenyWriteExecute = true;
108 NoNewPrivileges = true;
109 PrivateMounts = true;
111 ProtectControlGroups = true;
113 ProtectHostname = true;
114 ProtectKernelModules = true;
115 # pppd can be configured to tweak kernel settings.
116 ProtectKernelTunables = false;
117 ProtectSystem = "strict";
119 RestrictAddressFamilies = [
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
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;
148 wantedBy = mkIf peerCfg.autostart [ "multi-user.target" ];
152 etcFiles = listToAttrs (map mkEtc enabledConfigs);
153 systemdConfigs = listToAttrs (map mkSystemd enabledConfigs);
157 environment.etc = etcFiles;
158 systemd.services = systemdConfigs;