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}