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