CloudflareSpeedTest icon indicating copy to clipboard operation
CloudflareSpeedTest copied to clipboard

自动更新 Hosts 为最快 IP(Windows/Linux 脚本)

Open XIU2 opened this issue 4 years ago • 45 comments

因为每个域名解析网站的 API 都不同,而这些域名解析网站需要我托管的有域名才能写 API 相关教程/脚本,所以想了一种替代方案,可以把域名写在 Hosts,这样效果也一样,不过缺点就是只能在当前设备上体验最快的 IP。

如果用的是基于 Linux 系统的路由器(如 OpenWrt),则这个整个局域网都有效。

再考虑到很多人获得最快 Cloudflare CDN IP 后,需要替换 Hosts 文件中的 IP。

那我干脆写个简单的脚本吧!大家使用过程中遇到什么问题或者建议都可以告诉我。 如果用着不错,就点个 ⭐ 吧!


还在一个个添加 Hosts?完美本地加速所有使用 Cloudflare CDN 的网站方法来了!


  1. [x] Windows 脚本
  2. [x] Linux 脚本
  3. [x] 定时任务

XIU2 avatar Jan 27 '21 12:01 XIU2

# Windows 脚本

~~首先下载批处理脚本:...~~ 已内置压缩包中。

然后将其放到 CloudflareST 测速程序所在目录下,双击运行脚本,脚本会申请管理员权限,因此如果你没有关闭 UAC,就会看到用户账户控制提示,选择 [是] 继续。

如果想要在开启 UAC 的情况下不提示 UAC ,可以用我写的开源 UAC 白名单小工具 来解决(依然有管理员权限)。

「 点击查看 [不显示 CMD 黑窗口方式运行 bat 脚本方法] 」

考虑到有些人不想看到 CDM 的黑窗口,可以简单改为默认最小化运行 bat 脚本(只显示在任务栏)。

在 bat 文件头部 @echo off 下一行插入:if not "%~1"=="p" start /min cmd.exe /c %0 p&exit 保存即可。

插入代码后效果如下所示:

@echo off
if not "%~1"=="p" start /min cmd.exe /c %0 p&exit
Setlocal Enabledelayedexpansion
...

首次运行,脚本会提示以下内容:

该脚本的作用为 CloudflareST 测速后获取最快 IP 并替换 Hosts 中的所有 Cloudflare CDN IP。

第一次使用,请先将 Hosts 中所有 Cloudflare CDN IP 统一改为一个 IP。
输入该 Cloudflare CDN IP 并回车(后续不再需要该步骤):

因为脚本替换 IP 时需要先知道被替换的 IP 是什么才行,所以你需要先去 C:\Windows\System32\drivers\etc\hosts 文件中将里面所有 Cloudflare CDN IP 都给改为一个 IP(例如 1.1.1.1,然后再脚本提示中输入该 IP 回车即可,如果 Hosts 文件中以前没有加过 Cloudflare CDN 的 IP,那么你另起一行手动加上个,例如:1.1.1.1 cloudflare.com)。

然后在脚本中输入该 IP,按下回车键继续(IP 会存储在 nowip.txt 文件,以便下次脚本知道要替换哪个 IP)。


随后脚本就会开始测速、备份 Hosts 文件、替换 IP 等操作,提示内容大概如下:

开始测速...
# XIU2/CloudflareSpeedTest vX.X.X

开始延迟测速(模式:TCP IPv4,端口:443):
27936 / 27936 [-------------------------------------------------------------------------------------------------] 100.00%
...

旧 IP 为 X.X.X.X
新 IP 为 Y.Y.Y.Y

开始备份 Hosts 文件(hosts_backup)...
已复制         1 个文件。

开始替换...
完成...

请按任意键继续. . .

