使用信任dns
This commit is contained in:
parent
846b539e7e
commit
0369fe2750
8
FastGithub.Configuration/Class1.cs
Normal file
8
FastGithub.Configuration/Class1.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub.Configuration
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
}
|
||||
7
FastGithub.Configuration/FastGithub.Configuration.csproj
Normal file
7
FastGithub.Configuration/FastGithub.Configuration.csproj
Normal file
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
24
FastGithub.Core/DnsIPEndPoint.cs
Normal file
24
FastGithub.Core/DnsIPEndPoint.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
public class DnsIPEndPoint
|
||||
{
|
||||
[AllowNull]
|
||||
public string Address { get; set; } = IPAddress.Loopback.ToString();
|
||||
|
||||
public int Port { get; set; } = 53;
|
||||
|
||||
public IPEndPoint ToIPEndPoint()
|
||||
{
|
||||
return new IPEndPoint(IPAddress.Parse(this.Address), this.Port);
|
||||
}
|
||||
|
||||
public bool Validate()
|
||||
{
|
||||
return IPAddress.TryParse(this.Address, out var address) &&
|
||||
!(address.Equals(IPAddress.Loopback) && this.Port == 53);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,6 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RootNamespace>FastGithub</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
49
FastGithub.Core/FastGithubOptions.cs
Normal file
49
FastGithub.Core/FastGithubOptions.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
public class FastGithubOptions
|
||||
{
|
||||
private DomainMatch[]? domainMatches;
|
||||
|
||||
public DnsIPEndPoint TrustedDns { get; set; } = new DnsIPEndPoint { Address = "127.0.0.1", Port = 5533 };
|
||||
|
||||
public DnsIPEndPoint UntrustedDns { get; set; } = new DnsIPEndPoint { Address = "114.1114.114.114", Port = 53 };
|
||||
|
||||
public HashSet<string> DomainMatches { get; set; } = new();
|
||||
|
||||
public bool IsMatch(string domain)
|
||||
{
|
||||
if (this.domainMatches == null)
|
||||
{
|
||||
this.domainMatches = this.DomainMatches.Select(item => new DomainMatch(item)).ToArray();
|
||||
}
|
||||
return this.domainMatches.Any(item => item.IsMatch(domain));
|
||||
}
|
||||
|
||||
private class DomainMatch
|
||||
{
|
||||
private readonly Regex regex;
|
||||
private readonly string value;
|
||||
|
||||
public DomainMatch(string value)
|
||||
{
|
||||
this.value = value;
|
||||
var pattern = Regex.Escape(value).Replace(@"\*", ".*");
|
||||
this.regex = new Regex($"^{pattern}$");
|
||||
}
|
||||
|
||||
public bool IsMatch(string domain)
|
||||
{
|
||||
return this.regex.IsMatch(domain);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件的接口
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
public interface IMiddleware<TContext>
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行中间件
|
||||
/// </summary>
|
||||
/// <param name="context">上下文</param>
|
||||
/// <param name="next">下一个中间件</param>
|
||||
/// <returns></returns>
|
||||
Task InvokeAsync(TContext context, Func<Task> next);
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义中间件管道创建者的接口
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext">中间件上下文</typeparam>
|
||||
public interface IPipelineBuilder<TContext>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <typeparam name="TMiddleware"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use<TMiddleware>() where TMiddleware : class, IMiddleware<TContext>;
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use(Func<TContext, Func<Task>, Task> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware">中间件</param>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> Use(Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
InvokeDelegate<TContext> Build();
|
||||
|
||||
/// <summary>
|
||||
/// 使用默认配制创建新的PipelineBuilder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IPipelineBuilder<TContext> New();
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示所有中间件执行委托
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext">中间件上下文类型</typeparam>
|
||||
/// <param name="context">中间件上下文</param>
|
||||
/// <returns></returns>
|
||||
public delegate Task InvokeDelegate<TContext>(TContext context);
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示选项特性
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class OptionsAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取配置节点名称
|
||||
/// </summary>
|
||||
public string? SessionKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 选项特性
|
||||
/// </summary>
|
||||
public OptionsAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选项特性
|
||||
/// </summary>
|
||||
/// <param name="sessionKey">配置节点名称</param>
|
||||
public OptionsAttribute(string sessionKey)
|
||||
{
|
||||
this.SessionKey = sessionKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,103 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示中间件创建者
|
||||
/// </summary>
|
||||
public class PipelineBuilder<TContext> : IPipelineBuilder<TContext>
|
||||
{
|
||||
private readonly InvokeDelegate<TContext> completedHandler;
|
||||
private readonly List<Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>>> middlewares = new();
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务提供者
|
||||
/// </summary>
|
||||
public IServiceProvider AppServices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
public PipelineBuilder(IServiceProvider appServices)
|
||||
: this(appServices, context => Task.CompletedTask)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中间件创建者
|
||||
/// </summary>
|
||||
/// <param name="appServices"></param>
|
||||
/// <param name="completedHandler">完成执行内容处理者</param>
|
||||
public PipelineBuilder(IServiceProvider appServices, InvokeDelegate<TContext> completedHandler)
|
||||
{
|
||||
this.AppServices = appServices;
|
||||
this.completedHandler = completedHandler;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <typeparam name="TMiddleware"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use<TMiddleware>() where TMiddleware : class, IMiddleware<TContext>
|
||||
{
|
||||
var middleware = this.AppServices.GetRequiredService<TMiddleware>();
|
||||
return this.Use(middleware.InvokeAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use(Func<TContext, Func<Task>, Task> middleware)
|
||||
{
|
||||
return this.Use(next => context => middleware(context, () => next(context)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用中间件
|
||||
/// </summary>
|
||||
/// <param name="middleware"></param>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> Use(Func<InvokeDelegate<TContext>, InvokeDelegate<TContext>> middleware)
|
||||
{
|
||||
this.middlewares.Add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有中间件执行处理者
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public InvokeDelegate<TContext> Build()
|
||||
{
|
||||
var handler = this.completedHandler;
|
||||
for (var i = this.middlewares.Count - 1; i >= 0; i--)
|
||||
{
|
||||
handler = this.middlewares[i](handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 使用默认配制创建新的PipelineBuilder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IPipelineBuilder<TContext> New()
|
||||
{
|
||||
return new PipelineBuilder<TContext>(this.AppServices, this.completedHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 中间件创建者扩展
|
||||
/// </summary>
|
||||
public static class PipelineBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 中断执行中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="handler">处理者</param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> Run<TContext>(this IPipelineBuilder<TContext> builder, InvokeDelegate<TContext> handler)
|
||||
{
|
||||
return builder.Use(_ => handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 条件中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="handler"></param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> When<TContext>(this IPipelineBuilder<TContext> builder, Func<TContext, bool> predicate, InvokeDelegate<TContext> handler)
|
||||
{
|
||||
return builder.Use(next => async context =>
|
||||
{
|
||||
if (predicate.Invoke(context) == true)
|
||||
{
|
||||
await handler.Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 条件中间件
|
||||
/// </summary>
|
||||
/// <typeparam name="TContext"></typeparam>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="configureAction"></param>
|
||||
/// <returns></returns>
|
||||
public static IPipelineBuilder<TContext> When<TContext>(this IPipelineBuilder<TContext> builder, Func<TContext, bool> predicate, Action<IPipelineBuilder<TContext>> configureAction)
|
||||
{
|
||||
return builder.Use(next => async context =>
|
||||
{
|
||||
if (predicate.Invoke(context) == true)
|
||||
{
|
||||
var branchBuilder = builder.New();
|
||||
configureAction(branchBuilder);
|
||||
await branchBuilder.Build().Invoke(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示服务特性
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||
public sealed class ServiceAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取服务的生命周期
|
||||
/// </summary>
|
||||
public ServiceLifetime Lifetime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置注册的服务类型
|
||||
/// 为null直接使得当前类型
|
||||
/// </summary>
|
||||
public Type? ServiceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 将当前实现类型注册为服务的特性
|
||||
/// </summary>
|
||||
/// <param name="lifetime">生命周期</param>
|
||||
public ServiceAttribute(ServiceLifetime lifetime)
|
||||
{
|
||||
Lifetime = lifetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,118 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FastGithub
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务注册扩展
|
||||
/// </summary>
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 注册程序集下所有服务下选项
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration">配置</param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddServiceAndOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
|
||||
{
|
||||
services.AddAttributeServices(assembly);
|
||||
services.AddAttributeOptions(assembly, configuration);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加程序集下ServiceAttribute标记的服务
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
private static IServiceCollection AddAttributeServices(this IServiceCollection services, Assembly assembly)
|
||||
{
|
||||
var implTypes = assembly
|
||||
.GetTypes()
|
||||
.Where(item => item.IsClass && item.IsAbstract == false)
|
||||
.ToArray();
|
||||
|
||||
foreach (var implType in implTypes)
|
||||
{
|
||||
var attributes = implType.GetCustomAttributes<ServiceAttribute>(false);
|
||||
foreach (var attr in attributes)
|
||||
{
|
||||
var serviceType = attr.ServiceType ?? implType;
|
||||
if (services.Any(item => item.ServiceType == serviceType && item.ImplementationType == implType) == false)
|
||||
{
|
||||
var descriptor = ServiceDescriptor.Describe(serviceType, implType, attr.Lifetime);
|
||||
services.Add(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加程序集下OptionsAttribute标记的服务
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="assembly"></param>
|
||||
/// <param name="configuration"></param>
|
||||
private static IServiceCollection AddAttributeOptions(this IServiceCollection services, Assembly assembly, IConfiguration configuration)
|
||||
{
|
||||
foreach (var optionsType in assembly.GetTypes())
|
||||
{
|
||||
var optionsAttribute = optionsType.GetCustomAttribute<OptionsAttribute>();
|
||||
if (optionsAttribute != null)
|
||||
{
|
||||
var key = optionsAttribute.SessionKey ?? optionsType.Name;
|
||||
var section = configuration.GetSection(key);
|
||||
OptionsBinder.Create(services, optionsType).Bind(section);
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// options绑定器
|
||||
/// </summary>
|
||||
private abstract class OptionsBinder
|
||||
{
|
||||
public abstract void Bind(IConfiguration configuration);
|
||||
|
||||
/// <summary>
|
||||
/// 创建OptionsBinder实例
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="optionsType"></param>
|
||||
/// <returns></returns>
|
||||
public static OptionsBinder Create(IServiceCollection services, Type optionsType)
|
||||
{
|
||||
var binderType = typeof(OptionsBinderImpl<>).MakeGenericType(optionsType);
|
||||
var binder = Activator.CreateInstance(binderType, new object[] { services });
|
||||
|
||||
return binder is OptionsBinder optionsBinder
|
||||
? optionsBinder
|
||||
: throw new TypeInitializationException(binderType.FullName, null);
|
||||
}
|
||||
|
||||
private class OptionsBinderImpl<TOptions> : OptionsBinder where TOptions : class
|
||||
{
|
||||
private readonly IServiceCollection services;
|
||||
|
||||
public OptionsBinderImpl(IServiceCollection services)
|
||||
{
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
public override void Bind(IConfiguration configuration)
|
||||
{
|
||||
this.services.AddOptions<TOptions>().Bind(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
FastGithub.Dns.Configuration/Class1.cs
Normal file
8
FastGithub.Dns.Configuration/Class1.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub.Dns.Configuration
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace FastGithub.Dns
|
||||
{
|
||||
/// <summary>
|
||||
/// dns服务选项
|
||||
/// </summary>
|
||||
[Options("Dns")]
|
||||
sealed class DnsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置上游ip地址
|
||||
/// </summary>
|
||||
public string UpStream { get; set; } = "114.114.114.114";
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置github相关域名的ip存活时长
|
||||
/// </summary>
|
||||
public TimeSpan GithubTTL { get; set; } = TimeSpan.FromMinutes(10d);
|
||||
|
||||
/// <summary>
|
||||
/// 是否设置本机使用此dns
|
||||
/// </summary>
|
||||
public bool SetToLocalMachine { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用反向代理访问github
|
||||
/// </summary>
|
||||
public bool UseGithubReverseProxy { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
using DNS.Client.RequestResolver;
|
||||
using DNS.Protocol;
|
||||
using DNS.Protocol;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -18,15 +17,14 @@ namespace FastGithub.Dns
|
||||
{
|
||||
private const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C);
|
||||
|
||||
private readonly IRequestResolver requestResolver;
|
||||
private readonly IOptions<DnsOptions> options;
|
||||
private readonly FastGihubResolver fastGihubResolver;
|
||||
private readonly IOptions<FastGithubOptions> options;
|
||||
private readonly ILogger<DnsServerHostedService> logger;
|
||||
|
||||
private readonly Socket socket = new(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
private readonly byte[] buffer = new byte[ushort.MaxValue];
|
||||
private IPAddress[]? dnsAddresses;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// dns后台服务
|
||||
/// </summary>
|
||||
@ -34,15 +32,13 @@ namespace FastGithub.Dns
|
||||
/// <param name="options"></param>
|
||||
/// <param name="logger"></param>
|
||||
public DnsServerHostedService(
|
||||
GithubRequestResolver githubRequestResolver,
|
||||
IOptions<DnsOptions> options,
|
||||
FastGihubResolver fastGihubResolver,
|
||||
IOptions<FastGithubOptions> options,
|
||||
ILogger<DnsServerHostedService> logger)
|
||||
{
|
||||
this.fastGihubResolver = fastGihubResolver;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
|
||||
var upStream = IPAddress.Parse(options.Value.UpStream);
|
||||
this.requestResolver = new CompositeRequestResolver(upStream, githubRequestResolver);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -59,7 +55,7 @@ namespace FastGithub.Dns
|
||||
}
|
||||
|
||||
this.logger.LogInformation("dns服务启动成功");
|
||||
var upStream = IPAddress.Parse(options.Value.UpStream);
|
||||
var upStream = IPAddress.Parse(options.Value.UntrustedDns.Address);
|
||||
this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, upStream);
|
||||
return base.StartAsync(cancellationToken);
|
||||
}
|
||||
@ -93,7 +89,7 @@ namespace FastGithub.Dns
|
||||
{
|
||||
var request = Request.FromArray(datas);
|
||||
var remoteRequest = new RemoteRequest(request, remoteEndPoint);
|
||||
var response = await this.requestResolver.Resolve(remoteRequest, cancellationToken);
|
||||
var response = await this.fastGihubResolver.Resolve(remoteRequest, cancellationToken);
|
||||
await this.socket.SendToAsync(response.ToArray(), SocketFlags.None, remoteEndPoint);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -126,7 +122,7 @@ namespace FastGithub.Dns
|
||||
/// <returns></returns>
|
||||
private IPAddress[]? SetNameServers(params IPAddress[] nameServers)
|
||||
{
|
||||
if (this.options.Value.SetToLocalMachine && OperatingSystem.IsWindows())
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -140,34 +136,12 @@ namespace FastGithub.Dns
|
||||
this.logger.LogWarning($"设置本机dns失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.logger.LogError("不支持自动为本机设备设置dns值");
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private class CompositeRequestResolver : IRequestResolver
|
||||
{
|
||||
private readonly IRequestResolver upStreamResolver;
|
||||
private readonly IRequestResolver[] customResolvers;
|
||||
|
||||
public CompositeRequestResolver(IPAddress upStream, params IRequestResolver[] customResolvers)
|
||||
{
|
||||
this.upStreamResolver = new UdpRequestResolver(new IPEndPoint(upStream, 53));
|
||||
this.customResolvers = customResolvers;
|
||||
}
|
||||
|
||||
public async Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
foreach (IRequestResolver resolver in customResolvers)
|
||||
{
|
||||
var response = await resolver.Resolve(request, cancellationToken);
|
||||
if (response.AnswerRecords.Count > 0)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
return await this.upStreamResolver.Resolve(request, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using FastGithub.Dns;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FastGithub
|
||||
@ -12,14 +11,12 @@ namespace FastGithub
|
||||
/// <summary>
|
||||
/// 注册github的dns服务
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration">配置</param>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddGithubDns(this IServiceCollection services, IConfiguration configuration)
|
||||
public static IServiceCollection AddGithubDns(this IServiceCollection services)
|
||||
{
|
||||
var assembly = typeof(DnsServiceCollectionExtensions).Assembly;
|
||||
return services
|
||||
.AddServiceAndOptions(assembly, configuration)
|
||||
.AddSingleton<FastGihubResolver>()
|
||||
.AddHostedService<DnsServerHostedService>();
|
||||
}
|
||||
}
|
||||
|
||||
70
FastGithub.Dns/FastGihubResolver.cs
Normal file
70
FastGithub.Dns/FastGihubResolver.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using DNS.Client.RequestResolver;
|
||||
using DNS.Protocol;
|
||||
using DNS.Protocol.ResourceRecords;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Dns
|
||||
{
|
||||
/// <summary>
|
||||
/// 反向代理解析器
|
||||
/// </summary>
|
||||
sealed class FastGihubResolver : IRequestResolver
|
||||
{
|
||||
private readonly IRequestResolver untrustedDnsResolver;
|
||||
private readonly IOptionsMonitor<FastGithubOptions> options;
|
||||
private readonly ILogger<FastGihubResolver> logger;
|
||||
|
||||
/// <summary>
|
||||
/// github相关域名解析器
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="logger"></param>
|
||||
public FastGihubResolver(
|
||||
IOptionsMonitor<FastGithubOptions> options,
|
||||
ILogger<FastGihubResolver> logger)
|
||||
{
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
this.untrustedDnsResolver = new UdpRequestResolver(options.CurrentValue.UntrustedDns.ToIPEndPoint());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析域名
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var response = Response.FromRequest(request);
|
||||
if (request is not RemoteRequest remoteRequest)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
var question = request.Questions.FirstOrDefault();
|
||||
if (question == null || question.Type != RecordType.A)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
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}]");
|
||||
response.AnswerRecords.Add(record);
|
||||
return response;
|
||||
}
|
||||
|
||||
return await this.untrustedDnsResolver.Resolve(request, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,5 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj" />
|
||||
<ProjectReference Include="..\FastGithub.Scanner\FastGithub.Scanner.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -1,102 +0,0 @@
|
||||
using DNS.Client.RequestResolver;
|
||||
using DNS.Protocol;
|
||||
using DNS.Protocol.ResourceRecords;
|
||||
using FastGithub.Scanner;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.Dns
|
||||
{
|
||||
/// <summary>
|
||||
/// github相关域名解析器
|
||||
/// </summary>
|
||||
[Service(ServiceLifetime.Singleton)]
|
||||
sealed class GithubRequestResolver : IRequestResolver
|
||||
{
|
||||
private readonly IGithubResolver githubResolver;
|
||||
private readonly IOptionsMonitor<DnsOptions> options;
|
||||
private readonly ILogger<GithubRequestResolver> logger;
|
||||
|
||||
/// <summary>
|
||||
/// github相关域名解析器
|
||||
/// </summary>
|
||||
/// <param name="githubResolver"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="logger"></param>
|
||||
public GithubRequestResolver(
|
||||
IGithubResolver githubResolver,
|
||||
IOptionsMonitor<DnsOptions> options,
|
||||
ILogger<GithubRequestResolver> logger)
|
||||
{
|
||||
this.githubResolver = githubResolver;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析域名
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
IResponse response = Response.FromRequest(request);
|
||||
if (request is not RemoteRequest remoteRequest)
|
||||
{
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
var question = request.Questions.FirstOrDefault();
|
||||
if (question == null || question.Type != RecordType.A)
|
||||
{
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
var domain = question.Name;
|
||||
if (this.githubResolver.IsSupported(domain.ToString()) == false)
|
||||
{
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
var record = this.GetAnswerRecord(remoteRequest, domain);
|
||||
if (record != null)
|
||||
{
|
||||
this.logger.LogInformation($"[{domain}->{record.IPAddress}]");
|
||||
response.AnswerRecords.Add(record);
|
||||
}
|
||||
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取答案
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="domain"></param>
|
||||
/// <returns></returns>
|
||||
private IPAddressResourceRecord? GetAnswerRecord(RemoteRequest request, Domain domain)
|
||||
{
|
||||
if (this.options.CurrentValue.UseGithubReverseProxy == true)
|
||||
{
|
||||
var localAddress = request.GetLocalAddress() ?? IPAddress.Loopback;
|
||||
return new IPAddressResourceRecord(domain, localAddress, TimeSpan.FromMinutes(1d));
|
||||
}
|
||||
|
||||
var githubAddress = this.githubResolver.Resolve(domain.ToString());
|
||||
if (githubAddress == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var ttl = this.options.CurrentValue.GithubTTL;
|
||||
return new IPAddressResourceRecord(domain, githubAddress, ttl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,15 +3,16 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
|
||||
<PackageReference Include="DNS" Version="6.1.0" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="1.0.0-preview.12.21328.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FastGithub.Scanner\FastGithub.Scanner.csproj" />
|
||||
<ProjectReference Include="..\FastGithub.Core\FastGithub.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
84
FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
Normal file
84
FastGithub.ReverseProxy/GithubHttpClientHanlder.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.ReverseProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// 适用于请求github的HttpClientHandler
|
||||
/// </summary>
|
||||
class GithubHttpClientHanlder : DelegatingHandler
|
||||
{
|
||||
private readonly GithubResolver githubResolver;
|
||||
|
||||
/// <summary>
|
||||
/// 请求github的HttpClientHandler
|
||||
/// </summary>
|
||||
/// <param name="githubResolver"></param>
|
||||
public GithubHttpClientHanlder(GithubResolver githubResolver)
|
||||
{
|
||||
this.githubResolver = githubResolver;
|
||||
this.InnerHandler = CreateNoneSniHttpHandler();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建无Sni发送的httpHandler
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static HttpMessageHandler CreateNoneSniHttpHandler()
|
||||
{
|
||||
return new SocketsHttpHandler
|
||||
{
|
||||
Proxy = null,
|
||||
UseProxy = false,
|
||||
AllowAutoRedirect = false,
|
||||
ConnectCallback = async (ctx, ct) =>
|
||||
{
|
||||
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(ctx.DnsEndPoint, ct);
|
||||
var stream = new NetworkStream(socket, ownsSocket: true);
|
||||
if (ctx.InitialRequestMessage.Headers.Host == null)
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
var sslStream = new SslStream(stream, leaveInnerStreamOpen: false);
|
||||
await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions
|
||||
{
|
||||
TargetHost = string.Empty,
|
||||
RemoteCertificateValidationCallback = delegate { return true; }
|
||||
}, ct);
|
||||
return sslStream;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 替换github域名为ip
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
var uri = request.RequestUri;
|
||||
if (uri != null && uri.HostNameType == UriHostNameType.Dns)
|
||||
{
|
||||
var address = await this.githubResolver.ResolveAsync(uri.Host, cancellationToken);
|
||||
var builder = new UriBuilder(uri)
|
||||
{
|
||||
Scheme = Uri.UriSchemeHttp,
|
||||
Host = address.ToString(),
|
||||
Port = 443
|
||||
};
|
||||
request.RequestUri = builder.Uri;
|
||||
request.Headers.Host = uri.Host;
|
||||
}
|
||||
return await base.SendAsync(request, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
FastGithub.ReverseProxy/GithubResolver.cs
Normal file
64
FastGithub.ReverseProxy/GithubResolver.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using DNS.Client;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FastGithub.ReverseProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// github解析器
|
||||
/// </summary>
|
||||
sealed class GithubResolver
|
||||
{
|
||||
private readonly IMemoryCache memoryCache;
|
||||
private readonly IOptionsMonitor<FastGithubOptions> options;
|
||||
private readonly ILogger<GithubResolver> logger;
|
||||
|
||||
/// <summary>
|
||||
/// github解析器
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
public GithubResolver(
|
||||
IMemoryCache memoryCache,
|
||||
IOptionsMonitor<FastGithubOptions> options,
|
||||
ILogger<GithubResolver> logger)
|
||||
{
|
||||
this.memoryCache = memoryCache;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析指定的域名
|
||||
/// </summary>
|
||||
/// <param name="domain"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IPAddress> ResolveAsync(string domain, CancellationToken cancellationToken)
|
||||
{
|
||||
// 缓存,避免做不必要的并发查询
|
||||
var key = $"domain:{domain}";
|
||||
var address = await this.memoryCache.GetOrCreateAsync(key, async e =>
|
||||
{
|
||||
e.SetAbsoluteExpiration(TimeSpan.FromMinutes(2d));
|
||||
var dnsClient = new DnsClient(this.options.CurrentValue.TrustedDns.ToIPEndPoint());
|
||||
var addresses = await dnsClient.Lookup(domain, DNS.Protocol.RecordType.A, cancellationToken);
|
||||
return addresses?.FirstOrDefault();
|
||||
});
|
||||
|
||||
if (address == null)
|
||||
{
|
||||
var message = $"无法解析{domain}的ip";
|
||||
this.logger.LogWarning(message);
|
||||
throw new HttpRequestException(message);
|
||||
}
|
||||
this.logger.LogInformation($"[{domain}->{address}]");
|
||||
return address;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
using FastGithub.Scanner;
|
||||
using FastGithub.ReverseProxy;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net.Http;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
|
||||
@ -21,12 +22,12 @@ namespace FastGithub
|
||||
{
|
||||
var httpForwarder = app.ApplicationServices.GetRequiredService<IHttpForwarder>();
|
||||
var httpClientHanlder = app.ApplicationServices.GetRequiredService<GithubHttpClientHanlder>();
|
||||
var githubResolver = app.ApplicationServices.GetRequiredService<IGithubResolver>();
|
||||
var options = app.ApplicationServices.GetRequiredService<IOptionsMonitor<FastGithubOptions>>();
|
||||
|
||||
app.Use(next => async context =>
|
||||
{
|
||||
var host = context.Request.Host.Host;
|
||||
if (githubResolver.IsSupported(host) == false)
|
||||
if (options.CurrentValue.IsMatch(host) == false)
|
||||
{
|
||||
await context.Response.WriteAsJsonAsync(new { message = $"不支持以{host}访问" });
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using FastGithub.ReverseProxy;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FastGithub
|
||||
@ -11,15 +11,15 @@ namespace FastGithub
|
||||
/// <summary>
|
||||
/// gitub反向代理
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddGithubReverseProxy(this IServiceCollection services, IConfiguration configuration)
|
||||
public static IServiceCollection AddGithubReverseProxy(this IServiceCollection services)
|
||||
{
|
||||
var assembly = typeof(ReverseProxyServiceCollectionExtensions).Assembly;
|
||||
return services
|
||||
.AddServiceAndOptions(assembly, configuration)
|
||||
.AddHttpForwarder();
|
||||
.AddMemoryCache()
|
||||
.AddHttpForwarder()
|
||||
.AddSingleton<GithubResolver>()
|
||||
.AddTransient<GithubHttpClientHanlder>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,11 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Core", "FastGith
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Dns", "FastGithub.Dns\FastGithub.Dns.csproj", "{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Scanner", "FastGithub.Scanner\FastGithub.Scanner.csproj", "{7F24CD2F-07C0-4002-A534-80688DE95ECF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.Upgrade", "FastGithub.Upgrade\FastGithub.Upgrade.csproj", "{8239A077-A84C-4FDF-A204-02A2DE4243F3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastGithub.ReverseProxy", "FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj", "{28326D0F-B0FB-4B6B-A65A-C69ACB72CAD8}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.ReverseProxy", "FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj", "{28326D0F-B0FB-4B6B-A65A-C69ACB72CAD8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -33,10 +31,6 @@ Global
|
||||
{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{43FF9C79-51D5-4037-AA0B-CA3006E2A7E6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F24CD2F-07C0-4002-A534-80688DE95ECF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8239A077-A84C-4FDF-A204-02A2DE4243F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8239A077-A84C-4FDF-A204-02A2DE4243F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8239A077-A84C-4FDF-A204-02A2DE4243F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace FastGithub
|
||||
@ -30,16 +30,14 @@ namespace FastGithub
|
||||
{
|
||||
c.ValidateOnBuild = false;
|
||||
})
|
||||
.ConfigureAppConfiguration(c =>
|
||||
{
|
||||
c.AddJsonFile("appsettings.github.json", optional: true);
|
||||
})
|
||||
.ConfigureServices((ctx, services) =>
|
||||
{
|
||||
services.AddAppUpgrade();
|
||||
services.AddGithubDns(ctx.Configuration);
|
||||
services.AddGithubReverseProxy(ctx.Configuration);
|
||||
services.AddGithubScanner(ctx.Configuration);
|
||||
services.AddGithubDns();
|
||||
services.AddGithubReverseProxy();
|
||||
services.AddOptions<FastGithubOptions>()
|
||||
.Bind(ctx.Configuration.GetSection(nameof(FastGithub)))
|
||||
.Validate(opt => opt.TrustedDns.Validate() && opt.UntrustedDns.Validate(), "无效的Dns配置");
|
||||
})
|
||||
.ConfigureWebHostDefaults(web =>
|
||||
{
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
{
|
||||
"Lookup": { // ip查找
|
||||
"Domains": [ // 查找的域名,下面是github最主要的域名
|
||||
"github.com",
|
||||
"api.github.com",
|
||||
"collector.githubapp.com",
|
||||
"github.githubassets.com",
|
||||
"raw.githubusercontent.com",
|
||||
"avatars.githubusercontent.com",
|
||||
"favicons.githubusercontent.com"
|
||||
]
|
||||
},
|
||||
"Scan": {
|
||||
"HttpsScan": {
|
||||
"Rules": { // 域名扫描规则,缺失的域名,将默认HEAD请求到域名的根路径
|
||||
"github.com": {
|
||||
"Method": "HEAD",
|
||||
"Path": "/xljiulang/FastGithub"
|
||||
},
|
||||
"github.githubassets.com": {
|
||||
"Method": "HEAD",
|
||||
"Path": "/favicons/favicon.png"
|
||||
},
|
||||
"raw.githubusercontent.com": {
|
||||
"Method": "HEAD",
|
||||
"Path": "/xljiulang/FastGithub/master/README.md"
|
||||
},
|
||||
"avatars.githubusercontent.com": {
|
||||
"Method": "HEAD",
|
||||
"Path": "/u/8308014?s=40&v=4"
|
||||
},
|
||||
"favicons.githubusercontent.com": {
|
||||
"Method": "HEAD",
|
||||
"Path": "/github.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,43 +1,20 @@
|
||||
{
|
||||
"Dns": {
|
||||
"UpStream": "114.114.114.114", // 上游dns
|
||||
"GithubTTL": "00:05:00", // github相关域名解析结果的存活时长
|
||||
"SetToLocalMachine": true, // 是否设置本机使用此dns(仅支持windows)
|
||||
"UseGithubReverseProxy": true // 是否使用反向代理访问github以解决连接被重置的问题,客户端浏览器机器要安装FastGithub.cer证书
|
||||
},
|
||||
"Lookup": { // ip查找
|
||||
"IPAddressComProvider": {
|
||||
"Enable": true // 是从启用从address.com查找ip
|
||||
"FastGithub": {
|
||||
"TrustedDns": {
|
||||
"Address": "127.0.0.1",
|
||||
"Port": 5533
|
||||
},
|
||||
"GithubMetaProvider": {
|
||||
"Enable": true, // 是否从github获取ip列表
|
||||
"MetaUri": "https://gitee.com/jiulang/fast-github/raw/master/FastGithub/meta.json"
|
||||
"UnTrustedDns": {
|
||||
"Address": "114.114.114.114",
|
||||
"Port": 53
|
||||
},
|
||||
"PublicDnsProvider": {
|
||||
"Enable": true, // 是否需要从dns服务器查找ip
|
||||
"Timeout": "00:00:00.200", // dns查询超时时长
|
||||
"Dnss": [ // dns服务器列表
|
||||
"1.2.4.8",
|
||||
"8.8.8.8",
|
||||
"223.5.5.5",
|
||||
"123.125.81.6",
|
||||
"119.29.29.29",
|
||||
"208.67.220.220",
|
||||
"114.114.114.114"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Scan": {
|
||||
"FullScanInterval": "02:00:00", // 完整扫描时间间隔
|
||||
"ResultScanInterval": "00:01:00", // 结果扫描时间间隔
|
||||
"TcpScan": {
|
||||
"Timeout": "00:00:01", // tcp扫描超时时间
|
||||
"CacheExpiration": "00:30:00" // 扫描结果缓存时长
|
||||
},
|
||||
"HttpsScan": {
|
||||
"Timeout": "00:00:05", // https扫描超时时间
|
||||
"ConnectionClose": false // 是否使用https短连接
|
||||
}
|
||||
"DomainMatches": [
|
||||
"github.com",
|
||||
"*.github.com",
|
||||
"*.githubapp.com",
|
||||
"*.githubassets.com",
|
||||
"*.githubusercontent.com"
|
||||
]
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user