Pihole-style DNS ad blocking using Cloudflare Gateway Zero Trust, with a dedicated Allow rule that takes precedence over blocking.
For Devs, Ops, and everyone who hates Ads.
| Variable | Description | Example |
|---|---|---|
GITHUB_TOKEN |
Your GitHub Personal Access Token (Need Workflow permission and no expiration) | ghp_xxxxxxxxxxxx |
GITHUB_USER |
Your GitHub username | luxysiv |
GITHUB_REPO |
The name of your repository | Cloudflare-Gateway-DNS-Filter |
WORKFLOW_ID |
The filename of your workflow | main.yml |
-
Opt for a private repository when deploying.
-
Once deployment is complete, you may remove the cloned repository.
This script manages two sets of Cloudflare Gateway DNS rules in a single workflow run:
| Rule | Action | Precedence | Source |
|---|---|---|---|
[AdBlock-DNS-Filters] Block Ads |
block | 1000 | adlist.ini + dynamic_blacklist.txt |
[AdAllow-DNS-Filters] Allow |
allow | 999 (higher priority) | whitelist.ini + dynamic_whitelist.txt |
Because the Allow rule has a lower precedence number (999 < 1000), Cloudflare evaluates it first — so whitelisted domains are always resolved even if they appear in a blocklist. There is no need to subtract the whitelist from the block list in code.
The script also enforces Cloudflare Gateway's free tier limit of 300 lists across both rules combined. If your sources would require more than 300 lists, the script stops before making any changes.
-
Account ID — found in the URL after
https://dash.cloudflare.com/:https://dash.cloudflare.com/?to=/:account/workers -
API Token — create at
https://dash.cloudflare.com/profile/api-tokenswith these 3 permissions:Account › Zero Trust : EditAccount › Account Firewall Access Rules : EditAccount › Access: Apps and Policies : Edit
Go to https://github.com/<username>/Cloudflare-Gateway-DNS-Filter/settings/secrets/actions and add:
| Secret | Value |
|---|---|
CF_API_TOKEN |
Your Cloudflare API Token |
CF_IDENTIFIER |
Your Cloudflare Account ID |
Block list — edit lists/adlist.ini:
[Ad-Urls]
Adguard = https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txtAllow list — edit lists/whitelist.ini:
[Allow-Urls]
MyAllow = https://example.com/my-whitelist.txtBoth files accept plain URLs (one per line) or the [Section] key = url INI format.
Go to https://github.com/<username>/Cloudflare-Gateway-DNS-Filter/settings/variables/actions and add:
| Name | Value |
|---|---|
ADLIST_URLS |
Space-separated block list URLs |
WHITELIST_URLS |
Space-separated allow list URLs |
DYNAMIC_BLACKLIST |
Extra domains to block (one per line) |
DYNAMIC_WHITELIST |
Extra domains to allow (one per line) |
- You should add your ad list and whitelist to Action variables. If you update your fork, your custom list will not be lost.
# Plain URL
https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
# INI format
[Ad-Urls]
Adguard = https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txtSupported domain list styles: hosts files, AdBlock/uBlock syntax, plain domain lists.
Note: Use DNS filter lists, not browser extension filter lists. Browser lists contain cosmetic rules that cause errors when used as DNS blocklists.
To use this tool on the GOAT Termux, follow the steps below. If you are already familiar with setting up Python and the basics, you can skip this section.
- Open Termux and run the following commands one by one:
yes | pkg upgrade
yes | pkg install python-pip
yes | pkg install git
git clone https://github.com/<username>/Cloudflare-Gateway-DNS-Filter.git- Navigate to the cloned repository folder:
cd Cloudflare-Gateway-DNS-Filter- Edit the
.envfile (required):
nano .envAfter editing, press CTRL + X, then Y, and ENTER to save the file.
- Run the command to upload (update) your DNS list:
python -m src run- Run the command to delete your DNS list:
python -m src leave-
Download the ZIP file of the repository from the 'Code' button on the GitHub page and select 'Download ZIP'.
-
Unzip the downloaded file.
-
Edit the values in
.env,lists/adlist.ini,lists/whitelist.inietc... -
Open Termux and enter the following commands to set up Python and necessary tools:
yes | pkg upgrade
yes | pkg install python-pip
termux-setup-storage-
Allow Termux to access storage.
-
Navigate to the folder containing the unzipped source code:
cd storage/downloads/Cloudflare-Gateway-DNS-Filter-main- Run the command to upload (update) your DNS list:
python -m src run- Run the command to delete your DNS list:
python -m src leaveIf you encounter issues during setup, you can refer to termux-change-repo for changing Termux repositories.
-
The limit of
Cloudflare Gateway Zero Trustfree is 300 lists (block + allow combined), with 1,000 domains per list — up to 300,000 domains total. The script stops automatically if this limit would be exceeded. -
If you have uploaded lists using another script, you should delete them using the delete feature of that script or delete them manually.
-
To delete all lists and rules created by this script, go to main.yml and change the command:
- name: Cloudflare Gateway Zero Trust
run: python -m src leaveThanks a lot to @nhubaotruong for his contributions.
Readme by @minlaxz.