前言
Github 国内问题
国内网络访问 Github 速度过慢的原因有许多,但其中最直接的原因是其 CDN 域名遭到 DNS 污染,导致我们无法连接使用 GitHub 的加速服务,因此访问速度缓慢或访问不了。
什么是 DNS 污染
DNS 污染,是指一些刻意或无意制造出来的数据包,把域名指向不正确的 IP 地址阻碍了网络访问。我们默认从目标网址的最近 CDN 节点获取内容,但当节点过远或 DNS 指向错误时,就会造成访问速度过慢或无法访问等问题。
有哪些解决方案?
- 使用 VPN 进行科学上网,当然大部分的 VPN 并不是免费的。
- 查找 Github 正确的 DNS IP,然后借助于
SwitchHosts
配置 Host。
方案
在之前的章节中,我们简单介绍了国内 Github DNS 问题以及解决方案。毫无疑问第一种方案是能有效解决大部分国内资源被墙的问题。但作为IT技术爱好者,我更喜欢尝试用第二种方案来解决 Github 问题。
初步验证
-
在一台已经科学上网的电脑上,通过
nslookup github.com
找出正确的 Github IP。bashnslookup github.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: github.com Address: 20.205.243.166
-
在另一台无法访问 Github 电脑上,通过
SwitchHosts
如下配置,终于可以正常访问。
相关问题
虽然我们已经通过实践验证了第二种方案的可行性,但仍然有不少的问题有待解决:
-
上述验证阶段,我们通过
nslookup github.com
获取的 DNS IP,但 Github 域名所解析的 DNS 是随着时间而不断变化的,那怎么解决呢?关于这一点,我们想到了
Github Actions
, 借助于它,我们不仅可以正确解析 Github DNS IP, 我们还可以设置 cron 定期自动查询 (比如每2小时查询一次)。Perfect! -
解决了 Github DNS IP 定期自动更新问题,那我们如何在自己的电脑上配置 Github Host, 难道每一次 DNS IP 的变更,都需要手动重新配置吗?
其实并不需要这么麻烦,我可以借助于
SwitchHosts
这款软件的远程 Host 的配置来实现,同时它还可以帮我们定期同步远程的 Host。 -
还有一个比较棘手的问题,当我们借助于
Github Actions
定期生成 Github 正确的 Host 文件供SwitchHosts
配置远程的 Host 时。如果当时 Github 本身相关域名不可访问,那本机的SwitchHosts
又如何访问该域名下远程的 Host 文件呢?确实这一点,有点像鸡生蛋还是蛋生鸡的问题。怎么解决呢,我们打算借助大神提供的
Github Actions
, 将 Github 生成 Host 的整个仓库,同步到 Gitee 上, 同时生成 Gitee Pages,以便SwitchHosts
获取和配置远程的 Gitee 的 Github DNS Host 文件。
梳理思路
- 编写 ZX
nslookup
查询 Github DNS,生成 host 文件 的脚本 - 编写 Github
Workflow
定时执行,并创建 Github Pages 的配置 - 编写 Github
Workflow
同步 Github git 仓库部署到 Gitee 的配置 - 编写 Github
Workflow
创建 Gitee git 仓库 Gitee Pages 的配置 - 使用 本机
SwitchHost
配置远程 Github/Gitee DNS host,并设置定时刷新
实施
编写 ZX
脚本
-
执行
nslookup
查询 Github DNS,并将其生成 host 文件javascript#!/usr/bin/env zx const writer = async arr => { let temp = {} const list = [] for (const url of arr) { if (/^\.*\//.test(url)) { list.push(temp = { file: path.resolve(url), contents: [], content: '', }) continue } if (temp.contents) { temp.contents.push(url) } } for (const temp of list) { temp.content = await updater(temp.contents) } for (const temp of list) { fs.ensureFileSync(temp.file) fs.writeFile(temp.file, temp.content) } } const updater = async arr => { const templates = [] const datetime = new Date().toUTCString() templates.push(`# Update: ${datetime}\n`) for (const url of arr) { if (url) { const ip = await nslookup(url) const dns = `${ip}\t\t${url}` if (ip) { templates.push(dns) } } } templates.sort((next, prev) => { const nexts = next.split(/\s/) const prevs = prev.split(/\s/) return nexts[0].length < prevs[0].length ? -1 : 1 }) return templates.join('\n') } const nslookup = async url => { try { const regex = new RegExp(`.*Name:\\s*[\\S]+\\s*Address:\\s*([0-9.]+)\\s*.*`, 'ims') const dns = (await $`nslookup ${url}`).stdout const ip = dns.replace(regex, '$1') if (!/\d+\.\d+\.\d+\.\d+/.test(ip)) { return '' } if (ip === '127.0.0.1') { return '' } if (ip === '0.0.0.0') { return '' } if (ip) { return ip } } catch {} return '' } // Github 相关域名,仅摘录部分 writer([ './public/host.txt', 'github.blog', 'github.com', 'github.io', ... ])
-
host 文件范例
bash# Update: Sat, 18 May 2024 00:00:38 GMT 192.0.66.2 github.blog 140.82.116.4 github.com 185.199.111.153 github.io
配置 Workflow
-
编写 Github
Workflow
定时执行,并创建 Github Pages 的配置ymlname: update github dns ip on: schedule: - cron: '0 */2 * * *' # 每隔两小时自动执行 jobs: github-host: runs-on: ubuntu-latest # ubuntu 运行环境 steps: - name: Checkout uses: actions/checkout@v4 # 检出仓库 main 主分支 - name: Set pnpm uses: pnpm/action-setup@v3 # 安装 pnpm,版本 8 with: version: 8 - name: Set nodejs uses: actions/setup-node@v4 # 安装 node,版本 20 with: node-version: 20 registry-url: https://registry.npmjs.org/ cache: 'pnpm' - name: Install dependencies # 安装依赖 run: pnpm install - name: Building scripts # 运行构建,创建 public/host 文件 run: pnpm build - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v4 # 创建 Github Pages with: publish_dir: ./public user_name: ${{ secrets.MY_USER_NAME }} user_email: ${{ secrets.MY_USER_EMAIL }} github_token: ${{ secrets.GITHUB_TOKEN }}
-
编写 Github
Workflow
同步 Github git 仓库部署到 Gitee 的配置,主要借助于大神的 Yikun/hub-mirror-action@master 实现的ymlname: update github dns ip on: schedule: - cron: '0 */2 * * *' # 每隔两小时自动执行 jobs: push-gitee-repo: runs-on: ubuntu-latest needs: github-host steps: - name: Add And Push Gitee uses: Yikun/hub-mirror-action@master with: src: github/dns-host dst: gitee/dns-host dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} dst_token: ${{ secrets.GITEE_PERSONAL_TOKEN }} static_list: 'github' force_update: true account_type: org
-
编写 Github
Workflow
创建 Gitee git 仓库 Gitee Pages 的配置,主要借助于大神的 yanglbme/gitee-pages-action@main 实现的ymlname: update github dns ip on: schedule: - cron: '0 */2 * * *' # 每隔两小时自动执行 jobs: deploy-gitee-repo: runs-on: ubuntu-latest needs: push-gitee-repo steps: - name: Deploy Gitee Pages uses: yanglbme/gitee-pages-action@main with: gitee-username: ${{ secrets.GITEE_USERNAME }} gitee-password: ${{ secrets.GITEE_PASSWORD }} gitee-repo: dns-host/github branch: gh-pages
配置 SwitchHost
https://dns-host.github.io/github/host.txt
(目前 Gitee 已暂停 Pages 服务)https://dns-host.gitee.io/github/host.txt
https://gitee.com/dns-host/github/raw/gh-pages/host.txt
(推荐)
资源
Git repo
https://github.com/dns-host/github
https://gitee.com/dns-host/github
Git host
https://github.com/dns-host/github/blob/gh-pages/host.txt
https://gitee.com/dns-host/github/blob/gh-pages/host.txt
Git io
https://dns-host.github.io/github/host.txt
https://dns-host.gitee.io/github/host.txt