## 其他说明

  • 以上脚本只是一个示例,大家可以按需修改,比如在脚本代码中 CloudflareST.exe 后面添加其他参数
  • 每次替换前都会备份 hosts 文件到 hosts_backup 文件。
  • 如果你需要开机自动运行该脚本,只需要右键脚本 - 创建快捷方式,然后将快捷方式移动到 C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 目录下即可。
  • 如果你用了我的 UAC 白名单小工具 生成了免 UAC 的启动快捷方式,那就复制该快捷方式到开机启动目录下即可。

我对 Windows 的批处理脚本并不熟悉,如果有什么问题或者更好的建议,请务必告诉我!

XIU2 avatar Jan 27 '21 13:01 XIU2

# Linux 脚本

注意,修改 Hosts 需要 root(管理员)用户权限,因此如果你当前不是 root 用户,请使用 sudo su 切换。

请先进入 CloudflareST 目录下,~~再去下载脚本~~ 已内置压缩包中(并赋予执行权限):

# 因为脚本已经内置到压缩包中了,所以不再需要下载步骤了,直接执行下面的赋予执行权限命令就行了。
chmod +x cfst_hosts.sh

运行脚本:

bash cfst_hosts.sh

首次运行时,脚本会提示以下内容:

该脚本的作用为 CloudflareST 测速后获取最快 IP 并替换 Hosts 中的 Cloudflare CDN IP。

第一次使用,请先将 Hosts 中所有 Cloudflare CDN IP 统一改为一个 IP。
输入该 Cloudflare CDN IP 并回车(后续不再需要该步骤):

即你需要先去 /etc/hosts 文件中将所有 Cloudflare CDN IP 统一改为一个 IP

然后在脚本中输入该 IP,按下回车键继续(IP 会存储在 nowip.txt 文件,以便下次脚本知道替换哪个 IP)。


随后脚本就会开始测速、备份 Hosts 文件、替换 IP 等操作,提示内容大概如下:

开始测速...
# XIU2/CloudflareSpeedTest vX.X.X

开始延迟测速(模式:TCP IPv4,端口:443):
27936 / 27936 [-------------------------------------------------------------------------------------------------] 100.00%
...
完整测速结果已写入 result.csv 文件,请使用记事本/表格软件查看。

旧 IP 为 X.X.X.X
新 IP 为 Y.Y.Y.Y

开始备份 Hosts 文件(hosts_backup)...
已复制         1 个文件。

开始替换...
完成...

## 其他说明

  • 以上脚本只是一个示例,大家可以按需修改,比如在脚本代码中 ./CloudflareST 后面添加其他参数
  • 每次替换前都会备份 hosts 文件到 hosts_backup 文件。
  • 如果是在路由器上面跑该脚本(如 OpenWrt),请先关闭路由器内的代理,否则测速结果会不准确。

如果有什么问题或者更好的建议,请务必告诉我!

XIU2 avatar Jan 27 '21 13:01 XIU2

# 定时任务

## Linux 系统

Linux 自然要用 Cron 来定时执行脚本。

### 安装 Cron

一般各 Linux 系统都自带了 Cron,执行 crontab -l 命令,如果提示命令不存在,说明没有安装,反之则跳过该步骤

# 确认你是哪个系统,然后选择对应的命令安装 Cron 程序。

# CentOS 系统:
yum install vixie-cron
yum install crontabs

# Debian/Ubuntu 系统:
apt-get install cron

### 配置 Cron

开始编辑定时任务,

crontab -e

首次使用可能会提示你如下内容:

# 这就是让你选一个文本编辑器,新手建议用默认的 nano,直接回车即可。

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

然后就会看到一大片的文本,不用管,那些只是注释(井号 # 开头的都是注释),写的是使用方法。

  • 如果你选的是 nano 编辑器,那么可以直接开始编辑了。
  • 如果你选的是 vim 编辑器,则需要按下 I 键 进入编辑模式。

定时任务格式其实很简单:

*    *   *    *   * cd /xxx && ./cfst_hosts.sh
-    -   -   -   -
|    |    |    |    |
|    |    |    |    +----- 星期中星期几 (0 - 7) (星期天 为0)
|    |    |    +---------- 月份 (1 - 12) 
|    |    +--------------- 一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59) 

