feat: 实现依据 InboundSetting 和 OutboundSetting 生成配置的功能.
This commit is contained in:
@@ -20,12 +20,14 @@ public abstract class BaseOutboundSetting
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送出站数据所使用的网卡地址.
|
/// 发送出站数据所使用的网卡地址.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BindAddress { get; init; } = "0.0.0.0";
|
public string? BindAddress { get; init; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 出站代理协议类型.
|
/// 出站代理协议类型.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OutboundProtocolType Protocol { get; init; }
|
public OutboundProtocolType Protocol { get; init; }
|
||||||
|
|
||||||
|
public string? Address { get; init; }
|
||||||
|
|
||||||
public BaseStreamSetting StreamSetting { get; init; } = new RawStreamSetting();
|
public BaseStreamSetting StreamSetting { get; init; } = new RawStreamSetting();
|
||||||
|
|
||||||
public BaseTransportLayerSecuritySetting TransportLayerSecuritySetting { get; init; } = new NoneSecuritySetting();
|
public BaseTransportLayerSecuritySetting TransportLayerSecuritySetting { get; init; } = new NoneSecuritySetting();
|
||||||
@@ -41,12 +43,16 @@ public abstract class BaseOutboundSetting
|
|||||||
{
|
{
|
||||||
var root = new JsonObject
|
var root = new JsonObject
|
||||||
{
|
{
|
||||||
{ "sendThrough", BindAddress },
|
|
||||||
{ "protocol", Protocol.ToString().ToLower() },
|
{ "protocol", Protocol.ToString().ToLower() },
|
||||||
{ "tag", GetTag() },
|
{ "tag", GetTag() },
|
||||||
{ "settings", GetProtocolSetting() }
|
{ "settings", GetProtocolSetting() }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(BindAddress))
|
||||||
|
{
|
||||||
|
root.Add("sendThrough", BindAddress);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(NextOutboundTag))
|
if (!string.IsNullOrEmpty(NextOutboundTag))
|
||||||
{
|
{
|
||||||
root.Add("proxySettings", new JsonObject
|
root.Add("proxySettings", new JsonObject
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class ShadowSocksOutboundSetting : BaseOutboundSetting
|
|||||||
|
|
||||||
public string? UserEmail { get; init; } = null;
|
public string? UserEmail { get; init; } = null;
|
||||||
public required string Method { get; init; }
|
public required string Method { get; init; }
|
||||||
public required string Address { get; init; }
|
public new required string Address { get; init; }
|
||||||
public int Port { get; init; }
|
public int Port { get; init; }
|
||||||
public required string Password { get; init; }
|
public required string Password { get; init; }
|
||||||
public bool EnableUdpOverTcp { get; init; } = false;
|
public bool EnableUdpOverTcp { get; init; } = false;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ internal class Program
|
|||||||
await xrayCoreManager.InitialXrayCoreProgram();
|
await xrayCoreManager.InitialXrayCoreProgram();
|
||||||
|
|
||||||
var subscribeManager = serviceProvider.GetRequiredService<SubscribeManager>();
|
var subscribeManager = serviceProvider.GetRequiredService<SubscribeManager>();
|
||||||
subscribeManager.StartUpdateSubscribes();
|
await subscribeManager.CheckAndUpdateSubscribes();
|
||||||
|
|
||||||
// 监听 SIGTERM 和 SIGINT 信号, 以优雅退出
|
// 监听 SIGTERM 和 SIGINT 信号, 以优雅退出
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class SubscribeManager
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
_config.OnChange((_, _) => Task.Run(async () => await UpdateSubscribes()));
|
_config.OnChange((_, _) => Task.Run(async () => await CheckAndUpdateSubscribes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void SubscribeUpdatedEventHandler(IDictionary<SubscribeSource, List<BaseOutboundSetting>> subscribeOutbounds);
|
public delegate void SubscribeUpdatedEventHandler(IDictionary<SubscribeSource, List<BaseOutboundSetting>> subscribeOutbounds);
|
||||||
@@ -30,7 +30,7 @@ public class SubscribeManager
|
|||||||
|
|
||||||
private ProxdConfig Config => _config.Get(null);
|
private ProxdConfig Config => _config.Get(null);
|
||||||
|
|
||||||
public async Task UpdateSubscribes(CancellationToken cancellationToken = default)
|
public async Task CheckAndUpdateSubscribes(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var httpClient = new HttpClient();
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ public class SubscribeManager
|
|||||||
{
|
{
|
||||||
while (!cts.IsCancellationRequested)
|
while (!cts.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
await UpdateSubscribes(cts.Token);
|
await CheckAndUpdateSubscribes(cts.Token);
|
||||||
await Task.Delay(TimeSpan.FromHours(12), cts.Token);
|
await Task.Delay(TimeSpan.FromHours(12), cts.Token);
|
||||||
}
|
}
|
||||||
}, cts.Token);
|
}, cts.Token);
|
||||||
|
|||||||
+232
-40
@@ -4,44 +4,37 @@ using System.Net;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Proxd_man.Subscribe;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Proxd_man.Config;
|
||||||
|
using Proxd_man.Config.Outbound;
|
||||||
|
|
||||||
namespace Proxd_man;
|
namespace Proxd_man;
|
||||||
|
|
||||||
public class XrayCoreManager
|
public class XrayCoreManager(
|
||||||
|
ILogger<XrayCoreManager> logger,
|
||||||
|
IOptionsMonitor<ProxdConfig> config)
|
||||||
{
|
{
|
||||||
|
|
||||||
private const string XrayLatestReleaseApiUrl = "https://api.github.com/repos/XTLS/Xray-core/releases/latest";
|
private const string XrayLatestReleaseApiUrl = "https://api.github.com/repos/XTLS/Xray-core/releases/latest";
|
||||||
|
|
||||||
private const string XrayLatestReleaseAssetDownloadUrlPrefix =
|
private const string XrayLatestReleaseAssetDownloadUrlPrefix =
|
||||||
"https://github.com/XTLS/Xray-core/releases/latest/download/";
|
"https://github.com/XTLS/Xray-core/releases/latest/download/";
|
||||||
|
|
||||||
private readonly ILogger<XrayCoreManager> _logger;
|
private string CoreProgramDir => config.CurrentValue.XrayCoreProgramDirectory;
|
||||||
private readonly string _coreProgramDir;
|
private string WorkingDirectory => config.CurrentValue.XrayCoreWorkingDirectory;
|
||||||
private readonly string _workingDirectory;
|
|
||||||
|
|
||||||
public XrayCoreManager(
|
// TODO: 看看注册订阅更新事件后, 需要进行哪些操作.
|
||||||
ILogger<XrayCoreManager> logger,
|
|
||||||
SubscribeManager subscribeManager,
|
|
||||||
string coreProgramDir = "./xray-core",
|
|
||||||
string workingDirectory = "./xray-core-run")
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_coreProgramDir = coreProgramDir;
|
|
||||||
_workingDirectory = workingDirectory;
|
|
||||||
|
|
||||||
// TODO: 看看注册订阅更新事件后, 需要进行哪些操作.
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetXrayCoreProgramPath()
|
public string GetXrayCoreProgramPath()
|
||||||
{
|
{
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||||
{
|
{
|
||||||
return _coreProgramDir + "/xray.exe";
|
return CoreProgramDir + "/xray.exe";
|
||||||
}
|
}
|
||||||
|
|
||||||
return _coreProgramDir + "/xray";
|
return CoreProgramDir + "/xray";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetXrayCoreProgramDownloadUrl()
|
public string GetXrayCoreProgramDownloadUrl()
|
||||||
@@ -122,9 +115,9 @@ public class XrayCoreManager
|
|||||||
throw new Exception("Xray-Core program not found: " + programPath);
|
throw new Exception("Xray-Core program not found: " + programPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(_workingDirectory))
|
if (!Directory.Exists(WorkingDirectory))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(_workingDirectory);
|
Directory.CreateDirectory(WorkingDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Process
|
return new Process
|
||||||
@@ -136,7 +129,7 @@ public class XrayCoreManager
|
|||||||
RedirectStandardOutput = redirectOutput,
|
RedirectStandardOutput = redirectOutput,
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
WorkingDirectory = _workingDirectory
|
WorkingDirectory = WorkingDirectory
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -188,30 +181,30 @@ public class XrayCoreManager
|
|||||||
|
|
||||||
public async Task FetchXrayCoreProgram()
|
public async Task FetchXrayCoreProgram()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(_coreProgramDir))
|
if (!Directory.Exists(CoreProgramDir))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(_coreProgramDir);
|
Directory.CreateDirectory(CoreProgramDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
var programArchiveUrl = GetXrayCoreProgramDownloadUrl();
|
var programArchiveUrl = GetXrayCoreProgramDownloadUrl();
|
||||||
var programArchiveDigestUrl = programArchiveUrl + ".dgst";
|
var programArchiveDigestUrl = programArchiveUrl + ".dgst";
|
||||||
_logger.LogDebug("Xray-Core 下载地址: {programArchiveUrl}", programArchiveUrl);
|
logger.LogDebug("Xray-Core 下载地址: {programArchiveUrl}", programArchiveUrl);
|
||||||
_logger.LogDebug("Xray-Core 下载地址 (Digest): {programArchiveDigestUrl}", programArchiveDigestUrl);
|
logger.LogDebug("Xray-Core 下载地址 (Digest): {programArchiveDigestUrl}", programArchiveDigestUrl);
|
||||||
|
|
||||||
var tempArchiveFile = Path.GetTempFileName();
|
var tempArchiveFile = Path.GetTempFileName();
|
||||||
|
|
||||||
using var httpClient = new HttpClient();
|
using var httpClient = new HttpClient();
|
||||||
|
|
||||||
_logger.LogDebug("正在下载 Xray-Core...");
|
logger.LogDebug("正在下载 Xray-Core...");
|
||||||
await using var archiveStream = await httpClient.GetStreamAsync(programArchiveUrl);
|
await using var archiveStream = await httpClient.GetStreamAsync(programArchiveUrl);
|
||||||
await using (var programArchiveFileStream = new FileStream(tempArchiveFile, FileMode.Create, FileAccess.Write))
|
await using (var programArchiveFileStream = new FileStream(tempArchiveFile, FileMode.Create, FileAccess.Write))
|
||||||
{
|
{
|
||||||
await archiveStream.CopyToAsync(programArchiveFileStream);
|
await archiveStream.CopyToAsync(programArchiveFileStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("正在获取 SHA-256 Digest...");
|
logger.LogDebug("正在获取 SHA-256 Digest...");
|
||||||
var digests = await httpClient.GetStringAsync(programArchiveDigestUrl);
|
var digests = await httpClient.GetStringAsync(programArchiveDigestUrl);
|
||||||
_logger.LogDebug("可用的 Digests: \n{digests}", digests);
|
logger.LogDebug("可用的 Digests: \n{digests}", digests);
|
||||||
|
|
||||||
// digests 每行都有一个不同算法的 digest HEX 值, 因此从 digests 读出开头为 SHA-256= 的行, 并提取出其右侧的 Sha256 值
|
// digests 每行都有一个不同算法的 digest HEX 值, 因此从 digests 读出开头为 SHA-256= 的行, 并提取出其右侧的 Sha256 值
|
||||||
var sha256Digest =
|
var sha256Digest =
|
||||||
@@ -222,7 +215,7 @@ public class XrayCoreManager
|
|||||||
throw new Exception("Failed to get SHA-256 digest.");
|
throw new Exception("Failed to get SHA-256 digest.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("SHA-256 Digest: {sha256Digest}", sha256Digest);
|
logger.LogDebug("SHA-256 Digest: {sha256Digest}", sha256Digest);
|
||||||
// Verify digest
|
// Verify digest
|
||||||
using var sha256 = SHA256.Create();
|
using var sha256 = SHA256.Create();
|
||||||
|
|
||||||
@@ -230,17 +223,17 @@ public class XrayCoreManager
|
|||||||
{
|
{
|
||||||
var localDigest = await sha256.ComputeHashAsync(localArchiveFileStream);
|
var localDigest = await sha256.ComputeHashAsync(localArchiveFileStream);
|
||||||
var localDigestHex = BitConverter.ToString(localDigest).Replace("-", "").ToLower();
|
var localDigestHex = BitConverter.ToString(localDigest).Replace("-", "").ToLower();
|
||||||
_logger.LogDebug("本地 SHA-256 Digest: {localDigest}", localDigestHex);
|
logger.LogDebug("本地 SHA-256 Digest: {localDigest}", localDigestHex);
|
||||||
|
|
||||||
if (localDigestHex != sha256Digest)
|
if (localDigestHex != sha256Digest)
|
||||||
{
|
{
|
||||||
throw new Exception("SHA-256 digest mismatch.");
|
throw new Exception("SHA-256 digest mismatch.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("SHA-256 Digest 验证通过.");
|
logger.LogDebug("SHA-256 Digest 验证通过.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile.ExtractToDirectory(tempArchiveFile, _coreProgramDir, true);
|
ZipFile.ExtractToDirectory(tempArchiveFile, CoreProgramDir, true);
|
||||||
|
|
||||||
// Set permissions
|
// Set permissions
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
|
||||||
@@ -258,14 +251,14 @@ public class XrayCoreManager
|
|||||||
|
|
||||||
public async Task InitialXrayCoreProgram()
|
public async Task InitialXrayCoreProgram()
|
||||||
{
|
{
|
||||||
_logger.LogInformation("正在检查 Xray-Core 安装情况以及版本...");
|
logger.LogInformation("正在检查 Xray-Core 安装情况以及版本...");
|
||||||
var currentVersion = await GetCurrentXrayCoreVersion();
|
var currentVersion = await GetCurrentXrayCoreVersion();
|
||||||
_logger.LogDebug("当前 Xray-Core 版本: {currentVersion}", currentVersion);
|
logger.LogDebug("当前 Xray-Core 版本: {currentVersion}", currentVersion);
|
||||||
var requiredUpdate = false;
|
var requiredUpdate = false;
|
||||||
if (currentVersion == null)
|
if (currentVersion == null)
|
||||||
{
|
{
|
||||||
requiredUpdate = true;
|
requiredUpdate = true;
|
||||||
_logger.LogInformation("未找到 Xray-Core, 开始下载最新版本...");
|
logger.LogInformation("未找到 Xray-Core, 开始下载最新版本...");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -273,7 +266,7 @@ public class XrayCoreManager
|
|||||||
if (currentVersion != latestXrayCoreVersion)
|
if (currentVersion != latestXrayCoreVersion)
|
||||||
{
|
{
|
||||||
requiredUpdate = true;
|
requiredUpdate = true;
|
||||||
_logger.LogInformation("发现新版本 Xray-Core (Version: {latestVersion}), 开始下载最新版本...",
|
logger.LogInformation("发现新版本 Xray-Core (Version: {latestVersion}), 开始下载最新版本...",
|
||||||
latestXrayCoreVersion);
|
latestXrayCoreVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,11 +274,11 @@ public class XrayCoreManager
|
|||||||
if (requiredUpdate)
|
if (requiredUpdate)
|
||||||
{
|
{
|
||||||
await FetchXrayCoreProgram();
|
await FetchXrayCoreProgram();
|
||||||
_logger.LogInformation("Xray-Core 更新完成.");
|
logger.LogInformation("Xray-Core 更新完成.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogInformation("Xray-Core 已是最新版本, 无需更新.");
|
logger.LogInformation("Xray-Core 已是最新版本, 无需更新.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,4 +290,203 @@ public class XrayCoreManager
|
|||||||
await process.WaitForExitAsync();
|
await process.WaitForExitAsync();
|
||||||
return process.ExitCode == 0;
|
return process.ExitCode == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成最终的 Xray-Core 配置 JSON 对象.
|
||||||
|
///
|
||||||
|
/// 注意, 在 Xray-Core 中, Inbound 和 Outbound 的首位配置很重要.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inboundConfigs">配置使用的入站设置.</param>
|
||||||
|
/// <param name="outboundSetting">该配置使用的出站配置.</param>
|
||||||
|
/// <param name="onlyTest"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public JsonObject GenerateXrayCoreConfigJson(List<IInboundSetting> inboundConfigs,
|
||||||
|
BaseOutboundSetting outboundSetting, bool onlyTest = false)
|
||||||
|
{
|
||||||
|
// 基本的设置.
|
||||||
|
var proxyConfig = new JsonObject
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"log", new JsonObject
|
||||||
|
{
|
||||||
|
{ "loglevel", "warning" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"policy", new JsonObject
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"levels", new JsonObject
|
||||||
|
{
|
||||||
|
// 给 DNS 使用的.
|
||||||
|
{
|
||||||
|
"1", new JsonObject
|
||||||
|
{
|
||||||
|
{ "connIdle", 30 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system", new JsonObject
|
||||||
|
{
|
||||||
|
{ "statsOutboundDownlink", true },
|
||||||
|
{ "statsOutboundUplink", true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ "stats", new JsonObject() }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------- DNS 配置 -------------
|
||||||
|
var directResolveDomains = new JsonArray();
|
||||||
|
var localDnsServer = new JsonObject
|
||||||
|
{
|
||||||
|
{ "address", "localhost" },
|
||||||
|
{ "domains", directResolveDomains },
|
||||||
|
{ "queryStrategy", "" }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!onlyTest)
|
||||||
|
{
|
||||||
|
directResolveDomains.Add("geosite:cn");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果不是一个 IP 地址(v4 或 v6),则添加到 DNS 服务器列表中
|
||||||
|
if (!IPAddress.TryParse(outboundSetting.Address, out _))
|
||||||
|
{
|
||||||
|
directResolveDomains.Add($"full:{outboundSetting.Address}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var dnsServers = new JsonArray(new JsonObject
|
||||||
|
{
|
||||||
|
{ "address", config.CurrentValue.RemoteDnsServer },
|
||||||
|
{ "domains", new JsonArray() },
|
||||||
|
{ "queryStrategy", "" }
|
||||||
|
}, localDnsServer);
|
||||||
|
|
||||||
|
proxyConfig.Add("dns", new JsonObject
|
||||||
|
{
|
||||||
|
{ "disableFallback", true },
|
||||||
|
{ "servers", dnsServers }
|
||||||
|
});
|
||||||
|
// ------------- DNS 配置 ↑ -------------
|
||||||
|
// ------------ Inbound 配置 ------------
|
||||||
|
|
||||||
|
var inbounds = new JsonArray();
|
||||||
|
proxyConfig.Add("inbounds", inbounds);
|
||||||
|
foreach (var inboundConfig in inboundConfigs)
|
||||||
|
{
|
||||||
|
inbounds.Add(inboundConfig.ToJsonSetting());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------ Inbound 配置 ↑ ------------
|
||||||
|
|
||||||
|
var outbounds = new JsonArray();
|
||||||
|
proxyConfig.Add("outbounds", outbounds);
|
||||||
|
|
||||||
|
var proxyOutboundSettings = outboundSetting.ToJsonSetting();
|
||||||
|
proxyOutboundSettings.Add("domainStrategy", "AsIs");
|
||||||
|
outbounds.Add(proxyOutboundSettings);
|
||||||
|
|
||||||
|
outbounds.Add(new FreedomOutboundSetting("bypass")
|
||||||
|
{
|
||||||
|
Name = "bypass"
|
||||||
|
}.ToJsonSetting());
|
||||||
|
outbounds.Add(new FreedomOutboundSetting
|
||||||
|
{
|
||||||
|
Name = "direct"
|
||||||
|
}.ToJsonSetting());
|
||||||
|
outbounds.Add(new BlackholeOutboundSetting
|
||||||
|
{
|
||||||
|
Name = "block"
|
||||||
|
}.ToJsonSetting());
|
||||||
|
// 添加 DNS 出站配置, 要求 DNS 走 Proxy 代理出站.
|
||||||
|
outbounds.Add(new JsonObject
|
||||||
|
{
|
||||||
|
{ "protocol", "dns" },
|
||||||
|
{ "tag", "dns-out" },
|
||||||
|
{
|
||||||
|
"settings", new JsonObject
|
||||||
|
{
|
||||||
|
{ "address", "1.1.1.1" },
|
||||||
|
{ "port", 53 },
|
||||||
|
{ "network", "tcp" },
|
||||||
|
{ "userLevel", 1 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"proxySettings", new JsonObject
|
||||||
|
{
|
||||||
|
{ "tag", outboundSetting.GetTag() },
|
||||||
|
{ "transportLayer", true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------------ Outbound 配置 ------------
|
||||||
|
// ------------ Routing 配置 -------------
|
||||||
|
|
||||||
|
var routingSettings = new JsonObject
|
||||||
|
{
|
||||||
|
{ "domainStrategy", "AsIs" }
|
||||||
|
};
|
||||||
|
proxyConfig.Add("routing", routingSettings);
|
||||||
|
|
||||||
|
var inboundTags = new JsonArray();
|
||||||
|
foreach (var inboundConfig in inboundConfigs)
|
||||||
|
{
|
||||||
|
inboundTags.Add(inboundConfig.GetTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
var rules = new JsonArray(new JsonObject
|
||||||
|
{
|
||||||
|
{ "inboundTag", inboundTags },
|
||||||
|
{ "outboundTag", "dns-out" },
|
||||||
|
{ "type", "field" },
|
||||||
|
{ "port", "53" }
|
||||||
|
})
|
||||||
|
{
|
||||||
|
new JsonObject
|
||||||
|
{
|
||||||
|
{ "ip", new JsonArray("geoip:cn", "geoip:private") },
|
||||||
|
{ "outboundTag", "bypass" },
|
||||||
|
{ "type", "field" },
|
||||||
|
},
|
||||||
|
new JsonObject
|
||||||
|
{
|
||||||
|
{ "domain", new JsonArray("geosite:cn") },
|
||||||
|
{ "outboundTag", "bypass" },
|
||||||
|
{ "type", "field" },
|
||||||
|
},
|
||||||
|
new JsonObject
|
||||||
|
{
|
||||||
|
{ "outboundTag", "proxy" },
|
||||||
|
{ "port", "0-65535" },
|
||||||
|
{ "type", "field" },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
routingSettings.Add("rules", rules);
|
||||||
|
return proxyConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process CreateOutboundTestProcess(ushort inboundHttpPort, BaseOutboundSetting outboundSetting)
|
||||||
|
{
|
||||||
|
var configJson = GenerateXrayCoreConfigJson([
|
||||||
|
new HttpInboundSetting
|
||||||
|
{
|
||||||
|
Port = inboundHttpPort
|
||||||
|
}
|
||||||
|
], outboundSetting, true);
|
||||||
|
|
||||||
|
var configFilePath = Path.Combine(Path.Combine(WorkingDirectory, "test-config"), Path.GetRandomFileName() + ".json");
|
||||||
|
using var configFileStream = File.CreateText(configFilePath);
|
||||||
|
configFileStream.Write(JsonSerializer.Serialize(configJson));
|
||||||
|
|
||||||
|
return CreateXrayCoreProcess($"run -config {configFilePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user