From 0cf081ad89d6e7b245320750cf60181ef6d5927d Mon Sep 17 00:00:00 2001 From: sinspired Date: Wed, 20 Nov 2024 22:16:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0SSL=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 143 +++++++++++++------------------------------- hosts | 135 ++++++++++++----------------------------- setHosts.py | 70 +++++++++++++++++++--- setHosts_Classic.py | 84 ++++++++++++++++++++++---- 4 files changed, 218 insertions(+), 214 deletions(-) diff --git a/README.md b/README.md index 67a2afe..a8d7dbd 100644 --- a/README.md +++ b/README.md @@ -30,120 +30,61 @@ ```bash -# cnNetTool Start in 2024-11-14 22:07:51 +08:00 -140.82.113.26 alive.github.com -20.205.243.168 api.github.com -140.82.113.21 central.github.com +# cnNetTool Start in 2024-11-20 22:13:42 +08:00 +140.82.112.26 alive.github.com +140.82.114.22 central.github.com 20.205.243.165 codeload.github.com -140.82.114.21 collector.github.com -140.82.113.3 gist.github.com 20.205.243.166 github.com -140.82.112.17 github.community -151.101.193.194 github.global.ssl.fastly.net -3.5.29.79 github-com.s3.amazonaws.com -52.217.67.108 github-production-release-asset-2e65be.s3.amazonaws.com -140.82.113.25 live.github.com -13.107.42.16 pipelines.actions.githubusercontent.com +140.82.113.17 github.community +151.101.129.194 github.global.ssl.fastly.net +52.217.129.17 github-com.s3.amazonaws.com +52.216.161.219 github-production-release-asset-2e65be.s3.amazonaws.com +140.82.114.25 live.github.com +13.107.43.16 pipelines.actions.githubusercontent.com 2620:1ec:21::16 pipelines.actions.githubusercontent.com 185.199.110.154 github.githubassets.com -185.199.111.153 github.io -2606:50c0:8003::153 github.io -185.199.111.153 githubstatus.com -2606:50c0:8003::153 githubstatus.com -185.199.111.153 assets-cdn.github.com -2606:50c0:8003::153 assets-cdn.github.com -185.199.109.133 avatars.githubusercontent.com -2606:50c0:8001::154 avatars.githubusercontent.com -185.199.109.133 avatars0.githubusercontent.com -2606:50c0:8001::154 avatars0.githubusercontent.com -185.199.109.133 avatars1.githubusercontent.com -2606:50c0:8001::154 avatars1.githubusercontent.com -185.199.109.133 avatars2.githubusercontent.com -2606:50c0:8001::154 avatars2.githubusercontent.com -185.199.109.133 avatars3.githubusercontent.com -2606:50c0:8001::154 avatars3.githubusercontent.com -185.199.109.133 avatars4.githubusercontent.com -2606:50c0:8001::154 avatars4.githubusercontent.com -185.199.109.133 avatars5.githubusercontent.com -2606:50c0:8001::154 avatars5.githubusercontent.com -185.199.109.133 camo.githubusercontent.com -2606:50c0:8001::154 camo.githubusercontent.com -185.199.109.133 cloud.githubusercontent.com -2606:50c0:8001::154 cloud.githubusercontent.com -185.199.109.133 desktop.githubusercontent.com -2606:50c0:8001::154 desktop.githubusercontent.com -185.199.109.133 favicons.githubusercontent.com -2606:50c0:8001::154 favicons.githubusercontent.com -185.199.109.133 github.map.fastly.net -2606:50c0:8001::154 github.map.fastly.net -185.199.109.133 media.githubusercontent.com -2606:50c0:8001::154 media.githubusercontent.com -185.199.109.133 objects.githubusercontent.com -2606:50c0:8001::154 objects.githubusercontent.com -185.199.109.133 private-user-images.githubusercontent.com -2606:50c0:8001::154 private-user-images.githubusercontent.com -185.199.109.133 raw.githubusercontent.com -2606:50c0:8001::154 raw.githubusercontent.com -185.199.109.133 user-images.githubusercontent.com -2606:50c0:8001::154 user-images.githubusercontent.com -18.66.102.107 tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 tmdb.org -18.66.102.107 api.tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 api.tmdb.org -18.66.102.107 files.tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 files.tmdb.org -3.160.150.81 themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 themoviedb.org -3.160.150.81 api.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 api.themoviedb.org -3.160.150.81 www.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 www.themoviedb.org -3.160.150.81 auth.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 auth.themoviedb.org -185.93.1.243 image.tmdb.org -2400:52e0:1a01::996:1 image.tmdb.org -185.93.1.243 images.tmdb.org -2400:52e0:1a01::996:1 images.tmdb.org -52.94.237.74 imdb.com +18.155.202.52 themoviedb.org +18.155.202.52 api.themoviedb.org +18.155.202.52 www.themoviedb.org +18.155.202.52 auth.themoviedb.org +169.150.236.100 image.tmdb.org +2400:52e0:1a01::1114:1 image.tmdb.org +169.150.236.100 images.tmdb.org +2400:52e0:1a01::1114:1 images.tmdb.org 13.226.254.49 www.imdb.com -52.94.237.74 secure.imdb.com +52.94.225.248 secure.imdb.com 13.226.254.49 s.media-imdb.com 52.94.225.248 us.dd.imdb.com 13.226.254.49 www.imdb.to -52.94.225.248 imdb-webservice.amazon.com -98.82.155.134 origin-www.imdb.com -3.166.233.221 m.media-amazon.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 m.media-amazon.com -151.101.129.16 Images-na.ssl-images-amazon.com -2600:9000:274f:8a00:1d:d7f6:39d4:e6e1 Images-na.ssl-images-amazon.com -3.166.233.221 images-fe.ssl-images-amazon.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 images-fe.ssl-images-amazon.com -3.166.233.221 images-eu.ssl-images-amazon.com -2600:9000:274f:3000:1d:d7f6:39d4:e6e1 images-eu.ssl-images-amazon.com -3.166.233.221 ia.media-imdb.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 ia.media-imdb.com +151.101.89.16 m.media-amazon.com +2a04:4e42:15::272 m.media-amazon.com +151.101.89.16 Images-na.ssl-images-amazon.com +2a04:4e42:15::272 Images-na.ssl-images-amazon.com +151.101.89.16 images-fe.ssl-images-amazon.com +2a04:4e42:15::272 images-fe.ssl-images-amazon.com +151.101.89.16 images-eu.ssl-images-amazon.com +2a04:4e42:15::272 images-eu.ssl-images-amazon.com +151.101.89.16 ia.media-imdb.com +2a04:4e42:15::272 ia.media-imdb.com 151.101.89.16 f.media-amazon.com 2a04:4e42:15::272 f.media-amazon.com -18.238.192.108 imdb-video.media-imdb.com -13.226.220.89 dqpnq362acqdi.cloudfront.net -2600:9000:223e:6a00:5:ce70:a180:21 dqpnq362acqdi.cloudfront.net -64.233.189.148 translate.google.com -64.233.189.148 translate.googleapis.com -64.233.189.148 translate-pa.googleapis.com -3.166.228.13 plugins.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 plugins.jetbrains.com -3.166.228.13 download.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 download.jetbrains.com -3.166.228.13 cache-redirector.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 cache-redirector.jetbrains.com - -# Update time: 2024-11-14 22:07:51 +08:00 +172.217.31.136 translate.google.com +172.217.31.136 translate.googleapis.com +172.217.31.136 translate-pa.googleapis.com +3.168.86.87 plugins.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 plugins.jetbrains.com +3.168.86.87 download.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 download.jetbrains.com +3.168.86.87 cache-redirector.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 cache-redirector.jetbrains.com + +# Update time: 2024-11-20 22:13:42 +08:00 # GitHub仓库: https://github.com/sinspired/cnNetTool # cnNetTool End ``` -该内容会自动定时更新, 数据更新时间:2024-11-14 22:07:51 +08:00 +以上内容会自动定时更新, 数据更新时间:2024-11-20 22:13:42 +08:00 #### 1.2.2 修改 hosts 文件 @@ -160,6 +101,8 @@ hosts 文件在每个系统的位置不一,详情如下: 2. Linux、Mac 使用 Root 权限:`sudo vi /etc/hosts`。 3. iPhone、iPad 须越狱、Android 必须要 root。 +> [!NOTE] +> 请先把 `hosts` 文件复制到其他目录,修改后再复制回去,否则可能无法修改。 ## 二、安装 @@ -181,7 +124,7 @@ pip install -r requirements.txt * --debug 启用调试日志 * --show-availbale-list, --list 显示可用dns列表,通过 --num 控制显示数量 * --best-dns-num BEST_DNS_NUM, --num 显示最佳DNS服务器的数量 -* --algorithm --mode {region,overall} 默认 `region` 平衡IPv4和ipv6 DNS +* --algorithm --mode {region,overall} 默认 `region` 平衡IPv4和ipv6 DNS,选择 `overall` 则会在所有IP中选择最快IP * --show-resolutions, --show 显示域名解析结果 ### Hosts文件工具 `SetHosts.py` diff --git a/hosts b/hosts index c40e037..045da20 100644 --- a/hosts +++ b/hosts @@ -1,111 +1,52 @@ -# cnNetTool Start in 2024-11-14 22:07:51 +08:00 -140.82.113.26 alive.github.com -20.205.243.168 api.github.com -140.82.113.21 central.github.com +# cnNetTool Start in 2024-11-20 22:13:42 +08:00 +140.82.112.26 alive.github.com +140.82.114.22 central.github.com 20.205.243.165 codeload.github.com -140.82.114.21 collector.github.com -140.82.113.3 gist.github.com 20.205.243.166 github.com -140.82.112.17 github.community -151.101.193.194 github.global.ssl.fastly.net -3.5.29.79 github-com.s3.amazonaws.com -52.217.67.108 github-production-release-asset-2e65be.s3.amazonaws.com -140.82.113.25 live.github.com -13.107.42.16 pipelines.actions.githubusercontent.com +140.82.113.17 github.community +151.101.129.194 github.global.ssl.fastly.net +52.217.129.17 github-com.s3.amazonaws.com +52.216.161.219 github-production-release-asset-2e65be.s3.amazonaws.com +140.82.114.25 live.github.com +13.107.43.16 pipelines.actions.githubusercontent.com 2620:1ec:21::16 pipelines.actions.githubusercontent.com 185.199.110.154 github.githubassets.com -185.199.111.153 github.io -2606:50c0:8003::153 github.io -185.199.111.153 githubstatus.com -2606:50c0:8003::153 githubstatus.com -185.199.111.153 assets-cdn.github.com -2606:50c0:8003::153 assets-cdn.github.com -185.199.109.133 avatars.githubusercontent.com -2606:50c0:8001::154 avatars.githubusercontent.com -185.199.109.133 avatars0.githubusercontent.com -2606:50c0:8001::154 avatars0.githubusercontent.com -185.199.109.133 avatars1.githubusercontent.com -2606:50c0:8001::154 avatars1.githubusercontent.com -185.199.109.133 avatars2.githubusercontent.com -2606:50c0:8001::154 avatars2.githubusercontent.com -185.199.109.133 avatars3.githubusercontent.com -2606:50c0:8001::154 avatars3.githubusercontent.com -185.199.109.133 avatars4.githubusercontent.com -2606:50c0:8001::154 avatars4.githubusercontent.com -185.199.109.133 avatars5.githubusercontent.com -2606:50c0:8001::154 avatars5.githubusercontent.com -185.199.109.133 camo.githubusercontent.com -2606:50c0:8001::154 camo.githubusercontent.com -185.199.109.133 cloud.githubusercontent.com -2606:50c0:8001::154 cloud.githubusercontent.com -185.199.109.133 desktop.githubusercontent.com -2606:50c0:8001::154 desktop.githubusercontent.com -185.199.109.133 favicons.githubusercontent.com -2606:50c0:8001::154 favicons.githubusercontent.com -185.199.109.133 github.map.fastly.net -2606:50c0:8001::154 github.map.fastly.net -185.199.109.133 media.githubusercontent.com -2606:50c0:8001::154 media.githubusercontent.com -185.199.109.133 objects.githubusercontent.com -2606:50c0:8001::154 objects.githubusercontent.com -185.199.109.133 private-user-images.githubusercontent.com -2606:50c0:8001::154 private-user-images.githubusercontent.com -185.199.109.133 raw.githubusercontent.com -2606:50c0:8001::154 raw.githubusercontent.com -185.199.109.133 user-images.githubusercontent.com -2606:50c0:8001::154 user-images.githubusercontent.com -18.66.102.107 tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 tmdb.org -18.66.102.107 api.tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 api.tmdb.org -18.66.102.107 files.tmdb.org -2600:9000:275d:9e00:5:da10:7440:93a1 files.tmdb.org -3.160.150.81 themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 themoviedb.org -3.160.150.81 api.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 api.themoviedb.org -3.160.150.81 www.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 www.themoviedb.org -3.160.150.81 auth.themoviedb.org -2600:9000:27e3:c00:e:5373:440:93a1 auth.themoviedb.org -185.93.1.243 image.tmdb.org -2400:52e0:1a01::996:1 image.tmdb.org -185.93.1.243 images.tmdb.org -2400:52e0:1a01::996:1 images.tmdb.org -52.94.237.74 imdb.com +18.155.202.52 themoviedb.org +18.155.202.52 api.themoviedb.org +18.155.202.52 www.themoviedb.org +18.155.202.52 auth.themoviedb.org +169.150.236.100 image.tmdb.org +2400:52e0:1a01::1114:1 image.tmdb.org +169.150.236.100 images.tmdb.org +2400:52e0:1a01::1114:1 images.tmdb.org 13.226.254.49 www.imdb.com -52.94.237.74 secure.imdb.com +52.94.225.248 secure.imdb.com 13.226.254.49 s.media-imdb.com 52.94.225.248 us.dd.imdb.com 13.226.254.49 www.imdb.to -52.94.225.248 imdb-webservice.amazon.com -98.82.155.134 origin-www.imdb.com -3.166.233.221 m.media-amazon.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 m.media-amazon.com -151.101.129.16 Images-na.ssl-images-amazon.com -2600:9000:274f:8a00:1d:d7f6:39d4:e6e1 Images-na.ssl-images-amazon.com -3.166.233.221 images-fe.ssl-images-amazon.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 images-fe.ssl-images-amazon.com -3.166.233.221 images-eu.ssl-images-amazon.com -2600:9000:274f:3000:1d:d7f6:39d4:e6e1 images-eu.ssl-images-amazon.com -3.166.233.221 ia.media-imdb.com -2600:9000:274f:b200:1d:d7f6:39d4:e6e1 ia.media-imdb.com +151.101.89.16 m.media-amazon.com +2a04:4e42:15::272 m.media-amazon.com +151.101.89.16 Images-na.ssl-images-amazon.com +2a04:4e42:15::272 Images-na.ssl-images-amazon.com +151.101.89.16 images-fe.ssl-images-amazon.com +2a04:4e42:15::272 images-fe.ssl-images-amazon.com +151.101.89.16 images-eu.ssl-images-amazon.com +2a04:4e42:15::272 images-eu.ssl-images-amazon.com +151.101.89.16 ia.media-imdb.com +2a04:4e42:15::272 ia.media-imdb.com 151.101.89.16 f.media-amazon.com 2a04:4e42:15::272 f.media-amazon.com -18.238.192.108 imdb-video.media-imdb.com -13.226.220.89 dqpnq362acqdi.cloudfront.net -2600:9000:223e:6a00:5:ce70:a180:21 dqpnq362acqdi.cloudfront.net -64.233.189.148 translate.google.com -64.233.189.148 translate.googleapis.com -64.233.189.148 translate-pa.googleapis.com -3.166.228.13 plugins.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 plugins.jetbrains.com -3.166.228.13 download.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 download.jetbrains.com -3.166.228.13 cache-redirector.jetbrains.com -2600:9000:2365:f400:12:7c44:15c0:93a1 cache-redirector.jetbrains.com +172.217.31.136 translate.google.com +172.217.31.136 translate.googleapis.com +172.217.31.136 translate-pa.googleapis.com +3.168.86.87 plugins.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 plugins.jetbrains.com +3.168.86.87 download.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 download.jetbrains.com +3.168.86.87 cache-redirector.jetbrains.com +2600:9000:2365:d400:12:7c44:15c0:93a1 cache-redirector.jetbrains.com -# Update time: 2024-11-14 22:07:51 +08:00 +# Update time: 2024-11-20 22:13:42 +08:00 # GitHubֿ: https://github.com/sinspired/cnNetTool # cnNetTool End diff --git a/setHosts.py b/setHosts.py index 73c8e19..691bb0e 100644 --- a/setHosts.py +++ b/setHosts.py @@ -1,5 +1,6 @@ from math import floor import os +import ssl import sys from pathlib import Path import dns.resolver @@ -475,6 +476,43 @@ async def get_host_average_latency( logging.debug(f"ping {ip} 时出错: {e}") return ip, float("inf") + async def is_cert_valid( + self,domain:str,ip:str,port:int=443 + ) -> bool: + + # 设置SSL上下文,用于证书验证 + context = ssl.create_default_context() + context.verify_mode = ssl.CERT_REQUIRED # 验证服务器证书 + context.check_hostname = True # 确保证书主机名匹配 + + try: + # 1. 尝试与IP地址建立SSL连接 + with socket.create_connection((ip, port), timeout=5) as sock: + with context.wrap_socket(sock, server_hostname=domain) as ssock: + cert = ssock.getpeercert() + # 检查证书的有效期 + not_after = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z') + if not_after < datetime.now(): + logging.debug(f"{domain} ({ip}): 证书已过期") + return False + + # 验证证书域名(由context自动完成),同时获取连接状态 + logging.debug(f"{domain} ({ip}): SSL证书有效,截止日期为 {not_after}") + return True + + except ssl.SSLError as e: + logging.debug(f"{domain} ({ip}): SSL错误 - {e}") + return False + except socket.timeout as e: + logging.debug(f"{domain} ({ip}): 连接超时 - {e}") + return False + except ConnectionError as e: + logging.debug(f"{domain} ({ip}): 连接被强迫关闭,ip有效 - {e}") + return True + except Exception as e: + logging.error(f"{domain} ({ip}): 其他错误 - {e}") + return False + async def get_lowest_latency_hosts( self, group_name: str, @@ -534,18 +572,35 @@ async def get_lowest_latency_hosts( valid_results = [ result for result in results if result[1] < latency_limit ] - if not valid_results: + if not valid_results: + logging.warning(f"未发现延迟小于 {latency_limit}ms 的IP。") + return [] + else: return [] + # 排序结果 + valid_results = sorted(valid_results, key=lambda x: x[1]) + ipv4_results = [r for r in valid_results if not Utils.is_ipv6(r[0])] ipv6_results = [r for r in valid_results if Utils.is_ipv6(r[0])] best_hosts = [] - if ipv4_results and ipv6_results: - best_hosts.append(min(ipv4_results, key=lambda x: x[1])) - best_hosts.append(min(ipv6_results, key=lambda x: x[1])) - else: - best_hosts = sorted(valid_results, key=lambda x: x[1])[: self.hosts_num] + selected_count = 0 + + # 检测 IPv4 证书有效性 + for ip, latency in ipv4_results: + if await self.is_cert_valid(domains[0], ip): # shareGroup会传入多个域名,只需检测第一个就行 + best_hosts.append((ip, latency)) + selected_count += 1 + if ipv6_results or selected_count >= self.hosts_num: + break + + # 检测 IPv6 证书有效性 + if ipv6_results: + for ip, latency in ipv6_results: + if await self.is_cert_valid(domains[0], ip): + best_hosts.append((ip, latency)) + break if args.verbose: rprint( @@ -560,6 +615,7 @@ async def get_lowest_latency_hosts( return best_hosts + # -------------------- Hosts文件管理 -------------------- # class HostsManager: def __init__(self, resolver: DomainResolver): @@ -1029,7 +1085,7 @@ class Config: "us.dd.imdb.com", "www.imdb.to", "imdb-webservice.amazon.com", - "origin-www.imdb.com", + # "origin-www.imdb.com", "origin.www.geo.imdb.com", ], ips={}, diff --git a/setHosts_Classic.py b/setHosts_Classic.py index 7c61e14..e37b0ef 100644 --- a/setHosts_Classic.py +++ b/setHosts_Classic.py @@ -1,4 +1,5 @@ import os +import ssl import sys from pathlib import Path import dns.resolver @@ -392,6 +393,45 @@ async def get_host_average_latency( logging.debug(f"ping {ip} 时出错: {e}") return ip, float("inf") + async def is_cert_valid(self, domain: str, ip: str, port: int = 443) -> bool: + + # 设置SSL上下文,用于证书验证 + context = ssl.create_default_context() + context.verify_mode = ssl.CERT_REQUIRED # 验证服务器证书 + context.check_hostname = True # 确保证书主机名匹配 + + try: + # 1. 尝试与IP地址建立SSL连接 + with socket.create_connection((ip, port), timeout=5) as sock: + with context.wrap_socket(sock, server_hostname=domain) as ssock: + cert = ssock.getpeercert() + # 检查证书的有效期 + not_after = datetime.strptime( + cert["notAfter"], "%b %d %H:%M:%S %Y %Z" + ) + if not_after < datetime.now(): + logging.debug(f"{domain} ({ip}): 证书已过期") + return False + + # 验证证书域名(由context自动完成),同时获取连接状态 + logging.debug( + f"{domain} ({ip}): SSL证书有效,截止日期为 {not_after}" + ) + return True + + except ssl.SSLError as e: + logging.debug(f"{domain} ({ip}): SSL错误 - {e}") + return False + except socket.timeout as e: + logging.debug(f"{domain} ({ip}): 连接超时 - {e}") + return False + except ConnectionError as e: + logging.debug(f"{domain} ({ip}): 连接被强迫关闭,ip有效 - {e}") + return True + except Exception as e: + logging.error(f"{domain} ({ip}): 其他错误 - {e}") + return False + async def get_lowest_latency_hosts( self, domains: List[str], file_ips: Set[str], latency_limit: int ) -> List[Tuple[str, float]]: @@ -417,7 +457,7 @@ async def get_lowest_latency_hosts( all_ips.update(file_ips) rprint( - f"[bright_black]- 找到 [bold bright_green]{len(all_ips)}[/bold bright_green] 个唯一IP地址[/bright_black]" + f"[bright_black]- 解析到 [bold bright_green]{len(all_ips)}[/bold bright_green] 个唯一IP地址[/bright_black]" ) if args.log.upper() == "INFO": @@ -441,25 +481,49 @@ async def get_lowest_latency_hosts( valid_results = [result for result in results if result[1] < latency_limit] if not valid_results: - logging.warning(f"未找到延迟小于 {latency_limit}ms 的IP。") + logging.warning(f"未发现延迟小于 {latency_limit}ms 的IP。") if results: latency_limit = latency_limit * 2 - logging.info(f"放宽延迟限制为 {latency_limit}ms 重新搜索...") + logging.info(f"放宽延迟限制为 {latency_limit}ms 重新挑选...") valid_results = [ result for result in results if result[1] < latency_limit ] - if not valid_results: + if not valid_results: + logging.warning(f"未发现延迟小于 {latency_limit}ms 的IP。") + return [] + else: return [] + # 排序结果 + valid_results = sorted(valid_results, key=lambda x: x[1]) + + if len(valid_results) < len(all_ips): + rprint( + f"[bright_black]- 检测到 [bold bright_green]{len(valid_results)}[/bold bright_green] 个有效IP地址[/bright_black]" + ) + ipv4_results = [r for r in valid_results if not Utils.is_ipv6(r[0])] ipv6_results = [r for r in valid_results if Utils.is_ipv6(r[0])] best_hosts = [] - if ipv4_results and ipv6_results: - best_hosts.append(min(ipv4_results, key=lambda x: x[1])) - best_hosts.append(min(ipv6_results, key=lambda x: x[1])) - else: - best_hosts = sorted(valid_results, key=lambda x: x[1])[: self.hosts_num] + selected_count = 0 + + # 检测 IPv4 证书有效性 + for ip, latency in ipv4_results: + if await self.is_cert_valid(domains[0], ip): # shareGroup会传入多个域名,只需检测第一个就行 + best_hosts.append((ip, latency)) + selected_count += 1 + break + + if ipv6_results or selected_count >= self.hosts_num: + break + + # 检测 IPv6 证书有效性 + if ipv6_results: + for ip, latency in ipv6_results: + if await self.is_cert_valid(domains[0], ip): + best_hosts.append((ip, latency)) + break rprint( f"[bold yellow]最快的 DNS主机 IP(优先选择 IPv6) 丨 延迟 < {latency_limit}ms :[/bold yellow]" @@ -632,7 +696,7 @@ async def update_hosts(self): logging.warning(f"组 {group.name} 未找到任何可用IP。跳过该组。") continue - rprint(f" 找到 {len(all_ips)} 个 DNS 主机记录") + # rprint(f" 找到 {len(all_ips)} 个 DNS 主机记录") fastest_ips = await self.tester.get_lowest_latency_hosts( # [group.domains[0]], # 只需传入一个域名,因为只是用来测试IP