mirror of
https://github.com/snltty/linker.git
synced 2025-09-26 21:15:57 +08:00
186
This commit is contained in:
@@ -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": ""//服务器穿透的验证接口
|
||||
}
|
||||
```
|
||||
|
@@ -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 //自动同步到服务器版本
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@@ -8,11 +8,9 @@ sidebar_position: 2
|
||||
|
||||
:::tip[说明]
|
||||
|
||||
1. 如果你自建信标服务器,在服务端 `configs/server.json` 复制中继密钥(`Relay->SecretKey`),在客户端中填写,如果密钥正确,则可以管理服务器的中继cdkey,发布cdkey给别人使用
|
||||
1. 如果你自建信标服务器,填写你服务器的管理密钥和管理密码,则可以管理服务器的中继cdkey,发布cdkey给别人使用
|
||||
2. 如果你使用别人的服务器,你没有密钥可以不填写,则需要使用别人服务器的公开中继节点,或使用他提供的cdkey
|
||||
3. `按喜好调整好即可,往后的所有通信都是自动的,无需其它操作`
|
||||
|
||||

|
||||
:::
|
||||
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 109 KiB |
@@ -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、配置端口转发
|
||||
|
@@ -71,6 +71,10 @@ public sealed class JsonArgSignInInfo
|
||||
/// 分组id
|
||||
/// </summary>
|
||||
public string GroupId { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 是否超级管理员
|
||||
/// </summary>
|
||||
public bool Super { get; set; }
|
||||
}
|
||||
public sealed class JsonArgRelayInfo
|
||||
{
|
||||
|
@@ -11,6 +11,10 @@
|
||||
/// </summary>
|
||||
public string RelayActionUrl { get; }
|
||||
/// <summary>
|
||||
/// 中继节点验证地址
|
||||
/// </summary>
|
||||
public string RelayNodeUrl { get; }
|
||||
/// <summary>
|
||||
/// 内网穿透验证地址
|
||||
/// </summary>
|
||||
public string SForwardActionUrl { get; }
|
||||
@@ -27,6 +31,7 @@
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public bool SetRelayActionUrl(string url);
|
||||
public bool SetRelayNodeUrl(string url);
|
||||
/// <summary>
|
||||
/// 登录验证地址
|
||||
/// </summary>
|
||||
|
@@ -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
|
||||
/// </summary>
|
||||
public JsonArgRelayInfo Relay { get; set; }
|
||||
/// <summary>
|
||||
/// 中继节点验证,
|
||||
/// </summary>
|
||||
public JsonArgRelayNodeInfo RelayNode { get; set; }
|
||||
/// <summary>
|
||||
/// 穿透信息,非穿透验证时为null
|
||||
/// </summary>
|
||||
public JsonArgSForwardInfo SForward { get; set; }
|
||||
@@ -82,6 +88,24 @@ namespace linker.messenger.action
|
||||
/// </summary>
|
||||
public ulong FlowingId { get; set; }
|
||||
}
|
||||
public sealed class JsonArgRelayNodeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 来源设备id
|
||||
/// </summary>
|
||||
public string FromMachineId { get; set; }
|
||||
/// <summary>
|
||||
/// 来源设备名
|
||||
/// </summary>
|
||||
public string FromMachineName { get; set; }
|
||||
public List<JsonArgRelayNodeItemInfo> 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
|
||||
{
|
||||
/// <summary>
|
||||
@@ -204,6 +228,44 @@ namespace linker.messenger.action
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public async Task<List<RelayServerNodeReportInfo170>> Validate(string userid, SignCacheInfo fromMachine, List<RelayServerNodeReportInfo170> 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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -103,7 +103,7 @@ namespace linker.messenger.flow.messenger
|
||||
return;
|
||||
}
|
||||
|
||||
if (cache.Super == false)
|
||||
if (cache.Super)
|
||||
{
|
||||
info.GroupId = string.Empty;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ namespace linker.messenger.relay.messenger
|
||||
connection.Write(serializer.Serialize(new List<RelayServerNodeReportInfo170> { }));
|
||||
return;
|
||||
}
|
||||
(List<RelayServerNodeReportInfo170> nodes, bool validated) = await GetNodes(cache.Super, info.UserId);
|
||||
List<RelayServerNodeReportInfo170> 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<RelayServerNodeReportInfo170>, bool)> GetNodes(bool super, string userid)
|
||||
private async Task<List<RelayServerNodeReportInfo170>> GetNodes(string userid, SignCacheInfo from)
|
||||
{
|
||||
return (await relayServerTransfer.GetNodes(super, userid), super);
|
||||
return await relayServerTransfer.GetNodes(from.Super, userid);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -17,5 +17,13 @@ namespace linker.messenger.relay.server.validator
|
||||
/// <param name="toMachine">目标客户端,可能为null</param>
|
||||
/// <returns></returns>
|
||||
public Task<string> Validate(RelayInfo170 relayInfo, SignCacheInfo fromMachine, SignCacheInfo toMachine);
|
||||
/// <summary>
|
||||
/// 验证节点
|
||||
/// </summary>
|
||||
/// <param name="relayInfo"></param>
|
||||
/// <param name="fromMachine"></param>
|
||||
/// <param name="nodes"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<RelayServerNodeReportInfo170>> Validate(string userid, SignCacheInfo fromMachine, List<RelayServerNodeReportInfo170> nodes);
|
||||
}
|
||||
}
|
||||
|
@@ -60,6 +60,18 @@ namespace linker.messenger.relay.server.validator
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
public async Task<List<RelayServerNodeReportInfo170>> Validate(string userid, SignCacheInfo fromMachine, List<RelayServerNodeReportInfo170> 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<IRelayServerValidator>
|
||||
{
|
||||
|
@@ -17,7 +17,7 @@ namespace linker.messenger.sforward.server.validator
|
||||
|
||||
public async Task<string> Validate(SignCacheInfo signCacheInfo, SForwardAddInfo sForwardAddInfo)
|
||||
{
|
||||
if (signCacheInfo.Super)
|
||||
if (signCacheInfo.Super == false)
|
||||
{
|
||||
return $"need super key and password";
|
||||
}
|
||||
|
@@ -7,8 +7,10 @@ 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)
|
||||
{
|
||||
|
@@ -12,8 +12,10 @@ 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)
|
||||
{
|
||||
return text.DeJson<ConfigActionInfo>();
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -229,7 +229,7 @@ namespace linker.messenger.updater
|
||||
}
|
||||
|
||||
//需要密钥
|
||||
if (confirm.All && cache.Super)
|
||||
if (confirm.All && cache.Super == false)
|
||||
{
|
||||
connection.Write(Helper.FalseArray);
|
||||
return;
|
||||
|
@@ -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(()=>{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
v1.8.6
|
||||
2025-07-05 13:23:49
|
||||
2025-07-05 15:47:10
|
||||
1. 一些累计更新
|
||||
2. 白名单
|
||||
3. 优化防火墙
|
||||
|
Reference in New Issue
Block a user