summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/networking/xl2tpd.nix
blob: 21b70c9f16acc2b8854e0c740acd5f25c7aea557 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{
  config,
  pkgs,
  lib,
  ...
}:

with lib;

{
  options = {
    services.xl2tpd = {
      enable = mkEnableOption "xl2tpd, the Layer 2 Tunnelling Protocol Daemon";

      serverIp = mkOption {
        type = types.str;
        description = "The server-side IP address.";
        default = "10.125.125.1";
      };

      clientIpRange = mkOption {
        type = types.str;
        description = "The range from which client IPs are drawn.";
        default = "10.125.125.2-11";
      };

      extraXl2tpOptions = mkOption {
        type = types.lines;
        description = "Adds extra lines to the xl2tpd configuration file.";
        default = "";
      };

      extraPppdOptions = mkOption {
        type = types.lines;
        description = "Adds extra lines to the pppd options file.";
        default = "";
        example = ''
          ms-dns 8.8.8.8
          ms-dns 8.8.4.4
        '';
      };
    };
  };

  config = mkIf config.services.xl2tpd.enable {
    systemd.services.xl2tpd =
      let
        cfg = config.services.xl2tpd;

        # Config files from https://help.ubuntu.com/community/L2TPServer
        xl2tpd-conf = pkgs.writeText "xl2tpd.conf" ''
          [global]
          ipsec saref = no

          [lns default]
          local ip = ${cfg.serverIp}
          ip range = ${cfg.clientIpRange}
          pppoptfile = ${pppd-options}
          length bit = yes

          ; Extra
          ${cfg.extraXl2tpOptions}
        '';

        pppd-options = pkgs.writeText "ppp-options-xl2tpd.conf" ''
          refuse-pap
          refuse-chap
          refuse-mschap
          require-mschap-v2
          # require-mppe-128
          asyncmap 0
          auth
          crtscts
          idle 1800
          mtu 1200
          mru 1200
          lock
          hide-password
          local
          # debug
          name xl2tpd
          # proxyarp
          lcp-echo-interval 30
          lcp-echo-failure 4

          # Extra:
          ${cfg.extraPppdOptions}
        '';

        xl2tpd-ppp-wrapped = pkgs.stdenv.mkDerivation {
          name = "xl2tpd-ppp-wrapped";
          nativeBuildInputs = with pkgs; [ makeWrapper ];
          buildCommand = ''
            mkdir -p $out/bin

            makeWrapper ${pkgs.ppp}/sbin/pppd $out/bin/pppd \
              --set LD_PRELOAD    "${pkgs.libredirect}/lib/libredirect.so" \
              --set NIX_REDIRECTS "/etc/ppp=/etc/xl2tpd/ppp"

            makeWrapper ${pkgs.xl2tpd}/bin/xl2tpd $out/bin/xl2tpd \
              --set LD_PRELOAD    "${pkgs.libredirect}/lib/libredirect.so" \
              --set NIX_REDIRECTS "${pkgs.ppp}/sbin/pppd=$out/bin/pppd"
          '';
        };
      in
      {
        description = "xl2tpd server";

        requires = [ "network-online.target" ];
        wantedBy = [ "multi-user.target" ];

        preStart = ''
          install -m 700 -d /etc/xl2tpd/ppp

          [ -f /etc/xl2tpd/ppp/chap-secrets ] || install -m 600 -o root -g root /dev/stdin /etc/xl2tpd/ppp/chap-secrets <<EOF
          # Secrets for authentication using CHAP
          # client	server	secret		IP addresses
          #username	xl2tpd	password	*
          EOF

          # The documentation says this file should be present but doesn't explain why and things work even if not there:
          [ -f /etc/xl2tpd/l2tp-secrets ] || install -m 600 -o root -g root <(echo -n "* * "; ${pkgs.apg}/bin/apg -n 1 -m 32 -x 32 -a 1 -M LCN) /etc/xl2tpd/l2tp-secrets

          install -m 701 -o root -g root -d /run/xl2tpd
        '';

        serviceConfig = {
          ExecStart = "${xl2tpd-ppp-wrapped}/bin/xl2tpd -D -c ${xl2tpd-conf} -s /etc/xl2tpd/l2tp-secrets -p /run/xl2tpd/pid -C /run/xl2tpd/control";
          KillMode = "process";
          Restart = "on-success";
          Type = "simple";
          PIDFile = "/run/xl2tpd/pid";
        };
      };
  };
}