banner
MACSITE

@MACSITE

兴趣是学习的动力,学习也能成为消遣!--你愁啥-ncs.fun

Create a "mirror site" using Cloudflare

Can be used for indirect access to some websites that cannot be opened, such as Github.

Instructions#

This project uses the free service workers from Cloudflare, a generous and selfless cloud service provider.

By following this tutorial, you can set up your own mirror site for Github to resolve access issues in certain situations.

Note: Please comply with local laws and regulations, respect intellectual property rights, and maintain a clear online environment. Everyone is responsible.

About Cloudflare (skip if already registered)#

Introduction#

Note: Cloudflare has an official Chinese version, and you can select the language in the upper right corner of the interface.

Cloudflare is a conscientious CDN acceleration service provider from abroad, and their services are constantly expanding. Notably, all their services are free, and the free limits are very high. For example, the CDN is completely free with no traffic limits. Additionally, using their DNS does not pose any record-keeping issues.

I previously registered several free domains with Freenom, initially hosted on DNSPod, but now all have been transferred to Cloudflare. Here, I will briefly explain how to use their free domain service. ~~As for services like workers, which are more complex (flexible), it will rely on everyone's exploration.~~ By the way, I will also mention workers and pages.

After registering on the official website, you will be redirected to https://dash.cloudflare.com/, and the following steps will be done in the console.

Enable Workers#

Workers can be understood as a serverless platform from Cloudflare, and one of its major advantages is that it comes with CDN. According to the official statement:

Build serverless applications and deploy them globally in an instant for superior performance, reliability, and scalability.

You can find workers on the left side of the control panel homepage.

image

As shown in the image, you can create services in the middle, and the daily quota is displayed on the right. If you are just setting up personal services, these quotas are more than enough. Below will display all the services that have been set up.

image

The service creation interface only requires a slight configuration of the service name, as it will involve the link for future access:

image

Now our service is set up. But how do we edit the code? Wait for the deployment to complete, then go to the control interface, where you can find a quick edit button in the lower right corner.

image

Here you can submit modifications to the code. Regarding the Worker code configuration, I looked at the documentation and found it a bit complex; it is still based on javascript. It is recommended to use existing code examples. Modify the code on the left, deploy it below, and on the right, you can choose the preview window and open the link.

Generally, we just open this window, copy the code into it, save and deploy, and then directly access the link.

image

Code#

Originally set for Google, I changed it to Github. Just copy and paste everything into worker.

// The website you want to mirror.
const upstream = 'www.github.com'

// The directory of the mirrored website. For example, if you want to mirror a secondary directory of a certain website, fill in the name of the secondary directory. No need to specify for mirroring Google; the default is fine.
const upstream_path = '/'

// Whether the mirror site has a dedicated mobile access URL; if not, fill in the same.
const upstream_mobile = 'www.github.com'

// Blocked countries and regions.
const blocked_region = ['KP', 'SY', 'PK', 'CU']

// Blocked IP addresses.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

// Whether the mirror site has HTTPS enabled.
const https = true

// Text replacement.
const replace_dict = {
    '$upstream': '$custom_domain',
    '//github.com': ''
}

// Keep the following defaults; do not modify.
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;
}

Effect#

Google can no longer be opened, showing an error (it's normal to be overloaded).

image

However, Github is still accessible:

image

DEMO: GitHub: Where the world builds software · GitHub (kermshare.workers.dev)

You can download, and the download link has also been replaced with the workers address, which is quite fast.

https://kermgithub.kermshare.workers.dev/Fndroid/clash_for_windows_pkg/releases/download/0.19.1/Clash.for.Windows.Setup.0.19.1.exe

image

About the pollution of .kermshare.workers.dev, adding a custom domain to resolve#

Add the required subdomains to Cloudflare's DNS records#

The name can be based on personal preference, and the IP can be anything as long as it is not 1.1.1.1 (some free domains cannot set these special IPs). The main thing is to enable "proxy status," so that cloud is orange.

image

Add routes to workers#

  1. Click to add a route.

image

  1. Fill in the subdomain you just set in the route, for example, api-cf.baidu.cf/*, select the workers you need to set the custom domain for, and choose the environment you need.

image

Note that the format in the image is: domain/*
3. Then you're done, and you can use api-cf.baidu.cf to replace your original workers' default domain in the future.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.