diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..516f5da --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# Default severity for all analyzer diagnostics +dotnet_analyzer_diagnostic.severity = none diff --git a/ProxySU.sln b/ProxySU.sln index 6b8b4af..6f38af8 100644 --- a/ProxySU.sln +++ b/ProxySU.sln @@ -7,6 +7,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxySU", "ProxySU\ProxySU. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxySU_Core", "ProxySU_Core\ProxySU_Core.csproj", "{B066015C-D347-4493-92F1-6556D3863996}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18714411-764D-47E5-AFE6-A96200B7CE41}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/ProxySU/ProxySU.csproj b/ProxySU/ProxySU.csproj index 05b8fd7..9ae9d06 100644 --- a/ProxySU/ProxySU.csproj +++ b/ProxySU/ProxySU.csproj @@ -71,8 +71,8 @@ ..\qrcoder\net40\QRCoder.dll - - ..\ssh.net\net40\Renci.SshNet.dll + + ..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll @@ -181,6 +181,10 @@ ResXFileCodeGenerator Resources.Designer.cs + + .editorconfig + + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/ProxySU/packages.config b/ProxySU/packages.config index 6161026..cd7f780 100644 --- a/ProxySU/packages.config +++ b/ProxySU/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/ProxySU_Core/App.config b/ProxySU_Core/App.config index 731f6de..9626b5e 100644 --- a/ProxySU_Core/App.config +++ b/ProxySU_Core/App.config @@ -1,6 +1,14 @@ - + + + + + + + + + \ No newline at end of file diff --git a/ProxySU_Core/Common/Base64.cs b/ProxySU_Core/Common/Base64.cs new file mode 100644 index 0000000..0a61841 --- /dev/null +++ b/ProxySU_Core/Common/Base64.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProxySU_Core.Common +{ + public class Base64 + { + public static string Encode(string plainText) + { + var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); + return System.Convert.ToBase64String(plainTextBytes); + } + + public static string Decode(string base64EncodedData) + { + var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData); + return System.Text.Encoding.UTF8.GetString(base64EncodedBytes); + } + } +} diff --git a/ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs b/ProxySU_Core/Models/Developers/ConfigBuilder.cs similarity index 75% rename from ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs rename to ProxySU_Core/Models/Developers/ConfigBuilder.cs index 8946378..78bb2d8 100644 --- a/ProxySU_Core/ViewModels/Developers/ConfigBuilder.cs +++ b/ProxySU_Core/Models/Developers/ConfigBuilder.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public class ConfigBuilder { @@ -27,9 +27,16 @@ namespace ProxySU_Core.ViewModels.Developers public const int VLESS_TCP_Port = 1110; public const int VLESS_WS_Port = 1111; + public const int VLESS_H2_Port = 1112; + public const int VLESS_mKCP_Port = 1113; + public const int VMESS_TCP_Port = 2110; public const int VMESS_WS_Port = 2111; + public const int VMESS_H2_Port = 2112; + public const int VMESS_mKCP_Port = 2113; + public const int Trojan_TCP_Port = 3110; + public const int Trojan_WS_Port = 3111; public static dynamic LoadXrayConfig() @@ -48,7 +55,7 @@ namespace ProxySU_Core.ViewModels.Developers return new { log = logObj["log"], - api = apiObj["api"], + //api = apiObj["api"], api不能为空 dns = dnsObj["dns"], routing = routingObj["routing"], policy = policyObj["policy"], @@ -60,17 +67,26 @@ namespace ProxySU_Core.ViewModels.Developers }; } - public static string BuildCaddyConfig(XraySettings parameters) + public static string BuildCaddyConfig(XraySettings parameters, bool useCustomWeb = false) { var caddyStr = File.ReadAllText(Path.Combine(CaddyFileDir, "base.caddyfile")); - caddyStr.Replace("##domain##", parameters.Domain); - if (!string.IsNullOrEmpty(parameters.MaskDomain)) + caddyStr = caddyStr.Replace("##domain##", parameters.Domain); + if (!useCustomWeb && !string.IsNullOrEmpty(parameters.MaskDomain)) { - caddyStr.Replace("##server_proxy##", $"reverse_proxy http://{parameters.MaskDomain} {{ header_up Host {parameters.MaskDomain} }}"); + var prefix = "http://"; + if (parameters.MaskDomain.StartsWith("https://")) + { + prefix = "https://"; + } + var domain = parameters.MaskDomain + .TrimStart("http://".ToCharArray()) + .TrimStart("https://".ToCharArray()); + + caddyStr = caddyStr.Replace("##reverse_proxy##", $"reverse_proxy {prefix}{domain} {{ \n header_up Host {domain} \n }}"); } else { - caddyStr.Replace("##server_proxy##", ""); + caddyStr = caddyStr.Replace("##reverse_proxy##", ""); } return caddyStr; @@ -83,20 +99,13 @@ namespace ProxySU_Core.ViewModels.Developers baseBound.port = parameters.Port; baseBound.settings.fallbacks.Add(JToken.FromObject(new { - dest = 80, - xver = 1, + dest = 80 })); xrayConfig.inbounds.Add(baseBound); - - if (parameters.Types.Contains(XrayType.VLESS_TCP_XTLS)) - { - baseBound.settings.clients[0].id = parameters.UUID; - } + baseBound.settings.clients[0].id = parameters.UUID; if (parameters.Types.Contains(XrayType.VLESS_WS_TLS)) { - baseBound.settings.clients[0].id = parameters.UUID; - var wsInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_WS_TLS.json")); wsInbound.port = VLESS_WS_Port; wsInbound.settings.clients[0].id = parameters.UUID; @@ -104,12 +113,30 @@ namespace ProxySU_Core.ViewModels.Developers baseBound.settings.fallbacks.Add(JToken.FromObject(new { dest = VLESS_WS_Port, - path = parameters.VLESS_WS_Path, - xver = 1, + path = parameters.VLESS_WS_Path })); xrayConfig.inbounds.Add(JToken.FromObject(wsInbound)); } + if (parameters.Types.Contains(XrayType.VLESS_H2_TLS)) + { + var h2Inbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_HTTP2_TLS.json")); + h2Inbound.port = VLESS_H2_Port; + h2Inbound.settings.clients[0].id = parameters.UUID; + h2Inbound.streamSettings.httpSettings.path = parameters.VLESS_H2_Path; + baseBound.settings.fallbacks.Add(JToken.FromObject(new + { + dest = VLESS_H2_Port, + path = parameters.VLESS_H2_Path + })); + xrayConfig.inbounds.Add(JToken.FromObject(h2Inbound)); + } + + if (parameters.Types.Contains(XrayType.VLESS_mKCP_Speed)) + { + var kcpInbound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VLESS_mKCP")); + } + if (parameters.Types.Contains(XrayType.VMESS_TCP_TLS)) { var mtcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "VMESS_TCP_TLS.json")); @@ -140,6 +167,10 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(mwsBound)); } + if (parameters.Types.Contains(XrayType.VMESS_H2_TLS)) { } + + if (parameters.Types.Contains(XrayType.VMESS_mKCP_Speed)) { } + if (parameters.Types.Contains(XrayType.Trojan_TCP_TLS)) { var trojanTcpBound = LoadJsonObj(Path.Combine(ServerInboundsDir, "Trojan_TCP_TLS.json")); @@ -153,6 +184,8 @@ namespace ProxySU_Core.ViewModels.Developers xrayConfig.inbounds.Add(JToken.FromObject(trojanTcpBound)); } + if (parameters.Types.Contains(XrayType.Trojan_WS_TLS)) { } + return JsonConvert.SerializeObject( xrayConfig, Formatting.Indented, diff --git a/ProxySU_Core/ViewModels/Developers/IParameters.cs b/ProxySU_Core/Models/Developers/IParameters.cs similarity index 80% rename from ProxySU_Core/ViewModels/Developers/IParameters.cs rename to ProxySU_Core/Models/Developers/IParameters.cs index c54bcbf..11554c0 100644 --- a/ProxySU_Core/ViewModels/Developers/IParameters.cs +++ b/ProxySU_Core/Models/Developers/IParameters.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public interface IParameters { diff --git a/ProxySU_Core/ViewModels/Developers/Project.cs b/ProxySU_Core/Models/Developers/Project.cs similarity index 86% rename from ProxySU_Core/ViewModels/Developers/Project.cs rename to ProxySU_Core/Models/Developers/Project.cs index 5c24a10..c0bc53a 100644 --- a/ProxySU_Core/ViewModels/Developers/Project.cs +++ b/ProxySU_Core/Models/Developers/Project.cs @@ -1,4 +1,5 @@ using ProxySU_Core.Tools; +using ProxySU_Core.ViewModels; using Renci.SshNet; using System; using System.Collections.Generic; @@ -9,7 +10,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows; -namespace ProxySU_Core.ViewModels.Developers +namespace ProxySU_Core.Models.Developers { public enum CmdType { @@ -156,8 +157,14 @@ namespace ProxySU_Core.ViewModels.Developers /// protected void ConfigureSoftware() { + string cmd = RunCmd("command -v sudo"); + if (string.IsNullOrEmpty(cmd)) + { + RunCmd(GetInstallCmd("sudo")); + } + // 安装curl,wget,unzip - string cmd = RunCmd("command -v curl"); + cmd = RunCmd("command -v curl"); if (string.IsNullOrEmpty(cmd)) { RunCmd(GetInstallCmd("curl")); @@ -306,9 +313,7 @@ namespace ProxySU_Core.ViewModels.Developers var cmd = $"dig @resolver1.opendns.com AAAA {Parameters.Domain} +short -6 {cmdFilter}"; var result = RunCmd(cmd).TrimEnd('\r', '\n'); - if (result != IPv6) - { - } + if (result == IPv6) return; } else @@ -317,11 +322,19 @@ namespace ProxySU_Core.ViewModels.Developers var cmd = $"dig @resolver1.opendns.com A {Parameters.Domain} +short -4 {cmdFilter}"; var result = RunCmd(cmd).TrimEnd('\r', '\n'); - if (result != IPv4) - { - throw new Exception("域名未能解析到服务器IP,请检查域名配置"); - } + if (result == IPv4) return; + } + + + var btnResult = MessageBox.Show( + $"{Parameters.Domain}未能正常解析到服务器的IP,如果您使用了CDN请忽略,是否继续安装?", "提示", MessageBoxButton.YesNo); + + if (btnResult == MessageBoxResult.No) + { + throw new Exception($"域名解析失败,安装停止!"); + } + } /// @@ -341,26 +354,32 @@ namespace ProxySU_Core.ViewModels.Developers /// protected void InstallCaddy() { - if (CmdType == CmdType.Apt) - { - RunCmd("sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https"); - RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -"); - RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list"); - RunCmd("sudo apt update"); - RunCmd("sudo apt install caddy"); - } - else if (CmdType == CmdType.Dnf) - { - RunCmd("dnf install 'dnf-command(copr)'"); - RunCmd("dnf copr enable @caddy/caddy"); - RunCmd("dnf install caddy"); - } - else if (CmdType == CmdType.Yum) - { - RunCmd("yum install yum-plugin-copr"); - RunCmd("yum copr enable @caddy/caddy"); - RunCmd("yum install caddy"); - } + RunCmd("rm -rf caddy_install.sh"); + RunCmd("curl -o caddy_install.sh https://raw.githubusercontent.com/proxysu/shellscript/master/Caddy-Naive/caddy-naive-install.sh"); + RunCmd("yes | bash caddy_install.sh"); + + //if (CmdType == CmdType.Apt) + //{ + // RunCmd("sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https"); + // RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -"); + // RunCmd("curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list"); + // RunCmd(GetUpdateCmd()); + // RunCmd("sudo apt install caddy"); + //} + //else if (CmdType == CmdType.Dnf) + //{ + // RunCmd("echo y | dnf install 'dnf-command(copr)'"); + // RunCmd("echo y | dnf copr enable @caddy/caddy"); + // RunCmd(GetUpdateCmd()); + // RunCmd("dnf install caddy"); + //} + //else if (CmdType == CmdType.Yum) + //{ + // RunCmd("echo y | echo y | yum install yum-plugin-copr"); + // RunCmd("echo y | echo y | yum copr enable @caddy/caddy"); + // RunCmd(GetUpdateCmd()); + // RunCmd("yum install caddy"); + //} } @@ -399,7 +418,7 @@ namespace ProxySU_Core.ViewModels.Developers { if (force) { - var btnResult = MessageBox.Show("80/443端口之一,或全部被占用,将强制停止占用80/443端口的程序?", "提示", MessageBoxButton.YesNo); + var btnResult = MessageBox.Show($"{port}端口被占用,将强制停止占用{port}端口的程序?", "提示", MessageBoxButton.YesNo); if (btnResult == MessageBoxResult.No) { throw new Exception($"{port}端口被占用,安装停止!"); @@ -435,7 +454,7 @@ namespace ProxySU_Core.ViewModels.Developers } } - private void SetNat64() + protected void SetNat64() { var dns64List = FilterFastestIP(); if (dns64List.Count == 0) @@ -456,7 +475,7 @@ namespace ProxySU_Core.ViewModels.Developers } } - private void RemoveNat64() + protected void RemoveNat64() { RunCmd("rm /etc/resolv.conf"); RunCmd("mv /etc/resolv.conf.proxysu /etc/resolv.conf"); @@ -518,7 +537,7 @@ namespace ProxySU_Core.ViewModels.Developers { if (CmdType == CmdType.Apt) { - return "apt-get update "; + return "apt-get update"; } else if (CmdType == CmdType.Dnf) { @@ -541,15 +560,15 @@ namespace ProxySU_Core.ViewModels.Developers { if (CmdType == CmdType.Apt) { - return "apt-get install " + soft; + return "echo y | apt-get install " + soft; } else if (CmdType == CmdType.Dnf) { - return "dnf -y install " + soft; + return "echo y | dnf -y install " + soft; } else if (CmdType == CmdType.Yum) { - return "yum -y install " + soft; + return "echo y | yum -y install " + soft; } throw new Exception("未识别的系统"); diff --git a/ProxySU_Core/Models/Developers/XrayProject.cs b/ProxySU_Core/Models/Developers/XrayProject.cs new file mode 100644 index 0000000..4c65360 --- /dev/null +++ b/ProxySU_Core/Models/Developers/XrayProject.cs @@ -0,0 +1,403 @@ +using Renci.SshNet; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Windows; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using ProxySU_Core.Models; + +namespace ProxySU_Core.Models.Developers +{ + public class XrayProject : Project + { + + private const string ServerLogDir = @"Templates\xray\server\00_log"; + private const string ServerApiDir = @"Templates\xray\server\01_api"; + private const string ServerDnsDir = @"Templates\xray\server\02_dns"; + private const string ServerRoutingDir = @"Templates\xray\server\03_routing"; + private const string ServerPolicyDir = @"Templates\xray\server\04_policy"; + private const string ServerInboundsDir = @"Templates\xray\server\05_inbounds"; + private const string ServerOutboundsDir = @"Templates\xray\server\06_outbounds"; + private const string ServerTransportDir = @"Templates\xray\server\07_transport"; + private const string ServerStatsDir = @"Templates\xray\server\08_stats"; + private const string ServerReverseDir = @"Templates\xray\server\09_reverse"; + private const string CaddyFileDir = @"Templates\xray\caddy"; + + public XrayProject(SshClient sshClient, XraySettings parameters, Action writeOutput) : base(sshClient, parameters, writeOutput) + { + } + + + /// + /// 安装Xray + /// + public override void Install() + { + try + { + EnsureRootAuth(); + + if (FileExists("/usr/local/bin/xray")) + { + var btnResult = MessageBox.Show("已经安装Xray,是否需要重装?", "提示", MessageBoxButton.YesNo); + if (btnResult == MessageBoxResult.No) + { + MessageBox.Show("安装终止", "提示"); + return; + } + } + + WriteOutput("检测安装系统环境..."); + EnsureSystemEnv(); + WriteOutput("检测安装系统环境完成"); + + WriteOutput("配置服务器端口..."); + ConfigurePort(); + WriteOutput("端口配置完成"); + + WriteOutput("安装必要的系统工具..."); + ConfigureSoftware(); + WriteOutput("系统工具安装完成"); + + WriteOutput("检测IP6..."); + ConfigureIPv6(); + WriteOutput("检测IP6完成"); + + WriteOutput("配置防火墙..."); + ConfigureFirewall(); + WriteOutput("防火墙配置完成"); + + WriteOutput("同步系统和本地世间..."); + SyncTimeDiff(); + WriteOutput("时间同步完成"); + + WriteOutput("检测域名是否绑定本机IP..."); + ValidateDomain(); + WriteOutput("域名检测完成"); + + WriteOutput("安装Xray-Core..."); + InstallXrayWithCert(); + WriteOutput("Xray-Core安装完成"); + + WriteOutput("安装Caddy..."); + InstallCaddy(); + WriteOutput("Caddy安装完成"); + + WriteOutput("启动BBR"); + EnableBBR(); + WriteOutput("BBR启动成功"); + + UploadCaddyFile(); + WriteOutput("************"); + WriteOutput("安装完成,尽情享用吧......"); + WriteOutput("************"); + } + catch (Exception ex) + { + MessageBox.Show("安装终止," + ex.Message); + } + } + + /// + /// 更新xray内核 + /// + public void UpdateXrayCore() + { + EnsureRootAuth(); + EnsureSystemEnv(); + RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"); + RunCmd("systemctl restart xray"); + WriteOutput("************ 更新xray内核完成 ************"); + } + + /// + /// 更新xray配置 + /// + public void UpdateXraySettings() + { + EnsureRootAuth(); + EnsureSystemEnv(); + var configJson = ConfigBuilder.BuildXrayConfig(Parameters); + var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); + RunCmd("rm -rf /usr/local/etc/xray/config.json"); + UploadFile(stream, "/usr/local/etc/xray/config.json"); + RunCmd("systemctl restart xray"); + WriteOutput("************ 更新Xray配置成功,更新配置不包含域名,如果域名更换请重新安装。 ************"); + } + + /// + /// 重装Caddy + /// + public void ReinstallCaddy() + { + EnsureRootAuth(); + EnsureSystemEnv(); + InstallCaddy(); + UploadCaddyFile(); + WriteOutput("************ 重装Caddy完成 ************"); + } + + /// + /// 安装证书 + /// + public void InstallCert() + { + EnsureRootAuth(); + EnsureSystemEnv(); + this.InstallCertToXray(); + RunCmd("systemctl restart xray"); + WriteOutput("************ 安装证书完成 ************"); + } + + /// + /// 上传证书 + /// + /// + /// + public void UploadCert(Stream stream) + { + EnsureRootAuth(); + EnsureSystemEnv(); + + // 转移旧文件 + var oldFileName = $"ssl_{DateTime.Now.Ticks}"; + RunCmd($"mv /usr/local/etc/xray/ssl /usr/local/etc/xray/{oldFileName}"); + + // 上传新文件 + RunCmd("mkdir /usr/local/etc/xray/ssl"); + UploadFile(stream, "/usr/local/etc/xray/ssl/ssl.zip"); + RunCmd("unzip /usr/local/etc/xray/ssl/ssl.zip -d /usr/local/etc/xray/ssl"); + + // 改名 + var crtFiles = RunCmd("find /usr/local/etc/xray/ssl/*.crt").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (crtFiles.Length > 0) + { + RunCmd($"mv {crtFiles[0]} /usr/local/etc/xray/ssl/xray_ssl.crt"); + } + else + { + WriteOutput("************ 上传证书失败,请联系开发者 ************"); + RunCmd("rm -rf /usr/local/etc/xray/ssl"); + RunCmd($"mv /usr/local/etc/xray/ssl{oldFileName} /usr/local/etc/xray/ssl"); + WriteOutput("操作已回滚"); + return; + } + + var keyFiles = RunCmd("find /usr/local/etc/xray/ssl/*.key").Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (keyFiles.Length > 0) + { + RunCmd($"mv {keyFiles[0]} /usr/local/etc/xray/ssl/xray_ssl.key"); + } + else + { + WriteOutput("************ 上传证书失败,请联系开发者 ************"); + RunCmd("rm -rf /usr/local/etc/xray/ssl"); + RunCmd($"mv /usr/local/etc/xray/ssl{oldFileName} /usr/local/etc/xray/ssl"); + WriteOutput("操作已回滚"); + return; + } + + RunCmd("systemctl restart xray"); + WriteOutput("************ 上传证书完成 ************"); + } + + /// + /// 上传静态网站 + /// + /// + public void UploadWeb(Stream stream) + { + EnsureRootAuth(); + EnsureSystemEnv(); + if (!FileExists("/usr/share/caddy")) + { + RunCmd("mkdir /usr/share/caddy"); + } + RunCmd("rm -rf /usr/share/caddy/*"); + UploadFile(stream, "/usr/share/caddy/caddy.zip"); + RunCmd("unzip /usr/share/caddy/caddy.zip -d /usr/share/caddy"); + RunCmd("chmod -R 777 /usr/share/caddy"); + UploadCaddyFile(useCustomWeb: true); + WriteOutput("************ 上传网站模板完成 ************"); + } + + + private void UploadCaddyFile(bool useCustomWeb = false) + { + var configJson = ConfigBuilder.BuildCaddyConfig(Parameters, useCustomWeb); + var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); + RunCmd("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.back"); + UploadFile(stream, "/etc/caddy/Caddyfile"); + RunCmd("systemctl restart caddy"); + } + + private void EnableBBR() + { + var osVersion = RunCmd("uname -r"); + var canInstallBBR = CheckKernelVersionBBR(osVersion.Split('-')[0]); + + var bbrInfo = RunCmd("sysctl net.ipv4.tcp_congestion_control | grep bbr"); + var installed = bbrInfo.Contains("bbr"); + if (canInstallBBR && !installed) + { + RunCmd(@"bash -c 'echo ""net.core.default_qdisc=fq"" >> /etc/sysctl.conf'"); + RunCmd(@"bash -c 'echo ""net.ipv4.tcp_congestion_control=bbr"" >> /etc/sysctl.conf'"); + RunCmd(@"sysctl -p"); + + if (OnlyIpv6) + { + RemoveNat64(); + } + } + + if (!canInstallBBR) + { + WriteOutput("****** 系统不满足启用BBR条件,启动失败。 ******"); + } + + } + + private bool CheckKernelVersionBBR(string kernelVer) + { + string[] linuxKernelCompared = kernelVer.Split('.'); + if (int.Parse(linuxKernelCompared[0]) > 4) + { + return true; + } + else if (int.Parse(linuxKernelCompared[0]) < 4) + { + return false; + } + else if (int.Parse(linuxKernelCompared[0]) == 4) + { + if (int.Parse(linuxKernelCompared[1]) >= 9) + { + return true; + } + else if (int.Parse(linuxKernelCompared[1]) < 9) + { + return false; + } + + } + return false; + + } + + private void InstallXrayWithCert() + { + RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"); + + if (!FileExists("/usr/local/bin/xray")) + { + throw new Exception("Xray-Core安装失败,请联系开发者"); + } + + RunCmd($"sed -i 's/User=nobody/User=root/g' /etc/systemd/system/xray.service"); + RunCmd($"sed -i 's/CapabilityBoundingSet=/#CapabilityBoundingSet=/g' /etc/systemd/system/xray.service"); + RunCmd($"sed -i 's/AmbientCapabilities=/#AmbientCapabilities=/g' /etc/systemd/system/xray.service"); + RunCmd($"systemctl daemon-reload"); + + if (FileExists("/usr/local/etc/xray/config.json")) + { + RunCmd(@"mv /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.1"); + } + + WriteOutput("安装TLS证书"); + InstallCertToXray(); + WriteOutput("TLS证书安装完成"); + + + var configJson = ConfigBuilder.BuildXrayConfig(Parameters); + var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); + RunCmd("rm -rf /usr/local/etc/xray/config.json"); + UploadFile(stream, "/usr/local/etc/xray/config.json"); + RunCmd("systemctl restart xray"); + } + + private void InstallCertToXray() + { + // 安装依赖 + RunCmd(GetInstallCmd("socat")); + + // 解决搬瓦工CentOS缺少问题 + RunCmd(GetInstallCmd("automake autoconf libtool")); + + // 安装Acme + var result = RunCmd($"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m {GetRandomEmail()}"); + if (result.Contains("Install success")) + { + WriteOutput("安装 acme.sh 成功"); + } + else + { + throw new Exception("安装 acme.sh 失败,请联系开发者!"); + } + + RunCmd("cd ~/.acme.sh/"); + RunCmd("alias acme.sh=~/.acme.sh/acme.sh"); + + // 申请证书 + if (OnlyIpv6) + { + var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain} --listen-v6"; + result = RunCmd(cmd); + } + else + { + var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain}"; + result = RunCmd(cmd); + } + + if (result.Contains("Cert success")) + { + WriteOutput("申请证书成功"); + } + else + { + throw new Exception("申请证书失败,请联系开发者!"); + } + + // 安装证书到xray + RunCmd("mkdir -p /usr/local/etc/xray/ssl"); + RunCmd($"/root/.acme.sh/acme.sh --installcert -d {Parameters.Domain} --certpath /usr/local/etc/xray/ssl/xray_ssl.crt --keypath /usr/local/etc/xray/ssl/xray_ssl.key --capath /usr/local/etc/xray/ssl/xray_ssl.crt"); + result = RunCmd(@"if [ ! -f ""/usr/local/etc/xray/ssl/xray_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"); + if (result.Contains("1")) + { + WriteOutput("安装证书成功"); + } + else + { + throw new Exception("安装证书失败,请联系开发者!"); + } + + RunCmd(@"chmod 755 /usr/local/etc/xray/ssl"); + } + + private string GetRandomEmail() + { + Random r = new Random(); + var num = r.Next(200000000, 900000000); + return $"{num}@qq.com"; + } + + private int GetRandomPort() + { + var random = new Random(); + return random.Next(10001, 60000); + } + + private dynamic LoadJsonObj(string path) + { + if (File.Exists(path)) + { + var jsonStr = File.ReadAllText(path, Encoding.UTF8); + return JsonConvert.DeserializeObject(jsonStr); + } + return null; + } + + } +} diff --git a/ProxySU_Core/Models/ShareLink.cs b/ProxySU_Core/Models/ShareLink.cs new file mode 100644 index 0000000..dec2823 --- /dev/null +++ b/ProxySU_Core/Models/ShareLink.cs @@ -0,0 +1,170 @@ +using Newtonsoft.Json; +using ProxySU_Core.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace ProxySU_Core.Models +{ + public class ShareLink + { + public static string Build(XrayType xrayType, XraySettings settings) + { + switch (xrayType) + { + case XrayType.VLESS_TCP_TLS: + case XrayType.VLESS_TCP_XTLS: + case XrayType.VLESS_WS_TLS: + case XrayType.Trojan_TCP_TLS: + return BuildVlessShareLink(xrayType, settings); + case XrayType.VMESS_TCP_TLS: + case XrayType.VMESS_WS_TLS: + return BuildVmessShareLink(xrayType, settings); + default: + return string.Empty; + } + } + + + private static string BuildVmessShareLink(XrayType xrayType, XraySettings settings) + { + var vmess = new Vmess + { + v = "2", + add = settings.Domain, + port = settings.Port.ToString(), + id = settings.UUID, + aid = "0", + net = "", + type = "none", + host = settings.Domain, + path = "", + tls = "tls", + ps = "", + }; + + + switch (xrayType) + { + case XrayType.VMESS_TCP_TLS: + vmess.ps = "vmess-tcp-tls"; + vmess.net = "tcp"; + vmess.type = "http"; + vmess.path = settings.VMESS_TCP_Path; + break; + case XrayType.VMESS_WS_TLS: + vmess.ps = "vmess-ws-tls"; + vmess.net = "ws"; + vmess.type = "none"; + vmess.path = settings.VMESS_WS_Path; + break; + default: + return string.Empty; + } + + var base64Url = Base64.Encode(JsonConvert.SerializeObject(vmess)); + return $"vmess://" + base64Url; + } + + private static string BuildVlessShareLink(XrayType xrayType, XraySettings settings) + { + var _protocol = string.Empty; + var _uuid = settings.UUID; + var _domain = settings.Domain; + var _port = settings.Port; + var _type = string.Empty; + var _encryption = string.Empty; + var _security = "tls"; + var _path = "/"; + var _host = settings.Domain; + var _descriptiveText = string.Empty; + + switch (xrayType) + { + case XrayType.VLESS_TCP_TLS: + _protocol = "vless"; + _type = "tcp"; + _path = settings.VLESS_TCP_Path; + _encryption = "none"; + _descriptiveText = "vless-tcp-tls"; + break; + case XrayType.VLESS_TCP_XTLS: + _protocol = "vless"; + _type = "tcp"; + _security = "xtls"; + _encryption = "none"; + _descriptiveText = "vless-tcp-xtls"; + break; + case XrayType.VLESS_WS_TLS: + _protocol = "vless"; + _type = "ws"; + _path = settings.VLESS_WS_Path; + _encryption = "none"; + _descriptiveText = "vless-ws-tls"; + break; + case XrayType.VMESS_TCP_TLS: + _protocol = "vmess"; + _type = "tcp"; + _path = settings.VMESS_TCP_Path; + _encryption = "auto"; + _descriptiveText = "vmess-tcp-tls"; + break; + case XrayType.VMESS_WS_TLS: + _protocol = "vmess"; + _type = "ws"; + _path = settings.VMESS_WS_Path; + _encryption = "auto"; + _descriptiveText = "vmess-ws-tls"; + break; + case XrayType.Trojan_TCP_TLS: + _protocol = "trojan"; + _descriptiveText = "trojan-tcp"; + break; + default: + throw new Exception("暂未实现的协议"); + } + + + string parametersURL = string.Empty; + if (xrayType != XrayType.Trojan_TCP_TLS) + { + // 4.3 传输层相关段 + parametersURL = $"?type={_type}&encryption={_encryption}&security={_security}&host={_host}&path={HttpUtility.UrlEncode(_path)}"; + + + // if mKCP + // if QUIC + + // 4.4 TLS 相关段 + if (xrayType == XrayType.VLESS_TCP_XTLS) + { + parametersURL += "&flow=xtls-rprx-direct"; + } + } + + + return $"{_protocol}://{HttpUtility.UrlEncode(_uuid)}@{_domain}:{_port}{parametersURL}#{HttpUtility.UrlEncode(_descriptiveText)}"; + } + + } + + + + class Vmess + { + public string v { get; set; } + public string ps { get; set; } + public string add { get; set; } + public string port { get; set; } + public string id { get; set; } + public string aid { get; set; } + public string net { get; set; } + public string type { get; set; } + public string host { get; set; } + public string path { get; set; } + public string tls { get; set; } + } +} diff --git a/ProxySU_Core/Models/XraySettings.cs b/ProxySU_Core/Models/XraySettings.cs index 9e08eb2..56dbda9 100644 --- a/ProxySU_Core/Models/XraySettings.cs +++ b/ProxySU_Core/Models/XraySettings.cs @@ -1,9 +1,12 @@ -using ProxySU_Core.ViewModels.Developers; +using Newtonsoft.Json; +using ProxySU_Core.Common; +using ProxySU_Core.Models.Developers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; namespace ProxySU_Core.Models { @@ -12,14 +15,15 @@ namespace ProxySU_Core.Models public XraySettings() { + var guid = Guid.NewGuid().ToString(); Port = 443; - UUID = Guid.NewGuid().ToString(); - Types = new List { XrayType.VLESS_TCP_XTLS }; + UUID = guid; + Types = new List(); VLESS_WS_Path = "/vlessws"; VLESS_TCP_Path = "/vlesstcp"; VMESS_WS_Path = "/vmessws"; VMESS_TCP_Path = "/vmesstcp"; - TrojanPassword = Guid.NewGuid().ToString(); + TrojanPassword = guid; } /// @@ -42,6 +46,16 @@ namespace ProxySU_Core.Models /// public string VLESS_TCP_Path { get; set; } + /// + /// vless http2 path + /// + public string VLESS_H2_Path { get; set; } + + /// + /// vless mKcp seed + /// + public string VLESS_mKCP_Seed { get; set; } + /// /// vmess ws路径 /// @@ -52,11 +66,26 @@ namespace ProxySU_Core.Models /// public string VMESS_TCP_Path { get; set; } + /// + /// vmess http2 path + /// + public string VMESS_HTTP2_Path { get; set; } + + /// + /// vmess mKcp seed + /// + public string VMESS_mKCP_Seed { get; set; } + /// /// trojan密码 /// public string TrojanPassword { get; set; } + /// + /// trojan ws path + /// + public string Trojan_WS_Path { get; set; } + /// /// 域名 /// @@ -83,27 +112,48 @@ namespace ProxySU_Core.Models return VLESS_TCP_Path; case XrayType.VLESS_WS_TLS: return VLESS_WS_Path; + case XrayType.VLESS_H2_TLS: + return VLESS_H2_Path; + case XrayType.VMESS_TCP_TLS: return VMESS_TCP_Path; case XrayType.VMESS_WS_TLS: return VMESS_WS_Path; + case XrayType.Trojan_WS_TLS: + return Trojan_WS_Path; + + // no path + case XrayType.VLESS_mKCP_Speed: case XrayType.Trojan_TCP_TLS: + case XrayType.VMESS_mKCP_Speed: return string.Empty; default: return string.Empty; } } + } + public enum XrayType { - VLESS_TCP_TLS, - VLESS_TCP_XTLS, - VLESS_WS_TLS, + // 入口 + VLESS_TCP_XTLS = 100, - VMESS_TCP_TLS, - VMESS_WS_TLS, + // vless 101开头 + VLESS_TCP_TLS = 101, + VLESS_WS_TLS = 102, + VLESS_H2_TLS = 103, + VLESS_mKCP_Speed = 104, - Trojan_TCP_TLS + // vmess 201开头 + VMESS_TCP_TLS = 201, + VMESS_WS_TLS = 202, + VMESS_H2_TLS = 203, + VMESS_mKCP_Speed = 204, + + // trojan 301开头 + Trojan_TCP_TLS = 301, + Trojan_WS_TLS = 302, } } diff --git a/ProxySU_Core/ProxySU_Core.csproj b/ProxySU_Core/ProxySU_Core.csproj index 1daf4c3..8de2020 100644 --- a/ProxySU_Core/ProxySU_Core.csproj +++ b/ProxySU_Core/ProxySU_Core.csproj @@ -16,6 +16,22 @@ true + false + C:\Users\huife\Desktop\publish_new\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 1 + 1.0.0.%2a + false + true + true AnyCPU @@ -36,105 +52,24 @@ prompt 4 + + D529B8E43BC86188988D830C545B400612900BB3 + + + ProxySU_Core_TemporaryKey.pfx + + + true + + + false + - - ..\packages\ControlzEx.4.3.0\lib\net45\ControlzEx.dll + + ..\packages\ControlzEx.5.0.0\lib\net452\ControlzEx.dll - ..\packages\MahApps.Metro.2.0.0\lib\net46\MahApps.Metro.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BootstrapIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.BoxIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Codicons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Core.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Entypo.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.EvaIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FeatherIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FileIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Fontaudio.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.FontAwesome.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.ForkAwesome.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Ionicons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.JamIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Material.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialDesign.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.MaterialLight.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Microns.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Modern.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Octicons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PicolIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.PixelartIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RadixIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RemixIcon.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.RPGAwesome.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.SimpleIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Typicons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Unicons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.VaadinIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.WeatherIcons.dll - - - ..\packages\MahApps.Metro.IconPacks.4.8.0\lib\net46\MahApps.Metro.IconPacks.Zondicons.dll + ..\packages\MahApps.Metro.2.4.4\lib\net46\MahApps.Metro.dll ..\packages\MaterialDesignColors.2.0.0\lib\net452\MaterialDesignColors.dll @@ -146,7 +81,7 @@ ..\packages\MaterialDesignThemes.4.0.0\lib\net452\MaterialDesignThemes.Wpf.dll - ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.19\lib\net45\Microsoft.Xaml.Behaviors.dll + ..\packages\Microsoft.Xaml.Behaviors.Wpf.1.1.31\lib\net45\Microsoft.Xaml.Behaviors.dll ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll @@ -182,17 +117,19 @@ App.xaml Code + + - - - - + + + + @@ -201,6 +138,9 @@ + + ClientInfoWindow.xaml + MainWindow.xaml @@ -210,6 +150,9 @@ TerminalWindow.xaml + + TextBoxWindow.xaml + @@ -230,9 +173,6 @@ ResXFileCodeGenerator Resources.Designer.cs - - PreserveNewest - SettingsSingleFileGenerator @@ -301,12 +241,27 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -342,6 +297,10 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + MSBuild:Compile Designer @@ -354,6 +313,25 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + + + + + + + + False + Microsoft .NET Framework 4.6.1 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + diff --git a/ProxySU_Core/Templates/xray/server/00_log/00_log.json b/ProxySU_Core/Templates/xray/server/00_log/00_log.json index 6a4cf00..40c2cd5 100644 --- a/ProxySU_Core/Templates/xray/server/00_log/00_log.json +++ b/ProxySU_Core/Templates/xray/server/00_log/00_log.json @@ -1,5 +1,6 @@ { - "log": { - "loglevel": "warning" - } + "log": { + "access": "none", + "loglevel": "none" + } } \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/01_api/01_api.json b/ProxySU_Core/Templates/xray/server/01_api/01_api.json index aa1982b..34c6b17 100644 --- a/ProxySU_Core/Templates/xray/server/01_api/01_api.json +++ b/ProxySU_Core/Templates/xray/server/01_api/01_api.json @@ -1,3 +1,3 @@ { - "api": null + "api": {} } \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json index 0aca4d2..5f17571 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_TCP_TLS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "password": "", - "level": 0, - "email": "love@example.com" + "password": "" } ], "fallbacks": [ diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS_TLS.json new file mode 100644 index 0000000..51d725c --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/Trojan_WS_TLS.json @@ -0,0 +1,26 @@ +{ + "port": 1320, + "listen": "127.0.0.1", + "protocol": "trojan", + "settings": { + "clients": [ + { + "password": "" + } + ], + "fallbacks": [ + { + "dest": 80 + } + ] + }, + + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "acceptProxyProtocol": true, + "path": "/trojanws" + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2_TLS.json new file mode 100644 index 0000000..a99e848 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_HTTP2_TLS.json @@ -0,0 +1,19 @@ +{ + "port": 1234, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "decryption": "none", + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "h2", + "httpSettings": { + "path": "" + } + } +} \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json index 07a491a..d8cddd9 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_TCP_XTLS.json @@ -5,9 +5,7 @@ "clients": [ { "id": "", - "flow": "xtls-rprx-direct", - "level": 0, - "email": "love@example.com" + "flow": "xtls-rprx-direct" } ], "decryption": "none", @@ -17,9 +15,7 @@ "network": "tcp", "security": "xtls", "xtlsSettings": { - "alpn": [ - "http/1.1" - ], + "alpn": [ "h2", "http/1.1" ], "certificates": [ { "certificateFile": "/usr/local/etc/xray/ssl/xray_ssl.crt", diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json index 1b7d25c..0abf2e8 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_WS_TLS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ], "decryption": "none" diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_mKCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_mKCP.json new file mode 100644 index 0000000..77b6aba --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VLESS_mKCP.json @@ -0,0 +1,24 @@ +{ + "port": 3456, + "listen": "127.0.0.1", + "protocol": "vless", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "none" + }, + "seed": null + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2_TLS.json new file mode 100644 index 0000000..9957e76 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_HTTP2_TLS.json @@ -0,0 +1,18 @@ +{ + "port": 1234, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "h2", + "httpSettings": { + "path": "" + } + } +} \ No newline at end of file diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json index 2c569a8..b14181e 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_TCP_TLS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ] }, diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json index bbf6dbb..2e863a4 100644 --- a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_WS_TLS.json @@ -5,9 +5,7 @@ "settings": { "clients": [ { - "id": "", - "level": 0, - "email": "love@example.com" + "id": "" } ] }, diff --git a/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_mKCP.json b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_mKCP.json new file mode 100644 index 0000000..63bcf27 --- /dev/null +++ b/ProxySU_Core/Templates/xray/server/05_inbounds/VMESS_mKCP.json @@ -0,0 +1,24 @@ +{ + "port": 3456, + "listen": "127.0.0.1", + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "" + } + ] + }, + "streamSettings": { + "network": "mkcp", + "kcpSettings": { + "uplinkCapacity": 100, + "downlinkCapacity": 100, + "congestion": true, + "header": { + "type": "none" + }, + "seed": null + } + } +} diff --git a/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json b/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json index 02c9ed0..b406e15 100644 --- a/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json +++ b/ProxySU_Core/Templates/xray/server/08_stats/08_stats.json @@ -1,3 +1,3 @@ { - "stats": null + "stats": {} } \ No newline at end of file diff --git a/ProxySU_Core/ViewModels/Developers/XrayProject.cs b/ProxySU_Core/ViewModels/Developers/XrayProject.cs deleted file mode 100644 index b605860..0000000 --- a/ProxySU_Core/ViewModels/Developers/XrayProject.cs +++ /dev/null @@ -1,195 +0,0 @@ -using Renci.SshNet; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Windows; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using ProxySU_Core.Models; - -namespace ProxySU_Core.ViewModels.Developers -{ - public class XrayProject : Project - { - - private const string ServerLogDir = @"Templates\xray\server\00_log"; - private const string ServerApiDir = @"Templates\xray\server\01_api"; - private const string ServerDnsDir = @"Templates\xray\server\02_dns"; - private const string ServerRoutingDir = @"Templates\xray\server\03_routing"; - private const string ServerPolicyDir = @"Templates\xray\server\04_policy"; - private const string ServerInboundsDir = @"Templates\xray\server\05_inbounds"; - private const string ServerOutboundsDir = @"Templates\xray\server\06_outbounds"; - private const string ServerTransportDir = @"Templates\xray\server\07_transport"; - private const string ServerStatsDir = @"Templates\xray\server\08_stats"; - private const string ServerReverseDir = @"Templates\xray\server\09_reverse"; - private const string CaddyFileDir = @"Templates\xray\caddy"; - - public XrayProject(SshClient sshClient, XraySettings parameters, Action writeOutput) : base(sshClient, parameters, writeOutput) - { - } - - public override void Install() - { - try - { - EnsureRootAuth(); - - if (FileExists("/usr/local/bin/xray")) - { - var btnResult = MessageBox.Show("已经安装Xray,是否需要重装?", "提示", MessageBoxButton.YesNo); - if (btnResult == MessageBoxResult.No) - { - MessageBox.Show("安装终止", "提示"); - return; - } - } - - EnsureSystemEnv(); - - ConfigurePort(); - - ConfigureSoftware(); - - ConfigureIPv6(); - - ConfigureFirewall(); - - SyncTimeDiff(); - - ValidateDomain(); - - InstallXrayWithCert(); - - InstallCaddy(); - - UploadCaddyFile(); - } - catch (Exception ex) - { - MessageBox.Show("安装终止," + ex.Message); - } - } - - private void UploadCaddyFile() - { - var configJson = ConfigBuilder.BuildCaddyConfig(Parameters); - var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); - RunCmd("mv /etc/caddy/Caddyfile /etc/caddy/Caddyfile.back"); - UploadFile(stream, "/etc/caddy/Caddyfile"); - RunCmd("systemctl reload caddy"); - } - - private void InstallXrayWithCert() - { - RunCmd("bash -c \"$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)\" @ install"); - - if (FileExists("/usr/local/bin/xray")) - { - WriteOutput("Xray安装成功"); - } - - RunCmd($"sed -i 's/User=nobody/User=root/g' /etc/systemd/system/xray.service"); - RunCmd($"sed -i 's/CapabilityBoundingSet=/#CapabilityBoundingSet=/g' /etc/systemd/system/xray.service"); - RunCmd($"sed -i 's/AmbientCapabilities=/#AmbientCapabilities=/g' /etc/systemd/system/xray.service"); - RunCmd($"systemctl daemon-reload"); - - if (FileExists("/usr/local/etc/xray/config.json")) - { - RunCmd(@"mv /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.1"); - } - - InstallCertToXray(); - - - var configJson = ConfigBuilder.BuildXrayConfig(Parameters); - var stream = new MemoryStream(Encoding.UTF8.GetBytes(configJson)); - RunCmd("rm -rf /usr/local/etc/xray/config.json"); - UploadFile(stream, "/usr/local/etc/xray/config.json"); - } - - private void InstallCertToXray() - { - // 安装依赖 - RunCmd(GetInstallCmd("socat")); - - // 解决搬瓦工CentOS缺少问题 - RunCmd(GetInstallCmd("automake autoconf libtool")); - - // 安装Acme - var result = RunCmd($"curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m {GetRandomEmail()}"); - if (result.Contains("Install success")) - { - WriteOutput("安装 acme.sh 成功"); - } - else - { - throw new Exception("安装 acme.sh 失败,请联系开发者!"); - } - - RunCmd("cd ~/.acme.sh/"); - RunCmd("alias acme.sh=~/.acme.sh/acme.sh"); - - // 申请证书 - if (OnlyIpv6) - { - var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain} --listen-v6"; - result = RunCmd(cmd); - } - else - { - var cmd = $"/root/.acme.sh/acme.sh --force --debug --issue --standalone -d {Parameters.Domain}"; - result = RunCmd(cmd); - } - - if (result.Contains("Cert success")) - { - WriteOutput("申请证书成功"); - } - else - { - throw new Exception("申请证书失败,请联系开发者!"); - } - - // 安装证书到xray - RunCmd("mkdir -p /usr/local/etc/xray/ssl"); - RunCmd($"/root/.acme.sh/acme.sh --installcert -d {Parameters.Domain} --certpath /usr/local/etc/xray/ssl/xray_ssl.crt --keypath /usr/local/etc/xray/ssl/xray_ssl.key --capath /usr/local/etc/xray/ssl/xray_ssl.crt --reloadcmd \"systemctl restart xray\""); - result = RunCmd(@"if [ ! -f ""/usr/local/etc/xray/ssl/xray_ssl.key"" ]; then echo ""0""; else echo ""1""; fi | head -n 1"); - if (result.Contains("1")) - { - WriteOutput("安装证书成功"); - } - else - { - throw new Exception("安装证书失败,请联系开发者!"); - } - - - RunCmd(@"chmod 644 /usr/local/etc/xray/ssl/xray_ssl.key"); - } - - private string GetRandomEmail() - { - Random r = new Random(); - var num = r.Next(200000000, 900000000); - return $"{num}@qq.com"; - } - - private int GetRandomPort() - { - var random = new Random(); - return random.Next(10001, 60000); - } - - private dynamic LoadJsonObj(string path) - { - if (File.Exists(path)) - { - var jsonStr = File.ReadAllText(path, Encoding.UTF8); - return JsonConvert.DeserializeObject(jsonStr); - } - return null; - } - - } -} diff --git a/ProxySU_Core/ViewModels/HostViewModel.cs b/ProxySU_Core/ViewModels/HostViewModel.cs index 1d06af0..04ceb62 100644 --- a/ProxySU_Core/ViewModels/HostViewModel.cs +++ b/ProxySU_Core/ViewModels/HostViewModel.cs @@ -15,6 +15,7 @@ namespace ProxySU_Core.ViewModels private readonly ICommand _selectKeyCommand; + public HostViewModel(Host host) { _selectKeyCommand = new BaseCommand(obj => OpenFileDialog(obj)); diff --git a/ProxySU_Core/ViewModels/RecordViewModel.cs b/ProxySU_Core/ViewModels/RecordViewModel.cs index 70f0b81..e2270be 100644 --- a/ProxySU_Core/ViewModels/RecordViewModel.cs +++ b/ProxySU_Core/ViewModels/RecordViewModel.cs @@ -11,10 +11,22 @@ namespace ProxySU_Core.ViewModels public class RecordViewModel : BaseViewModel { public Record record; + private bool _isChecked; public RecordViewModel(Record record) { this.record = record; + this._isChecked = false; + } + + public bool IsChecked + { + get => _isChecked; + set + { + _isChecked = value; + Notify("IsChecked"); + } } public Host Host diff --git a/ProxySU_Core/ViewModels/Terminal.cs b/ProxySU_Core/ViewModels/Terminal.cs index 4c5028b..1f2a92a 100644 --- a/ProxySU_Core/ViewModels/Terminal.cs +++ b/ProxySU_Core/ViewModels/Terminal.cs @@ -8,37 +8,31 @@ namespace ProxySU_Core.ViewModels { public class Terminal : BaseViewModel { - private string outputText; + private bool hasConnected; public Terminal(Host host) { Host = host; + HasConnected = false; + } + + public bool HasConnected + { + get + { + return hasConnected; + } + set + { + hasConnected = value; + Notify("HasConnected"); + } } public Host Host { get; set; } public string CommandText { get; set; } - public string OutputText - { - get => outputText; - } - - public void ClearOutput() - { - outputText = ""; - Notify("OutputText"); - } - - public void AddOutput(string text) - { - outputText += text; - - if (!text.EndsWith("\n")) - { - outputText += "\n"; - } - Notify("OutputText"); - } + public string OutputText { get; set; } } } diff --git a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs index 3bf4ef3..54d1435 100644 --- a/ProxySU_Core/ViewModels/XraySettingsViewModel.cs +++ b/ProxySU_Core/ViewModels/XraySettingsViewModel.cs @@ -1,10 +1,12 @@ -using ProxySU_Core.Models; -using ProxySU_Core.ViewModels.Developers; +using Newtonsoft.Json; +using ProxySU_Core.Common; +using ProxySU_Core.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; using System.Windows; namespace ProxySU_Core.ViewModels @@ -76,7 +78,9 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.VLESS_TCP_TLS); + if (!settings.Types.Contains(XrayType.VLESS_TCP_TLS)) + settings.Types.Add(XrayType.VLESS_TCP_TLS); + } else { @@ -97,7 +101,8 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.VLESS_TCP_XTLS); + if (!settings.Types.Contains(XrayType.VLESS_TCP_XTLS)) + settings.Types.Add(XrayType.VLESS_TCP_XTLS); } else { @@ -117,7 +122,8 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.VLESS_WS_TLS); + if (!settings.Types.Contains(XrayType.VLESS_WS_TLS)) + settings.Types.Add(XrayType.VLESS_WS_TLS); } else { @@ -138,7 +144,8 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.VMESS_TCP_TLS); + if (!settings.Types.Contains(XrayType.VMESS_TCP_TLS)) + settings.Types.Add(XrayType.VMESS_TCP_TLS); } else { @@ -159,7 +166,8 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.VMESS_WS_TLS); + if (!settings.Types.Contains(XrayType.VMESS_WS_TLS)) + settings.Types.Add(XrayType.VMESS_WS_TLS); } else { @@ -180,7 +188,8 @@ namespace ProxySU_Core.ViewModels { if (value == true) { - settings.Types.Add(XrayType.Trojan_TCP_TLS); + if (!settings.Types.Contains(XrayType.Trojan_TCP_TLS)) + settings.Types.Add(XrayType.Trojan_TCP_TLS); } else { @@ -227,5 +236,31 @@ namespace ProxySU_Core.ViewModels } } + public string VLESS_TCP_XTLS_ShareLink + { + get => ShareLink.Build(XrayType.VLESS_TCP_XTLS, settings); + } + public string VLESS_TCP_TLS_ShareLink + { + get => ShareLink.Build(XrayType.VLESS_TCP_TLS, settings); + } + public string VLESS_WS_TLS_ShareLink + { + get => ShareLink.Build(XrayType.VLESS_WS_TLS, settings); + } + public string VMESS_TCP_TLS_ShareLink + { + get => ShareLink.Build(XrayType.VMESS_TCP_TLS, settings); + } + public string VMESS_WS_TLS_ShareLink + { + get => ShareLink.Build(XrayType.VMESS_WS_TLS, settings); + } + public string Trojan_TCP_TLS_ShareLink + { + get => ShareLink.Build(XrayType.Trojan_TCP_TLS, settings); + } + } + } diff --git a/ProxySU_Core/Views/ClientInfoWindow.xaml b/ProxySU_Core/Views/ClientInfoWindow.xaml new file mode 100644 index 0000000..3380bc7 --- /dev/null +++ b/ProxySU_Core/Views/ClientInfoWindow.xaml @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ProxySU_Core/Views/ClientInfoWindow.xaml.cs b/ProxySU_Core/Views/ClientInfoWindow.xaml.cs new file mode 100644 index 0000000..a0cf9b7 --- /dev/null +++ b/ProxySU_Core/Views/ClientInfoWindow.xaml.cs @@ -0,0 +1,36 @@ +using ProxySU_Core.Models; +using ProxySU_Core.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace ProxySU_Core.Views +{ + /// + /// ClientInfoWindow.xaml 的交互逻辑 + /// + public partial class ClientInfoWindow + { + public XraySettingsViewModel Settings { get; set; } + + public ClientInfoWindow(Record record) + { + InitializeComponent(); + ResizeMode = ResizeMode.NoResize; + WindowStartupLocation = WindowStartupLocation.CenterScreen; + + Settings = new XraySettingsViewModel(record.Settings); + DataContext = this; + } + } +} diff --git a/ProxySU_Core/Views/MainWindow.xaml b/ProxySU_Core/Views/MainWindow.xaml index 22e7029..2649b91 100644 --- a/ProxySU_Core/Views/MainWindow.xaml +++ b/ProxySU_Core/Views/MainWindow.xaml @@ -7,7 +7,6 @@ mc:Ignorable="d" BorderThickness="1" xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls" - xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks" xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" TextElement.FontSize="14" Title="ProxySU Core" Height="800" Width="1200"> @@ -15,10 +14,7 @@ @@ -58,9 +54,21 @@