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 jobs.softether = {
65 description = "SoftEther VPN services initial job";
66 startOn = "started network-interfaces";
67 preStart = ''
68 for d in vpnserver vpnbridge vpnclient vpncmd; do
69 if ! test -e ${cfg.dataDir}/$d; then
70 ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
71 install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
72 fi
73 done
74 rm -rf ${cfg.dataDir}/vpncmd/vpncmd
75 ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
76 '';
77 exec = "true";
78 };
79 }
80
81 (mkIf (cfg.vpnserver.enable) {
82 systemd.services.vpnserver = {
83 description = "SoftEther VPN Server";
84 after = [ "network-interfaces.target" ];
85 wantedBy = [ "multi-user.target" ];
86 serviceConfig = {
87 ExecStart = "${pkg}/bin/vpnserver start";
88 ExecStop = "${pkg}/bin/vpnserver stop";
89 Type = "forking";
90 };
91 preStart = ''
92 rm -rf ${cfg.dataDir}/vpnserver/vpnserver
93 ln -s ${pkg}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
94 '';
95 postStop = ''
96 rm -rf ${cfg.dataDir}/vpnserver/vpnserver
97 '';
98 };
99 })
100
101 (mkIf (cfg.vpnbridge.enable) {
102 systemd.services.vpnbridge = {
103 description = "SoftEther VPN Bridge";
104 after = [ "network-interfaces.target" ];
105 wantedBy = [ "multi-user.target" ];
106 serviceConfig = {
107 ExecStart = "${pkg}/bin/vpnbridge start";
108 ExecStop = "${pkg}/bin/vpnbridge stop";
109 Type = "forking";
110 };
111 preStart = ''
112 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
113 ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
114 '';
115 postStop = ''
116 rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
117 '';
118 };
119 })
120
121 (mkIf (cfg.vpnclient.enable) {
122 systemd.services.vpnclient = {
123 description = "SoftEther VPN Client";
124 after = [ "network-interfaces.target" ];
125 wantedBy = [ "multi-user.target" ];
126 serviceConfig = {
127 ExecStart = "${pkg}/bin/vpnclient start";
128 ExecStop = "${pkg}/bin/vpnclient stop";
129 Type = "forking";
130 };
131 preStart = ''
132 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
133 ln -s ${pkg}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
134 '';
135 postStart = ''
136 sleep 1
137 ${cfg.vpnclient.up}
138 '';
139 postStop = ''
140 rm -rf ${cfg.dataDir}/vpnclient/vpnclient
141 sleep 1
142 ${cfg.vpnclient.down}
143 '';
144 };
145 boot.kernelModules = [ "tun" ];
146 })
147
148 ]);
149
150}