{"id":20515027,"url":"https://github.com/junkurihara/doh-auth-proxy","last_synced_at":"2025-04-14T00:16:12.697Z","repository":{"id":40415001,"uuid":"385593139","full_name":"junkurihara/doh-auth-proxy","owner":"junkurihara","description":"Local DNS proxy for DNS over HTTPS (DoH), Oblivious DoH (ODoH) and Multiple-relay-based ODoH extension (Mutualized ODoH; MODoH), which additionally supports domain-based filtering and proxy/resolver authentication","archived":false,"fork":false,"pushed_at":"2025-03-23T00:42:03.000Z","size":1106,"stargazers_count":32,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2025-04-14T00:16:00.233Z","etag":null,"topics":["ad-blocking","anonymization","dns","dns-over-https","dns-privacy","dns-proxy","doh","domain-blocker","domain-filtering","mutualized-odoh","oblivious-doh","odoh","privacy","rust"],"latest_commit_sha":null,"homepage":"https://junkurihara.github.io/dns","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/junkurihara.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"junkurihara"}},"created_at":"2021-07-13T12:17:33.000Z","updated_at":"2025-03-23T00:42:07.000Z","dependencies_parsed_at":"2023-02-17T03:00:49.906Z","dependency_job_id":"b798dfa4-aab3-4786-ae60-572c5ac58e0a","html_url":"https://github.com/junkurihara/doh-auth-proxy","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkurihara%2Fdoh-auth-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkurihara%2Fdoh-auth-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkurihara%2Fdoh-auth-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkurihara%2Fdoh-auth-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/junkurihara","download_url":"https://codeload.github.com/junkurihara/doh-auth-proxy/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799952,"owners_count":21163404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ad-blocking","anonymization","dns","dns-over-https","dns-privacy","dns-proxy","doh","domain-blocker","domain-filtering","mutualized-odoh","oblivious-doh","odoh","privacy","rust"],"created_at":"2024-11-15T21:19:20.500Z","updated_at":"2025-04-14T00:16:12.673Z","avatar_url":"https://github.com/junkurihara.png","language":"Rust","funding_links":["https://github.com/sponsors/junkurihara"],"categories":[],"sub_categories":[],"readme":"# doh-auth-proxy\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n![Unit Test](https://github.com/junkurihara/doh-auth-proxy/actions/workflows/test.yml/badge.svg)\n![Build and Publish Docker](https://github.com/junkurihara/doh-auth-proxy/actions/workflows/release-docker.yml/badge.svg)\n![ShiftLeft Scan](https://github.com/junkurihara/doh-auth-proxy/actions/workflows/shiftleft-analysis.yml/badge.svg)\n[![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/jqtype/doh-auth-proxy)](https://hub.docker.com/r/jqtype/doh-auth-proxy)\n\nLocal proxy for DoH, Oblivious DoH and ODoH-based Mutualized Oblivious DNS (ODoH-based \u0026mu;ODNS; \u0026mu;ODoH) supporting super-fast domain-based blocking and authenticated connection, written in Rust.\n\n\u003e **For the detailed information on \u0026mu;ODNS, please also refer to [https://junkurihara.github.io/dns/](https://junkurihara.github.io/dns/).**\n\n## Introduction\n\n*DNS over HTTPS* (DoH) is an encrypted DNS protocol in which DNS queries and responses are exchanged with the target full-service resolver via HTTPS, i.e., over an encrypted-secure channel ([RFC8484](https://datatracker.ietf.org/doc/rfc8484)). To enhance the privacy of DoH, *Oblivious DNS over HTTPS* (ODoH) has been developed  ([RFC9230](https://datatracker.ietf.org/doc/rfc9230/)). ODoH leverages an intermediate *relay* (or *proxy*) and an end-to-end encryption ([HPKE](https://datatracker.ietf.org/doc/rfc9180/)) in order to decouple the client's IP address and content of his queries. *Mutualized Oblivious DNS over HTTPS* (\u0026mu;ODoH) is an extension of ODoH, which has been (is still being) developed from the concern of the collusion between the relay and the target resolver and corruption of the client's privacy ([Resource](https://junkurihara.github.io/dns/)). To this end, \u0026mu;ODNS leverages multiple relays towards the target resolver, where relays are selected in a random fashion and employed in a distributed manner.\n\n`doh-auth-proxy` is client software that translates the standard DNS over port 53 (Do53) protocol to these three encrypted and privacy-enhanced DNS protocols. In other words, `doh-auth-proxy` protects the plaintext Do53 queries from being eavesdropped by encryption.\n\n### Network structure of \u0026mu;ODoH\n\nHere is an example of the network architecture of \u0026mu;ODoH.\n\n![\u0026mu;ODoH Network Structure](./assets/modoh-structure.jpg)\n\nThe \u0026mu;ODoH network consists of \u0026mu;ODoH client ([`doh-auth-proxy`](https://github.com/junkurihara/doh-auth-proxy)), \u0026mu;ODoH relay and target servers([`modoh-server`](https://github.com/junkurihara/modoh-server)), and supplementary authentication server ([`rust-token-server`](https://github.com/junkurihara/rust-token-server)). Note that when there exist two `modoh-server`, i.e., single relay and single target available, it exactly coincides with ODoH.\n\n`doh-auth-proxy` and `modoh-server` supplementary provide access control function for queries, i.e., client authentication. In this mechanism, client queries are authenticated by Bearer token in their HTTP header (based on Open ID Connect ID token or Anonymous Token using blind RSA signatures). Note that to enable this client authentication, the `rust-token-server` must be configured and deployed on the Internet.\n\n## Installing/building an executable binary\n\nYou can build an executable binary yourself by checking out this Git repository.\n\n```shell\n# debug mode\n% cargo build\n\n# release mode\n% cargo build --release\n```\n\nNow you have a compiled executable binary `doh-auth-proxy` in `./target/debug/` or `./target/release/`.\n\n## Basic Usage\n\n### First step: Connecting to Google public DoH server\n\nStart `doh-auth-proxy` as\n\n```shell\n% ./path/to/doh-auth-proxy --config config.toml\n```\n\nwhere we assume that `config.toml` is configured like follows.\n\n```toml:config.toml\nlisten_addresses = ['127.0.0.1:50053', '[::1]:50053']\nbootstrap_dns = [\"1.1.1.1\"]\n\ntarget_urls = [\"https://dns.google/dns-query\"]\n```\n\nNow you can query through `127.0.0.1:50053` as\n\n```shell\n% dig github.com @localhost -p 50053\n~~~~~~~\n;; ANSWER SECTION:\ngithub.com.             60      IN      A       52.69.186.44\n~~~~~~~\n```\n\nThe parameter `bootstrap_dns` is used to resolve the IP address of the host of `target_urls` (i.e., target DoH server). The `bootstrap_dns` allows non-standard DNS ports other than `53` and TCP queries, which can be specified as an url-like format, e.g., `tcp://1.1.1.1`, `tcp://127.0.0.1:12345`, `127.0.0.1:50053`, where UDP and port `53` are used if omitted.\n\nIf you run without `--config` option, i.e., simply hit `$ ./doh-auth-proxy`, the followings are applied as default parameters:\n\n```:toml:config.toml\nlisten_addresses = ['127.0.0.1:50053', '[::1]:50053']\nbootstrap_dns = [\"1.1.1.1\"]\nendpoint_resolution_period = 60 # mins\nhealthcheck_period = 10 # mins\nmax_cache_size = 16384\ntarget_urls = [\"https://dns.google/dns-query\"]\n```\n\nAll the options are referred to below. Using your specific config file is recommended for better setting in your environment.\n\n### Second step: Connecting to Cloudflare ODoH server via `odohrelay-ams` ODoH relay\n\nStart `doh-auth-proxy` as\n\n```shell\n% ./path/to/doh-auth-proxy --config config.toml\n```\n\nwhere we assume that `config.toml` is configured as follows.\n\n```toml:config.toml\nlisten_addresses = ['127.0.0.1:50053', '[::1]:50053']\nbootstrap_dns = [\"8.8.8.8\"]\n\ntarget_urls = [\"https://odoh.cloudflare-dns.com/dns-query\"]\n\n[anonymization]\nodoh_relay_urls = [\"https://odoh-nl.alekberg.net:443/proxy\"]\n```\n\nThis example issues ODoH encrypted queries by an URL `https://odoh-nl.alekberg.net:443/proxy?targethost=odoh.cloudflare-dns.com\u0026targetpath=/dns-query`.\n\nNow you can query through `127.0.0.1:50053` as\n\n```shell\n% dig github.com @localhost -p 50053\n~~~~~~~\n;; ANSWER SECTION:\ngithub.com.             11      IN      A       140.82.121.4\n~~~~~~~\n```\n\nwhere this takes more round-trip time than the above ordinary DoH example due to the intermediate relay (especially when it is far from your location).\n\n## Advanced usage\n\n### Query plugins for name-based/domain-based blocking and overriding IP addresses\n\nOptionally, `doh-auth-proxy` has functions of domain-based blocking and overriding (cloaking) IP Addresses. Former means that queries for domain names of specific patterns would be blocked and reject messages would be obtained. This can be done **super-fast** by enabling a trie-based data structure thanks to `Cedarwood` crate. Latter means that IP addresses you specified are always obtained for specific domain names.\n\nTo enable these functions, specify files defining blocking/overriding rules in `config.toml` as\n\n```toml:config.toml\n[plugins]\n\ndomains_blocked_file = \"./blocklist.txt\"\ndomains_overridden_file = \"./overridelist.txt\"\n```\n\nRefer to their example files for detailed format.\n\n### Mutualized Oblivious DNS (\u0026mu;ODNS) based on ODoH (\u0026mu;ODoH)\n\n`doh-auth-proxy` extends the ODoH protocol to the multiple-relay-based anonymization protocol, where its concept is called *Mutualized Oblivious DNS* (\u0026mu;ODNS). We call by *\u0026mu;ODoH* the ODoH-based \u0026mu;ODNS.\n\nTo leverage the protocol, you need to run or find relay servers running \u0026mu;ODoH. The implementation of the \u0026mu;ODoH relay and target server is\n\n- [`modoh-server`](https://github.com/junkurihara/modoh-server)\n\nNote that the target resolver in \u0026mu;ODoH is exactly same as that in the standard ODoH, and hence you can specify existing ODoH targets, e.g., Cloudflare's one `https://odoh.cloudflare-dns.com/dns-query`.\n\n**When you run your relay servers, please make sure their security settings and fully understand the risk.** Everything must be done at your own risk.\n\nSee also the DNSCrypt-based \u0026mu;ODNS as well, by referring to [our website](https://junkurihara.github.io/dns/).\n\n## All options in a configuration file\n\n```shell\nUsage: doh-auth-proxy [OPTIONS] --config \u003cFILE\u003e\n\nOptions:\n  -c, --config \u003cFILE\u003e     Configuration file path like ./config.toml\n  -w, --watch             Activate dynamic reloading of the config file via continuous monitoring\n  -q, --query-log \u003cPATH\u003e  Enable query logging. Unless specified, it is disabled.\n  -j, --json-query-log    Enable query logging in json format. Unless specified, it is recorded in human-readable compact format. Must be used with --query-log option.\n  -h, --help              Print help\n  -V, --version           Print version\n```\n\n`config.toml` can be configured as follows.\n\n```toml:config.toml\n##############################################\n#                                            #\n#        doh-auth-proxy configuration        #\n#                                            #\n##############################################\n\n##################################\n#         Global settings        #\n##################################\n\n## Address to listen to.\nlisten_addresses = ['127.0.0.1:50053', '[::1]:50053']\n\n## DNS (Do53) resolver address for bootstrap\nbootstrap_dns = ['8.8.8.8']\n\n## Minutes to re-resolve the IP addr of the nexthop and authentication endpoint url\n## Ip addresses are first resolved by bootstrap DNS, after that, they will be resolved by (MO)DoH resolver itself.\n# endpoint_resolution_period = 60\n\n## Health check period in minitus. Check health of all path candidates and purge DNS cache.\n# healthcheck_period = 10\n\n## Cache entry size (Default 16384)\nmax_cache_size = 16384\n\n## URL of (O)DoH target server like \"https://dns.google/dns-query\".\n## You can specify multiple servers by repeatedly set this option, then one of given\n## servers is randomly chosen every time.\ntarget_urls = [\"https://odoh.cloudflare-dns.com/dns-query\"]\n\n## According to the suggestion in \"Designing for Tussle in Encrypted DNS\" (HotNets'21),\n## multiple (O)DoH servers should be specified and used in randomized fashion in this\n## proxy when \"target_randomization = true\". Otherwise, the first one is always chosen.\n## To this end, 'Global' objects should have Vec\u003cDoHClient\u003e object as clients configured\n## with different target servers. Default value is true\ntarget_randomization = true\n\n## Use Get method to query if true. Default is false\n# use_get_method = false\n\n\n##################################\n#         Auth settings          #\n##################################\n[authentication]\n\n## (optional)\n## API url to retrieve and refresh tokens and validation keys (jwks and blindjwks) like \"https://example.com/v1.0\",\n## where /tokens and /refresh are used for login and refresh, respectively.\n## Also /jwks and /blindjwks are used for jwks retrieval.\n# token_api = \"https://token.api.example.org/v1.0\"\n\n## (optional)\n## Credential env file path for login endpoint like \"./credential.env\"\n# credential_file = \"./.credential\"\n\n\n##################################\n#         Anon settings          #\n##################################\n[anonymization]\n\n## (optional) URL of ODoH nexthop relay server like \"https://relay.example.com/relay\"\nodoh_relay_urls = [\"https://odoh-nl.alekberg.net:443/proxy\"]\n\n\n## (optional)\n## Choose ODoH relay in a randomized fashion from `odoh_relay_urls`.\nodoh_relay_randomization = true\n\n## (optional)\n## URL of multiple-relay-based ODoH's intermediate relay like \"https://relay.example.com/inter-relay\".\n## Specified relay is used after the relay of 'odoh_relay_url' in a randomized fashion.\n# mid_relay_urls = [\"htps://relay.url.after.surfdomeinen.example.org/proxy\"]\n\n## (optional)\n## Maximum number of intermediate relays between nexthop and target.\n# max_mid_relays = 2\n\n##################################\n#       Plugin settings          #\n##################################\n# [plugins]\n\n## (optional)\n## List of domain names to be blocked.\n# domains_blocked_file = \"./blocklist.txt\"\n\n## (optional)\n## List of pairs of a domain name and an IPv4/v6 address, which will be overridden by specified address.\n# domains_overridden_file = \"./overridelist.txt\"\n\n```\n\n## Docker container\n\nYou can run this proxy as a docker container, where the docker image is hosted at [Docker Hub](https://hub.docker.com/r/jqtype/doh-auth-proxy). You can run the docker container by appropriately configure env vers or an env file imported by the container.\n\nSee the [`./docker`](./docker) directory and [`./docker/README.md`](./docker/README.md) for the detailed configuration for the docker container.\n\n## Authentication at the next hop node (DoH target or ODoH relay)\n\nThis proxy provides **authenticated connection** to a DoH target resolver (in DoH) or to an ODoH relay (in ODoH).\nThis function allows the nexthop node (DoH target/ODoH relay) to be private to users, and avoids unauthorized access.\n**This additional function is introduced in order to prevent attacks against external servers through our relays.**\n\nTo leverage the function, an authentication server issuing Authorization Bearer tokens and an authentication-enabled DoH target/ODoH relay, given in the following.\n\n- [`modoh-server`](https://github.com/junkurihara/modoh-server): Relay and target implementation for Oblivious DoH (ODoH) and ODoH-based Mutualized Oblivious DNS (ODoH-based \u0026mu;ODNS; \u0026mu;ODoH) supporting authenticated connection, written in Rust. Standard DoH target server is also supported.\n\n- [`rust-token-server`](https://github.com/junkurihara/rust-token-server): An implementation of authentication server issuing `id_token` in the context of OIDC and anonymous token based on blind RSA signatures ([RFC9474](https://www.rfc-editor.org/rfc/rfc9474.html)).\n\nThe authenticated connection can be established either the ID token or the anonymous token. Both are periodically refreshed by querying the `rust-token-server`, and the use of ID token is prioritized over the anonymous token. This means that the identity of the user is exposed to the next hop relay in addition to the user's IP address. If this is not acceptable, the anonymous token should be used (make `use_anonymous_token=true`).\n\n## Distribution of queries to multiple target resolvers and relays\n\nReferring to the recent paper from Princeton University, we added a function to distribute queries among multiple target resolver. This is in order to support \"design for choice\".\n\n\u003e A. Hounsel, et al., \"Designing for Tussle in Encrypted DNS\", ACM HotNets'21\n\nCurrently if you specify multiple target resolvers and `target_randomization = true` in `config.toml`, your query is dispatched towards one of targets chosen in a random fashion. Otherwise, the first one is always selected.\n\nFrom the same perspective of distribution of queries, our implementation enables the **relay randomization** in (Mutualized) Oblivious DNS over HTTPS simultaneously with the target randomization. This can be enabled by `odoh_relay_randomization = true` in `config.toml`.\n\nWe plan to implement kinds of 'round-robin' based distribution and other variants.\n\n## Notes\n\nODoH implementation follows [RFC9230](https://datatracker.ietf.org/doc/rfc9230/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunkurihara%2Fdoh-auth-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjunkurihara%2Fdoh-auth-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunkurihara%2Fdoh-auth-proxy/lists"}