From c96dab0df8ae20de9658b9791241e5e02ce680de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com>
Date: Fri, 16 Jul 2021 13:44:55 +0800
Subject: [PATCH] =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=87=8D=E9=87=8D=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FastGithub.Core/DnsIPEndPoint.cs | 28 ++++++++--
FastGithub.Core/FastGithubOptions.cs | 52 ++++++++++++++++---
FastGithub.Dns/DnsServerHostedService.cs | 21 ++++----
...> DnsServerServiceCollectionExtensions.cs} | 4 +-
...oteRequest.cs => RemoteEndPointRequest.cs} | 8 +--
...astGihubResolver.cs => RequestResolver.cs} | 28 +++++-----
.../{NameServiceUtil.cs => SystemDnsUtil.cs} | 4 +-
...ntHanlder.cs => NoSniHttpClientHanlder.cs} | 18 +++----
...everseProxyApplicationBuilderExtensions.cs | 2 +-
...ReverseProxyServiceCollectionExtensions.cs | 4 +-
.../{GithubResolver.cs => TrustedResolver.cs} | 20 +++----
FastGithub/appsettings.json | 1 +
FastGithub/publish.cmd | 4 +-
13 files changed, 125 insertions(+), 69 deletions(-)
rename FastGithub.Dns/{DnsServiceCollectionExtensions.cs => DnsServerServiceCollectionExtensions.cs} (82%)
rename FastGithub.Dns/{RemoteRequest.cs => RemoteEndPointRequest.cs} (84%)
rename FastGithub.Dns/{FastGihubResolver.cs => RequestResolver.cs} (69%)
rename FastGithub.Dns/{NameServiceUtil.cs => SystemDnsUtil.cs} (97%)
rename FastGithub.ReverseProxy/{GithubHttpClientHanlder.cs => NoSniHttpClientHanlder.cs} (82%)
rename FastGithub.ReverseProxy/{GithubResolver.cs => TrustedResolver.cs} (77%)
diff --git a/FastGithub.Core/DnsIPEndPoint.cs b/FastGithub.Core/DnsIPEndPoint.cs
index 640d2e8..8c6c6df 100644
--- a/FastGithub.Core/DnsIPEndPoint.cs
+++ b/FastGithub.Core/DnsIPEndPoint.cs
@@ -3,22 +3,40 @@ using System.Net;
namespace FastGithub
{
+ ///
+ /// dns的终节点
+ ///
public class DnsIPEndPoint
{
+ ///
+ /// IP地址
+ ///
[AllowNull]
- public string Address { get; set; } = IPAddress.Loopback.ToString();
+ public string IPAddress { get; set; }
- public int Port { get; set; } = 53;
+ ///
+ /// 端口
+ ///
+ public int Port { get; set; }
+ ///
+ /// 转换为IPEndPoint
+ ///
+ ///
public IPEndPoint ToIPEndPoint()
{
- return new IPEndPoint(IPAddress.Parse(this.Address), this.Port);
+ return new IPEndPoint(System.Net.IPAddress.Parse(this.IPAddress), this.Port);
}
+ ///
+ /// 验证
+ ///
+ ///
public bool Validate()
{
- return IPAddress.TryParse(this.Address, out var address) &&
- !(address.Equals(IPAddress.Loopback) && this.Port == 53);
+ return System.Net.IPAddress.TryParse(this.IPAddress, out var address)
+ ? !(address.Equals(System.Net.IPAddress.Loopback) && this.Port == 53)
+ : false;
}
}
}
diff --git a/FastGithub.Core/FastGithubOptions.cs b/FastGithub.Core/FastGithubOptions.cs
index 148f04d..a57918a 100644
--- a/FastGithub.Core/FastGithubOptions.cs
+++ b/FastGithub.Core/FastGithubOptions.cs
@@ -4,16 +4,36 @@ using System.Text.RegularExpressions;
namespace FastGithub
{
+ ///
+ /// FastGithub的配置
+ ///
public class FastGithubOptions
{
+ ///
+ /// 域名
+ ///
private DomainMatch[]? domainMatches;
- public DnsIPEndPoint TrustedDns { get; set; } = new DnsIPEndPoint { Address = "127.0.0.1", Port = 5533 };
+ ///
+ /// 受信任的dns服务
+ ///
+ public DnsIPEndPoint TrustedDns { get; set; } = new DnsIPEndPoint { IPAddress = "127.0.0.1", Port = 5533 };
- public DnsIPEndPoint UntrustedDns { get; set; } = new DnsIPEndPoint { Address = "114.1114.114.114", Port = 53 };
+ ///
+ /// 不受信任的dns服务
+ ///
+ public DnsIPEndPoint UntrustedDns { get; set; } = new DnsIPEndPoint { IPAddress = "114.114.114.114", Port = 53 };
+ ///
+ /// 代理的域名匹配
+ ///
public HashSet DomainMatches { get; set; } = new();
+ ///
+ /// 是否匹配指定的域名
+ ///
+ ///
+ ///
public bool IsMatch(string domain)
{
if (this.domainMatches == null)
@@ -23,26 +43,42 @@ namespace FastGithub
return this.domainMatches.Any(item => item.IsMatch(domain));
}
+ ///
+ /// 域名匹配
+ ///
private class DomainMatch
{
private readonly Regex regex;
- private readonly string value;
+ private readonly string pattern;
- public DomainMatch(string value)
+ ///
+ /// 域名匹配
+ ///
+ /// 域名表达式
+ public DomainMatch(string pattern)
{
- this.value = value;
- var pattern = Regex.Escape(value).Replace(@"\*", ".*");
- this.regex = new Regex($"^{pattern}$");
+ this.pattern = pattern;
+ var regexPattern = Regex.Escape(pattern).Replace(@"\*", ".*");
+ this.regex = new Regex($"^{regexPattern}$", RegexOptions.IgnoreCase);
}
+ ///
+ /// 是否与指定域名匹配
+ ///
+ ///
+ ///
public bool IsMatch(string domain)
{
return this.regex.IsMatch(domain);
}
+ ///
+ /// 转换为文本
+ ///
+ ///
public override string ToString()
{
- return this.value;
+ return this.pattern;
}
}
}
diff --git a/FastGithub.Dns/DnsServerHostedService.cs b/FastGithub.Dns/DnsServerHostedService.cs
index 45cf53d..812f3af 100644
--- a/FastGithub.Dns/DnsServerHostedService.cs
+++ b/FastGithub.Dns/DnsServerHostedService.cs
@@ -15,9 +15,7 @@ namespace FastGithub.Dns
///
sealed class DnsServerHostedService : BackgroundService
{
- private const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C);
-
- private readonly FastGihubResolver fastGihubResolver;
+ private readonly RequestResolver requestResolver;
private readonly IOptions options;
private readonly ILogger logger;
@@ -28,15 +26,15 @@ namespace FastGithub.Dns
///
/// dns后台服务
///
- ///
+ ///
///
///
public DnsServerHostedService(
- FastGihubResolver fastGihubResolver,
+ RequestResolver requestResolver,
IOptions options,
ILogger logger)
{
- this.fastGihubResolver = fastGihubResolver;
+ this.requestResolver = requestResolver;
this.options = options;
this.logger = logger;
}
@@ -51,12 +49,13 @@ namespace FastGithub.Dns
this.socket.Bind(new IPEndPoint(IPAddress.Any, 53));
if (OperatingSystem.IsWindows())
{
+ const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C);
this.socket.IOControl(SIO_UDP_CONNRESET, new byte[4], new byte[4]);
}
this.logger.LogInformation("dns服务启动成功");
- var upStream = IPAddress.Parse(options.Value.UntrustedDns.Address);
- this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, upStream);
+ var secondary = IPAddress.Parse(options.Value.UntrustedDns.IPAddress);
+ this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, secondary);
return base.StartAsync(cancellationToken);
}
@@ -88,8 +87,8 @@ namespace FastGithub.Dns
try
{
var request = Request.FromArray(datas);
- var remoteRequest = new RemoteRequest(request, remoteEndPoint);
- var response = await this.fastGihubResolver.Resolve(remoteRequest, cancellationToken);
+ var remoteEndPointRequest = new RemoteEndPointRequest(request, remoteEndPoint);
+ var response = await this.requestResolver.Resolve(remoteEndPointRequest, cancellationToken);
await this.socket.SendToAsync(response.ToArray(), SocketFlags.None, remoteEndPoint);
}
catch (Exception ex)
@@ -126,7 +125,7 @@ namespace FastGithub.Dns
{
try
{
- var results = NameServiceUtil.SetNameServers(nameServers);
+ var results = SystemDnsUtil.SetNameServers(nameServers);
this.logger.LogInformation($"设置本机dns成功");
return results;
}
diff --git a/FastGithub.Dns/DnsServiceCollectionExtensions.cs b/FastGithub.Dns/DnsServerServiceCollectionExtensions.cs
similarity index 82%
rename from FastGithub.Dns/DnsServiceCollectionExtensions.cs
rename to FastGithub.Dns/DnsServerServiceCollectionExtensions.cs
index 2ad2699..1321ee1 100644
--- a/FastGithub.Dns/DnsServiceCollectionExtensions.cs
+++ b/FastGithub.Dns/DnsServerServiceCollectionExtensions.cs
@@ -6,7 +6,7 @@ namespace FastGithub
///
/// 服务注册扩展
///
- public static class DnsServiceCollectionExtensions
+ public static class DnsServerServiceCollectionExtensions
{
///
/// 注册github的dns服务
@@ -16,7 +16,7 @@ namespace FastGithub
public static IServiceCollection AddGithubDns(this IServiceCollection services)
{
return services
- .AddSingleton()
+ .AddSingleton()
.AddHostedService();
}
}
diff --git a/FastGithub.Dns/RemoteRequest.cs b/FastGithub.Dns/RemoteEndPointRequest.cs
similarity index 84%
rename from FastGithub.Dns/RemoteRequest.cs
rename to FastGithub.Dns/RemoteEndPointRequest.cs
index 7a8e745..4ec6116 100644
--- a/FastGithub.Dns/RemoteRequest.cs
+++ b/FastGithub.Dns/RemoteEndPointRequest.cs
@@ -6,12 +6,12 @@ using System.Net.Sockets;
namespace FastGithub.Dns
{
///
- /// 远程请求
+ /// 带远程终节点的请求
///
- sealed class RemoteRequest : Request
+ sealed class RemoteEndPointRequest : Request
{
///
- /// 获取远程地址
+ /// 获取程终节点
///
public EndPoint RemoteEndPoint { get; }
@@ -20,7 +20,7 @@ namespace FastGithub.Dns
///
///
///
- public RemoteRequest(Request request, EndPoint remoteEndPoint)
+ public RemoteEndPointRequest(Request request, EndPoint remoteEndPoint)
: base(request)
{
this.RemoteEndPoint = remoteEndPoint;
diff --git a/FastGithub.Dns/FastGihubResolver.cs b/FastGithub.Dns/RequestResolver.cs
similarity index 69%
rename from FastGithub.Dns/FastGihubResolver.cs
rename to FastGithub.Dns/RequestResolver.cs
index 0520069..a94261b 100644
--- a/FastGithub.Dns/FastGihubResolver.cs
+++ b/FastGithub.Dns/RequestResolver.cs
@@ -12,26 +12,27 @@ using System.Threading.Tasks;
namespace FastGithub.Dns
{
///
- /// 反向代理解析器
+ /// dns解析者
///
- sealed class FastGihubResolver : IRequestResolver
+ sealed class RequestResolver : IRequestResolver
{
- private readonly IRequestResolver untrustedDnsResolver;
+ private readonly TimeSpan ttl = TimeSpan.FromMinutes(1d);
+ private readonly IRequestResolver untrustedResolver;
private readonly IOptionsMonitor options;
- private readonly ILogger logger;
+ private readonly ILogger logger;
///
- /// github相关域名解析器
+ /// dns解析者
///
///
///
- public FastGihubResolver(
+ public RequestResolver(
IOptionsMonitor options,
- ILogger logger)
+ ILogger logger)
{
this.options = options;
this.logger = logger;
- this.untrustedDnsResolver = new UdpRequestResolver(options.CurrentValue.UntrustedDns.ToIPEndPoint());
+ this.untrustedResolver = new UdpRequestResolver(options.CurrentValue.UntrustedDns.ToIPEndPoint());
}
///
@@ -43,7 +44,7 @@ namespace FastGithub.Dns
public async Task Resolve(IRequest request, CancellationToken cancellationToken = default)
{
var response = Response.FromRequest(request);
- if (request is not RemoteRequest remoteRequest)
+ if (request is not RemoteEndPointRequest remoteEndPointRequest)
{
return response;
}
@@ -57,14 +58,15 @@ namespace FastGithub.Dns
var domain = question.Name;
if (this.options.CurrentValue.IsMatch(domain.ToString()) == true)
{
- var localAddress = remoteRequest.GetLocalAddress() ?? IPAddress.Loopback;
- var record = new IPAddressResourceRecord(domain, localAddress, TimeSpan.FromMinutes(1d));
- this.logger.LogInformation($"[{domain}->{localAddress}]");
+ var localAddress = remoteEndPointRequest.GetLocalAddress() ?? IPAddress.Loopback;
+ var record = new IPAddressResourceRecord(domain, localAddress, this.ttl);
response.AnswerRecords.Add(record);
+
+ this.logger.LogInformation($"[{domain}->{localAddress}]");
return response;
}
- return await this.untrustedDnsResolver.Resolve(request, cancellationToken);
+ return await this.untrustedResolver.Resolve(request, cancellationToken);
}
}
}
diff --git a/FastGithub.Dns/NameServiceUtil.cs b/FastGithub.Dns/SystemDnsUtil.cs
similarity index 97%
rename from FastGithub.Dns/NameServiceUtil.cs
rename to FastGithub.Dns/SystemDnsUtil.cs
index 80a524e..1b2dce3 100644
--- a/FastGithub.Dns/NameServiceUtil.cs
+++ b/FastGithub.Dns/SystemDnsUtil.cs
@@ -9,10 +9,10 @@ using System.Runtime.Versioning;
namespace FastGithub.Dns
{
///
- /// 域名服务工具
+ /// 系统域名服务工具
///
[SupportedOSPlatform("windows")]
- static class NameServiceUtil
+ static class SystemDnsUtil
{
///
/// www.baidu.com的ip
diff --git a/FastGithub.ReverseProxy/GithubHttpClientHanlder.cs b/FastGithub.ReverseProxy/NoSniHttpClientHanlder.cs
similarity index 82%
rename from FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
rename to FastGithub.ReverseProxy/NoSniHttpClientHanlder.cs
index 2894191..fc23c62 100644
--- a/FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
+++ b/FastGithub.ReverseProxy/NoSniHttpClientHanlder.cs
@@ -8,19 +8,19 @@ using System.Threading.Tasks;
namespace FastGithub.ReverseProxy
{
///
- /// 适用于请求github的HttpClientHandler
+ /// 不发送NoSni的HttpClientHandler
///
- class GithubHttpClientHanlder : DelegatingHandler
+ class NoSniHttpClientHanlder : DelegatingHandler
{
- private readonly GithubResolver githubResolver;
+ private readonly TrustedResolver trustedDomainResolver;
///
- /// 请求github的HttpClientHandler
+ /// 不发送NoSni的HttpClientHandler
///
- ///
- public GithubHttpClientHanlder(GithubResolver githubResolver)
+ ///
+ public NoSniHttpClientHanlder(TrustedResolver trustedDomainResolver)
{
- this.githubResolver = githubResolver;
+ this.trustedDomainResolver = trustedDomainResolver;
this.InnerHandler = CreateNoneSniHttpHandler();
}
@@ -58,7 +58,7 @@ namespace FastGithub.ReverseProxy
///
- /// 替换github域名为ip
+ /// 替换域名为ip
///
///
///
@@ -68,7 +68,7 @@ namespace FastGithub.ReverseProxy
var uri = request.RequestUri;
if (uri != null && uri.HostNameType == UriHostNameType.Dns)
{
- var address = await this.githubResolver.ResolveAsync(uri.Host, cancellationToken);
+ var address = await this.trustedDomainResolver.ResolveAsync(uri.Host, cancellationToken);
var builder = new UriBuilder(uri)
{
Scheme = Uri.UriSchemeHttp,
diff --git a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
index 5b565e8..9fcc6c8 100644
--- a/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
+++ b/FastGithub.ReverseProxy/ReverseProxyApplicationBuilderExtensions.cs
@@ -21,7 +21,7 @@ namespace FastGithub
public static IApplicationBuilder UseGithubReverseProxy(this IApplicationBuilder app)
{
var httpForwarder = app.ApplicationServices.GetRequiredService();
- var httpClientHanlder = app.ApplicationServices.GetRequiredService();
+ var httpClientHanlder = app.ApplicationServices.GetRequiredService();
var options = app.ApplicationServices.GetRequiredService>();
app.Use(next => async context =>
diff --git a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
index e1e5a05..8b45ce0 100644
--- a/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
+++ b/FastGithub.ReverseProxy/ReverseProxyServiceCollectionExtensions.cs
@@ -18,8 +18,8 @@ namespace FastGithub
return services
.AddMemoryCache()
.AddHttpForwarder()
- .AddSingleton()
- .AddTransient();
+ .AddSingleton()
+ .AddTransient();
}
}
}
diff --git a/FastGithub.ReverseProxy/GithubResolver.cs b/FastGithub.ReverseProxy/TrustedResolver.cs
similarity index 77%
rename from FastGithub.ReverseProxy/GithubResolver.cs
rename to FastGithub.ReverseProxy/TrustedResolver.cs
index e08474b..2f8d721 100644
--- a/FastGithub.ReverseProxy/GithubResolver.cs
+++ b/FastGithub.ReverseProxy/TrustedResolver.cs
@@ -12,22 +12,23 @@ using System.Threading.Tasks;
namespace FastGithub.ReverseProxy
{
///
- /// github解析器
+ /// 受信任的域名解析器
///
- sealed class GithubResolver
+ sealed class TrustedResolver
{
private readonly IMemoryCache memoryCache;
+ private readonly TimeSpan cacheTimeSpan = TimeSpan.FromSeconds(10d);
private readonly IOptionsMonitor options;
- private readonly ILogger logger;
+ private readonly ILogger logger;
///
- /// github解析器
+ /// 受信任的域名解析器
///
///
- public GithubResolver(
+ public TrustedResolver(
IMemoryCache memoryCache,
IOptionsMonitor options,
- ILogger logger)
+ ILogger logger)
{
this.memoryCache = memoryCache;
this.options = options;
@@ -41,11 +42,11 @@ namespace FastGithub.ReverseProxy
///
public async Task ResolveAsync(string domain, CancellationToken cancellationToken)
{
- // 缓存,避免做不必要的并发查询
+ // 缓存以避免做不必要的并发查询
var key = $"domain:{domain}";
var address = await this.memoryCache.GetOrCreateAsync(key, async e =>
{
- e.SetAbsoluteExpiration(TimeSpan.FromMinutes(2d));
+ e.SetAbsoluteExpiration(this.cacheTimeSpan);
var dnsClient = new DnsClient(this.options.CurrentValue.TrustedDns.ToIPEndPoint());
var addresses = await dnsClient.Lookup(domain, DNS.Protocol.RecordType.A, cancellationToken);
return addresses?.FirstOrDefault();
@@ -57,7 +58,8 @@ namespace FastGithub.ReverseProxy
this.logger.LogWarning(message);
throw new HttpRequestException(message);
}
- this.logger.LogInformation($"[{domain}->{address}]");
+
+ this.logger.LogInformation($"[{address}->{domain}]");
return address;
}
}
diff --git a/FastGithub/appsettings.json b/FastGithub/appsettings.json
index 8adf40c..9746d27 100644
--- a/FastGithub/appsettings.json
+++ b/FastGithub/appsettings.json
@@ -11,6 +11,7 @@
"DomainMatches": [
"github.com",
"*.github.com",
+ "*.github.io",
"*.githubapp.com",
"*.githubassets.com",
"*.githubusercontent.com"
diff --git a/FastGithub/publish.cmd b/FastGithub/publish.cmd
index d294743..976424b 100644
--- a/FastGithub/publish.cmd
+++ b/FastGithub/publish.cmd
@@ -1,4 +1,2 @@
dotnet publish -c Release -f net6.0 /p:PublishSingleFile=true /p:PublishTrimmed=true -r linux-x64 -o ./bin/publish/linux-x64
-dotnet publish -c Release -f net6.0 /p:PublishSingleFile=true /p:PublishTrimmed=true -r win-x86 -o ./bin/publish/win-x86
-dotnet publish -c Release -f net6.0 /p:PublishSingleFile=true /p:PublishTrimmed=true -r win-x64 -o ./bin/publish/win-x64
-dotnet publish -c Release -f net6.0 /p:PublishSingleFile=true /p:PublishTrimmed=true -r osx-x64 -o ./bin/publish/osx-x64
+dotnet publish -c Release -f net6.0 /p:PublishSingleFile=true /p:PublishTrimmed=true -r win-x64 -o ./bin/publish/win-x64
\ No newline at end of file