增加DnsOverHttps服务
This commit is contained in:
parent
a9d3ffbfb5
commit
0f94f118ca
23
FastGithub.Dns/DnsOverHttpsApplicationBuilderExtensions.cs
Normal file
23
FastGithub.Dns/DnsOverHttpsApplicationBuilderExtensions.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using FastGithub.Dns;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace FastGithub
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DoH的中间件扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class DnsOverHttpsApplicationBuilderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用DoH的中间件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="app"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IApplicationBuilder UseDnsOverHttps(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
var middleware = app.ApplicationServices.GetRequiredService<DnsOverHttpsMiddleware>();
|
||||||
|
return app.Use(next => context => middleware.InvokeAsync(context, next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
103
FastGithub.Dns/DnsOverHttpsMiddleware.cs
Normal file
103
FastGithub.Dns/DnsOverHttpsMiddleware.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using DNS.Protocol;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FastGithub.Dns
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DoH中间件
|
||||||
|
/// </summary>
|
||||||
|
sealed class DnsOverHttpsMiddleware
|
||||||
|
{
|
||||||
|
private static readonly PathString dnsQueryPath = "/dns-query";
|
||||||
|
private const string MEDIA_TYPE = "application/dns-message";
|
||||||
|
private readonly RequestResolver requestResolver;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DoH中间件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requestResolver"></param>
|
||||||
|
public DnsOverHttpsMiddleware(RequestResolver requestResolver)
|
||||||
|
{
|
||||||
|
this.requestResolver = requestResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <param name="next"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = await ParseDnsRequestAsync(context.Request);
|
||||||
|
if (request == null)
|
||||||
|
{
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var remoteIPAddress = context.Connection.RemoteIpAddress ?? IPAddress.Loopback;
|
||||||
|
var remoteEndPoint = new IPEndPoint(remoteIPAddress, context.Connection.RemotePort);
|
||||||
|
var remoteEndPointRequest = new RemoteEndPointRequest(request, remoteEndPoint);
|
||||||
|
var response = await this.requestResolver.Resolve(remoteEndPointRequest);
|
||||||
|
|
||||||
|
context.Response.ContentType = MEDIA_TYPE;
|
||||||
|
await context.Response.BodyWriter.WriteAsync(response.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析dns请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static async Task<Request?> ParseDnsRequestAsync(HttpRequest request)
|
||||||
|
{
|
||||||
|
if (request.Path != dnsQueryPath ||
|
||||||
|
request.Headers.TryGetValue("accept", out var accept) == false ||
|
||||||
|
accept.Contains(MEDIA_TYPE) == false)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.Method == HttpMethods.Get)
|
||||||
|
{
|
||||||
|
if (request.Query.TryGetValue("dns", out var dns) == false)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dnsRequest = dns.ToString().Replace('-', '+').Replace('_', '/');
|
||||||
|
int mod = dnsRequest.Length % 4;
|
||||||
|
if (mod > 0)
|
||||||
|
{
|
||||||
|
dnsRequest = dnsRequest.PadRight(dnsRequest.Length - mod + 4, '=');
|
||||||
|
}
|
||||||
|
|
||||||
|
var message = Convert.FromBase64String(dnsRequest);
|
||||||
|
return Request.FromArray(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.Method == HttpMethods.Post && request.ContentType == MEDIA_TYPE)
|
||||||
|
{
|
||||||
|
using var message = new MemoryStream();
|
||||||
|
await request.Body.CopyToAsync(message);
|
||||||
|
return Request.FromArray(message.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
<PackageReference Include="DNS" Version="6.1.0" />
|
<PackageReference Include="DNS" Version="6.1.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -18,6 +18,7 @@ namespace FastGithub
|
|||||||
{
|
{
|
||||||
services.TryAddSingleton<RequestResolver>();
|
services.TryAddSingleton<RequestResolver>();
|
||||||
services.TryAddSingleton<DnsServer>();
|
services.TryAddSingleton<DnsServer>();
|
||||||
|
services.TryAddSingleton<DnsOverHttpsMiddleware>();
|
||||||
services.AddSingleton<IDnsValidator, HostsValidator>();
|
services.AddSingleton<IDnsValidator, HostsValidator>();
|
||||||
services.AddSingleton<IDnsValidator, ProxyValidtor>();
|
services.AddSingleton<IDnsValidator, ProxyValidtor>();
|
||||||
return services.AddHostedService<DnsHostedService>();
|
return services.AddHostedService<DnsHostedService>();
|
||||||
|
|||||||
@ -45,6 +45,7 @@ namespace FastGithub
|
|||||||
public void Configure(IApplicationBuilder app)
|
public void Configure(IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
app.UseRequestLogging();
|
app.UseRequestLogging();
|
||||||
|
app.UseDnsOverHttps();
|
||||||
app.UseReverseProxy();
|
app.UseReverseProxy();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user