Browse Source

增加hosts文件配置验证功能

xljiulang 4 years ago
parent
commit
defe09213d

+ 8 - 2
FastGithub.Dns/DnsServerHostedService.cs

@@ -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);
         }
         }
 
 

+ 1 - 0
FastGithub.Dns/DnsServerServiceCollectionExtensions.cs

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

+ 1 - 1
FastGithub.Dns/FastGithub.Dns.csproj

@@ -4,7 +4,7 @@
 		<TargetFramework>net5.0</TargetFramework>
 		<TargetFramework>net5.0</TargetFramework>
 		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 	</PropertyGroup> 
 	</PropertyGroup> 
-
+	
 	<ItemGroup>
 	<ItemGroup>
 		<ProjectReference Include="..\FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj" />
 		<ProjectReference Include="..\FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj" />
 	</ItemGroup>
 	</ItemGroup>

+ 98 - 0
FastGithub.Dns/HostsValidator.cs

@@ -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;
+                }
+            }
+        }
+    }
+}