diff --git a/FastGithub.Configuration/DnsConfig.cs b/FastGithub.Configuration/DnsConfig.cs
index f636a38..e03055b 100644
--- a/FastGithub.Configuration/DnsConfig.cs
+++ b/FastGithub.Configuration/DnsConfig.cs
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
@@ -52,17 +53,10 @@ namespace FastGithub.Configuration
///
private static bool IsLocalMachineIPAddress(IPAddress address)
{
- foreach (var @interface in NetworkInterface.GetAllNetworkInterfaces())
- {
- foreach (var addressInfo in @interface.GetIPProperties().UnicastAddresses)
- {
- if (addressInfo.Address.Equals(address))
- {
- return true;
- }
- }
- }
- return false;
+ return IPGlobalProperties
+ .GetIPGlobalProperties()
+ .GetUnicastAddresses()
+ .Any(item => item.Address.Equals(address));
}
}
}
diff --git a/FastGithub.Dns/DnsServer.cs b/FastGithub.Dns/DnsServer.cs
index 6116aa3..9ab0a1d 100644
--- a/FastGithub.Dns/DnsServer.cs
+++ b/FastGithub.Dns/DnsServer.cs
@@ -1,8 +1,10 @@
using DNS.Protocol;
+using FastGithub.Configuration;
using Microsoft.Extensions.Logging;
using System;
-using System.Diagnostics;
+using System.Linq;
using System.Net;
+using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
@@ -40,9 +42,15 @@ namespace FastGithub.Dns
///
public void Bind(IPAddress address, int port)
{
- if (OperatingSystem.IsWindows() && UdpTable.TryGetOwnerProcessId(port, out var processId))
+ if (OperatingSystem.IsWindows())
{
- Process.GetProcessById(processId).Kill();
+ UdpTable.KillPortOwner(port);
+ }
+
+ var udpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners();
+ if (udpListeners.Any(item => item.Port == port))
+ {
+ throw new FastGithubException($"udp端口{port}已经被其它进程占用");
}
if (OperatingSystem.IsWindows())
diff --git a/FastGithub.Dns/HostsValidator.cs b/FastGithub.Dns/HostsValidator.cs
index 2fb76b2..3ba84f4 100644
--- a/FastGithub.Dns/HostsValidator.cs
+++ b/FastGithub.Dns/HostsValidator.cs
@@ -84,15 +84,9 @@ namespace FastGithub.Dns
///
private static IEnumerable GetLocalMachineIPAddress()
{
- yield return IPAddress.Loopback;
- yield return IPAddress.IPv6Loopback;
-
- foreach (var @interface in NetworkInterface.GetAllNetworkInterfaces())
+ foreach (var item in IPGlobalProperties.GetIPGlobalProperties().GetUnicastAddresses())
{
- foreach (var addressInfo in @interface.GetIPProperties().UnicastAddresses)
- {
- yield return addressInfo.Address;
- }
+ yield return item.Address;
}
}
}
diff --git a/FastGithub.Dns/UdpTable.cs b/FastGithub.Dns/UdpTable.cs
index 8657c96..f126fdc 100644
--- a/FastGithub.Dns/UdpTable.cs
+++ b/FastGithub.Dns/UdpTable.cs
@@ -1,5 +1,6 @@
using System;
using System.Buffers.Binary;
+using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
@@ -18,6 +19,34 @@ namespace FastGithub.Dns
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern uint GetExtendedUdpTable(void* pUdpTable, ref int pdwSize, bool bOrder, AddressFamily ulAf, UDP_TABLE_CLASS tableClass, uint reserved = 0);
+
+ ///
+ /// 杀死占用进程
+ ///
+ ///
+ ///
+ public static bool KillPortOwner(int port)
+ {
+ if (TryGetOwnerProcessId(port, out var pid) == false)
+ {
+ return true;
+ }
+
+ try
+ {
+ Process.GetProcessById(pid).Kill();
+ return true;
+ }
+ catch (ArgumentException)
+ {
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
///
/// 获取udp端口的占用进程id
///
diff --git a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs
index 8be4fe0..f4871c9 100644
--- a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs
+++ b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs
@@ -22,9 +22,34 @@ namespace FastGithub
public static class KestrelServerOptionsExtensions
{
///
- /// 域名证书缓存
+ /// 服务器证书缓存
///
- private static readonly IMemoryCache domainCertCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
+ private static readonly IMemoryCache serverCertCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
+
+ ///
+ /// 监听http的反向代理
+ ///
+ ///
+ public static void ListenHttpReverseProxy(this KestrelServerOptions kestrel)
+ {
+ var loggerFactory = kestrel.ApplicationServices.GetRequiredService();
+ var logger = loggerFactory.CreateLogger($"{nameof(FastGithub)}.{nameof(ReverseProxy)}");
+
+ const int HTTP_PORT = 80;
+ if (OperatingSystem.IsWindows())
+ {
+ TcpTable.KillPortOwner(HTTP_PORT);
+ }
+
+ if (CanTcpListen(HTTP_PORT) == false)
+ {
+ logger.LogWarning($"无法监听tcp端口{HTTP_PORT},{nameof(FastGithub)}无法http反向代理");
+ }
+ else
+ {
+ kestrel.Listen(IPAddress.Any, HTTP_PORT);
+ }
+ }
///
/// 监听https的反向代理
@@ -43,10 +68,34 @@ namespace FastGithub
GeneratorCaCert(caPublicCerPath, caPrivateKeyPath);
InstallCaCert(caPublicCerPath, logger);
- kestrel.Listen(IPAddress.Any, 443, listen =>
- listen.UseHttps(https =>
- https.ServerCertificateSelector = (ctx, domain) =>
- GetDomainCert(domain, caPublicCerPath, caPrivateKeyPath)));
+ const int HTTPS_PORT = 443;
+ if (OperatingSystem.IsWindows())
+ {
+ TcpTable.KillPortOwner(HTTPS_PORT);
+ }
+
+ if (CanTcpListen(HTTPS_PORT) == false)
+ {
+ logger.LogWarning($"无法监听tcp端口{HTTPS_PORT},{nameof(FastGithub)}无法https反向代理");
+ }
+ else
+ {
+ kestrel.Listen(IPAddress.Any, HTTPS_PORT, listen =>
+ listen.UseHttps(https =>
+ https.ServerCertificateSelector = (ctx, domain) =>
+ GetServerCert(domain, caPublicCerPath, caPrivateKeyPath)));
+ }
+ }
+
+ ///
+ /// 是否可以监听指定端口
+ ///
+ ///
+ ///
+ private static bool CanTcpListen(int port)
+ {
+ var tcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
+ return tcpListeners.Any(item => item.Port == port) == false;
}
///
@@ -81,25 +130,24 @@ namespace FastGithub
if (OperatingSystem.IsWindows() == false)
{
logger.LogWarning($"不支持自动安装证书{caPublicCerPath}:请手动安装证书到根证书颁发机构");
+ return;
}
- else
+
+ try
{
- try
+ var caCert = new X509Certificate2(caPublicCerPath);
+ using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
+ store.Open(OpenFlags.ReadWrite);
+ if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
{
- var caCert = new X509Certificate2(caPublicCerPath);
- using var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
- store.Open(OpenFlags.ReadWrite);
- if (store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, true).Count == 0)
- {
- store.Add(caCert);
- store.Close();
- }
- }
- catch (Exception)
- {
- logger.LogWarning($"安装证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
+ store.Add(caCert);
+ store.Close();
}
}
+ catch (Exception)
+ {
+ logger.LogWarning($"安装证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”");
+ }
}
///
@@ -109,9 +157,9 @@ namespace FastGithub
///
///
///
- private static X509Certificate2 GetDomainCert(string? domain, string caPublicCerPath, string caPrivateKeyPath)
+ private static X509Certificate2 GetServerCert(string? domain, string caPublicCerPath, string caPrivateKeyPath)
{
- return domainCertCache.GetOrCreate(domain ?? string.Empty, GetOrCreateCert);
+ return serverCertCache.GetOrCreate(domain ?? string.Empty, GetOrCreateCert);
// 生成域名的1年证书
X509Certificate2 GetOrCreateCert(ICacheEntry entry)
@@ -138,17 +186,14 @@ namespace FastGithub
yield return host;
}
- yield return Environment.MachineName;
- yield return IPAddress.Loopback.ToString();
+ var globalPropreties = IPGlobalProperties.GetIPGlobalProperties();
- foreach (var @interface in NetworkInterface.GetAllNetworkInterfaces())
+ yield return globalPropreties.HostName;
+ foreach (var item in globalPropreties.GetUnicastAddresses())
{
- foreach (var addressInfo in @interface.GetIPProperties().UnicastAddresses)
+ if (item.Address.AddressFamily == AddressFamily.InterNetwork)
{
- if (addressInfo.Address.AddressFamily == AddressFamily.InterNetwork)
- {
- yield return addressInfo.Address.ToString();
- }
+ yield return item.Address.ToString();
}
}
}
diff --git a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
index 79f6996..be7febd 100644
--- a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
+++ b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
@@ -21,11 +21,11 @@ namespace FastGithub
}
///
- /// 使用https反向代理中间件
+ /// 使用反向代理中间件
///
///
///
- public static IApplicationBuilder UseHttpsReverseProxy(this IApplicationBuilder app)
+ public static IApplicationBuilder UseReverseProxy(this IApplicationBuilder app)
{
var middleware = app.ApplicationServices.GetRequiredService();
return app.Use(next => context => middleware.InvokeAsync(context, next));
diff --git a/FastGithub.ReverseProxy/ReverseProxyHostedService.cs b/FastGithub.ReverseProxy/ReverseProxyHostedService.cs
deleted file mode 100644
index 5bae00d..0000000
--- a/FastGithub.ReverseProxy/ReverseProxyHostedService.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace FastGithub.ReverseProxy
-{
- ///
- /// 反向代理端口检测后台服务
- ///
- sealed class ReverseProxyHostedService : IHostedService
- {
- private readonly ILogger logger;
-
- ///
- /// 反向代理端口检测后台服务
- ///
- ///
- public ReverseProxyHostedService(ILogger logger)
- {
- this.logger = logger;
- }
-
- ///
- /// 服务启动时
- ///
- ///
- ///
- public Task StartAsync(CancellationToken cancellationToken)
- {
- const int HTTPSPORT = 443;
- if (OperatingSystem.IsWindows())
- {
- if (TcpTable.TryGetOwnerProcessId(HTTPSPORT, out var pid))
- {
- try
- {
- Process.GetProcessById(pid).Kill();
- }
- catch (ArgumentException)
- {
- }
- catch (Exception)
- {
- var processName = Process.GetProcessById(pid).ProcessName;
- this.logger.LogError($"由于进程{processName}({pid})占用了{HTTPSPORT}端口,{nameof(FastGithub)}的反向代理无法工作");
- }
- }
- }
- return Task.CompletedTask;
- }
-
- ///
- /// 服务停止时
- ///
- ///
- ///
- public Task StopAsync(CancellationToken cancellationToken)
- {
- return Task.CompletedTask;
- }
- }
-}
diff --git a/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs b/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs
index 2600627..b0c451c 100644
--- a/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs
+++ b/FastGithub.ReverseProxy/ReverseProxyMiddleware.cs
@@ -23,7 +23,7 @@ namespace FastGithub.ReverseProxy
IHttpClientFactory httpClientFactory,
FastGithubConfig fastGithubConfig,
ILogger logger)
- {
+ {
this.httpForwarder = httpForwarder;
this.httpClientFactory = httpClientFactory;
this.fastGithubConfig = fastGithubConfig;
@@ -54,7 +54,8 @@ namespace FastGithub.ReverseProxy
}
else
{
- var destinationPrefix = GetDestinationPrefix(host, domainConfig.Destination);
+ var scheme = context.Request.Scheme;
+ var destinationPrefix = GetDestinationPrefix(scheme, host, domainConfig.Destination);
var httpClient = this.httpClientFactory.CreateHttpClient(domainConfig);
var error = await httpForwarder.SendAsync(context, destinationPrefix, httpClient);
await HandleErrorAsync(context, error);
@@ -64,12 +65,13 @@ namespace FastGithub.ReverseProxy
///
/// 获取目标前缀
///
- ///
+ ///
+ ///
///
///
- private string GetDestinationPrefix(string host, Uri? destination)
+ private string GetDestinationPrefix(string scheme, string host, Uri? destination)
{
- var defaultValue = $"https://{host}/";
+ var defaultValue = $"{scheme}://{host}/";
if (destination == null)
{
return defaultValue;
diff --git a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
index 72858a9..069a745 100644
--- a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
+++ b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
@@ -19,8 +19,7 @@ namespace FastGithub
.AddMemoryCache()
.AddHttpForwarder()
.AddSingleton()
- .AddSingleton()
- .AddHostedService();
+ .AddSingleton();
}
}
}
diff --git a/FastGithub.ReverseProxy/TcpTable.cs b/FastGithub.ReverseProxy/TcpTable.cs
index fcf0033..4e8065d 100644
--- a/FastGithub.ReverseProxy/TcpTable.cs
+++ b/FastGithub.ReverseProxy/TcpTable.cs
@@ -1,5 +1,6 @@
using System;
using System.Buffers.Binary;
+using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
@@ -18,6 +19,34 @@ namespace FastGithub.ReverseProxy
[DllImport("iphlpapi.dll", SetLastError = true)]
private static extern uint GetExtendedTcpTable(void* pTcpTable, ref int pdwSize, bool bOrder, AddressFamily ulAf, TCP_TABLE_CLASS tableClass, uint reserved = 0);
+
+ ///
+ /// 杀死占用进程
+ ///
+ ///
+ ///
+ public static bool KillPortOwner(int port)
+ {
+ if (TryGetOwnerProcessId(port, out var pid) == false)
+ {
+ return true;
+ }
+
+ try
+ {
+ Process.GetProcessById(pid).Kill();
+ return true;
+ }
+ catch (ArgumentException)
+ {
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
///
/// 获取tcp端口的占用进程id
///
diff --git a/FastGithub/HostedService.cs b/FastGithub/HostedService.cs
index daffbac..8d1bd99 100644
--- a/FastGithub/HostedService.cs
+++ b/FastGithub/HostedService.cs
@@ -29,7 +29,7 @@ namespace FastGithub
///
public Task StartAsync(CancellationToken cancellationToken)
{
- this.logger.LogInformation($"{nameof(FastGithub)}启动完成,访问https://127.0.0.1或本机其它任意ip可进入Dashboard");
+ this.logger.LogInformation($"{nameof(FastGithub)}启动完成,访问http://127.0.0.1或本机其它任意ip可进入Dashboard");
return Task.CompletedTask;
}
diff --git a/FastGithub/Program.cs b/FastGithub/Program.cs
index d297bdf..6a455f6 100644
--- a/FastGithub/Program.cs
+++ b/FastGithub/Program.cs
@@ -41,7 +41,11 @@ namespace FastGithub
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
- webBuilder.UseKestrel(kestrel => kestrel.ListenHttpsReverseProxy());
+ webBuilder.UseKestrel(kestrel =>
+ {
+ kestrel.ListenHttpReverseProxy();
+ kestrel.ListenHttpsReverseProxy();
+ });
});
}
}
diff --git a/FastGithub/Startup.cs b/FastGithub/Startup.cs
index f927251..fc80690 100644
--- a/FastGithub/Startup.cs
+++ b/FastGithub/Startup.cs
@@ -43,7 +43,7 @@ namespace FastGithub
public void Configure(IApplicationBuilder app)
{
app.UseRequestLogging();
- app.UseHttpsReverseProxy();
+ app.UseReverseProxy();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
diff --git a/README.md b/README.md
index 7206a53..3ec3d25 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ github加速神器
如果不能下载[releases](https://github.com/xljiulang/FastGithub/releases)里发布的程序,可以到Q群`307306673`里面的群文件下载。
### 使用说明
-运行FastGithub,然后浏览器访问 https://127.0.0.1 或其它ip进入Dashboard
+运行FastGithub,然后浏览器访问 http://127.0.0.1 或其它ip进入Dashboard
### 安全性说明
FastGithub生成自签名CA证书,要求安装到本机设备。FastGithub为每台不同设备生成的CA不同的证书,保存在CACert文件夹下,请不要将证书私钥泄露给他人,以免造成损失。