1{ config, stdenv, pkgs, lib, ... }:
2
3with lib;
4
5{
6 options = {
7 services.xl2tpd = {
8 enable = mkEnableOption "Whether xl2tpd should be run on startup.";
9
10 serverIp = mkOption {
11 type = types.string;
12 description = "The server-side IP address.";
13 default = "10.125.125.1";
14 };
15
16 clientIpRange = mkOption {
17 type = types.string;
18 description = "The range from which client IPs are drawn.";
19 default = "10.125.125.2-11";
20 };
21
22 extraXl2tpOptions = mkOption {
23 type = types.lines;
24 description = "Adds extra lines to the xl2tpd configuration file.";
25 default = "";
26 };
27
28 extraPppdOptions = mkOption {
29 type = types.lines;
30 description = "Adds extra lines to the pppd options file.";
31 default = "";
32 example = ''
33 ms-dns 8.8.8.8
34 ms-dns 8.8.4.4
35 '';
36 };
37 };
38 };
39
40 config = mkIf config.services.xl2tpd.enable {
41 systemd.services.xl2tpd = let
42 cfg = config.services.xl2tpd;
43
44 # Config files from https://help.ubuntu.com/community/L2TPServer
45 xl2tpd-conf = pkgs.writeText "xl2tpd.conf" ''
46 [global]
47 ipsec saref = no
48
49 [lns default]
50 local ip = ${cfg.serverIp}
51 ip range = ${cfg.clientIpRange}
52 pppoptfile = ${pppd-options}
53 length bit = yes
54
55 ; Extra
56 ${cfg.extraXl2tpOptions}
57 '';
58
59 pppd-options = pkgs.writeText "ppp-options-xl2tpd.conf" ''
60 refuse-pap
61 refuse-chap
62 refuse-mschap
63 require-mschap-v2
64 # require-mppe-128
65 asyncmap 0
66 auth
67 crtscts
68 idle 1800
69 mtu 1200
70 mru 1200
71 lock
72 hide-password
73 local
74 # debug
75 name xl2tpd
76 # proxyarp
77 lcp-echo-interval 30
78 lcp-echo-failure 4
79
80 # Extra:
81 ${cfg.extraPppdOptions}
82 '';
83
84 xl2tpd-ppp-wrapped = pkgs.stdenv.mkDerivation {
85 name = "xl2tpd-ppp-wrapped";
86 phases = [ "installPhase" ];
87 buildInputs = with pkgs; [ makeWrapper ];
88 installPhase = ''
89 mkdir -p $out/bin
90
91 makeWrapper ${pkgs.ppp}/sbin/pppd $out/bin/pppd \
92 --set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
93 --set NIX_REDIRECTS "/etc/ppp=/etc/xl2tpd/ppp"
94
95 makeWrapper ${pkgs.xl2tpd}/bin/xl2tpd $out/bin/xl2tpd \
96 --set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
97 --set NIX_REDIRECTS "${pkgs.ppp}/sbin/pppd=$out/bin/pppd"
98 '';
99 };
100 in {
101 description = "xl2tpd server";
102
103 requires = [ "network-online.target" ];
104 wantedBy = [ "multi-user.target" ];
105
106 preStart = ''
107 mkdir -p -m 700 /etc/xl2tpd
108
109 pushd /etc/xl2tpd > /dev/null
110
111 mkdir -p -m 700 ppp
112
113 [ -f ppp/chap-secrets ] || cat > ppp/chap-secrets << EOF
114 # Secrets for authentication using CHAP
115 # client server secret IP addresses
116 #username xl2tpd password *
117 EOF
118
119 chown root.root ppp/chap-secrets
120 chmod 600 ppp/chap-secrets
121
122 # The documentation says this file should be present but doesn't explain why and things work even if not there:
123 [ -f l2tp-secrets ] || (echo -n "* * "; ${pkgs.apg}/bin/apg -n 1 -m 32 -x 32 -a 1 -M LCN) > l2tp-secrets
124 chown root.root l2tp-secrets
125 chmod 600 l2tp-secrets
126
127 popd > /dev/null
128
129 mkdir -p /run/xl2tpd
130 chown root.root /run/xl2tpd
131 chmod 700 /run/xl2tpd
132 '';
133
134 serviceConfig = {
135 ExecStart = "${xl2tpd-ppp-wrapped}/bin/xl2tpd -D -c ${xl2tpd-conf} -s /etc/xl2tpd/l2tp-secrets -p /run/xl2tpd/pid -C /run/xl2tpd/control";
136 KillMode = "process";
137 Restart = "on-success";
138 Type = "simple";
139 PIDFile = "/run/xl2tpd/pid";
140 };
141 };
142 };
143}