中国大陆 GitHub被墙 ,使用 Cloudflare Worker加速GitHub站点,实现国内加速访问

近期教程:Docker hub 被墙替代方案 / 在中国大陆通过Cloudflare Workers代理访问Docker Hub

前几天写的 dockerhub镜像加速教程,流量还挺不错的。这里再整理下镜像加速 github

Cloudflare Worker 简介

Cloudflare Worker 是 Cloudflare 公司提供的一项服务,它允许开发者在 Cloudflare 的边缘服务器上运行自定义的 JavaScript 代码。通俗地说,它就像是一个小型的服务器,可以在互联网上的不同地点快速执行你编写的代码。Cloudflare free计划每天可以免费调用 worker 10 万次,对于小网站和普通人足够使用了。

Cloudflare Worker 简介

Cloudflare Worker 的主要用途包括网站加速和优化、路由请求、访问控制、CDN 功能增强、网站镜像与路由转发等。

本文将使用其网站镜像和路由转发,实现 GitHub 站点的镜像,实现自有域名在墙内的访问github。

Cloudflare Worker镜像加速 GitHub 站点过程如下:

1、创建 Worker

首先登录 cloudflare(如果是英文界面右上角可以切换到简体中文),点击左侧菜单 Workers & Pages,然后在右侧点击创建 Worker

使用 Cloudflare Worker 镜像加速 GitHub 站点
使用 Cloudflare Worker 镜像加速 GitHub 站点
使用 Cloudflare Worker 镜像加速 GitHub 站点

2、部署 worker

2.1、右上角点击编辑代码

使用 Cloudflare Worker 镜像加速 GitHub 站点

2.2、复制下面 js代码到 worker中

// 你要镜像的网站.
const upstream = 'github.com'

// 镜像网站的目录,比如你想镜像某个网站的二级目录则填写二级目录的目录名,镜像 google 用不到,默认即可.
const upstream_path = '/'

// 镜像站是否有手机访问专用网址,没有则填一样的.
const upstream_mobile = 'github.com'

// 屏蔽国家和地区.
const blocked_region = ['KP', 'SY', 'PK', 'CU']

// 屏蔽 IP 地址.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

// 镜像站是否开启 HTTPS.
const https = true

// 文本替换.
const replace_dict = {'$upstream': '$custom_domain', '//github.com': ''}

// 以下保持默认,不要动
addEventListener('fetch', event => {
  event.respondWith(fetchAndApply(event.request))
})

async function fetchAndApply(request) {
  const region = request.headers.get('cf-ipcountry').toUpperCase()
  const ip_address = request.headers.get('cf-connecting-ip')
  const user_agent = request.headers.get('user-agent')

  let response = null
  let url = new URL(request.url)
  let url_hostname = url.hostname

  if (https == true) {
    url.protocol = 'https:'
  } else {
    url.protocol = 'http:'
  }

  if (await device_status(user_agent)) {
    var upstream_domain = upstream
  } else {
    var upstream_domain = upstream_mobile
  }

  url.host = upstream_domain
  if (url.pathname == '/') {
    url.pathname = upstream_path
  } else {
    url.pathname = upstream_path + url.pathname
  }

  if (blocked_region.includes(region)) {
    response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
      status: 403
    })
  } else if (blocked_ip_address.includes(ip_address)) {
    response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
      status: 403
    })
  } else {
    let method = request.method
    let request_headers = request.headers
    let new_request_headers = new Headers(request_headers)

    new_request_headers.set('Host', url.hostname)
    new_request_headers.set('Referer', url.hostname)

    let original_response = await fetch(url.href, {
            method: method,
            headers: new_request_headers
    })

    let original_response_clone = original_response.clone()
    let original_text = null
    let response_headers = original_response.headers
    let new_response_headers = new Headers(response_headers)
    let status = original_response.status

    new_response_headers.set('access-control-allow-origin', '*')
    new_response_headers.set('access-control-allow-credentials', true)
    new_response_headers.delete('content-security-policy')
    new_response_headers.delete('content-security-policy-report-only')
    new_response_headers.delete('clear-site-data')
    
    const content_type = new_response_headers.get('content-type')
    if (content_type.includes('text/html') && content_type.includes('UTF-8')) {
      original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname)
    } else {
      original_text = original_response_clone.body
    }

    response = new Response(original_text, {
      status,
      headers: new_response_headers
    })
  }
  return response
}

async function replace_response_text(response, upstream_domain, host_name) {
  let text = await response.text()

  var i, j
  for (i in replace_dict) {
    j = replace_dict[i]

    if (i == '$upstream') {
      i = upstream_domain
    } else if (i == '$custom_domain') {
      i = host_name
    }

    if (j == '$upstream') {
      j = upstream_domain
    } else if (j == '$custom_domain') {
      j = host_name
    }

    let re = new RegExp(i, 'g')
    text = text.replace(re, j)
  }
  return text
}

async function device_status(user_agent_info) {
  var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]
  var flag = true
  for (var v = 0; v < agents.length; v++) {
    if (user_agent_info.indexOf(agents[v]) > 0) {
      flag = false
      break
    }
  }
  return flag
}

2.3、删除默认代码之后,将复制的 js代码进行粘贴,最后点击部署即可。

使用 Cloudflare Worker 镜像加速 GitHub 站点

此时可以通过 https://github.xxxx.workers.dev/访问,但需要翻墙,因为 worker.dev dns被污染了。我们绑定一个自定义域名。如我这里添加一个 github二级域名

3、绑定自定义域名

3.1、左侧菜单点击DNS,然后点击添加记录,添加类型为: CNAME,名称: github,目标:git hub.xxx.workers.dev(将 xxx替换为你的地址),最后保存

注意:代理状态一定要代开

使用 Cloudflare Worker 镜像加速 GitHub 站点

此时还打不开,需要将github.zhpengfei.com的所有请求都指向我新建的github worker上。

3.2、添加路由

使用 Cloudflare Worker加速GitHub站点
使用 Cloudflare Worker 镜像加速 GitHub 站点
使用 Cloudflare Worker 镜像加速 GitHub 站点

4、测试镜像站点

关闭科学上网,浏览器打开https://github.zhpengfei.com/ 并搜索 chatgpt,如下图所示,速度很快。

使用 Cloudflare Worker 镜像加速 GitHub 站点

从 github下载开源 软件很快。

使用 Cloudflare Worker加速GitHub站点

查看下载地址确实是自定义域名

使用 Cloudflare Worker加速GitHub站点

我这里只是为了给大家演示,演示完已经停止了github.zhpengfei.com的 DNS解析,请大家自备一个域名哈

备注:DNS添加 CNAME后,再添加路由,如果有多个域名托管在 cloudlfare上,可以共享这个worker

Comments

No comments yet. Why don’t you start the discussion?

发表评论