增加hosts文件配置验证功能

This commit is contained in:
xljiulang 2021-07-19 20:53:29 +08:00
parent d3b01002cd
commit defe09213d
4 changed files with 108 additions and 3 deletions

View File

@ -20,6 +20,7 @@ namespace FastGithub.Dns
{ {
private readonly RequestResolver requestResolver; private readonly RequestResolver requestResolver;
private readonly FastGithubConfig fastGithubConfig; private readonly FastGithubConfig fastGithubConfig;
private readonly HostsValidator hostsValidator;
private readonly ILogger<DnsServerHostedService> logger; private readonly ILogger<DnsServerHostedService> logger;
private readonly Socket socket = new(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); private readonly Socket socket = new(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
@ -40,11 +41,13 @@ namespace FastGithub.Dns
public DnsServerHostedService( public DnsServerHostedService(
RequestResolver requestResolver, RequestResolver requestResolver,
FastGithubConfig fastGithubConfig, FastGithubConfig fastGithubConfig,
HostsValidator hostsValidator,
IOptionsMonitor<FastGithubOptions> options, IOptionsMonitor<FastGithubOptions> options,
ILogger<DnsServerHostedService> logger) ILogger<DnsServerHostedService> logger)
{ {
this.requestResolver = requestResolver; this.requestResolver = requestResolver;
this.fastGithubConfig = fastGithubConfig; this.fastGithubConfig = fastGithubConfig;
this.hostsValidator = hostsValidator;
this.logger = logger; this.logger = logger;
options.OnChange(opt => FlushResolverCache()); options.OnChange(opt => FlushResolverCache());
} }
@ -74,18 +77,21 @@ namespace FastGithub.Dns
} }
await BindAsync(this.socket, new IPEndPoint(IPAddress.Any, DNS_PORT), cancellationToken); await BindAsync(this.socket, new IPEndPoint(IPAddress.Any, DNS_PORT), cancellationToken);
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {
const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C); const int SIO_UDP_CONNRESET = unchecked((int)0x9800000C);
this.socket.IOControl(SIO_UDP_CONNRESET, new byte[4], new byte[4]); this.socket.IOControl(SIO_UDP_CONNRESET, new byte[4], new byte[4]);
} }
this.logger.LogInformation("dns服务启动成功"); // 验证host文件
await this.hostsValidator.ValidateAsync();
// 设置网关的dns
var secondary = this.fastGithubConfig.FastDns.Address; var secondary = this.fastGithubConfig.FastDns.Address;
this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, secondary); this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, secondary);
FlushResolverCache(); FlushResolverCache();
this.logger.LogInformation("dns服务启动成功");
await base.StartAsync(cancellationToken); await base.StartAsync(cancellationToken);
} }

View File

@ -17,6 +17,7 @@ namespace FastGithub
{ {
return services return services
.AddSingleton<RequestResolver>() .AddSingleton<RequestResolver>()
.AddSingleton<HostsValidator>()
.AddHostedService<DnsServerHostedService>(); .AddHostedService<DnsServerHostedService>();
} }
} }

View File

@ -0,0 +1,98 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace FastGithub.Dns
{
/// <summary>
/// host文件配置验证器
/// </summary>
sealed class HostsValidator
{
private readonly FastGithubConfig fastGithubConfig;
private readonly ILogger<HostsValidator> logger;
/// <summary>
/// host文件配置验证器
/// </summary>
/// <param name="fastGithubConfig"></param>
/// <param name="logger"></param>
public HostsValidator(
FastGithubConfig fastGithubConfig,
ILogger<HostsValidator> logger)
{
this.fastGithubConfig = fastGithubConfig;
this.logger = logger;
}
/// <summary>
/// 验证host文件的域名解析配置
/// </summary>
/// <returns></returns>
public async Task ValidateAsync()
{
var hostsPath = @"/etc/hosts";
if (OperatingSystem.IsWindows())
{
hostsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), $"drivers/{hostsPath}");
}
if (File.Exists(hostsPath) == false)
{
return;
}
var lines = await File.ReadAllLinesAsync(hostsPath);
var records = lines.Where(item => item.TrimStart().StartsWith("#") == false);
var localAddresses = GetLocalMachineIPAddress().ToArray();
foreach (var record in records)
{
var items = record.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (items.Length < 2)
{
continue;
}
if (IPAddress.TryParse(items[0], out var address) == false)
{
continue;
}
if (localAddresses.Contains(address))
{
continue;
}
var domain = items[1];
if (this.fastGithubConfig.IsMatch(domain))
{
this.logger.LogWarning($"hosts文件设置了[{domain}->{address}]{nameof(FastGithub)}对此域名反向代理失效");
}
}
}
/// <summary>
/// 获取本机所有ip
/// </summary>
/// <returns></returns>
private static IEnumerable<IPAddress> GetLocalMachineIPAddress()
{
yield return IPAddress.Loopback;
yield return IPAddress.IPv6Loopback;
foreach (var @interface in NetworkInterface.GetAllNetworkInterfaces())
{
foreach (var addressInfo in @interface.GetIPProperties().UnicastAddresses)
{
yield return addressInfo.Address;
}
}
}
}
}