support Wireguard endpoint

This commit is contained in:
DHR60 2025-04-08 21:23:01 +08:00
parent 0edfb2b08b
commit b938538926
2 changed files with 169 additions and 39 deletions

View file

@ -8,6 +8,7 @@ public class SingboxConfig
public Dns4Sbox? dns { get; set; } public Dns4Sbox? dns { get; set; }
public List<Inbound4Sbox> inbounds { get; set; } public List<Inbound4Sbox> inbounds { get; set; }
public List<Outbound4Sbox> outbounds { get; set; } public List<Outbound4Sbox> outbounds { get; set; }
public List<Endpoints4Sbox>? endpoints { get; set; }
public Route4Sbox route { get; set; } public Route4Sbox route { get; set; }
public Experimental4Sbox? experimental { get; set; } public Experimental4Sbox? experimental { get; set; }
} }
@ -123,11 +124,6 @@ public class Outbound4Sbox
public string? version { get; set; } public string? version { get; set; }
public string? network { get; set; } public string? network { get; set; }
public string? packet_encoding { get; set; } public string? packet_encoding { get; set; }
public List<string>? local_address { get; set; }
public string? private_key { get; set; }
public string? peer_public_key { get; set; }
public List<int>? reserved { get; set; }
public int? mtu { get; set; }
public string? plugin { get; set; } public string? plugin { get; set; }
public string? plugin_opts { get; set; } public string? plugin_opts { get; set; }
public Tls4Sbox? tls { get; set; } public Tls4Sbox? tls { get; set; }
@ -152,6 +148,8 @@ public class Endpoints4Sbox
public string? udp_timeout { get; set; } public string? udp_timeout { get; set; }
public int? workers { get; set; } public int? workers { get; set; }
public List<Peer4Sbox> peers { get; set; } public List<Peer4Sbox> peers { get; set; }
public string? detour { get; set; }
public Rule4Sbox? domain_resolver { get; set; }
} }
public class Peer4Sbox public class Peer4Sbox

View file

