about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorDavid Anderson <dave@natulte.net>2019-10-14 01:59:50 -0700
committerDavid Anderson <dave@natulte.net>2019-10-15 08:36:09 -0700
commit997a6f6f1eee4f2191bbb73fab08a5765014cd1e (patch)
tree97c10cb67fca82078d8963d4e63861b03258f3ba /nixos
parentc5c5baf5afbdc648bdf5beb67ec9acb5fcf9068b (diff)
downloadnixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar.gz
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar.bz2
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar.lz
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar.xz
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.tar.zst
nixlib-997a6f6f1eee4f2191bbb73fab08a5765014cd1e.zip
nixos/pppd: init
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/networking/pppd.nix133
2 files changed, 134 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 4d177ae9699e..5214126ff7ed 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -666,6 +666,7 @@
   ./services/networking/polipo.nix
   ./services/networking/powerdns.nix
   ./services/networking/pdns-recursor.nix
+  ./services/networking/pppd.nix
   ./services/networking/pptpd.nix
   ./services/networking/prayer.nix
   ./services/networking/privoxy.nix
diff --git a/nixos/modules/services/networking/pppd.nix b/nixos/modules/services/networking/pppd.nix
new file mode 100644
index 000000000000..db1359117644
--- /dev/null
+++ b/nixos/modules/services/networking/pppd.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.pppd;
+in
+{
+  meta = {
+    maintainers = with maintainers; [ danderson ];
+  };
+
+  options = {
+    services.pppd = {
+      enable = mkEnableOption "pppd";
+
+      package = mkOption {
+        default = pkgs.ppp;
+        defaultText = "pkgs.ppp";
+        type = types.package;
+        description = "pppd package to use.";
+      };
+
+      peers = mkOption {
+        default = {};
+        type = types.attrsOf (types.submodule (
+          { name, ... }:
+          {
+            options = {
+              name = mkOption {
+                type = types.str;
+                default = name;
+                example = "dialup";
+                description = "Name of the PPP peer.";
+              };
+
+              enable = mkOption {
+                type = types.bool;
+                default = true;
+                example = false;
+                description = "Whether to enable this PPP peer.";
+              };
+
+              autostart = mkOption {
+                type = types.bool;
+                default = true;
+                example = false;
+                description = "Whether the PPP session is automatically started at boot time.";
+              };
+
+              config = mkOption {
+                type = types.lines;
+                default = "";
+                description = "pppd configuration for this peer, see the pppd(8) man page.";
+              };
+            };
+          }));
+      };
+    };
+  };
+
+  config = let
+    enabledConfigs = filter (f: f.enable) (attrValues cfg.peers);
+
+    mkEtc = peerCfg: {
+      "ppp/peers/${peerCfg.name}".text = peerCfg.config;
+    };
+
+    mkSystemd = peerCfg: {
+      "pppd-${peerCfg.name}" = {
+        restartTriggers = [ config.environment.etc."ppp/peers/${peerCfg.name}".source ];
+        before = [ "network.target" ];
+        wants = [ "network.target" ];
+        after = [ "network-pre.target" ];
+        environment = {
+          # pppd likes to write directly into /var/run. This is rude
+          # on a modern system, so we use libredirect to transparently
+          # move those files into /run/pppd.
+          LD_PRELOAD = "${pkgs.libredirect}/lib/libredirect.so";
+          NIX_REDIRECTS = "/var/run=/run/pppd";
+        };
+        serviceConfig = {
+          ExecStart = "${getBin cfg.package}/sbin/pppd call ${peerCfg.name} nodetach nolog";
+          Restart = "always";
+          RestartSec = 5;
+
+          AmbientCapabilities = "CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN";
+          CapabilityBoundingSet = "CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN";
+          KeyringMode = "private";
+          LockPersonality = true;
+          MemoryDenyWriteExecute = true;
+          NoNewPrivileges = true;
+          PrivateMounts = true;
+          PrivateTmp = true;
+          ProtectControlGroups = true;
+          ProtectHome = true;
+          ProtectHostname = true;
+          ProtectKernelModules = true;
+          # pppd can be configured to tweak kernel settings.
+          ProtectKernelTunables = false;
+          ProtectSystem = "strict";
+          RemoveIPC = true;
+          RestrictAddressFamilies = "AF_PACKET AF_UNIX AF_PPPOX AF_ATMPVC AF_ATMSVC AF_INET AF_INET6 AF_IPX";
+          RestrictNamespaces = true;
+          RestrictRealtime = true;
+          RestrictSUIDSGID = true;
+          SecureBits = "no-setuid-fixup-locked noroot-locked";
+          SystemCallFilter = "@system-service";
+          SystemCallArchitectures = "native";
+
+          # All pppd instances on a system must share a runtime
+          # directory in order for PPP multilink to work correctly. So
+          # we give all instances the same /run/pppd directory to store
+          # things in.
+          #
+          # For the same reason, we can't set PrivateUsers=true, because
+          # all instances need to run as the same user to access the
+          # multilink database.
+          RuntimeDirectory = "pppd";
+          RuntimeDirectoryPreserve = true;
+        };
+        wantedBy = mkIf peerCfg.autostart [ "multi-user.target" ];
+      };
+    };
+
+    etcFiles = map mkEtc enabledConfigs;
+    systemdConfigs = map mkSystemd enabledConfigs;
+
+  in mkIf cfg.enable {
+    environment.etc = mkMerge etcFiles;
+    systemd.services = mkMerge systemdConfigs;
+  };
+}