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 serviceConfig = {
67 Type = "oneshot";
68 RemainAfterExit = false;
69 };
70 script = ''
71 for d in vpnserver vpnbridge vpnclient vpncmd; do
72 if ! test -e ${cfg.dataDir}/$d; then
73 ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
74 install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
75 fi
76 done
77 rm -rf ${cfg.dataDir}/vpncmd/vpncmd
78 ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
79 '';
80 };
81 }
82
83 (mkIf (cfg.vpnserver.enable) {
84 systemd.services.vpnserver = {
85 description = "SoftEther VPN Server";
86 after = [ "softether-init.service" "network.target" ];
87 wants = [ "softether-init.service" ];
88 wantedBy = [ "multi-user.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" "network.target" ];
108 wants = [ "softether-init.service" ];
109 wantedBy = [ "multi-user.target" ];
110 serviceConfig = {
111 Type = "forking";
112 ExecStart = "${pkg}/bin/vpnbridge start";
113 ExecStop = "${pkg}/bin/vpnbridge stop";
114 };
115 preStart = ''
116 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
117 ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
118 '';
119 postStop = ''
120 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
121 '';
122 };
123 })
124
125 (mkIf (cfg.vpnclient.enable) {
126 systemd.services.vpnclient = {
127 description = "SoftEther VPN Client";
128 after = [ "softether-init.service" "network.target" ];
129 wants = [ "softether-init.service" ];
130 wantedBy = [ "multi-user.target" ];
131 serviceConfig = {
132 Type = "forking";
133 ExecStart = "${pkg}/bin/vpnclient start";
134 ExecStop = "${pkg}/bin/vpnclient stop";
135 };
136 preStart = ''
137 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
138 ln -s ${pkg}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
139 '';
140 postStart = ''
141 sleep 1
142 ${cfg.vpnclient.up}
143 '';
144 postStop = ''
145 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
146 sleep 1
147 ${cfg.vpnclient.down}
148 '';
149 };
150 boot.kernelModules = [ "tun" ];
151 })
152
153 ]);
154
155}