This is free, open source RethinkDNS serverless DoH and DoT resolvers with custom blocklists that can be hosted on cloudflare, fly.io and deno-deploy. This initiative is to provide first level of anti-censorship and data privacy to every person on the earth.
Difficulty: Easy
Supports DoH resolver only
-
- Once the hosting is successful, lets consider rethink serverless dns is hosted
to
example.com
. - To configure your dns level blocking visit to
example.com/configure
which will take to configuration page, which currently contains 171 blocklists with 5 Million too block domains in category like notracking, dating, gambling, privacy, porn, cryptojacking, security ... - Navigate through and select your blocklists.
- Once selected you can find your domain name
example.com
followed by configuration token on screen like thishttps://example.com/1:AIAA7g==
copy it and add to your dns DOH client. - Now your own trusted dns resolver with custom blocking is up and running.
- Once the hosting is successful, lets consider rethink serverless dns is hosted
to
-
- By default dns request are resolved by cloudflare
cloudflare-dns.com
. - To change resolver login to your cloudflare dash board
- click on
worker
- click on
serverless-dns
worker - click on
Settings
tab - under
Environment Variables
click onEdit variables
- if your new DOH resolver url is
example.dns.resolver.com/dns-query/resolve
- change below variables and click on save button
CF_DNS_RESOLVER_URL = example.dns.resolver.com/dns-query/resolve
- click on
- By default dns request are resolved by cloudflare
Difficulty: Moderate
Supports DoH resolver only
User will be liable for fly.io billing
- Fork this repository (You will need a GitHub account).
- In your fork, click on the Actions tab and Confirm that you want to use Actions, if asked.
- Click on "🦕 Deno deploy" on the left pane. Click on the "Run workflow" dropdown on the right side, and run the workflow using the Run workflow button.
- Now, navigate to deno.com/deploy and Sign Up for an account.
- Create a new project in deno deploy dash. Name it appropriately.
- Click on "Continue" button under "Deploy from GitHub" and proceed to install the GitHub app on your GitHub Account. Make sure you give access the fork you had made in step 1.
- Now, head back the deno dash and select the repository as the fork you had made in step 1 for integration. And branch as "build/deno-deploy/dev". And select the file as "http.bundle.js".
- In this deno project, navigate to Settings -> Environment variables. Add the essential environment variables as described
.env.example
file. Values of the required variables can be inferred fromwrangler.toml
andfly.toml
files. - Done. Now your DoH resolver should be available on
https://<name>.deno.dev
, where<name>
is the name of the project you had created on step 5.
Difficulty: Hard
Supports both DoH and DoT resolver
User will be liable for fly.io billing
- Install
flyctl
on your device. Please refer to fly.io docs for the same. - Signup or Login to fly.io. Please refer to fly.io docs for the same.
- Create an empty directory anywhere on your PC. Open you terminal or powershell and navigate to this directory.
- Launch a fly app
flyctl launch
- Choose a unique name here or let it auto-generate.
- Choose a location (closest to you would be better for you to use).
- Note down the name of the app and you may delete this directory along with the generated
fly.toml
.
- Now, you would need a SSL or TLS certificate for your domain name. Both getting a domain name and CA certificate generation are beyond the scope of this README.
- Once you have your CA certificate and key files, you need to encode them as base64 with no wrapping. How this can be done in bash terminal is shown below.
# Locate your CA certificate & key files CRT="path/to/full-chain-certificate.pem" KEY="path/to/key.pem"
# Encode them in base64 with no wrappings and store them in variables B64NOWRAP_KEY="$(base64 -w0 "$KEY")" B64NOWRAP_CRT="$(base64 -w0 "$CRT")"
- As described in
.env.example
file, this base64 encoded certificate-key pair need to set as a single environment variable calledTLS_
. Within this variable, the certificate and key encodings needs to be separated by a newline (\n
) and described byCRT=
andKEY=
. On a bash terminal this can be done by following steps continued by by above.# This creates a single file called "FLY_TLS" in the current directory echo "KEY=$B64NOWRAP_KEY" > FLY_TLS echo "CRT=$B64NOWRAP_CRT" >> FLY_TLS # And now, this "FLY_TLS" file contains both certificate and key encoded and # as required
- Upload this to fly secrets like so in terminal or powershell:
where "app-id" is the name of the fly app you had launched in step 4.
fly secrets set TLS_=- < FLY_TLS -a app-id
- Other essential environment variables are already present in
fly.toml
file of this repository, but you may read.env.example
for it's use case and configuration.
- Upload this to fly secrets like so in terminal or powershell:
- Fork this repository (You will need a GitHub account).
- In your fork, click on the Actions tab and Confirm that you want to use Actions, if asked.
- Similarly, click on Settings tab and select Secrets on the left pane. Add a new GitHub secret called FLY_APP_NAME and set it's value as the name of the fly app you had launched in step 4. And add another secret called FLY_API_TOKEN and set's value as what you get from running
flyctl auth token
in terminal or powershell. - Head back to Actions tab and click on "🪰 Fly" on the left pane. Click on the "Run workflow" dropdown on the right side, and run the workflow using the Run workflow button.
- Once this action workflow finishes, open the terminal or powershell again and type in:
flyctl ips list -a [app-id]
- Here, you can get the IP address of the application, update the DNS records of your domain name you had used in step 5.
- Done. Your application should be available on the said domain name in a few minutes. To configure, say, to change the upstream resolver, you can edit the environment variables on
fly.toml
file of your fork and re-run the Action workflow.
Run:
deno run --allow-net --allow-env --allow-read --import-map=import_map.json http.ts
List of environment variables can be found in .env.example
file. Load them as required. For convenience, you can also put them in a .env
file and they will also be loaded into the environment.
Run:
node server.js
Proxies DNS over HTTPS & DNS over TLS requests to the main app (index.js
).
List of environment variables can be found in .env.example
file. Load them as required. For convenience in non-production environment, you
can also put them in a .env
file and they will be loaded into the environment
if not already present.
The flow of rethink dns is based on plugin module, current plugin flow is as below. Five plugins are currently loaded.
- CommandControl
This is optional plugin used to provide command to rethink serverless dns using GET request. - UserOperation
This plugin loads current user details if not found in cache.
e.g. dns resolvegoogle.com
request to rethink serverless cloudflare resolverhttps://example.com/1:AIAA7g==
, configuration string1:AIAA7g==
is treated as user id and loads selected blocklists files for configuration string and cache it under user id. - DNSBlock
This is optional plugin used to check whether requested domain should be blocked or processed further. - DNSResolver
This plugin forward dns request to upstream resolver based on environment variableCF_DNS_RESOLVER_URL
if not blocked by DNSBlock plugin. - DNSCnameBlock
This is optional plugin used to check whether dns resolved response contains cname and cname has blocked domain name, if cname has blocked domain name then request is blocked.
Custom plugins can be developed by adding following function to class
export class CustomPlugin {
constructor() {
}
async RethinkModule(param) {
let response = {};
response.isException = false;
response.exceptionStack = "";
response.exceptionFrom = "";
response.data = {};
try {
} catch (e) {
response.isException = true;
response.exceptionStack = e.stack;
response.exceptionFrom = "CustomPlugin RethinkModule";
}
return response;
}
}
RethinkModule(param)
is entry point for every plugin.- Inside
RethinkModule
method your custom logic can be build for your rethink serverless dns. - example if published to npm as
@your-plugin/plugin
- add your plugin to rethink serverless dns at plugin.js
/**
* Import and Initialize plugins
*/
import { CustomPlugin } from "@your-plugin/plugin";
const customPlugin = new CustomPlugin();
// Start RethinkPlugin constructor
/**
* Here, register the plugins that should run before custom plugin if any.
* So as if any of it's output is available to the next plugin. For example,
* "userBlocklistInfo" is the output of "userOperation" plugin and is only
* available after it's run.
*/
/**
* custom plugin registration
*/
this.registerPlugin(
"customPlugin",
customPlugin,
["event", "userBlocklistInfo", "dnsResolverResponse"],
customCallBack,
false,
);
/**
* Here, register the plugins that should run after custom plugin if any.
*/
// End RethinkPlugin constructor
/**
* custom plugin call back after execution
*/
function customCallBack(response, currentRequest) {
if (response.isException) {
loadException(response, currentRequest);
} else if (response.data.decision) {
currentRequest.stopProcessing = true;
} else {
// "customResponse" param can be registered and passed onto next plugin
this.registerParameter("customResponse", response.data);
}
}
this.registerPlugin(Plugin_Name, Plugin_Object , [Parameters_to_Plugin], Plugin_Callback_Function, Plugin_Execution_After_StopProcessing)
Plugin_Name
- string denotes name of the plugin.Plugin_Object
- object of plugin class, which implements RethinkModule function within class.Parameters_to_Plugin
- list of parameters passed to RethinkModule function.Plugin_Callback_Function
- function that will be called back after plugin execution with plugin response and current request object.Plugin_Execution_After_StopProcessing
- boolean indicates the plugin execution status after currentRequest.stopProcessing is set.
- In the example snippet above, three parameters are passed to custom rethink
module
event
parameter passed by workeruserBlocklistInfo
is output of userOperation plugindnsResolverResponse
is output of dnsResolver plugin
- Once plugin execution is done
customCallBack
function is initiated with pluginresponse
andcurrentRequest
. - Inside the plugin call-back based on the plugin response dns process can be
stopped or moved further by saving response
this.registerParameter("parameter-name", parameter data)
. - By setting
currentRequest.stopProcessing = true
, no further plugin will be executed except if Plugin Execution After StopProcessing is set to true. - Publish to cloudflare with updated plugin which will reflect to all your pointed devices.