Open-source project
xingpingcn/enhanced-FaaS-in-China avatar
xingpingcn/enhanced-FaaS-in-China

enhanced-FaaS-in-China: swapping one CNAME record to fix mainland access

提升部署在cloudflare、vercel或netlify的网页在中国的访问速度和稳定性 cf优选域名 | cf优选ip | cloudflare | vercel | netlify | 加速 | 国内 | 中国 | 境内 | 大陆.

3,152 stars180 forksPythonMIT

At a glance

What is it?
A Python crawler measures edge addresses for Cloudflare, Vercel and Netlify and publishes them through three CNAME records. Using them means editing DNS by hand, and the failure modes are specific rather than general.
Who is it for?
Use enhanced-FaaS-in-China when your site already sits on Vercel, Netlify or Cloudflare, your visitors are on the Chinese mainland, and you are willing to edit DNS by hand. Leave it alone if the zone apex sits on a provider that forbids CNAMEs, if the zone has to stay on Cloudflare and the SaaS path is not open to you, or if you need numbers about your own origin rather than a chain of hops someone else runs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • xingpingcn/enhanced-FaaS-in-China3,152 ★ · +104
Star history
Repository2026-07-282026-11-13
xingpingcn/enhanced-FaaS-in-China3k3.2k

104 Stars in the last 108 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

One CNAME record is the whole install

There is no install step, no client library and no API here. The entire change happens at your authoritative DNS server: take the hostname your visitors actually type, for example `app.domain.com`, and replace its CNAME record with the one the project publishes for your host. Three hostnames are offered, one per platform: `vercel-cname.xingpingcn.top` for Vercel, `netlify-cname.xingpingcn.top` for Netlify, and `cf-cname.xingpingcn.top` for Cloudflare.

Vercel takes two passes. Point the record at the official hostname first, go back to the Vercel console, wait until the SSL certificate has been issued, and only then switch the record to `vercel-cname.xingpingcn.top`. Skipping that order is what takes most Vercel sites offline.

The written instructions exist only in Chinese, so an English reader gets the hostnames, the ordering rule and the failure warnings rather than a translated walkthrough.

Why the retired verlify hostname takes a site offline

`verlify-cname.xingpingcn.top` is deprecated, and issue 35 records the change. The reason matters if you inherited that record from an older tutorial: it resolved to addresses belonging to two platforms at once, so a request could hand the platform an address of the other one. The platform then concluded that the domain typed into its console was not yours, and refused to serve the site or issue a certificate for it. Once a certificate has been issued it stays cached at the platform, which is why the ordering rule (official hostname, wait for the certificate, then the project hostname) is also the repair path for a site that has already broken once.

For Netlify, `netlify_cert/readme.md` covers uploading your own certificate, and if that does not settle it the advice is to apply for a certificate that renews itself. A site that only misbehaves inside a speed test platform is a separate problem, and points at the measurement setup rather than at DNS.

A Cloudflare hosted zone can answer with 403

If your zone is served by Cloudflare, `cf-cname.xingpingcn.top` may answer with 403. The path given is to move the zone to a host that is not Cloudflare, Huawei Cloud is named as an example, delete the site from Cloudflare, and only then apply the CNAME. If Cloudflare hosting is not optional, as with a CF Worker or an orange cloud in front of a VPS origin, the project points you at Cloudflare's SaaS custom hostname feature instead, written up in `docs/how2use-SaaS-for-CF/how2use-SaaS-for-CF.md`.

Where the zone lives also changes the speed. Cloudflare DNS resolution is already slow inside the mainland, and a CNAME adds one more recursive lookup on top of it, so a zone on a domestic authoritative server avoids that cost. One documented failure is Huawei Cloud DNS reading mainland visitors as overseas users and handing back the default overseas route, `japan.com.` in the sample configuration, which puts the visitor on the slow path. Zone apex records are a separate constraint: Cloudflare and NS1.COM do not allow a CNAME at the apex, and issue 9 holds that discussion.

A crawler refreshes the addresses every 40 minutes

Behind the CNAMEs sits a scheduled job. It selects addresses for Cloudflare, Vercel and Netlify, tests them on a timer, and writes the stable, fast ones into the zone's A records. Domestic traffic gets per-carrier routes, while everything outside the mainland is pointed at the platform's own default address. Records refresh roughly every 40 minutes, and three files in the repository root, `Cf.json`, `Netlify.json` and `Vercel.json`, hold the values as they stand. Their sample output mixes address types, which matters before you copy anything, since the Vercel and Netlify entries are IPv4 addresses while the Cloudflare entry is a hostname with a trailing dot.

json
{
  "VERCEL": "76.76.21.21",
  "NETLIFY": "75.2.60.5",
  "CF": "japan.com."
}

Where the candidates come from is stated too: a community gist for Vercel plus the A records of the official `cname.vercel-dns.com.`, the links Netlify publishes, and preferred addresses collected from Cloudflare paying customers. You can skip the CNAME entirely and sync those files into your own A records.

Some routes fall back to the official default address

Not every line in those files carries a measured address. When the candidates for a route are of poor quality, resolution for that route is stopped and the official default address is served instead. An empty list in a JSON file means the same thing, so a blank entry is a quality decision rather than a broken sync.