@ -55,7 +55,18 @@ public class CoreConfigSingboxService
await GenInbounds(singboxConfig); await GenInbounds(singboxConfig);
if (node.ConfigType == EConfigType.WireGuard)
{
singboxConfig.outbounds.RemoveAt(0);
var endpoints = new Endpoints4Sbox();
await GenEndpoint(node, endpoints);
endpoints.tag = Global.ProxyTag;
singboxConfig.endpoints = new() { endpoints };
}
else
{
await GenOutbound(node, singboxConfig.outbounds.First()); await GenOutbound(node, singboxConfig.outbounds.First());
}
await GenMoreOutbounds(node, singboxConfig); await GenMoreOutbounds(node, singboxConfig);
@ -204,16 +215,32 @@ public class CoreConfigSingboxService
continue; continue;
} }
var tag = string.Empty;
if (item.ConfigType == EConfigType.WireGuard)
{
var endpoints = new Endpoints4Sbox();
await GenEndpoint(item, endpoints);
endpoints.tag = Global.ProxyTag + inbound.listen_port.ToString();
singboxConfig.endpoints ??= new();
singboxConfig.endpoints.Add(endpoints);
tag = endpoints.tag;
}
else
{
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(item, outbound); await GenOutbound(item, outbound);
outbound.tag = Global.ProxyTag + inbound.listen_port.ToString(); outbound.tag = Global.ProxyTag + inbound.listen_port.ToString();
singboxConfig.outbounds.Add(outbound); singboxConfig.outbounds.Add(outbound);
tag = outbound.tag;
}
//rule //rule
Rule4Sbox rule = new() Rule4Sbox rule = new()
{ {
inbound = new List<string> { inbound.tag }, inbound = new List<string> { inbound.tag },
outbound = outbound.tag outbound = tag
}; };
singboxConfig.route.rules.Add(rule); singboxConfig.route.rules.Add(rule);
} }
@ -277,7 +304,18 @@ public class CoreConfigSingboxService
} }
await GenLog(singboxConfig); await GenLog(singboxConfig);
if (node.ConfigType == EConfigType.WireGuard)
{
singboxConfig.outbounds.RemoveAt(0);
var endpoints = new Endpoints4Sbox();
await GenEndpoint(node, endpoints);
endpoints.tag = Global.ProxyTag;
singboxConfig.endpoints = new() { endpoints };
}
else
{
await GenOutbound(node, singboxConfig.outbounds.First()); await GenOutbound(node, singboxConfig.outbounds.First());
}
await GenMoreOutbounds(node, singboxConfig); await GenMoreOutbounds(node, singboxConfig);
await GenDnsDomains(null, singboxConfig, null); await GenDnsDomains(null, singboxConfig, null);
@ -371,6 +409,19 @@ public class CoreConfigSingboxService
continue; continue;
} }
if (item.ConfigType == EConfigType.WireGuard)
{
//endpoint
var endpoints = new Endpoints4Sbox();
await GenEndpoint(item, endpoints);
endpoints.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
singboxConfig.endpoints ??= new();
singboxConfig.endpoints.Add(endpoints);
tagProxy.Add(endpoints.tag);
}
else
{
//outbound //outbound
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(item, outbound); await GenOutbound(item, outbound);
@ -378,6 +429,7 @@ public class CoreConfigSingboxService
singboxConfig.outbounds.Insert(0, outbound); singboxConfig.outbounds.Insert(0, outbound);
tagProxy.Add(outbound.tag); tagProxy.Add(outbound.tag);
} }
}
if (tagProxy.Count <= 0) if (tagProxy.Count <= 0)
{ {
ret.Msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
@ -750,15 +802,6 @@ public class CoreConfigSingboxService
outbound.congestion_control = node.HeaderType; outbound.congestion_control = node.HeaderType;
break; break;
} }
case EConfigType.WireGuard:
{
outbound.private_key = node.Id;
outbound.peer_public_key = node.PublicKey;
outbound.reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList();
outbound.local_address = Utils.String2List(node.RequestHost);
outbound.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
break;
}
case EConfigType.Anytls: case EConfigType.Anytls:
{ {
outbound.password = node.Id; outbound.password = node.Id;
@ -777,6 +820,51 @@ public class CoreConfigSingboxService
return 0; return 0;
} }
private async Task<int> GenEndpoint(ProfileItem node, Endpoints4Sbox endpoints)
{
try
{
endpoints.address = Utils.String2List(node.RequestHost);
// Utils.GetFreePort() 9090 ?
endpoints.listen_port = Utils.GetFreePort();
endpoints.type = Global.ProtocolTypes[node.ConfigType];
if (Utils.IsDomain(node.Address))
{
var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
endpoints.domain_resolver = new()
{
server = "local_local",
strategy = string.IsNullOrEmpty(item?.DomainStrategy4Freedom) ? null : item?.DomainStrategy4Freedom
};
}
switch (node.ConfigType)
{
case EConfigType.WireGuard:
{
var peer = new Peer4Sbox
{
public_key = node.PublicKey,
reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList(),
address = node.Address,
port = node.Port,
// TODO default ["0.0.0.0/0", "::/0"]
allowed_ips = new() { "0.0.0.0/0", "::/0" },
};
endpoints.private_key = node.Id;
endpoints.mtu = node.ShortId.IsNullOrEmpty() ? Global.TunMtus.First() : node.ShortId.ToInt();
break;
}
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return await Task.FromResult(0);
}
private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound) private async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
{ {
try try
@ -942,34 +1030,78 @@ public class CoreConfigSingboxService
} }
//current proxy //current proxy
var outbound = singboxConfig.outbounds.First(); var endpoint = singboxConfig.endpoints?.FirstOrDefault(t => t.tag == Global.ProxyTag);
var outbound = endpoint == null ? singboxConfig.outbounds.First() : null;
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
//Previous proxy //Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
if (prevNode is not null if (prevNode is not null
&& prevNode.ConfigType != EConfigType.Custom) && prevNode.ConfigType != EConfigType.Custom)
{
var tag = string.Empty;
if (prevNode.ConfigType == EConfigType.WireGuard)
{
var prevEndpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
await GenEndpoint(prevNode, prevEndpoint);
prevEndpoint.tag = $"{Global.ProxyTag}2";
singboxConfig.endpoints ??= new();
singboxConfig.endpoints.Add(prevEndpoint);
tag = prevEndpoint.tag;
}
else
{ {
var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(prevNode, prevOutbound); await GenOutbound(prevNode, prevOutbound);
prevOutbound.tag = $"{Global.ProxyTag}2"; prevOutbound.tag = $"{Global.ProxyTag}2";
singboxConfig.outbounds.Add(prevOutbound); singboxConfig.outbounds.Add(prevOutbound);
outbound.detour = prevOutbound.tag; tag = prevOutbound.tag;
}
if (endpoint != null)
{
endpoint.detour = tag;
}
else
{
outbound.detour = tag;
}
} }
//Next proxy //Next proxy
var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.NextProfile); var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
if (nextNode is not null if (nextNode is not null
&& nextNode.ConfigType != EConfigType.Custom) && nextNode.ConfigType != EConfigType.Custom)
{
var tag = $"{Global.ProxyTag}1";
if (endpoint != null)
{
endpoint.tag = tag;
}
else
{
outbound.tag = tag;
}
if (nextNode.ConfigType == EConfigType.WireGuard)
{
var nextEndpoint = JsonUtils.Deserialize<Endpoints4Sbox>(txtOutbound);
await GenEndpoint(nextNode, nextEndpoint);
nextEndpoint.tag = Global.ProxyTag;
singboxConfig.endpoints.Insert(0, nextEndpoint);
nextEndpoint.detour = tag;
}
else
{ {
var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(nextNode, nextOutbound); await GenOutbound(nextNode, nextOutbound);
nextOutbound.tag = Global.ProxyTag; nextOutbound.tag = Global.ProxyTag;
singboxConfig.outbounds.Insert(0, nextOutbound); singboxConfig.outbounds.Insert(0, nextOutbound);
outbound.tag = $"{Global.ProxyTag}1"; nextOutbound.detour = tag;
nextOutbound.detour = outbound.tag; }
} }
} }
catch (Exception ex) catch (Exception ex)