nixos/pppd: init (#71105)

nixos/pppd: init
This commit is contained in:
Florian Klink 2019-10-17 01:15:55 +02:00 committed by GitHub
commit fff04a0a49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 0 deletions

View file

@ -1450,6 +1450,12 @@
githubId = 245394;
name = "Hannu Hartikainen";
};
danderson = {
email = "dave@natulte.net";
github = "danderson";
githubId = 1918;
name = "David Anderson";
};
danharaj = {
email = "dan@obsidian.systems";
github = "danharaj";

View file

@ -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

View file

@ -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;
};
}

View file

@ -227,6 +227,7 @@ in
postgresql = handleTest ./postgresql.nix {};
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
powerdns = handleTest ./powerdns.nix {};
pppd = handleTest ./pppd.nix {};
predictable-interface-names = handleTest ./predictable-interface-names.nix {};
printing = handleTest ./printing.nix {};
prometheus = handleTest ./prometheus.nix {};

62
nixos/tests/pppd.nix Normal file
View file

@ -0,0 +1,62 @@
import ./make-test.nix (
let
chap-secrets = {
text = ''"flynn" * "reindeerflotilla" *'';
mode = "0640";
};
in {
nodes = {
server = {config, pkgs, ...}: {
config = {
# Run a PPPoE access concentrator server. It will spawn an
# appropriate PPP server process when a PPPoE client sets up a
# PPPoE session.
systemd.services.pppoe-server = {
restartTriggers = [
config.environment.etc."ppp/pppoe-server-options".source
config.environment.etc."ppp/chap-secrets".source
];
after = ["network.target"];
serviceConfig = {
ExecStart = "${pkgs.rpPPPoE}/sbin/pppoe-server -F -O /etc/ppp/pppoe-server-options -q ${pkgs.ppp}/sbin/pppd -I eth1 -L 192.0.2.1 -R 192.0.2.2";
};
wantedBy = ["multi-user.target"];
};
environment.etc = {
"ppp/pppoe-server-options".text = ''
lcp-echo-interval 10
lcp-echo-failure 2
plugin rp-pppoe.so
require-chap
nobsdcomp
noccp
novj
'';
"ppp/chap-secrets" = chap-secrets;
};
};
};
client = {config, pkgs, ...}: {
services.pppd = {
enable = true;
peers.test = {
config = ''
plugin rp-pppoe.so eth1
name "flynn"
noipdefault
persist
noauth
debug
'';
};
};
environment.etc."ppp/chap-secrets" = chap-secrets;
};
};
testScript = ''
startAll;
$client->waitUntilSucceeds("ping -c1 -W1 192.0.2.1");
$server->waitUntilSucceeds("ping -c1 -W1 192.0.2.2");
'';
})