modules.services.xray.xmuPersist: init

This commit is contained in:
2025-08-01 13:56:58 +08:00
parent 2acd77be56
commit b0fee64fc7
7 changed files with 81 additions and 20 deletions

View File

@@ -113,7 +113,7 @@ inputs:
gitea = {};
grafana = {};
fail2ban = {};
xray.server = {};
xray = { server = {}; xmuPersist = {}; };
podman = {};
peertube = {};
nginx.applications.webdav.instances."webdav.chn.moe" = {};

View File

@@ -84,6 +84,8 @@ peertube:
open-webui:
openai: ENC[AES256_GCM,data:5B1wPAOx3GsLDoYBKHWFzoyXFmn93fdcq6UC2rCt/P5zYLA4VNzfsp0=,iv:Y2gTLCmwB5wY4dhN73HRvTqSMVXbAEd+RjRbgUEuTeE=,tag:vcfNhXpG0C3twFBsm7PHwA==,type:str]
webui: ENC[AES256_GCM,data:Lg32DZ5GC+AYzWc4WloNMQlnpsqW67s5/kXzYwE=,iv:ECncgdYoLkX9GUOX26MXFSO8JOZahUDjTdKV87IRNJ8=,tag:J/5tTR3MI0iGIVDrlacYEg==,type:str]
xray-xmu-client:
cookie: ENC[AES256_GCM,data:z1KI3CUfPqyiI/B/qgrNhg==,iv:QEjUlMkkF/fdwwEIGiJJ5UxFGw869qAnpApmWaRn3GY=,tag:EbdJsYEslwJbARxDoEWrDA==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -104,7 +106,7 @@ sops:
d0h3aDh5QXFZYWJFdmNVYnJxQ3pBeVUKTl0XVvtwJcz+RpSylgDPl/R8msInxvWX
eQGmrDHibeE1V+KSDiuNzC4MVRIrOnh1beHrhnVQ86HwPVgJqs2FoQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-07-27T07:31:29Z"
mac: ENC[AES256_GCM,data:SKxLkMb07dubyKuLKXlnmUIXnzFQh6fTzN6BmsQ/FJzIOtT9T3G7WnoMkp71VhXDCMWCxiF5MvnX/EjrcquZjxnfPtib6OaAx+XFFcpPMLWSGJY+HtmECLYQncZpMJGC4hW2cj7T/iCHKAyyV9OGYeyNvRoZNpPRlpUL6VbN1UI=,iv:o3lEXl30PYCEUpe6jTXXB0AhuBwGFUaN88drFeeh7pc=,tag:Zbr2POkKq5/zk2AgHbTNMg==,type:str]
lastmodified: "2025-08-01T05:55:35Z"
mac: ENC[AES256_GCM,data:MEgCbEJ/bwx3EVWVYQjb1RbNx8OlJkqelHPbMG5DzSRgcBcllptTFCanLIPZrg4FihkHx3b41Q5xsCXbras1njh4R1FeyLVVGZH7pYjZaPF2MRaD8nYeCHKlItWUVvHQTf5bRrTOOQoo4Kmn2by/xdMWwZlZwt0aBoGnEYBxGf0=,iv:lrPlg8cM5qPgQPpIUHF6WBVglTe9YQtI28hfJSgJ1vU=,tag:tjucRsf+tt9F03Mhjf+jeg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -26,7 +26,7 @@ inputs:
services =
{
sshd = {};
xray.server = {};
xray = { server = {}; xmuPersist = {}; };
nginx =
{
streamProxy.map =

View File

@@ -44,6 +44,8 @@ send:
coturn:
auth-secret: ENC[AES256_GCM,data:50KqO4GQ1ERbCnK4IjYu6aywT+IPMtVlTzh/TE4MwWApU4pO9yqz25ENGUAKRLi4p+Ecug+Rn3InRl1b+q6bAQ==,iv:SgHkHvHg/+yA1Z5E9effgCnZMVXv5amGNUsVKErai54=,tag:PoYLV9Xr0IXXsA39n7wiTQ==,type:str]
wireguard: ENC[AES256_GCM,data:5M7EAy/6+2UASWkjxE0Jrxwl0aNdAVZaUjQnD1wU3YvOAQ/c2DSL8hVtKf8=,iv:a2tXFf1+aP0JhdNtzP8e82KJ71m2o8nx+G0wIx4VMig=,tag:l4TS4QBz2fIkC9/GnZgHnQ==,type:str]
xray-xmu-client:
cookie: ENC[AES256_GCM,data:RZ2WFnsX7s/PVqA7ZKhGqw==,iv:CknFoAcHIiIwJI1IEXkFdWXcOCAZr50pfwmQN72OI8o=,tag:w2pNU1APxlSQsGMIEdE2OA==,type:str]
sops:
age:
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
@@ -64,7 +66,7 @@ sops:
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-12T23:51:02Z"
mac: ENC[AES256_GCM,data:3QxWxinb3a7jvmHJO1kcePNwd/igurjFWVJw/sGKBuZpo47LU+W8132b9GpKs79AedDa5BM5yu0XN+CPrkviMcNuX5a3lLy8oI22a1N8fuKjEehld1Jq/boitGIsgJgb/M0Hn6yIq1ytuWuxoj2cOvmkEfNuyWRew+htI4DhJ/E=,iv:OyCWfcn218oaA970T9miIWIGSwOFeUbtWI0xO/02Hrw=,tag:c8riJplInFN1ZSPH3ze0QQ==,type:str]
lastmodified: "2025-08-01T05:54:47Z"
mac: ENC[AES256_GCM,data:OtHwr58A1UOfYxQR88ay76fWmAyWPl5YtNbAiv0LXPLZPRtLGBJKuTjMaHr17AMepFZ+u5IPV2r8z1AUDj0opLXlv3Ik/DJ2PCcQTOBH+/lnSgzJKWfdCip9/wFR6N3dT0PKKLuBiURB9ZCYmtnq6E5+Guadc6ATYDSEpwbENZQ=,iv:kXsYMGjAtUlv1UqFU8Xv0zagohnpHkzSI72mq5HKY7k=,tag:KR+1A8l2VvbzDZV/00hbJg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

View File

@@ -46,20 +46,7 @@ inputs:
security = "tls";
xhttpSettings =
{
path =
let
inherit (xmuClient) hostname;
paddedLength = ((builtins.div ((builtins.stringLength hostname) - 1) 16) + 1) * 16;
paddedString = builtins.concatStringsSep ""
(builtins.genList
(n: if n < builtins.stringLength hostname then builtins.substring n 1 hostname else "0")
paddedLength);
paddedHex = inputs.pkgs.localPackages.aes128CfbHex
{ data = hostname; key = "wrdvpnisthebest!"; iv = "wrdvpnisthebest!"; };
prefix = builtins.concatStringsSep "" (builtins.map
(c: inputs.lib.toHexString (inputs.lib.strings.charToInt c))
(inputs.lib.stringToCharacters "wrdvpnisthebest!"));
in "/https/${prefix}${paddedHex}/xsession";
path = "${inputs.pkgs.localPackages.webvpnPath xmuClient.hostname}/xsession";
mode = "packet-up";
security = "tls";
extra.headers.Cookie =

View File

@@ -0,0 +1,57 @@
inputs:
{
options.nixos.services.xray.xmuPersist = let inherit (inputs.lib) mkOption types; in mkOption
{
type = types.nullOr (types.submodule (submoduleInputs: { options =
{
keepAliveHost = mkOption { type = types.nonEmptyStr; default = "blog.chn.moe"; };
};}));
default = null;
};
config = let inherit (inputs.config.nixos.services.xray) xmuPersist; in inputs.lib.mkIf (xmuPersist != null)
{
nixos.system.sops =
{
templates."xray-xmu-persist-cookie.txt" =
{
owner = inputs.config.users.users.v2ray.name;
group = inputs.config.users.users.v2ray.group;
content = let cookie = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie"; in
''
.webvpn.xmu.edu.cn TRUE / TRUE 0 wengine_vpn_ticketwebvpn_xmu_edu_cn ${cookie}
webvpn.xmu.edu.cn FALSE / TRUE 0 show_vpn 0
webvpn.xmu.edu.cn FALSE / TRUE 0 heartbeat 1
webvpn.xmu.edu.cn FALSE / TRUE 0 show_faq 0
webvpn.xmu.edu.cn FALSE / FALSE 0 refresh 0
'';
};
secrets."xray-xmu-client/cookie" = {};
};
systemd =
{
services.xray-xmu-persist =
{
script =
let
curl = "${inputs.pkgs.curl}/bin/curl";
cookie = inputs.config.nixos.system.sops.templates."xray-xmu-persist-cookie.txt".path;
in
''
${curl} -s -o /dev/null -w "%{http_code}\n" -b ${cookie} \
"https://webvpn.xmu.edu.cn${inputs.pkgs.localPackages.webvpnPath xmuPersist.keepAliveHost}/";
'';
serviceConfig = { Type = "oneshot"; User = "v2ray"; Group = "v2ray"; };
};
timers.xray-xmu-persist =
{
wantedBy = [ "timers.target" ];
timerConfig = { OnCalendar = "*-*-* *:*:00"; Unit = "xray-xmu-persist.service"; };
};
};
users =
{
users.v2ray = { uid = inputs.config.nixos.user.uid.v2ray; group = "v2ray"; isSystemUser = true; };
groups.v2ray.gid = inputs.config.nixos.user.gid.v2ray;
};
};
}

View File

@@ -165,4 +165,17 @@ inputs: rec
hexEncryptedFile = inputs.pkgs.runCommand "aes128cfb-hex-encrypted" {}
"${xxd} -p ${encryptedFile} | ${tr} -d '\n' > $out";
in builtins.readFile hexEncryptedFile;
webvpnPath = hostname:
let
paddedLength = ((builtins.div ((builtins.stringLength hostname) - 1) 16) + 1) * 16;
paddedString = builtins.concatStringsSep ""
(builtins.genList
(n: if n < builtins.stringLength hostname then builtins.substring n 1 hostname else "0")
paddedLength);
paddedHex = aes128CfbHex
{ data = hostname; key = "wrdvpnisthebest!"; iv = "wrdvpnisthebest!"; };
prefix = builtins.concatStringsSep "" (builtins.map
(c: inputs.pkgs.lib.toHexString (inputs.pkgs.lib.strings.charToInt c))
(inputs.pkgs.lib.stringToCharacters "wrdvpnisthebest!"));
in "/https/${prefix}${paddedHex}";
}