还是看不懂?没关系,我直接给你几个示例(脚本下载):

# 假设脚本位于 /root/CloudflareST 目录下(其他位置自己改下面示例),那么:

# 每天凌晨 5 点 0 分,执行一次脚本
0 5 * * * cd /root/CloudflareST && ./cfst_hosts.sh

# 每天凌晨 5 点 30 分,执行一次脚本
30 5 * * * cd /root/CloudflareST && ./cfst_hosts.sh

# 每 6 个小时(0 分时),执行一次脚本
0 */6 * * * cd /root/CloudflareST && ./cfst_hosts.sh

# 每小时 0 分,执行一次脚本
0 * * * * cd /root/CloudflareST && ./cfst_hosts.sh

写入后,保存定时任务:

  • nano:按下 Ctrl+X 键、按下 Y 键、按下回车键,即可保存。
  • vim:按下 Esc 键退出编辑模式,直接输入 :wq 并回车(英文模式下),即可保存。

这时候再去查看定时任务,看看是否保存成功:

crontab -l

XIU2 avatar Jan 28 '21 04:01 XIU2

# Windows 脚本

你好,请问这个脚本测速是直连的情况下吧?比如我已经 用客户端上网后再运行该脚本,是不是会不准?据说直连的情况下最准,可不可以把它改成在服务器上测速,这样肯定是直连,比较准

mongoliabao555 avatar Jan 31 '21 14:01 mongoliabao555

@mongoliabao555

不是很明白你具体指的是什么?你说的客户端是什么? 另外,你不需要回复引用上面全部内容,这样会显得回答很长。。。不方便别人观看参考(我给你精简了一下)。

XIU2 avatar Jan 31 '21 14:01 XIU2

@mongoliabao555

如果要测试结果准确,必须在你的当前网络下进行测速(不管是在电脑还是路由器中运行)。 测速前要确保,CloudflareST 不会经过代理、VPN 网络,否则只能测速出代理服务器链接 CDN 的最快 IP。

你要得到的是你链接速度最快的 IP,而不是服务器链接速度最快的 IP。


一般而言,除非你是在路由器上配置了代理账号,否则代理软件是不会影响 CloudflareST 测速结果的。 至于 VPN,则根据路由表可能会影响 CloudflareST 测速结果,建议测速前关闭 VPN

XIU2 avatar Jan 31 '21 14:01 XIU2

@huanx9

默认不写入 Hosts ? 那你看这个 Issues 就行了。

XIU2 avatar Feb 01 '21 23:02 XIU2

你好, 感谢回复。 我实际是和Winxray结合起来用的,把每次测速的节点放到winxray上,让其测速挑出最快的运行。 那些节点并不失效,只是过了一段时间后速度下降了,时间并不确定,有时一周,有时只有一天,可以理解为动态吧。 我们有个群友他把badafans的测速脚本改了, 直接放到路由器里定时启动测速,并且定时杀进程以防测速没有结果 死循环。最后用微信推送测速结果。我在想如果你能把每次的结果写入winxray,或者是把新的IP与以往的速度做个 比较就更完美了,有时测速并不准确,速度 最快但是油管表现却差强人意。