Route based resolution itself comes from whatever features the authoritative DNS server offers, and those misclassify users. The answer offered is to pick a resolver with finer control: move to something like dnspod and enter the addresses from `Netlify.json` or `Vercel.json` as A records yourself, or use NS1.COM as the authoritative server and set routing by ASN. The ASN list the author maintains sits in a separate repository, xingpingcn/china-mainland-asn.

The stated goal is stability rather than a headline number: average response kept near one second, worst case around two seconds, and at most about two provinces returning a non-200 status, against an official hostname that is sometimes quick on average and unavailable in several provinces at once.

Running the crawler: python 3.11, two pinned packages, an external network

The crawler is plain Python on 3.11, and `requirements.txt` pins exactly two dependencies, both behind a `python_version>="3.11"` marker.

code
aiohttp==3.9.3;python_version>="3.11"
aiosqlite==0.20.0;python_version>="3.11"

The image starts from `python:3.11`, sets the work directory to `/bin/enhanced-faas`, installs the requirements file, and declares `CMD [ "test.py" ]`. No `test.py` sits among the top-level repository entries, and Compose replaces that command anyway.

yaml
    build:
      context: ./
    container_name: enhanced-faas
    volumes:
      - "./:/bin/enhanced-faas"
    expose:
      - 443,80
    command: ./main.py
    networks:
      - faas-proxy

Two lines in that file change how you run it. The bind mount puts your checkout over the image work directory, so the code that runs is the code on the host, and the network is declared external, which means Compose expects an existing `faas-proxy` network rather than creating one. Adding a platform such as render or railway is manual work: bring your own speed test tool and domain, rewrite `crawler.py`, add a module under `platforms_to_test` with a `run_sub()` method written along the lines of its neighbours, then edit the matching settings in `config.py`.

Reading the speed tests without fooling yourself

Measurement is where most of the warnings sit. Always include the scheme and compare several test sites, because the test sites fail on their own from time to time. Do not run tests against the project's own hostnames: probes from many places at once can make the platform read the traffic as a DDoS, and the false negative that follows says nothing about DNS resolution. Itdog.cn is reported to return large blocks of red for unknown reasons, with boce.com, cesu.net and the Aliyun dial test named as alternatives.

The blocking picture has narrowed. Earlier notes listed individual ISPs in Zhejiang, Fujian and Henan, and those were struck out in favour of a single city, Quanzhou, that now appears to be blocked. The official hostname shows the same symptom there, so the cause may be an ISP restriction and it tracks the domain being tested closely. Free second level domains such as eu.org and us.kg, and cheap suffixes like .xyz and .top, can fall into the same trap through carrier allowlists, and the only fix offered is a different domain. One more limit on the numbers: every published comparison used static pages on Cloudflare Pages, Vercel and Netlify, so none of it describes your origin.

Editorial conclusion

Use enhanced-FaaS-in-China when your site already sits on Vercel, Netlify or Cloudflare, your visitors are on the Chinese mainland, and you are willing to edit DNS by hand. Leave it alone if the zone apex sits on a provider that forbids CNAMEs, if the zone has to stay on Cloudflare and the SaaS path is not open to you, or if you need numbers about your own origin rather than a chain of hops someone else runs. Before switching anything, confirm the certificate is already issued on the platform, make sure the zone is on an authoritative server you can also read, and re-measure from several provinces on more than one test site, because one red cell in one tool means nothing.

Frequently asked questions

Which CNAME do I point a Vercel site at in enhanced-FaaS-in-China?

vercel-cname.xingpingcn.top, but only after the official hostname has been live long enough for Vercel to issue the SSL certificate. Switch too early and the platform sees an address that is not its own and refuses to serve the site.

Why does enhanced-FaaS-in-China return 403 when my DNS is hosted on Cloudflare?

A Cloudflare hosted zone is a known cause of 403 on this CNAME. Move the zone to a non Cloudflare host such as Huawei Cloud, delete the site from Cloudflare, then apply the record. If the zone must stay on Cloudflare for a Worker or an orange cloud origin, use the SaaS custom hostname guide instead.

Can I use my own addresses instead of the enhanced-FaaS-in-China CNAME?

Yes. Cf.json, Netlify.json and Vercel.json in the repository root carry the current addresses and are refreshed about every 40 minutes, so you can sync them into your own A records. An empty list in one of those files means that route was dropped for poor quality and is served the official default address.

How do I add another platform such as Render to enhanced-FaaS-in-China?

Bring your own speed test tool and a domain, then rewrite crawler.py, add a module inside platforms_to_test with a run_sub() method written like the others, and update the related settings in config.py. The repository ships with Cloudflare, Vercel and Netlify only.

Which DNS server should I pair with enhanced-FaaS-in-China?

A domestic authoritative server, because Cloudflare DNS resolves slowly inside the mainland and a CNAME adds another recursive lookup. Note the documented Huawei Cloud case where mainland visitors were read as overseas users and handed the default overseas route.

Official sources

  1. Official README
  2. Project repository
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/xingpingcn-enhanced-faas-in-china.svg)](https://hysenlabs.com/projects/xingpingcn-enhanced-faas-in-china)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/xingpingcn-enhanced-faas-in-china.svg)](https://hysenlabs.com/projects/xingpingcn-enhanced-faas-in-china)

Was this useful?