diff --git a/ProxySU/MainWindow.xaml b/ProxySU/MainWindow.xaml index 10dd126..48f5169 100644 --- a/ProxySU/MainWindow.xaml +++ b/ProxySU/MainWindow.xaml @@ -106,8 +106,8 @@ - - + + @@ -118,8 +118,7 @@ - - + @@ -128,13 +127,37 @@ + + + + --> + + - + + + + + + + + + + + + + + + + + + + @@ -179,8 +202,7 @@ - - + diff --git a/ProxySU/MainWindow.xaml.cs b/ProxySU/MainWindow.xaml.cs index 5dab172..6411e24 100644 --- a/ProxySU/MainWindow.xaml.cs +++ b/ProxySU/MainWindow.xaml.cs @@ -169,7 +169,7 @@ namespace ProxySU //Action startSetUpAction = new Action(StartSetUpRemoteHost); //string serverConfig = TextBoxJsonPath.Text.ToString().Replace("\\","\\\\"); //读取模板配置 - //sed -i 's/PermitRootLogin no/PermitRootLogin yes/' /etc/v2ray/config.json + string serverConfig=""; //服务端配置文件 string clientConfig = ""; //生成的客户端配置文件 string upLoadPath = "/etc/v2ray/config.json"; //服务端文件位置 @@ -254,7 +254,7 @@ namespace ProxySU } //Thread thread - Thread thread = new Thread(() => StartSetUpRemoteHost(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing, serverConfig, clientConfig, upLoadPath)); + Thread thread = new Thread(() => StartSetUpV2ray(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing, serverConfig, clientConfig, upLoadPath)); thread.SetApartmentState(ApartmentState.STA); thread.Start(); // Task task = new Task(() => StartSetUpRemoteHost(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing, serverConfig, clientConfig, upLoadPath)); @@ -408,8 +408,8 @@ namespace ProxySU } #endregion - //登录远程主机布署程序 - private void StartSetUpRemoteHost(ConnectionInfo connectionInfo,TextBlock textBlockName, ProgressBar progressBar, string serverConfig,string clientConfig,string upLoadPath) + //登录远程主机布署V2ray程序 + private void StartSetUpV2ray(ConnectionInfo connectionInfo,TextBlock textBlockName, ProgressBar progressBar, string serverConfig,string clientConfig,string upLoadPath) { string currentStatus = "正在登录远程主机......"; Action updateAction = new Action(UpdateTextBlock); @@ -800,7 +800,7 @@ namespace ProxySU //设置Caddyfile文件中的tls 邮箱 //string sshCmdEmail = $"email={ReceiveConfigurationParameters[4]};email=${{email/./@}};echo $email";//结尾有回车符 //string email = client.RunCommand(sshCmdEmail).Result.Replace("\n", "");//删除结尾的回车符 - string email = $"admin@{ReceiveConfigurationParameters[4]}"; + string email = $"user@{ReceiveConfigurationParameters[4]}"; string sshCmd = $"sed -i 's/off/{email}/' {upLoadPath}";//设置Caddyfile中的邮箱 client.RunCommand(sshCmd); //设置Path @@ -883,9 +883,9 @@ namespace ProxySU currentStatus = "生成客户端配置......"; textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); Thread.Sleep(1000); - if (!Directory.Exists("config"))//如果不存在就创建file文件夹      + if (!Directory.Exists("v2ray_config"))//如果不存在就创建file文件夹      { - Directory.CreateDirectory("config");//创建该文件夹   + Directory.CreateDirectory("v2ray_config");//创建该文件夹   } //string clientConfig = "TemplateConfg\\tcp_client_config.json"; using (StreamReader reader = File.OpenText(clientConfig)) @@ -918,7 +918,7 @@ namespace ProxySU } - using (StreamWriter sw = new StreamWriter(@"config\config.json")) + using (StreamWriter sw = new StreamWriter(@"v2ray_config\config.json")) { sw.Write(clientJson.ToString()); } @@ -975,6 +975,7 @@ namespace ProxySU #endregion } + //上传配置文件 private void UploadConfig(ConnectionInfo connectionInfo,string uploadConfig,string upLoadPath) { @@ -999,6 +1000,7 @@ namespace ProxySU MessageBox.Show("sftp出现未知错误"); } } + //下载配置文件 private void DownloadConfig(ConnectionInfo connectionInfo, string downloadConfig,string downloadPath) { @@ -1110,7 +1112,7 @@ namespace ProxySU } - //打开模板设置窗口 + //打开v2ray模板设置窗口 private void ButtonTemplateConfiguration_Click(object sender, RoutedEventArgs e) { //清空初始化模板参数 @@ -1185,15 +1187,15 @@ namespace ProxySU MessageBox.Show(ex.Message); } } - private void ButtonGuideConfiguration_Click(object sender, RoutedEventArgs e) - { - MessageBox.Show("尚未完善,敬请期待"); - } + //private void ButtonGuideConfiguration_Click(object sender, RoutedEventArgs e) + //{ + // MessageBox.Show("尚未完善,敬请期待"); + //} - private void ButtonAdvancedConfiguration_Click(object sender, RoutedEventArgs e) - { - MessageBox.Show("尚未完善,敬请期待"); - } + //private void ButtonAdvancedConfiguration_Click(object sender, RoutedEventArgs e) + //{ + // MessageBox.Show("尚未完善,敬请期待"); + //} private void ButtonWebBrowserBack_Click(object sender, RoutedEventArgs e) { @@ -1231,213 +1233,528 @@ namespace ProxySU } } - //private void Button_Click(object sender, RoutedEventArgs e) - //{ - // string[] testString = new string[6]; - // for (int i = 0; i != testString.Length; i++) - // { - - // testString[i] = i.ToString(); - - // } - // foreach (string str in testString) - // { - // MessageBox.Show(str); - // } - //} - - private void Button_Click_1(object sender, RoutedEventArgs e) + //打开Trojan参数设置界面 + private void ButtonTrojanTemplate_Click(object sender, RoutedEventArgs e) { for (int i = 0; i != ReceiveConfigurationParameters.Length; i++) { - MessageBox.Show(ReceiveConfigurationParameters[i]); + ReceiveConfigurationParameters[i] = ""; } + TrojanTemplateWindow windowTrojanTemplateConfiguration = new TrojanTemplateWindow(); + windowTrojanTemplateConfiguration.ShowDialog(); + } + //Trojan一键安装 + private void ButtonTrojanSetUp_Click(object sender, RoutedEventArgs e) + { + ConnectionInfo connectionInfo = GenerateConnectionInfo(); + if (connectionInfo == null) + { + MessageBox.Show("远程主机连接信息有误,请检查"); + return; + } + string serverConfig = ""; //服务端配置文件 + string clientConfig = ""; //生成的客户端配置文件 + string upLoadPath = "/usr/local/etc/trojan/config.json"; //服务端文件位置 + if (String.IsNullOrEmpty(ReceiveConfigurationParameters[4]) == true) + { + ReceiveConfigurationParameters[4] = TextBoxHost.Text.ToString(); + } + if (String.IsNullOrEmpty(ReceiveConfigurationParameters[0]) == true) + { + MessageBox.Show("请先选择配置模板!"); + return; + } + else if (String.Equals(ReceiveConfigurationParameters[0], "TrojanTLS2Web")) + { + serverConfig = "TemplateConfg\\trojan_server_config.json"; + clientConfig = "TemplateConfg\\trojan_client_config.json"; + } + Thread thread = new Thread(() => StartSetUpTrojan(connectionInfo, TextBlockSetUpProcessing, ProgressBarSetUpProcessing, serverConfig, clientConfig, upLoadPath)); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); } - //private void TestresultClientInform_Click(object sender, RoutedEventArgs e) - //{ - // ResultClientInformation resultClientInformation = new ResultClientInformation(); - // resultClientInformation.ShowDialog(); - //} + //登录远程主机布署Trojan程序 + private void StartSetUpTrojan(ConnectionInfo connectionInfo, TextBlock textBlockName, ProgressBar progressBar, string serverConfig, string clientConfig, string upLoadPath) + { + string currentStatus = "正在登录远程主机......"; + Action updateAction = new Action(UpdateTextBlock); + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); - //private void TestPortOccupy_Click(object sender, RoutedEventArgs e) - //{ - // MessageBoxResult dialogResult = MessageBox.Show("将强制停止占用80/443端口的程序?", "Stop application", MessageBoxButton.YesNo); - // if (dialogResult == MessageBoxResult.No) - // { - // return; - // } - // ConnectionInfo testconnect = GenerateConnectionInfo(); - // using (var client = new SshClient(testconnect)) - // { - // client.Connect(); - // string cmdTestPort = @"lsof -n -P -i :443 | grep LISTEN"; - // MessageBox.Show(cmdTestPort); - // string cmdResult = client.RunCommand(cmdTestPort).Result; - // client.Disconnect(); - // MessageBox.Show(cmdResult); - // string[] cmdResultArry = cmdResult.Split(' '); - // //foreach(string arry in cmdResultArry) - // //{ - // // MessageBox.Show(arry); - // //} - // MessageBox.Show(cmdResultArry[0]);//程序名字 - // MessageBox.Show(cmdResultArry[3]);//程序PID - // } - //} + try + { + #region 主机指纹,暂未启用 + //byte[] expectedFingerPrint = new byte[] { + // 0x66, 0x31, 0xaf, 0x00, 0x54, 0xb9, 0x87, 0x31, + // 0xff, 0x58, 0x1c, 0x31, 0xb1, 0xa2, 0x4c, 0x6b + // }; + #endregion + using (var client = new SshClient(connectionInfo)) - //private void TestInstalledV2ray_Click(object sender, RoutedEventArgs e) - //{ - // ConnectionInfo testconnect = GenerateConnectionInfo(); - // using (var client = new SshClient(testconnect)) - // { - // client.Connect(); - // //string cmdTestPort = @"find / -name v2ray"; - // //MessageBox.Show(cmdTestPort); - // //string cmdResult = client.RunCommand(cmdTestPort).Result; - // //设置Caddyfile文件中的tls 邮箱 - // string upLoadPath = "/etc/caddy/Caddyfile.test"; - // string emailAddress = ReceiveConfigurationParameters[4]; - // string sshCmdEmail = $"email={emailAddress};email=${{email/./@}};echo $email";//结尾有回车符 - // string email = client.RunCommand(sshCmdEmail).Result.Replace("\n",""); - // MessageBox.Show(email); - // string sshCmd = $"sed -i 's/off/{email}/' {upLoadPath}"; + { + #region ssh登录验证主机指纹代码块,暂未启用 + // client.HostKeyReceived += (sender, e) => + // { + // if (expectedFingerPrint.Length == e.FingerPrint.Length) + // { + // for (var i = 0; i < expectedFingerPrint.Length; i++) + // { + // if (expectedFingerPrint[i] != e.FingerPrint[i]) + // { + // e.CanTrust = false; + // break; + // } + // } + // } + // else + // { + // e.CanTrust = false; + // } + // }; + #endregion - // MessageBox.Show(sshCmd); - // client.RunCommand(sshCmd); - // sshCmd = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; - // MessageBox.Show(sshCmd); - // client.RunCommand(sshCmd); - // //sshCmd = "sed -i 's/##path##/\\" + ReceiveConfigurationParameters[3] + "/' " + upLoadPath; - // //MessageBox.Show(sshCmd); - // //client.RunCommand("sed -i 's/##path##/\\" + ReceiveConfigurationParameters[3] + "/' " + upLoadPath); - // sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; - // MessageBox.Show(sshCmd); - // client.RunCommand(sshCmd); - // //client.RunCommand("sed -i 's/##domain##/" + ReceiveConfigurationParameters[4] + "/' " + upLoadPath); - // if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) - // { - // sshCmd = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - // //client.RunCommand("sed -i 's/##sites##/proxy \\/ " + ReceiveConfigurationParameters[7] + "/' " + upLoadPath); - // MessageBox.Show(sshCmd); - // client.RunCommand(sshCmd); - // } - // Thread.Sleep(2000); + client.Connect(); + if (client.IsConnected == true) + { + currentStatus = "主机登录成功"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + } + //检测是否安装有Trojan + currentStatus = "检测系统是否已经安装V2ray......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); - // //生成安装服务命令中的邮箱 - // //string sshCmdEmail = $"email={emailAddress};email=${{email/./@}};echo $email"; - // //string email = client.RunCommand(sshCmdEmail).Result.ToString(); + //string cmdTestTrojanInstalled = @"find / -name trojan"; + string resultCmdTestTrojanInstalled = client.RunCommand(@"find / -name trojan").Result; - // //MessageBox.Show(email); + if (resultCmdTestTrojanInstalled.Contains("/usr/local/bin/trojan") == true) + { + MessageBoxResult messageBoxResult = MessageBox.Show("远程主机已安装Trojan,是否强制重新安装?", "", MessageBoxButton.YesNo, MessageBoxImage.Question); + if (messageBoxResult == MessageBoxResult.No) + { + currentStatus = "安装取消,退出"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + return; + } + } - // //安装Caddy服务 - // //sshCmd = "caddy -service install -agree -conf /etc/caddy/Caddyfile -email " + email; - // sshCmd = $"caddy -service install -agree -conf /etc/caddy/Caddyfile -email {email}"; + //检测远程主机系统环境是否符合要求 + currentStatus = "检测系统是否符合安装要求......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + string resultCmd = client.RunCommand("uname -m").Result; + //var result = client.RunCommand("cat /root/test.ver"); + //string[] linuxKernelVerStr = resultCmd.Split('-'); + + //bool detectResult = DetectKernelVersion(linuxKernelVerStr[0]); + + if (resultCmd.Contains("x86_64") == false) + { + MessageBox.Show($"请在x86_64系统中安装Trojan"); + currentStatus = "系统不符合要求,安装失败!!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + } + + //检测系统是否支持yum 或 apt-get或zypper,且支持Systemd + //如果不存在组件,则命令结果为空,string.IsNullOrEmpty值为真, + bool getApt = String.IsNullOrEmpty(client.RunCommand("command -v apt-get").Result); + bool getYum = String.IsNullOrEmpty(client.RunCommand("command -v yum").Result); + bool getZypper = String.IsNullOrEmpty(client.RunCommand("command -v zypper").Result); + bool getSystemd = String.IsNullOrEmpty(client.RunCommand("command -v systemctl").Result); + bool getGetenforce = String.IsNullOrEmpty(client.RunCommand("command -v getenforce").Result); + + //没有安装apt-get,也没有安装yum,也没有安装zypper,或者没有安装systemd的,不满足安装条件 + //也就是apt-get ,yum, zypper必须安装其中之一,且必须安装Systemd的系统才能安装。 + if ((getApt && getYum && getZypper) || getSystemd) + { + MessageBox.Show($"系统缺乏必要的安装组件如:apt-get||yum||zypper||Syetemd,主机系统推荐使用:CentOS 7/8,Debian 8/9/10,Ubuntu 16.04及以上版本"); + currentStatus = "系统环境不满足要求,安装失败!!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + return; + } + //判断是否启用了SELinux,如果启用了,并且工作在Enforcing模式下,则改为Permissive模式 + if (getGetenforce == false) + { + string testSELinux = client.RunCommand("getenforce").Result; + //MessageBox.Show(testSELinux); + if (testSELinux.Contains("Enforcing") == true) + { + //MessageBox.Show("Enforcing"); + client.RunCommand("setenforce 0");//不重启改为Permissive模式 + client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 + } + + } + + //如果使用如果是WebSocket + TLS + Web/http2/Http2Web/tcp_TLS/WebSocket_TLS模式,需要检测域名解析是否正确 + if (serverConfig.Contains("trojan_server") == true) + { + currentStatus = "正在检测域名是否解析到当前VPS的IP上......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + //在相应系统内安装curl(如果没有安装curl) + if (string.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true) + { + //为假则表示系统有相应的组件。 + if (getApt == false) + { + client.RunCommand("apt-get -qq update"); + client.RunCommand("apt-get -y -qq install curl"); + } + if (getYum == false) + { + client.RunCommand("yum -q makecache"); + client.RunCommand("yum -y -q install curl"); + } + if (getZypper == false) + { + client.RunCommand("zypper ref"); + client.RunCommand("zypper -y install curl"); + } + } + + string nativeIp = client.RunCommand("curl -4 ip.sb").Result.ToString(); + string testDomainCmd = "ping " + ReceiveConfigurationParameters[4] + " -c 1 | grep -oE -m1 \"([0-9]{1,3}\\.){3}[0-9]{1,3}\""; + string resultTestDomainCmd = client.RunCommand(testDomainCmd).Result.ToString(); + + if (String.Equals(nativeIp, resultCmd) == true) + { + currentStatus = "解析正确!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + } + else + { + currentStatus = "域名未能正确解析到当前VPS的IP上!安装失败!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + MessageBox.Show("域名未能正确解析到当前VPS的IP上,请检查!若解析设置正确,请等待生效后再重试安装。如果域名使用了CDN,请先关闭!"); + return; + } + + } + if (serverConfig.Contains("trojan_server") == true) + { + //检测是否安装lsof + if (string.IsNullOrEmpty(client.RunCommand("command -v lsof").Result) == true) + { + //为假则表示系统有相应的组件。 + if (getApt == false) + { + client.RunCommand("apt-get -qq update"); + client.RunCommand("apt-get -y -qq install lsof"); + } + if (getYum == false) + { + client.RunCommand("yum -q makecache"); + client.RunCommand("yum -y -q install lsof"); + } + if (getZypper == false) + { + client.RunCommand("zypper ref"); + client.RunCommand("zypper -y install lsof"); + } + } + currentStatus = "正在检测端口占用情况......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + //MessageBox.Show(@"lsof -n -P -i :80 | grep LISTEN"); + //MessageBox.Show(client.RunCommand(@"lsof -n -P -i :80 | grep LISTEN").Result); + if (String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :80 | grep LISTEN").Result) == false || String.IsNullOrEmpty(client.RunCommand(@"lsof -n -P -i :443 | grep LISTEN").Result) == false) + { + MessageBox.Show("80/443端口之一,或全部被占用,请先用系统工具中的“释放80/443端口”工具,释放出,再重新安装"); + currentStatus = "端口被占用,安装失败......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + return; + } + } + currentStatus = "符合安装要求,布署中......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + //在相应系统内安装curl(如果没有安装curl) + if (string.IsNullOrEmpty(client.RunCommand("command -v curl").Result) == true) + { + //为假则表示系统有相应的组件。 + if (getApt == false) + { + client.RunCommand("apt-get -qq update"); + client.RunCommand("apt-get -y -qq install curl"); + } + if (getYum == false) + { + client.RunCommand("yum -q makecache"); + client.RunCommand("yum -y -q install curl"); + } + if (getZypper == false) + { + client.RunCommand("zypper ref"); + client.RunCommand("zypper -y install curl"); + } + } - // client.Disconnect(); - // //MessageBox.Show(cmdResult); - // //if (cmdResult.Contains("/usr/bin/v2ray")==true) - // //{ - // // MessageBox.Show("已安装"); - // //} - // //else - // //{ - // // MessageBox.Show("未安装"); - // //} - // //string[] cmdResultArry = cmdResult.Split('\n'); - // //foreach(string arry in cmdResultArry) - // //{ - // // MessageBox.Show(arry); - // //} - // //MessageBox.Show(cmdResultArry[0]);//程序名字 - // //MessageBox.Show(cmdResultArry[3]);//程序PID - // } - //} + //下载官方安装脚本安装 - //private void TestsshCmd_Click(object sender, RoutedEventArgs e) - //{ - // ReceiveConfigurationParameters[3] = "https://tes.te.tt"; - // ReceiveConfigurationParameters[7] = "http://77.77.77"; - // string upLoadPath = "/etc/caddy/Caddyfile"; - // string sshCmd = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; - // //MessageBox.Show(sshCmd); - // //sshCmd = "sed -i 's/##path##/\\" + ReceiveConfigurationParameters[3] + "/' " + upLoadPath; - // //MessageBox.Show(sshCmd); - // //sshCmd = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; - // //MessageBox.Show(sshCmd); - // //sshCmd = "sed -i 's/##path##/\\" + ReceiveConfigurationParameters[3] + "/' " + upLoadPath; - // //MessageBox.Show(sshCmd); - // //client.RunCommand("sed -i 's/##path##/\\" + ReceiveConfigurationParameters[3] + "/' " + upLoadPath); - // sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; - // MessageBox.Show(sshCmd); - // string testDomain = ReceiveConfigurationParameters[7].Substring(0,7); - // if (String.Equals(testDomain,"https:/")||String.Equals(testDomain,"http://")) - // { - // MessageBox.Show(testDomain); - // ReceiveConfigurationParameters[7]=ReceiveConfigurationParameters[7].Replace("/","\\/"); - // } - // else - // { - // ReceiveConfigurationParameters[7] = "http:\\/\\/" + ReceiveConfigurationParameters[7]; - // } - // sshCmd = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; - // MessageBox.Show(sshCmd); - //} + client.RunCommand("bash -c \"$(curl - fsSL https://raw.githubusercontent.com/trojan-gfw/trojan-quickstart/master/trojan-quickstart.sh)\""); + //client.RunCommand("bash /tmp/go.sh -f"); + string installResult = client.RunCommand("find / -name trojan").Result.ToString(); + + if (!installResult.Contains("/usr/local/bin/trojan")) + { + MessageBox.Show("安装Trojan失败(官方脚本运行出错!"); + client.Disconnect(); + currentStatus = "安装Trojan失败(官方脚本运行出错!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + return; + } + client.RunCommand("mv /usr/local/etc/trojan/config.json /usr/local/etc/trojan/config.json.1"); + + //上传配置文件 + currentStatus = "Trojan程序安装完毕,配置文件上传中......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + //生成服务端配置 + using (StreamReader reader = File.OpenText(serverConfig)) + { + JObject serverJson = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); + //设置密码 + serverJson["password"][0] = ReceiveConfigurationParameters[2]; + //设置监听端口 + //serverJson["inbounds"][0]["port"] = int.Parse(ReceiveConfigurationParameters[1]); + + using (StreamWriter sw = new StreamWriter(@"config.json")) + { + sw.Write(serverJson.ToString()); + } + } + UploadConfig(connectionInfo, @"config.json", upLoadPath); + + File.Delete(@"config.json"); + + //打开防火墙端口 + string openFireWallPort = ReceiveConfigurationParameters[1]; + if (String.IsNullOrEmpty(client.RunCommand("command -v firewall-cmd").Result) == false) + { + if (String.Equals(openFireWallPort, "443")) + { + client.RunCommand("firewall-cmd --zone=public --add-port=80/tcp --permanent"); + client.RunCommand("firewall-cmd --zone=public --add-port=443/tcp --permanent"); + client.RunCommand("firewall-cmd --reload"); + } + else + { + client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/tcp --permanent"); + client.RunCommand($"firewall-cmd --zone=public --add-port={openFireWallPort}/udp --permanent"); + client.RunCommand("firewall-cmd --reload"); + } + } + if (String.IsNullOrEmpty(client.RunCommand("command -v ufw").Result) == false) + { + if (String.Equals(openFireWallPort, "443")) + { + client.RunCommand("ufw allow 80"); + client.RunCommand("ufw allow 443"); + client.RunCommand("ufw reset"); + } + else + { + client.RunCommand($"ufw allow {openFireWallPort}/tcp"); + client.RunCommand($"ufw allow {openFireWallPort}/udp"); + client.RunCommand("ufw reset"); + } + } + + //安装nginx + if (serverConfig.Contains("trojan_server") == true) + { + currentStatus = "正在安装Caddy"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + client.RunCommand("curl https://getcaddy.com -o getcaddy"); + client.RunCommand("bash getcaddy personal hook.service"); + client.RunCommand("mkdir -p /etc/caddy"); + client.RunCommand("mkdir -p /var/www"); + currentStatus = "上传Caddy配置文件......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + if (serverConfig.Contains("trojan_server") == true) + { + serverConfig = "TemplateConfg\\trojan_caddy_config.caddyfile"; + } + + upLoadPath = "/etc/caddy/Caddyfile"; + UploadConfig(connectionInfo, serverConfig, upLoadPath); - //private void Button_Click(object sender, RoutedEventArgs e) - //{ - // ConnectionInfo testconnect = GenerateConnectionInfo(); - // using (var client = new SshClient(testconnect)) - // { - // client.Connect(); - // bool getGetenforce = String.IsNullOrEmpty(client.RunCommand("command -v getenforce").Result); + //设置Caddyfile文件中的tls 邮箱 + //string sshCmdEmail = $"email={ReceiveConfigurationParameters[4]};email=${{email/./@}};echo $email";//结尾有回车符 + //string email = client.RunCommand(sshCmdEmail).Result.Replace("\n", "");//删除结尾的回车符 + string email = $"user@{ReceiveConfigurationParameters[4]}"; + string sshCmd;// = $"sed -i 's/off/{email}/' {upLoadPath}";//设置Caddyfile中的邮箱 + //client.RunCommand(sshCmd); + //设置Path + //sshCmd = $"sed -i 's/##path##/\\{ReceiveConfigurationParameters[3]}/' {upLoadPath}"; + //MessageBox.Show(sshCmd); + //client.RunCommand(sshCmd); + //设置域名 + sshCmd = $"sed -i 's/##domain##/{ReceiveConfigurationParameters[4]}/' {upLoadPath}"; + //MessageBox.Show(sshCmd); + client.RunCommand(sshCmd); + //设置伪装网站 + if (String.IsNullOrEmpty(ReceiveConfigurationParameters[7]) == false) + { + sshCmd = $"sed -i 's/##sites##/proxy \\/ {ReceiveConfigurationParameters[7]}/' {upLoadPath}"; + //MessageBox.Show(sshCmd); + client.RunCommand(sshCmd); + } + Thread.Sleep(2000); - // if (getGetenforce == false) - // { - // string testSELinux = client.RunCommand("getenforce").Result; - // MessageBox.Show(testSELinux); - // if (testSELinux.Contains("Enforcing") == true) - // { - // MessageBox.Show("Enforcing"); - // client.RunCommand("setenforce 0");//不重启改为Permissive模式 - // client.RunCommand("sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config");//重启也工作在Permissive模式下 - // } - // else - // { - // MessageBox.Show("非Enforcing"); - // } - // } - // client.Disconnect(); - // } - //} - //private void ButtonWebBrowserProxyGo_Click(object sender, RoutedEventArgs e) - //{ - // try - // { - // string urlStartchar = TextBoxWebBrowserProxyUrl.Text.Substring(0, 4); - // //MessageBox.Show(urlStartchar); - // if (String.Equals(urlStartchar,"http")==true) - // { - // WebBrowserResourcesAndTools.Source = new Uri(TextBoxWebBrowserProxyUrl.Text); - // } - // else - // { - // WebBrowserResourcesAndTools.Source = new Uri("http://" + TextBoxWebBrowserProxyUrl.Text);//如果没有前置代理,此处应为:"http://" + TextBoxWebBrowserProxyUrl.Text - // } - - // } - // catch (Exception ex) - // { - // MessageBox.Show(ex.Message); - // } - // } + //安装Caddy服务 + sshCmd = $"caddy -service install -agree -conf /etc/caddy/Caddyfile -email {email}"; + //MessageBox.Show(sshCmd); + client.RunCommand(sshCmd); + //启动Caddy服务 + client.RunCommand("caddy -service restart"); + } + + if (serverConfig.Contains("trojan_server") == true) + { + currentStatus = "使用Trojan+TLS+Web模式,正在安装acme.sh......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + if (getApt == false) + { + //client.RunCommand("apt-get -qq update"); + client.RunCommand("apt-get -y -qq install socat"); + } + if (getYum == false) + { + //client.RunCommand("yum -q makecache"); + client.RunCommand("yum -y -q install socat"); + } + if (getZypper == false) + { + // client.RunCommand("zypper ref"); + client.RunCommand("zypper -y install socat"); + } + client.RunCommand("curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | INSTALLONLINE=1 sh"); + client.RunCommand("cd ~/.acme.sh/"); + client.RunCommand("alias acme.sh=~/.acme.sh/acme.sh"); + + currentStatus = "申请域名证书......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + //client.RunCommand("mkdir -p /etc/v2ray/ssl"); + client.RunCommand($"/root/.acme.sh/acme.sh --issue --standalone -d {ReceiveConfigurationParameters[4]}"); + + currentStatus = "安装证书到V2ray......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + client.RunCommand($"/root/.acme.sh/acme.sh --installcert -d {ReceiveConfigurationParameters[4]} --certpath /usr/local/etc/trojan/trojan_ssl.crt --keypath /usr/local/etc/trojan/trojan_ssl.key --capath /usr/local/etc/trojan/trojan_ssl.crt --reloadcmd \"systemctl restart trojan\""); + } + + currentStatus = "正在启动Trojan......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + //启动V2ray服务 + client.RunCommand("systemctl restart trojan"); + + currentStatus = "Trojan启动成功!"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + + //生成客户端配置 + currentStatus = "生成客户端配置......"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + if (!Directory.Exists("trojan_config"))//如果不存在就创建file文件夹      + { + Directory.CreateDirectory("trojan_config");//创建该文件夹   + } + //string clientConfig = "TemplateConfg\\tcp_client_config.json"; + using (StreamReader reader = File.OpenText(clientConfig)) + { + JObject clientJson = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); + + clientJson["remote_addr"] = ReceiveConfigurationParameters[4]; + clientJson["remote_port"] = int.Parse(ReceiveConfigurationParameters[1]); + clientJson["password"][0] = ReceiveConfigurationParameters[2]; + + using (StreamWriter sw = new StreamWriter(@"trojan_config\config.json")) + { + sw.Write(clientJson.ToString()); + } + } + + client.Disconnect(); + + currentStatus = "安装成功"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + Thread.Sleep(1000); + + //显示服务端连接参数 + //MessageBox.Show("用于V2ray官方客户端的配置文件已保存在config文件夹中"); + TrojanResultClientInfoWindow resultClientInformation = new TrojanResultClientInfoWindow(); + resultClientInformation.ShowDialog(); + + return; + } + } + catch (Exception ex1)//例外处理 + #region 例外处理 + { + //MessageBox.Show(ex1.Message); + if (ex1.Message.Contains("连接尝试失败") == true) + { + MessageBox.Show($"{ex1.Message}\n请检查主机地址及端口是否正确,如果通过代理,请检查代理是否正常工作"); + } + + else if (ex1.Message.Contains("denied (password)") == true) + { + MessageBox.Show($"{ex1.Message}\n密码错误或用户名错误"); + } + else if (ex1.Message.Contains("Invalid private key file") == true) + { + MessageBox.Show($"{ex1.Message}\n所选密钥文件错误或者格式不对"); + } + else if (ex1.Message.Contains("denied (publickey)") == true) + { + MessageBox.Show($"{ex1.Message}\n使用密钥登录,密钥文件错误或用户名错误"); + } + else if (ex1.Message.Contains("目标计算机积极拒绝") == true) + { + MessageBox.Show($"{ex1.Message}\n主机地址错误,如果使用了代理,也可能是连接代理的端口错误"); + } + else + { + MessageBox.Show("发生错误"); + MessageBox.Show(ex1.Message); + } + currentStatus = "主机登录失败"; + textBlockName.Dispatcher.BeginInvoke(updateAction, textBlockName, progressBar, currentStatus); + + } + #endregion + + } } } diff --git a/ProxySU/ProxySU.csproj b/ProxySU/ProxySU.csproj index 097a7f9..9ad6c79 100644 --- a/ProxySU/ProxySU.csproj +++ b/ProxySU/ProxySU.csproj @@ -90,6 +90,12 @@ TemplateConfiguration.xaml + + TrojanResultClientInfoWindow.xaml + + + TrojanTemplateWindow.xaml + MSBuild:Compile Designer @@ -114,6 +120,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + diff --git a/ProxySU/ResultClientInformation.xaml.cs b/ProxySU/ResultClientInformation.xaml.cs index 3c77d92..f186a54 100644 --- a/ProxySU/ResultClientInformation.xaml.cs +++ b/ProxySU/ResultClientInformation.xaml.cs @@ -250,7 +250,7 @@ namespace ProxySU HidePath(); HideQuicKey(); } - CheckDir("config"); + CheckDir("v2ray_config"); GenerateV2rayShareQRcodeAndBase64Url(); @@ -329,29 +329,29 @@ namespace ProxySU string saveFileFolderFirst = v2rayNjsonObject["ps"].ToString(); int num = 1; saveFileFolder = saveFileFolderFirst; - while (Directory.Exists(@"config\" + saveFileFolder)) + while (Directory.Exists(@"v2ray_config\" + saveFileFolder)) { saveFileFolder = saveFileFolderFirst + "_copy_" + num.ToString(); num++; } - CheckDir(@"config\" + saveFileFolder); + CheckDir(@"v2ray_config\" + saveFileFolder); //MessageBox.Show(v2rayNjsonObject.ToString()); string vmessUrl = "vmess://" + ToBase64Encode(v2rayNjsonObject.ToString()); TextBoxvVmessUrl.Text = vmessUrl; - using (StreamWriter sw = new StreamWriter($"config\\{saveFileFolder}\\url.txt")) + using (StreamWriter sw = new StreamWriter($"v2ray_config\\{saveFileFolder}\\url.txt")) { sw.WriteLine(vmessUrl); } CreateQRCode(vmessUrl); - if (File.Exists(@"config\config.json")) + if (File.Exists(@"v2ray_config\config.json")) { - File.Move(@"config\config.json", @"config\" + saveFileFolder + @"\config.json"); + File.Move(@"v2ray_config\config.json", @"v2ray_config\" + saveFileFolder + @"\config.json"); //File.Delete(@"config\config.json");//删除该文件 } - using (StreamWriter sw = new StreamWriter($"config\\{saveFileFolder}\\说明.txt")) + using (StreamWriter sw = new StreamWriter($"v2ray_config\\{saveFileFolder}\\说明.txt")) { sw.WriteLine("config.json"); sw.WriteLine("此文件为v2ray官方程序所使用的客户端配置文件,配置为全局模式,socks5地址:127.0.0.1:1080,http代理地址:127.0.0.1:1081"); @@ -410,7 +410,7 @@ namespace ProxySU BitmapSource imgsource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(myImagePtr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); ImageShareQRcode.Source = imgsource; //DeleteObject(myImagePtr); - qrCodeImage.Save($"config\\{saveFileFolder}\\QR.bmp"); + qrCodeImage.Save($"v2ray_config\\{saveFileFolder}\\QR.bmp"); //ImageShareQRcode.Source = @"config\v2rayN.bmp"; } //判断目录是否存在,不存在则创建 @@ -430,7 +430,7 @@ namespace ProxySU private void ButtonOpenSaveDir_Click(object sender, RoutedEventArgs e) { - string openFolderPath = @"config\" + saveFileFolder; + string openFolderPath = @"v2ray_config\" + saveFileFolder; System.Diagnostics.Process.Start("explorer.exe", openFolderPath); this.Close(); } diff --git a/ProxySU/TrojanResultClientInfoWindow.xaml b/ProxySU/TrojanResultClientInfoWindow.xaml new file mode 100644 index 0000000..3f8da0f --- /dev/null +++ b/ProxySU/TrojanResultClientInfoWindow.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/ProxySU/TrojanResultClientInfoWindow.xaml.cs b/ProxySU/TrojanResultClientInfoWindow.xaml.cs new file mode 100644 index 0000000..eab8844 --- /dev/null +++ b/ProxySU/TrojanResultClientInfoWindow.xaml.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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 +{ + /// + /// TrojanResultClientInfoWindow.xaml 的交互逻辑 + /// + public partial class TrojanResultClientInfoWindow : Window + { + public TrojanResultClientInfoWindow() + { + InitializeComponent(); + } + } +} diff --git a/ProxySU/TrojanTemplateWindow.xaml b/ProxySU/TrojanTemplateWindow.xaml new file mode 100644 index 0000000..1337a7c --- /dev/null +++ b/ProxySU/TrojanTemplateWindow.xaml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ProxySU/TrojanTemplateWindow.xaml.cs b/ProxySU/TrojanTemplateWindow.xaml.cs new file mode 100644 index 0000000..d93ec8f --- /dev/null +++ b/ProxySU/TrojanTemplateWindow.xaml.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +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 +{ + /// + /// TrojanTemplateWindow.xaml 的交互逻辑 + /// + public partial class TrojanTemplateWindow : Window + { + public TrojanTemplateWindow() + { + InitializeComponent(); + RadioButtonTrojanTLS2Web.IsChecked = true; + } + private void ButtondDecide_Click(object sender, RoutedEventArgs e) + { + if (RadioButtonTrojanTLS2Web.IsChecked == true) + { + if (string.IsNullOrEmpty(TextBoxDomain.Text.ToString()) == true) + { + MessageBox.Show("域名不能为空!"); + return; + } + //传递模板类型 + MainWindow.ReceiveConfigurationParameters[0] = "TrojanTLS2Web"; + + //传递域名 + MainWindow.ReceiveConfigurationParameters[4] = TextBoxDomain.Text.ToString(); + //传递伪装网站 + MainWindow.ReceiveConfigurationParameters[7] = TextBoxMaskSites.Text.ToString(); + //处理伪装网站域名中的前缀 + if (TextBoxMaskSites.Text.ToString().Length >= 7) + { + string testDomain = TextBoxMaskSites.Text.Substring(0, 7); + if (String.Equals(testDomain, "https:/") || String.Equals(testDomain, "http://")) + { + //MessageBox.Show(testDomain); + MainWindow.ReceiveConfigurationParameters[7] = TextBoxMaskSites.Text.Replace("/", "\\/"); + } + else + { + MainWindow.ReceiveConfigurationParameters[7] = "http:\\/\\/" + TextBoxMaskSites.Text; + } + } + } + //传递服务端口 + MainWindow.ReceiveConfigurationParameters[1] = TextBoxServerListenPort.Text.ToString(); + //传递密码(uuid) + MainWindow.ReceiveConfigurationParameters[2] = TextBoxNewUUID.Text.ToString(); + + this.Close(); + } + private void ButtonNewUUID_Click(object sender, RoutedEventArgs e) + { + Guid uuid = Guid.NewGuid(); + TextBoxNewUUID.Text = uuid.ToString(); + } + private void ButtonServerListenPort_Click(object sender, RoutedEventArgs e) + { + Random random = new Random(); + int randomServerPort = random.Next(10000, 50000); + TextBoxServerListenPort.Text = randomServerPort.ToString(); + } + private void ButtondCancel_Click(object sender, RoutedEventArgs e) => Close(); + + private void RadioButtonTrojanTLS2Web_Checked(object sender, RoutedEventArgs e) + { + Guid uuid = Guid.NewGuid(); + TextBoxNewUUID.Text = uuid.ToString(); + //Random random = new Random(); + //int randomServerPort = random.Next(10000, 50000); + TextBoxServerListenPort.Text = "443"; + } + } +} diff --git a/ProxySU/bin/Release/ProxySU.exe b/ProxySU/bin/Release/ProxySU.exe index fa6d26f..23952f7 100644 Binary files a/ProxySU/bin/Release/ProxySU.exe and b/ProxySU/bin/Release/ProxySU.exe differ diff --git a/ProxySU/bin/Release/Release.zip b/ProxySU/bin/Release/Release.zip index a6ccaa0..169ab9d 100644 Binary files a/ProxySU/bin/Release/Release.zip and b/ProxySU/bin/Release/Release.zip differ diff --git a/appPreview0.png b/appPreview0.png deleted file mode 100644 index 5a06944..0000000 Binary files a/appPreview0.png and /dev/null differ diff --git a/appPreview1.png b/appPreview1.png deleted file mode 100644 index 0a89537..0000000 Binary files a/appPreview1.png and /dev/null differ diff --git a/appPreview2.png b/appPreview2.png deleted file mode 100644 index 0e9d3e6..0000000 Binary files a/appPreview2.png and /dev/null differ diff --git a/appPreview3.png b/appPreview3.png deleted file mode 100644 index daae538..0000000 Binary files a/appPreview3.png and /dev/null differ diff --git a/appPreview4.png b/appPreview4.png deleted file mode 100644 index 15e6fe7..0000000 Binary files a/appPreview4.png and /dev/null differ diff --git a/appPreview5.png b/appPreview5.png deleted file mode 100644 index 1ae62eb..0000000 Binary files a/appPreview5.png and /dev/null differ diff --git a/appPreview6.png b/appPreview6.png deleted file mode 100644 index b2f4187..0000000 Binary files a/appPreview6.png and /dev/null differ