发件人: XIU2 发送时间: 2021-02-02 07:47 收件人: XIU2/CloudflareSpeedTest 抄送: mongoliabao555; Mention 主题: Re: [XIU2/CloudflareSpeedTest] 自动更新 Hosts 为最快 IP(Windows/Linux 脚本) (#42) @huanx9 默认不写入 Hosts ? 那你看这个 Issues 就行了。 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

mongoliabao555 avatar Feb 02 '21 01:02 mongoliabao555

@mongoliabao555

我没用过 winxray,所以并不清楚,因此也不会去专门适配这些软件(或者说这不应该我来做)。


“把新的IP与以往的速度做个比较”

这个只要把新 IP 和旧 IP 单独写到一个文本文件 1.txt 中,例如:

1.1.1.1/32
1.0.0.1/32

然后再运行 CloudflareST 并加上 -f 1.txt 启动参数,测速结果中排在前面的就是更快的 IP。

IP 后面的 /32 是子网掩码,指的就是这个 IP 自身,因为软件目前只能读入 IP 段(带子网掩码)。

因为每次测速都是随机的 IP,所以每次测速结果也不可能一样,因此今天测速结果中最快的 IP 不一定比昨天的更好。 不过我也实测过,新旧两个 IP 测速对比,因为网络等各种因素影响,测速结果顺序也不是固定的


另外,虽然现在很多人拿 CloudflareST 来选择代理速度最快的 IP,但是我写这个软件的初衷只是简单的为了访问使用 Cloudflare CDN 的网站速度更快,自己改 Hosts 用的,只是后来用的人多了,我才发现大家的新用法。

因此,我不会去保证 CloudflareST 测速出来的 IP 用作代理会更快、看油管会更快。

XIU2 avatar Feb 02 '21 01:02 XIU2

exe文件运行后能否静默运行,不会弹出cmd窗口?

leozhangpd avatar Feb 05 '21 06:02 leozhangpd

@leozhangpd

我记得我写 bat 脚本的时候,查过能不能隐藏 CMD 窗口,但是似乎很麻烦,就没继续研究了...

批处理 bat 自身是无法实现的,似乎是需要依赖 vbs 脚本,而且始终会有黑窗口一闪而过...


至于直接运行程序自身,也只能用以上方法,因为 CloudflareST 是个控制台程序,因此无法自己隐藏自己,程序无法控制。

XIU2 avatar Feb 05 '21 06:02 XIU2

@leozhangpd

但是有个方法可以默认最小化运行 bat 脚本(只显示在任务栏)。

在 bat 文件头部 @echo off 下一行插入:if not "%~1"=="p" start /min cmd.exe /c %0 p&exit 保存即可。

插入代码后效果如下所示:

@echo off
if not "%~1"=="p" start /min cmd.exe /c %0 p&exit
Setlocal Enabledelayedexpansion
...

XIU2 avatar Feb 05 '21 06:02 XIU2

软路由openwrt里提示env: can't execute 'bash': No such file or directory

ljm1447669873 avatar Feb 11 '21 08:02 ljm1447669873

@ljm1447669873

查了下,这是因为你的 openwrt 系统中没有 Bash 这个 Shell 解释器。

XIU2 avatar Feb 11 '21 09:02 XIU2

@ljm1447669873

查了下,这是因为你的 openwrt 系统中没有 Bash 这个 Shell 解释器。

确实,opkg update && opkg install bash即可,忘记update了,还以为装不了

ljm1447669873 avatar Feb 11 '21 10:02 ljm1447669873

新年好!我是centos7,我碰到的问题是手动在服务器上执行bash没问题,可是在定时计划里就失败。opkg update && opkg install bash这个命令 我显示 -bash: opkg: command not found。

发件人: ljm1447669873 发送时间: 2021-02-11 18:15 收件人: XIU2/CloudflareSpeedTest 抄送: mongoliabao555; Mention 主题: Re: [XIU2/CloudflareSpeedTest] 自动更新 Hosts 为最快 IP(Windows/Linux 脚本) (#42) @ljm1447669873 查了下,这是因为你的 openwrt 系统中没有 Bash 这个 Shell 解释器。 确实,opkg update && opkg install bash即可,忘记update了,还以为装不了 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

mongoliabao555 avatar Feb 13 '21 13:02 mongoliabao555

@mongoliabao555

他那个是 openwrt 系统下缺少 Bash 时用的命令。

你的 CentOS 7 系统肯定不会缺少 Bash 的,所以不需要执行那个人用的命令。

XIU2 avatar Feb 13 '21 13:02 XIU2

大神您好。先膜拜撒花~~ 小白请教一下,比如,v2ray+ws+cdn的情况,如果手动搜索出一个CF的IP,可以填写到地址中去,伪装域名填写自己的域名。那么,配合此工具,用法是否是将“IP 自己的域名”写到hosts,v2ray客户端地址填自己的域名即可? 感谢解惑。

denniszzg avatar Mar 10 '21 07:03 denniszzg

@denniszzg

是的,软件上填写你的域名,Hosts 文件中把你的域名指向某个 Cloudflare CDN IP。 这样的话,软件在连接你的域名时,就会被强制解析为你指定的 Cloudflare CDN IP。

XIU2 avatar Mar 10 '21 08:03 XIU2

@XIU2

感谢解答。明白了。

另外,还有个疑惑,在 #66 这个帖子里,您分享了查看当前网站IP归属地的功能,我访问我的网站域名,解析出来的并不是我hosts里指向的IP,(ping域名返回的ip是正确的),那么,那个查看ip归属地功能返回的ip到底是什么呢?

denniszzg avatar Mar 10 '21 13:03 denniszzg

@denniszzg

这是正常的,因为你只是在电脑上 Hosts 文件中指向了自定义 IP,因此只有在你电脑上访问该域名才会被强制解析为自定义 IP。 那个帖子里写的方法,本质就是调用一个查 IP 的 API,而这个 API 是位于别人服务器上的,所以它们解析出来的都是默认的 IP。

修改 Hosts 文件的影响范围只有你的电脑,除你电脑外的设备去访问/解析该域名,得到的都是默认的 IP。

XIU2 avatar Mar 11 '21 04:03 XIU2

@XIU2 非常感谢。跟着大佬学知识了。尤其感谢您认真仔细的回复。赠人玫瑰,手有余香。

denniszzg avatar Mar 11 '21 11:03 denniszzg

感谢大佬,好久不来,出了这个超级工具。 补充,根据host域名进行写入win下的 批处理 比如:更新 best.ip.xray 的ip为最快的ip,然后再命令行启动xray工具

CD /d "C:\Windows\System32\drivers\etc"
echo.

echo 备份删除原有hosts记录
findstr /v "best.ip.xray" hosts>>hosts.bak
del hosts
ren hosts.bak hosts

echo 写入记录
@echo %bestip%  best.ip.xray>>hosts
echo 完成...
echo.
echo 开始运行xray代理 socks:127.0.0.1:2080 http:127.0.0.1:2081
 %~dp0\xray.exe -c  %~dp0\best.ip.xray.json

另外,批处理下如何更新CloudflareST.exe 和xray的二进制文件?

lost1984 avatar Apr 18 '21 14:04 lost1984

@lost1984 我对批处理(bat/cmd)也不熟,我更擅长 Linux Shell 脚本,当然原理都是一样的。

把当前软件版本写入一个文件,检查更新时就要去获取最新版本并对比,如果一致说明不需要更新,如果不一致说明需要更新,然后把最新版本号写入文件供下次对比,下载最新版本,解压、运行。

不过 Windows 下的批处理如果想要下载文件,还需要额外安装命令行工具,例如 curl 。

XIU2 avatar Apr 18 '21 23:04 XIU2

使用方法里有句话是这样的 “即你需要先去 C:\Windows\System32\drivers\etc\hosts 文件中将所有 Cloudflare CDN IP 统一改为一个 IP。” 问题是我的hosts文件里并没有Cloudflare CDN IP怎么办,不知道怎么改了 @XIU2

mrbin233 avatar Jun 28 '21 13:06 mrbin233

使用方法里有句话是这样的 “即你需要先去 C:\Windows\System32\drivers\etc\hosts 文件中将所有 Cloudflare CDN IP 统一改为一个 IP。” 问题是我的hosts文件里并没有Cloudflare CDN IP怎么办,不知道怎么改了 @XIU2

@mrbin233 Hosts 文件里没有 Cloudflare CDN IP 的话,你用这个脚本干嘛?。。。 这个脚本是用来在测速后修改 Hosts 文件中的 Cloudflare CDN IP 的。

XIU2 avatar Jun 29 '21 02:06 XIU2

大佬,我的在自动替换host成功了。关于定时我想问下,因为我的openwrt上代理一直是打开的,定时运行的时候,代理也没法关掉,这个怎么半呀。有什么办法让测速的时候,IP不走代理吗

uminoai avatar Jul 14 '21 16:07 uminoai

@uminoai 因为我没有 openwrt 设备,所以对你这种情况不熟悉,不过 openwrt 依然是基于 Linux 的,你可以理解为轻量化的 Linux 系统,所以你在 openwrt 管理面板上开启/关闭代理实际上就是执行了某条命令,你需要去找到这条命令是什么,然后在定时脚本中加上这两条命令即可(测速前关闭,测速后开启)。

XIU2 avatar Jul 15 '21 00:07 XIU2

# OpenWrt 下 PassWall 替换脚本

小白一个,OpenWrt 我用的 PassWall 刚才自己试了下修改可以替换。 先在 OpenWrt - 网络 - dhch/dns - 自定义挟持域名,添加对应的域名 IP 或者自定义 hosts 位置。 然后修改 cfst_hosts.sh 脚本(在脚本末尾添加几行代码即可)。

#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

#	项目: CloudflareSpeedTest 自动更新 Hosts
#	版本: 1.0.0
#	作者: XIU2
#	项目: https://github.com/XIU2/CloudflareSpeedTest

_CHECK() {
	while true
		do
		if [[ ! -e "nowip.txt" ]]; then
			echo -e "该脚本的作用为 CloudflareST 测速后获取最快 IP 并替换 Hosts 中的 Cloudflare CDN IP。\n使用前请先阅读:https://github.com/XIU2/CloudflareSpeedTest/issues/42#issuecomment-768273848"
			echo -e "第一次使用,请先将 Hosts 中所有 Cloudflare CDN IP 统一改为一个 IP。"
			read -e -p "输入该 Cloudflare CDN IP 并回车(后续不再需要该步骤):" NOWIP
			if [[ ! -z "${NOWIP}" ]]; then
				echo ${NOWIP} nowip.txt
				break
			else
				echo "该 IP 不能是空!"
			fi
		else
			break
		fi
	done
}

_UPDATE() {
	echo -e "开始测速..."
	NOWIP=$(head -1 nowip.txt)
	./CloudflareST
	BESTIP=$(sed -n "2,1p" result.csv | awk -F, '{print $1}')
	echo ${BESTIP} nowip.txt
	echo -e "\n旧 IP 为 ${NOWIP}\n新 IP 为 ${BESTIP}\n"

	echo "开始备份 Hosts 文件(hosts_backup)..."
	\cp -f /etc/config/dhcp /etc/config/dhcp_backup # 修改hosts的位置 这里就是dhcp/dns对应的劫持位置 也可以修改为自定义的hosts位置

	echo -e "开始替换..."
	sed -i 's/'${NOWIP}'/'${BESTIP}'/g' /etc/config/dhcp # 修改为对应的hosts位置
	echo -e "完成..."
}
/etc/init.d/passwall stop # 停止代理软件 ,password 可以替换成其他代理软件名字
_CHECK
_UPDATE
/etc/init.d/passwall start # 启动代理软件
#/etc/init.d/dnsmasq restart # 开启 passwall 后自动会重启 dnsmasq,如果运行完该脚本后 ping 对应域名不是刚刚替换的 IP 的话,可能需要再额外重启 dnsmasq 一下,去掉本行开头的井号 # 即可 

2021-08-07_15-18-41

avijxxx avatar Aug 07 '21 07:08 avijxxx

@avijxiong 看你排版比较乱,替你优化了下。 另外那个停止代理软件的命令,不需要放那么靠前,只需要放到 _CHECK 前面就行了。

XIU2 avatar Aug 07 '21 09:08 XIU2