增加hosts文件配置验证功能
This commit is contained in:
		
							parent
							
								
									d3b01002cd
								
							
						
					
					
						commit
						defe09213d
					
				@ -20,6 +20,7 @@ namespace FastGithub.Dns
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestResolver requestResolver;
 | 
			
		||||
        private readonly FastGithubConfig fastGithubConfig;
 | 
			
		||||
        private readonly HostsValidator hostsValidator;
 | 
			
		||||
        private readonly ILogger<DnsServerHostedService> logger;
 | 
			
		||||
 | 
			
		||||
        private readonly Socket socket = new(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
 | 
			
		||||
@ -40,11 +41,13 @@ namespace FastGithub.Dns
 | 
			
		||||
        public DnsServerHostedService(
 | 
			
		||||
            RequestResolver requestResolver,
 | 
			
		||||
            FastGithubConfig fastGithubConfig,
 | 
			
		||||
            HostsValidator hostsValidator,
 | 
			
		||||
            IOptionsMonitor<FastGithubOptions> options,
 | 
			
		||||
            ILogger<DnsServerHostedService> logger)
 | 
			
		||||
        {
 | 
			
		||||
            this.requestResolver = requestResolver;
 | 
			
		||||
            this.fastGithubConfig = fastGithubConfig;
 | 
			
		||||
            this.hostsValidator = hostsValidator;
 | 
			
		||||
            this.logger = logger;
 | 
			
		||||
            options.OnChange(opt => FlushResolverCache());
 | 
			
		||||
        }
 | 
			
		||||
@ -74,18 +77,21 @@ namespace FastGithub.Dns
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await BindAsync(this.socket, new IPEndPoint(IPAddress.Any, DNS_PORT), cancellationToken);
 | 
			
		||||
 | 
			
		||||
            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服务启动成功");
 | 
			
		||||
            // 验证host文件 
 | 
			
		||||
            await this.hostsValidator.ValidateAsync();
 | 
			
		||||
 | 
			
		||||
            // 设置网关的dns
 | 
			
		||||
            var secondary = this.fastGithubConfig.FastDns.Address;
 | 
			
		||||
            this.dnsAddresses = this.SetNameServers(IPAddress.Loopback, secondary);
 | 
			
		||||
            FlushResolverCache();
 | 
			
		||||
 | 
			
		||||
            this.logger.LogInformation("dns服务启动成功");
 | 
			
		||||
            await base.StartAsync(cancellationToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ namespace FastGithub
 | 
			
		||||
        {
 | 
			
		||||
            return services
 | 
			
		||||
                .AddSingleton<RequestResolver>()
 | 
			
		||||
                .AddSingleton<HostsValidator>()
 | 
			
		||||
                .AddHostedService<DnsServerHostedService>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										98
									
								
								FastGithub.Dns/HostsValidator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								FastGithub.Dns/HostsValidator.cs
									
									
									
									
									
										Normal 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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user