feat: 目前完成了订阅功能和 Xray-Core 的更新管理.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using Proxd_man.Config.Stream;
|
||||
using Proxd_man.Config.TransportLayerSecurity;
|
||||
|
||||
namespace Proxd_man.Config.Outbound;
|
||||
|
||||
/// <summary>
|
||||
/// 基本的出站代理配置类.
|
||||
///
|
||||
/// 所有协议的出站配置都要继承这个类.
|
||||
/// </summary>
|
||||
public abstract class BaseOutboundSetting
|
||||
{
|
||||
/// <summary>
|
||||
/// 出站配置名称.
|
||||
///
|
||||
/// 便于管理的名字, 可以直接从订阅中获取.
|
||||
/// </summary>
|
||||
public required string Name { get; init; }
|
||||
/// <summary>
|
||||
/// 发送出站数据所使用的网卡地址.
|
||||
/// </summary>
|
||||
public string BindAddress { get; init; } = "0.0.0.0";
|
||||
/// <summary>
|
||||
/// 出站代理协议类型.
|
||||
/// </summary>
|
||||
public required OutboundProtocolType Protocol { get; init; }
|
||||
|
||||
public BaseStreamSetting StreamSetting { get; init; } = new RawStreamSetting();
|
||||
|
||||
public BaseTransportLayerSecuritySetting TransportLayerSecuritySetting { get; init; } = new NoneSecuritySetting();
|
||||
|
||||
public string? NextOutboundTag { get; init; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 根据<a href="https://xtls.github.io/config/outbound.html">Xray-Core 的配置文件格式</a>,
|
||||
/// 生成对应的 OutboundObject JSON 配置.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public JsonObject ToJsonSetting()
|
||||
{
|
||||
var root = new JsonObject
|
||||
{
|
||||
{ "sendThrough", BindAddress },
|
||||
{ "protocol", Protocol.ToString().ToLower() },
|
||||
{ "tag", GetTag() },
|
||||
{ "settings", GetProtocolSetting() }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(NextOutboundTag))
|
||||
{
|
||||
root.Add("proxySettings", new JsonObject
|
||||
{
|
||||
{ "tag", NextOutboundTag }
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var streamSetting = StreamSetting.ToJsonSetting();
|
||||
TransportLayerSecuritySetting.ApplyJsonSetting(streamSetting);
|
||||
root.Add("streamSettings", streamSetting);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实现依据配置内容, 生成对应的 Outbound Tag.
|
||||
/// </summary>
|
||||
/// <returns>返回该 Outbound 的 Tag, 最好唯一.</returns>
|
||||
public abstract string GetTag();
|
||||
|
||||
/// <summary>
|
||||
/// 实现类依据自身对应协议类型的设定, 生成对应的 V2Ray/Xray-Core Outbound Protocol Setting JSON 对象.
|
||||
/// </summary>
|
||||
/// <returns>返回协议配置的 JSON 对象.</returns>
|
||||
protected abstract JsonObject? GetProtocolSetting();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.Outbound;
|
||||
|
||||
/// <summary>
|
||||
/// Xray-Core 的 ShadowSocks 出站配置.
|
||||
///
|
||||
/// 目前不支持设置多服务器.
|
||||
/// </summary>
|
||||
public class ShadowSocksOutboundSetting : BaseOutboundSetting
|
||||
{
|
||||
|
||||
public string? UserEmail { get; init; } = null;
|
||||
public required string Method { get; init; }
|
||||
public required string Address { get; init; }
|
||||
public int Port { get; init; }
|
||||
public required string Password { get; init; }
|
||||
public bool EnableUdpOverTcp { get; init; } = false;
|
||||
public uint? UdpOverTcpVersion { get; init; } = null;
|
||||
|
||||
public override string GetTag()
|
||||
{
|
||||
return $"ShadowSocks-{GetHashCode()}";
|
||||
}
|
||||
|
||||
protected override JsonObject GetProtocolSetting()
|
||||
{
|
||||
var root = new JsonObject();
|
||||
|
||||
var setting = new JsonObject();
|
||||
setting.Add("address", Address);
|
||||
setting.Add("port", Port);
|
||||
setting.Add("method", Method);
|
||||
setting.Add("password", Password);
|
||||
|
||||
setting.Add("uot", EnableUdpOverTcp);
|
||||
if (EnableUdpOverTcp)
|
||||
{
|
||||
setting.Add("UoTVersion", UdpOverTcpVersion);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(UserEmail))
|
||||
{
|
||||
setting.Add("email", UserEmail);
|
||||
}
|
||||
|
||||
root.Add("servers", new JsonArray { setting });
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace Proxd_man.Config;
|
||||
|
||||
public class ProxdConfig
|
||||
{
|
||||
public InboundConfig Inbound { get; } = new(new HttpInboundSetting());
|
||||
public SubscribeSetting Subscribe { get; } = new();
|
||||
}
|
||||
|
||||
public class InboundConfig(HttpInboundSetting? http = null)
|
||||
{
|
||||
public HttpInboundSetting? Http { get; } = http;
|
||||
}
|
||||
|
||||
public class HttpInboundSetting(string? bindAddress = null, ushort port = 1080, BasicInboundAuthSetting? authentication = null)
|
||||
{
|
||||
public string? BindAddress { get; } = bindAddress;
|
||||
public ushort Port = port;
|
||||
|
||||
public BasicInboundAuthSetting? Authentication { get; } = authentication;
|
||||
}
|
||||
|
||||
public class BasicInboundAuthSetting(string username, string password)
|
||||
{
|
||||
public string Username { get; } = username;
|
||||
public string Password { get; } = password;
|
||||
}
|
||||
|
||||
public class SubscribeSetting
|
||||
{
|
||||
public List<SubscribeSource> Subscribes { get; } = [];
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.Stream;
|
||||
|
||||
public abstract class BaseStreamSetting
|
||||
{
|
||||
|
||||
public StreamType StreamType { get; init; }
|
||||
|
||||
public JsonObject ToJsonSetting()
|
||||
{
|
||||
var setting = new JsonObject
|
||||
{
|
||||
{ "network", StreamType.ToString().ToLower() }
|
||||
};
|
||||
|
||||
var specificSettingFieldName = GetSpecificSettingFieldName();
|
||||
if (!string.IsNullOrEmpty(specificSettingFieldName))
|
||||
{
|
||||
setting.Add(specificSettingFieldName, ToJsonSpecificSetting());
|
||||
}
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
protected abstract string? GetSpecificSettingFieldName();
|
||||
|
||||
protected abstract JsonObject? ToJsonSpecificSetting();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.Stream;
|
||||
|
||||
/// <summary>
|
||||
/// 以 TCP 形式不加密直接传输.
|
||||
///
|
||||
/// 目前暂时不支持设置 Proxy Protocol.
|
||||
/// </summary>
|
||||
public class RawStreamSetting : BaseStreamSetting
|
||||
{
|
||||
|
||||
public RawStreamSetting()
|
||||
{
|
||||
StreamType = StreamType.Raw;
|
||||
}
|
||||
|
||||
protected override string GetSpecificSettingFieldName()
|
||||
{
|
||||
return "rawSettings";
|
||||
}
|
||||
|
||||
protected override JsonObject ToJsonSpecificSetting()
|
||||
{
|
||||
var setting = new JsonObject();
|
||||
|
||||
return setting;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Proxd_man.Config;
|
||||
|
||||
public class SubscribeSource
|
||||
{
|
||||
public required Uri Url { get; init; }
|
||||
public string? Name { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.TransportLayerSecurity;
|
||||
|
||||
public abstract class BaseTransportLayerSecuritySetting
|
||||
{
|
||||
|
||||
public TransportLayerSecurityType TransportLayerSecurityType { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 将配置写入到 StreamSetting JSON 对象中.
|
||||
/// </summary>
|
||||
/// <param name="streamSettingJson">现有的 StreamSetting JSON 对象.</param>
|
||||
public abstract void ApplyJsonSetting(JsonObject streamSettingJson);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.TransportLayerSecurity;
|
||||
|
||||
public class NoneSecuritySetting : BaseTransportLayerSecuritySetting
|
||||
{
|
||||
|
||||
public NoneSecuritySetting()
|
||||
{
|
||||
TransportLayerSecurityType = TransportLayerSecurityType.None;
|
||||
}
|
||||
|
||||
public override void ApplyJsonSetting(JsonObject streamSettingJson)
|
||||
{
|
||||
streamSettingJson.Add("security", "none");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.TransportLayerSecurity;
|
||||
|
||||
public class RealitySecuritySetting : BaseTransportLayerSecuritySetting
|
||||
{
|
||||
|
||||
public string ServerName { get; init; } = "0.0.0.0";
|
||||
public string FingerPrint { get; init; } = "chrome";
|
||||
public required string ShortId { get; init; }
|
||||
public required string PublicKey { get; init; }
|
||||
|
||||
public RealitySecuritySetting()
|
||||
{
|
||||
TransportLayerSecurityType = TransportLayerSecurityType.Reality;
|
||||
}
|
||||
|
||||
public override void ApplyJsonSetting(JsonObject streamSettingJson)
|
||||
{
|
||||
streamSettingJson.Add("security", "reality");
|
||||
|
||||
var realitySetting = new JsonObject();
|
||||
realitySetting.Add("serverName", ServerName);
|
||||
realitySetting.Add("fingerprint", FingerPrint);
|
||||
realitySetting.Add("shortId", ShortId);
|
||||
realitySetting.Add("publicKey", PublicKey);
|
||||
|
||||
streamSettingJson.Add("realitySettings", realitySetting);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace Proxd_man.Config.TransportLayerSecurity;
|
||||
|
||||
public class TlsSecuritySetting : BaseTransportLayerSecuritySetting
|
||||
{
|
||||
|
||||
public string? ServerName { get; init; } = null;
|
||||
public bool IsRejectUnknownSni { get; init; } = false;
|
||||
public List<string> Alpn { get; init; } = ["h2", "http/1.1"];
|
||||
public string MinVersion { get; init; } = "1.2";
|
||||
public string MaxVersion { get; init; } = "1.3";
|
||||
public string? CipherSuites { get; init; } = null;
|
||||
public bool IsAllowInsecure { get; init; } = false;
|
||||
public string FingerPrint { get; init; } = "chrome";
|
||||
|
||||
public TlsSecuritySetting()
|
||||
{
|
||||
TransportLayerSecurityType = TransportLayerSecurityType.Tls;
|
||||
}
|
||||
|
||||
public override void ApplyJsonSetting(JsonObject streamSettingJson)
|
||||
{
|
||||
streamSettingJson.Add("security", "tls");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user