diff --git a/src/linker.doc.web/docs/2、安装运行/2.7、初始化配置2(服务端).md b/src/linker.doc.web/docs/2、安装运行/2.7、初始化配置2(服务端).md
index 6c0eb1c3..f1264db5 100644
--- a/src/linker.doc.web/docs/2、安装运行/2.7、初始化配置2(服务端).md
+++ b/src/linker.doc.web/docs/2、安装运行/2.7、初始化配置2(服务端).md
@@ -22,30 +22,21 @@ server.json
//cdkey 加密密钥
"SecretKey": "snltty"
},
- //中继
- "Relay": {
- //中继密钥,客户端密钥不准确时无法使用本中继
- "SecretKey": "",
-
- },
//信标服务器端口
"ServicePort": 1802,
//内网穿透配置
"SForward": {
- //内网穿透密钥
- "SecretKey": "",
"BufferSize": 3,
//web端口,用于按域名穿透
"WebPort": 0,
//隧道端口范围,用于按端口穿透
- "TunnelPortRange": [
- 10000,
- 60000
- ]
+ "TunnelPortRange": [ 10000,60000]
},
//登入信标密钥,默认为空,即为所有客户端均可登入本信标服务器
"SignIn": {
- "SecretKey": "",
+ "Anonymous": true, //允许匿名登录
+ "SuperKey": "snltty", //超级密钥
+ "SuperPassword": "snltty",//超级密码
"CleanDays": 7 //当一组内的所有设备都超过7天未上线则清理
},
//虚拟网卡
@@ -56,11 +47,10 @@ server.json
"NetworkDays": 30 //网络租期
}
},
-
- //更新密钥,客户端密钥不正确时,只能更新自己本身
"Updater": {
- "SecretKey": ""
+ "Sync2Server": false //客户端自动同步到服务器版本
}
+
}
```
action.json,这个可以不管,等用得上自定义验证的时候就知道了
@@ -68,6 +58,7 @@ action.json,这个可以不管,等用得上自定义验证的时候就知道
{
"SignInActionUrl": "", //登入信标的验证接口
"RelayActionUrl": "", //中继验证接口
+ "RelayNodeUrl": "", //中继节点验证接口
"SForwardActionUrl": ""//服务器穿透的验证接口
}
```
diff --git a/src/linker.doc.web/docs/2、安装运行/2.8、初始化配置3(客户端).md b/src/linker.doc.web/docs/2、安装运行/2.8、初始化配置3(客户端).md
index 033c2a1f..e228bd6a 100644
--- a/src/linker.doc.web/docs/2、安装运行/2.8、初始化配置3(客户端).md
+++ b/src/linker.doc.web/docs/2、安装运行/2.8、初始化配置3(客户端).md
@@ -20,6 +20,10 @@ sidebar_position: 8
对应配置文件 client.json
```
{
+ //自定义验证
+ "Action": {
+ "Args": {} //自定义验证的参数
+ },
"Name": "A", //客户端名
//顶级满权限
"FullAccess": true,
@@ -31,17 +35,16 @@ sidebar_position: 8
"WebPort": 1804, //web端口
"WebRoot": "./web/" //web根目录
},
- //cdkey
- "Cdkey": {
- "SecretKey": "snltty"
- },
//服务器
"Servers": [
{
"Name": "Linker", //信标服务器名称
"Host": "127.0.0.1:1802", //信标服务器地址
- "SecretKey": null, //信标密钥
- "UserId": "8225e9d4-0ac7-4d76-9946-c4fe04ad4696" //用户标识,多个客户端可相同
+ "Host1": "127.0.0.1:1802", //信标服务器地址1
+ "UserId": "8225e9d4-0ac7-4d76-9946-c4fe04ad4696", //用户标识,多个客户端可相同
+ "SuperKey": "", //服务器密钥
+ "SuperPassword": "" //服务器密码
+
}
],
//分组
@@ -56,23 +59,17 @@ sidebar_position: 8
"Relay": {
"Servers": [
{
- "SecretKey": "snltty", //中继密钥
"Disabled": false, //是否禁用
- "SSL": true //启用ssl
+ "SSL": true, //启用ssl
+ "RelayType": 0, //默认0
+ "UseCdkey": true //使用cdkey
+
}
]
},
- //内网穿透
- "SForward": {
- "SecretKey": "snltty" //服务器穿透密钥
- },
//更新
"Updater": {
- "SecretKey": "snltty" //更新密钥
- },
- //自定义验证
- "Action": {
- "Args": {} //自定义验证的参数
+ "Sync2Server": true //自动同步到服务器版本
}
}
```
diff --git a/src/linker.doc.web/docs/3、打洞和中继/3.2、中继.md b/src/linker.doc.web/docs/3、打洞和中继/3.2、中继.md
index cec90a27..bb893762 100644
--- a/src/linker.doc.web/docs/3、打洞和中继/3.2、中继.md
+++ b/src/linker.doc.web/docs/3、打洞和中继/3.2、中继.md
@@ -8,11 +8,9 @@ sidebar_position: 2
:::tip[说明]
-1. 如果你自建信标服务器,在服务端 `configs/server.json` 复制中继密钥(`Relay->SecretKey`),在客户端中填写,如果密钥正确,则可以管理服务器的中继cdkey,发布cdkey给别人使用
+1. 如果你自建信标服务器,填写你服务器的管理密钥和管理密码,则可以管理服务器的中继cdkey,发布cdkey给别人使用
2. 如果你使用别人的服务器,你没有密钥可以不填写,则需要使用别人服务器的公开中继节点,或使用他提供的cdkey
3. `按喜好调整好即可,往后的所有通信都是自动的,无需其它操作`
-
-
:::
diff --git a/src/linker.doc.web/docs/3、打洞和中继/img/relay.jpg b/src/linker.doc.web/docs/3、打洞和中继/img/relay.jpg
deleted file mode 100644
index 401eee3b..00000000
Binary files a/src/linker.doc.web/docs/3、打洞和中继/img/relay.jpg and /dev/null differ
diff --git a/src/linker.doc.web/docs/4、通信功能/4.4、服务器穿透.md b/src/linker.doc.web/docs/4、通信功能/4.4、服务器穿透.md
index 6ced00d4..68ff49e6 100644
--- a/src/linker.doc.web/docs/4、通信功能/4.4、服务器穿透.md
+++ b/src/linker.doc.web/docs/4、通信功能/4.4、服务器穿透.md
@@ -11,14 +11,12 @@ sidebar_position: 4
3. 只在被访问端运行linker客户端,访问端不需要运行客户端
:::
-## 1、配置穿透密钥和端口
+## 1、配置穿透
:::tip[说明]
1. 在服务端`configs/server.json`中
2. `WebPort` 用于单一端口承载多个HTTP服务,因为HTTP Headers 中有Host字段,可以用于区分不同的HTTP服务
3. `TunnelPortRange` 用于开放一个端口范围,提供给客户端动态添加端口监听,每个端口对应不同的TCP+UDP服务
-4. `SecretKey` 为密钥,客户端填写此密钥,才能使用穿透
-
:::
## 2、配置端口转发
diff --git a/src/linker.doc.web/docs/6、自定义验证.md b/src/linker.doc.web/docs/6、自定义验证.md
index cd292082..ebcbbe12 100644
--- a/src/linker.doc.web/docs/6、自定义验证.md
+++ b/src/linker.doc.web/docs/6、自定义验证.md
@@ -71,6 +71,10 @@ public sealed class JsonArgSignInInfo
/// 分组id
///
public string GroupId { get; set; } = string.Empty;
+ ///
+ /// 是否超级管理员
+ ///
+ public bool Super { get; set; }
}
public sealed class JsonArgRelayInfo
{
diff --git a/src/linker.messenger.action/IActionServerStore.cs b/src/linker.messenger.action/IActionServerStore.cs
index aa07316f..e26c8170 100644
--- a/src/linker.messenger.action/IActionServerStore.cs
+++ b/src/linker.messenger.action/IActionServerStore.cs
@@ -11,6 +11,10 @@
///
public string RelayActionUrl { get; }
///
+ /// 中继节点验证地址
+ ///
+ public string RelayNodeUrl { get; }
+ ///
/// 内网穿透验证地址
///
public string SForwardActionUrl { get; }
@@ -27,6 +31,7 @@
///
///
public bool SetRelayActionUrl(string url);
+ public bool SetRelayNodeUrl(string url);
///
/// 登录验证地址
///
diff --git a/src/linker.messenger.action/SignInArgsAction.cs b/src/linker.messenger.action/SignInArgsAction.cs
index 4df5fc32..27e4ff52 100644
--- a/src/linker.messenger.action/SignInArgsAction.cs
+++ b/src/linker.messenger.action/SignInArgsAction.cs
@@ -1,4 +1,6 @@
using linker.libs.extends;
+using linker.messenger.relay.client.transport;
+using linker.messenger.relay.server;
using linker.messenger.relay.server.validator;
using linker.messenger.sforward;
using linker.messenger.sforward.server.validator;
@@ -20,6 +22,10 @@ namespace linker.messenger.action
///
public JsonArgRelayInfo Relay { get; set; }
///
+ /// 中继节点验证,
+ ///
+ public JsonArgRelayNodeInfo RelayNode { get; set; }
+ ///
/// 穿透信息,非穿透验证时为null
///
public JsonArgSForwardInfo SForward { get; set; }
@@ -82,6 +88,24 @@ namespace linker.messenger.action
///
public ulong FlowingId { get; set; }
}
+ public sealed class JsonArgRelayNodeInfo
+ {
+ ///
+ /// 来源设备id
+ ///
+ public string FromMachineId { get; set; }
+ ///
+ /// 来源设备名
+ ///
+ public string FromMachineName { get; set; }
+ public List Nodes { get; set; } = [];
+ }
+ public sealed class JsonArgRelayNodeItemInfo
+ {
+ public string Id { get; set; }
+ public string Name { get; set; }
+ public bool Public { get; set; }
+ }
public sealed class JsonArgSForwardInfo
{
///
@@ -204,6 +228,44 @@ namespace linker.messenger.action
}
return string.Empty;
}
+ public async Task> Validate(string userid, SignCacheInfo fromMachine, List nodes)
+ {
+ if (string.IsNullOrWhiteSpace(actionServerStore.RelayNodeUrl) == false)
+ {
+ if (actionServerStore.TryGetActionArg(fromMachine.Args, out string str, out string machineKey) == false)
+ {
+ return [];
+ }
+ JsonArgInfo replace = new JsonArgInfo
+ {
+ RelayNode = new JsonArgRelayNodeInfo
+ {
+ FromMachineId = fromMachine.Id,
+ FromMachineName = fromMachine.MachineName,
+ Nodes = nodes.Select(c => new JsonArgRelayNodeItemInfo
+ {
+ Id = c.Id,
+ Name = c.Name,
+ Public = c.Public
+ }).ToList() ?? []
+ },
+ Signin = new JsonArgSignInInfo
+ {
+ GroupId = fromMachine.GroupId,
+ MachineId = fromMachine.MachineId,
+ MachineName = fromMachine.MachineName,
+ MachineKey = machineKey,
+ IPAddress = fromMachine.Connection.Address.Address,
+ Super = fromMachine.Super
+ }
+ };
+ string ids = await actionTransfer.ExcuteActions(Replace(replace, str), actionServerStore.RelayNodeUrl).ConfigureAwait(false);
+ if (string.IsNullOrWhiteSpace(ids)) return [];
+
+ return nodes.Where(c => ids.Split(',').Contains(c.Id)).ToList();
+ }
+ return nodes;
+ }
}
public sealed class SForwardValidatorAction : JsonArgReplace, ISForwardValidator
diff --git a/src/linker.messenger.cdkey/CdkeyMessenger.cs b/src/linker.messenger.cdkey/CdkeyMessenger.cs
index f4e8dd89..d896beea 100644
--- a/src/linker.messenger.cdkey/CdkeyMessenger.cs
+++ b/src/linker.messenger.cdkey/CdkeyMessenger.cs
@@ -52,7 +52,7 @@ namespace linker.messenger.cdkey
connection.Write(Helper.FalseArray);
return;
}
- if (cache.Super == false)
+ if (cache.Super)
{
await cdkeyStore.Del(info.Id).ConfigureAwait(false);
}
diff --git a/src/linker.messenger.flow/messenger/FlowMessenger.cs b/src/linker.messenger.flow/messenger/FlowMessenger.cs
index 278bc024..71545711 100644
--- a/src/linker.messenger.flow/messenger/FlowMessenger.cs
+++ b/src/linker.messenger.flow/messenger/FlowMessenger.cs
@@ -103,7 +103,7 @@ namespace linker.messenger.flow.messenger
return;
}
- if (cache.Super == false)
+ if (cache.Super)
{
info.GroupId = string.Empty;
}
diff --git a/src/linker.messenger.relay/messenger/RelayMessenger.cs b/src/linker.messenger.relay/messenger/RelayMessenger.cs
index 5404f40c..5fa4ee66 100644
--- a/src/linker.messenger.relay/messenger/RelayMessenger.cs
+++ b/src/linker.messenger.relay/messenger/RelayMessenger.cs
@@ -79,7 +79,7 @@ namespace linker.messenger.relay.messenger
connection.Write(serializer.Serialize(new List { }));
return;
}
- (List nodes, bool validated) = await GetNodes(cache.Super, info.UserId);
+ List nodes = await GetNodes(info.UserId, cache);
connection.Write(serializer.Serialize(nodes));
}
@@ -103,18 +103,18 @@ namespace linker.messenger.relay.messenger
}
RelayAskResultInfo170 result = new RelayAskResultInfo170();
- (result.Nodes, bool validated) = await GetNodes(from.Super, info.UserId).ConfigureAwait(false);
+ result.Nodes = await GetNodes(info.UserId, from).ConfigureAwait(false);
if (result.Nodes.Count > 0)
{
- result.FlowingId = relayServerTransfer.AddRelay(from.MachineId, from.MachineName, to.MachineId, to.MachineName, from.GroupId, info.UserId, validated, info.UseCdkey);
+ result.FlowingId = relayServerTransfer.AddRelay(from.MachineId, from.MachineName, to.MachineId, to.MachineName, from.GroupId, info.UserId, from.Super, info.UseCdkey);
}
connection.Write(serializer.Serialize(result));
}
- private async Task<(List, bool)> GetNodes(bool super, string userid)
+ private async Task> GetNodes(string userid, SignCacheInfo from)
{
- return (await relayServerTransfer.GetNodes(super, userid), super);
+ return await relayServerTransfer.GetNodes(from.Super, userid);
}
@@ -248,7 +248,7 @@ namespace linker.messenger.relay.messenger
public async Task UpdateNodeForward(IConnection connection)
{
RelayServerNodeUpdateWrapInfo info = serializer.Deserialize(connection.ReceiveRequestWrap.Payload.Span);
- if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) && cache.Super)
+ if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) && cache.Super)
{
await relayServerTransfer.UpdateNodeReport(info.Info).ConfigureAwait(false);
connection.Write(Helper.TrueArray);
diff --git a/src/linker.messenger.relay/server/validator/IRelayServerValidator.cs b/src/linker.messenger.relay/server/validator/IRelayServerValidator.cs
index 522006d7..52be0715 100644
--- a/src/linker.messenger.relay/server/validator/IRelayServerValidator.cs
+++ b/src/linker.messenger.relay/server/validator/IRelayServerValidator.cs
@@ -17,5 +17,13 @@ namespace linker.messenger.relay.server.validator
/// 目标客户端,可能为null
///
public Task Validate(RelayInfo170 relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine);
+ ///
+ /// 验证节点
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Task> Validate(string userid, SignCacheInfo fromMachine, List nodes);
}
}
diff --git a/src/linker.messenger.relay/server/validator/RelayServerValidatorTransfer.cs b/src/linker.messenger.relay/server/validator/RelayServerValidatorTransfer.cs
index c0120d70..4536041d 100644
--- a/src/linker.messenger.relay/server/validator/RelayServerValidatorTransfer.cs
+++ b/src/linker.messenger.relay/server/validator/RelayServerValidatorTransfer.cs
@@ -60,6 +60,18 @@ namespace linker.messenger.relay.server.validator
}
return string.Empty;
}
+ public async Task> Validate(string userid, SignCacheInfo fromMachine, List nodes)
+ {
+ foreach (var item in validators)
+ {
+ nodes = await item.Validate(userid, fromMachine, nodes).ConfigureAwait(false);
+ if (nodes == null || nodes.Count == 0)
+ {
+ return [];
+ }
+ }
+ return nodes;
+ }
public sealed class RelayServerValidatorEqualityComparer : IEqualityComparer
{
diff --git a/src/linker.messenger.sforward/server/validator/SForwardValidator.cs b/src/linker.messenger.sforward/server/validator/SForwardValidator.cs
index 1593cfc8..7eda9c4f 100644
--- a/src/linker.messenger.sforward/server/validator/SForwardValidator.cs
+++ b/src/linker.messenger.sforward/server/validator/SForwardValidator.cs
@@ -17,7 +17,7 @@ namespace linker.messenger.sforward.server.validator
public async Task Validate(SignCacheInfo signCacheInfo, SForwardAddInfo sForwardAddInfo)
{
- if (signCacheInfo.Super)
+ if (signCacheInfo.Super == false)
{
return $"need super key and password";
}
diff --git a/src/linker.messenger.store.file/action/ActionServerStore.cs b/src/linker.messenger.store.file/action/ActionServerStore.cs
index 244de2bd..f7290c52 100644
--- a/src/linker.messenger.store.file/action/ActionServerStore.cs
+++ b/src/linker.messenger.store.file/action/ActionServerStore.cs
@@ -7,7 +7,9 @@ namespace linker.messenger.store.file.action
public string SignInActionUrl => config.Data.Action.SignInActionUrl;
public string RelayActionUrl => config.Data.Action.RelayActionUrl;
+ public string RelayNodeUrl => config.Data.Action.RelayNodeUrl;
public string SForwardActionUrl => config.Data.Action.SForwardActionUrl;
+
private readonly FileConfig config;
public ActionServerStore(FileConfig config)
@@ -26,6 +28,11 @@ namespace linker.messenger.store.file.action
config.Data.Action.RelayActionUrl = url;
return true;
}
+ public bool SetRelayNodeUrl(string url)
+ {
+ config.Data.Action.RelayNodeUrl = url;
+ return true;
+ }
public bool SetSForwardActionUrl(string url)
{
@@ -47,7 +54,7 @@ namespace linker.messenger.store.file.action
return true;
}
-
+
}
}
\ No newline at end of file
diff --git a/src/linker.messenger.store.file/action/Config.cs b/src/linker.messenger.store.file/action/Config.cs
index 5e3929a9..0c8978b0 100644
--- a/src/linker.messenger.store.file/action/Config.cs
+++ b/src/linker.messenger.store.file/action/Config.cs
@@ -12,7 +12,9 @@ namespace linker.messenger.store.file
public ConfigActionInfo() { }
public string SignInActionUrl { get; set; } = string.Empty;
public string RelayActionUrl { get; set; } = string.Empty;
+ public string RelayNodeUrl { get; set; } = string.Empty;
public string SForwardActionUrl { get; set; } = string.Empty;
+
public object Deserialize(string text)
{
diff --git a/src/linker.messenger.store.file/relay/Config.cs b/src/linker.messenger.store.file/relay/Config.cs
index 982f42f2..98e9147b 100644
--- a/src/linker.messenger.store.file/relay/Config.cs
+++ b/src/linker.messenger.store.file/relay/Config.cs
@@ -58,7 +58,6 @@ namespace linker.messenger.store.file
public string SecretKey { get; set; } = Helper.GlobalString;
#else
public string SecretKey { get; set; } = Guid.NewGuid().ToString().ToUpper();
- public string SuperPassword { get; set; } = Guid.NewGuid().ToString().ToUpper();
#endif
}
}
diff --git a/src/linker.messenger.updater/UpdaterMessenger.cs b/src/linker.messenger.updater/UpdaterMessenger.cs
index 67087d73..cd0916fb 100644
--- a/src/linker.messenger.updater/UpdaterMessenger.cs
+++ b/src/linker.messenger.updater/UpdaterMessenger.cs
@@ -229,7 +229,7 @@ namespace linker.messenger.updater
}
//需要密钥
- if (confirm.All && cache.Super)
+ if (confirm.All && cache.Super == false)
{
connection.Write(Helper.FalseArray);
return;
diff --git a/src/linker.web/src/views/full/server/Updater.vue b/src/linker.web/src/views/full/server/Updater.vue
index 4ff17d2b..0cd34707 100644
--- a/src/linker.web/src/views/full/server/Updater.vue
+++ b/src/linker.web/src/views/full/server/Updater.vue
@@ -19,7 +19,7 @@ export default {
const {t} = useI18n();
const globalData = injectGlobalData();
const state = reactive({
- sync2Server:false
+ sync2Server:globalData.value.config.Client.Updater.Sync2Server,
});
const handleSync2ServerChange = ()=>{
setSync2Server(state.sync2Server).then(()=>{
diff --git a/version.txt b/version.txt
index 0f20e1e3..f693546d 100644
--- a/version.txt
+++ b/version.txt
@@ -1,5 +1,5 @@
v1.8.6
-2025-07-05 13:23:49
+2025-07-05 15:47:10
1. 一些累计更新
2. 白名单
3. 优化防火墙