1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.softether;
7
8 package = cfg.package.override { inherit (cfg) dataDir; };
9
10in
11{
12
13 ###### interface
14
15 options = {
16
17 services.softether = {
18
19 enable = mkEnableOption "SoftEther VPN services";
20
21 package = mkPackageOption pkgs "softether" { };
22
23 vpnserver.enable = mkEnableOption "SoftEther VPN Server";
24
25 vpnbridge.enable = mkEnableOption "SoftEther VPN Bridge";
26
27 vpnclient = {
28 enable = mkEnableOption "SoftEther VPN Client";
29 up = mkOption {
30 type = types.lines;
31 default = "";
32 description = ''
33 Shell commands executed when the Virtual Network Adapter(s) is/are starting.
34 '';
35 };
36 down = mkOption {
37 type = types.lines;
38 default = "";
39 description = ''
40 Shell commands executed when the Virtual Network Adapter(s) is/are shutting down.
41 '';
42 };
43 };
44
45 dataDir = mkOption {
46 type = types.path;
47 default = "/var/lib/softether";
48 description = ''
49 Data directory for SoftEther VPN.
50 '';
51 };
52
53 };
54
55 };
56
57 ###### implementation
58
59 config = mkIf cfg.enable (
60
61 mkMerge [{
62 environment.systemPackages = [ package ];
63
64 systemd.services.softether-init = {
65 description = "SoftEther VPN services initial task";
66 wantedBy = [ "network.target" ];
67 serviceConfig = {
68 Type = "oneshot";
69 RemainAfterExit = false;
70 };
71 script = ''
72 for d in vpnserver vpnbridge vpnclient vpncmd; do
73 if ! test -e ${cfg.dataDir}/$d; then
74 ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
75 install -m0600 ${package}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
76 fi
77 done
78 rm -rf ${cfg.dataDir}/vpncmd/vpncmd
79 ln -s ${package}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
80 '';
81 };
82 }
83
84 (mkIf cfg.vpnserver.enable {
85 systemd.services.vpnserver = {
86 description = "SoftEther VPN Server";
87 after = [ "softether-init.service" ];
88 requires = [ "softether-init.service" ];
89 wantedBy = [ "network.target" ];
90 serviceConfig = {
91 Type = "forking";
92 ExecStart = "${package}/bin/vpnserver start";
93 ExecStop = "${package}/bin/vpnserver stop";
94 };
95 preStart = ''
96 rm -rf ${cfg.dataDir}/vpnserver/vpnserver
97 ln -s ${package}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
98 '';
99 postStop = ''
100 rm -rf ${cfg.dataDir}/vpnserver/vpnserver
101 '';
102 };
103 })
104
105 (mkIf cfg.vpnbridge.enable {
106 systemd.services.vpnbridge = {
107 description = "SoftEther VPN Bridge";
108 after = [ "softether-init.service" ];
109 requires = [ "softether-init.service" ];
110 wantedBy = [ "network.target" ];
111 serviceConfig = {
112 Type = "forking";
113 ExecStart = "${package}/bin/vpnbridge start";
114 ExecStop = "${package}/bin/vpnbridge stop";
115 };
116 preStart = ''
117 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
118 ln -s ${package}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
119 '';
120 postStop = ''
121 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
122 '';
123 };
124 })
125
126 (mkIf cfg.vpnclient.enable {
127 systemd.services.vpnclient = {
128 description = "SoftEther VPN Client";
129 after = [ "softether-init.service" ];
130 requires = [ "softether-init.service" ];
131 wantedBy = [ "network.target" ];
132 serviceConfig = {
133 Type = "forking";
134 ExecStart = "${package}/bin/vpnclient start";
135 ExecStop = "${package}/bin/vpnclient stop";
136 };
137 preStart = ''
138 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
139 ln -s ${package}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
140 '';
141 postStart = ''
142 sleep 1
143 ${cfg.vpnclient.up}
144 '';
145 postStop = ''
146 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
147 sleep 1
148 ${cfg.vpnclient.down}
149 '';
150 };
151 boot.kernelModules = [ "tun" ];
152 })
153
154 ]);
155
156}