🍀 借助 Github Actions 解决 Github DNS 污染问题

🍀 借助 Github Actions 解决 Github DNS 污染问题

技术博客 admin 493 浏览

前言

Github 国内问题

国内网络访问 Github 速度过慢的原因有许多,但其中最直接的原因是其 CDN 域名遭到 DNS 污染,导致我们无法连接使用 GitHub 的加速服务,因此访问速度缓慢或访问不了。

什么是 DNS 污染

DNS 污染,是指一些刻意或无意制造出来的数据包,把域名指向不正确的 IP 地址阻碍了网络访问。我们默认从目标网址的最近 CDN 节点获取内容,但当节点过远或 DNS 指向错误时,就会造成访问速度过慢或无法访问等问题。

有哪些解决方案?

  1. 使用 VPN 进行科学上网,当然大部分的 VPN 并不是免费的。
  2. 查找 Github 正确的 DNS IP,然后借助于 SwitchHosts 配置 Host。

方案

在之前的章节中,我们简单介绍了国内 Github DNS 问题以及解决方案。毫无疑问第一种方案是能有效解决大部分国内资源被墙的问题。但作为IT技术爱好者,我更喜欢尝试用第二种方案来解决 Github 问题。

初步验证

  1. 在一台已经科学上网的电脑上,通过 nslookup github.com 找出正确的 Github IP。

    bash
    复制代码
    nslookup github.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: github.com Address: 20.205.243.166
  2. 在另一台无法访问 Github 电脑上,通过 SwitchHosts 如下配置,终于可以正常访问。

相关问题

虽然我们已经通过实践验证了第二种方案的可行性,但仍然有不少的问题有待解决:

  1. 上述验证阶段,我们通过 nslookup github.com 获取的 DNS IP,但 Github 域名所解析的 DNS 是随着时间而不断变化的,那怎么解决呢?

    关于这一点,我们想到了 Github Actions, 借助于它,我们不仅可以正确解析 Github DNS IP, 我们还可以设置 cron 定期自动查询 (比如每2小时查询一次)。Perfect!

  2. 解决了 Github DNS IP 定期自动更新问题,那我们如何在自己的电脑上配置 Github Host, 难道每一次 DNS IP 的变更,都需要手动重新配置吗?

    其实并不需要这么麻烦,我可以借助于 SwitchHosts 这款软件的远程 Host 的配置来实现,同时它还可以帮我们定期同步远程的 Host。

  3. 还有一个比较棘手的问题,当我们借助于 Github Actions 定期生成 Github 正确的 Host 文件供 SwitchHosts 配置远程的 Host 时。如果当时 Github 本身相关域名不可访问,那本机的 SwitchHosts 又如何访问该域名下远程的 Host 文件呢?

    确实这一点,有点像鸡生蛋还是蛋生鸡的问题。怎么解决呢,我们打算借助大神提供的 Github Actions, 将 Github 生成 Host 的整个仓库,同步到 Gitee 上, 同时生成 Gitee Pages,以便 SwitchHosts 获取和配置远程的 Gitee 的 Github DNS Host 文件。

梳理思路

  1. 编写 ZX nslookup 查询 Github DNS,生成 host 文件 的脚本
  2. 编写 Github Workflow 定时执行,并创建 Github Pages 的配置
  3. 编写 Github Workflow 同步 Github git 仓库部署到 Gitee 的配置
  4. 编写 Github Workflow 创建 Gitee git 仓库 Gitee Pages 的配置
  5. 使用 本机 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 的配置

    yml
    复制代码
    name: 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 实现的

    yml
    复制代码
    name: 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 实现的

    yml
    复制代码
    name: 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
  • https://dns-host.gitee.io/github/host.txt (目前 Gitee 已暂停 Pages 服务)
  • 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

源文:🍀 借助 Github Actions 解决 Github DNS 污染问题

如有侵权请联系站点删除!

技术合作服务热线,欢迎来电咨询!