{"id":15620875,"url":"https://github.com/jinliming2/secure-dns","last_synced_at":"2025-04-28T16:16:48.312Z","repository":{"id":49967451,"uuid":"278060065","full_name":"jinliming2/secure-dns","owner":"jinliming2","description":"A DNS client which implemented DoT and DoH, with load balancing, DNS cache, custom ECS and HOSTs.","archived":false,"fork":false,"pushed_at":"2024-09-03T22:22:08.000Z","size":80,"stargazers_count":14,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-28T16:16:42.692Z","etag":null,"topics":["dns","dns-over-https","dns-over-tls","doh","dot","ecs","edns","rfc-7858","rfc-8484","subnet"],"latest_commit_sha":null,"homepage":"","language":"Go","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/jinliming2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2020-07-08T10:30:55.000Z","updated_at":"2025-01-14T13:55:31.000Z","dependencies_parsed_at":"2024-06-19T09:58:57.958Z","dependency_job_id":"e40bfedc-b4d4-4c8e-963a-316c63f05131","html_url":"https://github.com/jinliming2/secure-dns","commit_stats":{"total_commits":52,"total_committers":2,"mean_commits":26.0,"dds":"0.019230769230769273","last_synced_commit":"45c970cc3660e595736e3f47e80a4bd705abf95d"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinliming2%2Fsecure-dns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinliming2%2Fsecure-dns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinliming2%2Fsecure-dns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinliming2%2Fsecure-dns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinliming2","download_url":"https://codeload.github.com/jinliming2/secure-dns/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251342725,"owners_count":21574245,"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":["dns","dns-over-https","dns-over-tls","doh","dot","ecs","edns","rfc-7858","rfc-8484","subnet"],"created_at":"2024-10-03T09:03:09.890Z","updated_at":"2025-04-28T16:16:48.290Z","avatar_url":"https://github.com/jinliming2.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Secure DNS\n\n[![Build Status](https://app.travis-ci.com/jinliming2/secure-dns.svg?branch=master)](https://app.travis-ci.com/jinliming2/secure-dns)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jinliming2/secure-dns)](https://goreportcard.com/report/github.com/jinliming2/secure-dns)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fjinliming2%2Fsecure-dns.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fjinliming2%2Fsecure-dns?ref=badge_shield)\n\nA DNS client which implemented DoT and DoH, with load balancing, DNS cache, custom ECS and HOSTs.\n\n## Table of Content\n\n- [Table of Content](#table-of-content)\n- [Config](#config)\n  - [Example](#example)\n  - [Basic config](#basic-config)\n  - [Upstream DNS](#upstream-dns)\n    - [Traditional DNS](#traditional-dns)\n    - [DNS over TLS (DoT)](#dns-over-tls-dot)\n    - [DNS over HTTPS (DoH)](#dns-over-https-doh)\n  - [Custom Hosts](#custom-hosts)\n    - [Import domain list from file](#import-domain-list-from-file)\n\n## Config\n\n### Example\n\n```toml\n[config]\nlisten = [\n  '[::1]:53',\n  '127.0.0.1:53',\n]\ncustom_ecs = [\n  '10.20.30.40',\n  '50.60.70.80',\n]\nround_robin = 'swrr'\n\n[[traditional]]\nhost = ['8.8.4.4', '8.8.8.8']\nbootstrap = true\n\n[[https]]\nhost = ['dns.google']\npath = '/resolve'\ngoogle = true\n\n[[https]]\nhost = ['dns.google']\nweight = 10\n\n[[https]]\nhost = ['1.1.1.1', '1.0.0.1']\n\n[[tls]]\nhost = ['dns.google']\n\n[[traditional]]\n# Resolve private domain name using local DNS server\nhost = ['10.0.0.1']\nsuffix = [ 'private.network.org' ]\n\n[hosts.'example.com']\nA = [ '127.0.0.1' ]\nAAAA = [ '::1' ]\nTXT = [ 'text' ]\n```\n\n### Basic config\n\n| Key                |    Type    | Required |                             Default                             | Description                                                                                                  |\n| :----------------- | :--------: | :------: | :-------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------- |\n| listen             | `string[]` |    ✔️    |                                                                 | host and port to listen                                                                                      |\n| timeout            |   `uint`   |          |                               `5`                               | timeout in seconds for each DNS request, 0 to disable                                                        |\n| round_robin        |  `string`  |          |                            `'clock'`                            | upstream select round robin, can only be `'clock'`, `'random'`, `'wrandom'` or `'swrr'`                      |\n| cache_no_answer    |   `uint`   |          |                               `0`                               | Cache response for specified seconds even if query returns with no specified answer or domain was not exists |\n| no_cache           | `boolean`  |          |                             `false`                             | disable global DNS result cache                                                                              |\n| custom_ecs         | `string[]` |          |                                                                 | custom EDNS Subnet to override                                                                               |\n| fallback_no_ecs    | `boolean`  |          |                             `false`                             | fallback to no_ecs=`true` when DNS request got no answer                                                     |\n| no_ecs             | `boolean`  |          |                             `false`                             | disable EDNS Subnet and remove EDNS Subnet from DNS request                                                  |\n| user_agent         |  `string`  |          | `'secure-dns/VERSION https://github.com/jinliming2/secure-dns'` | User-Agent field for DNS over HTTPS                                                                          |\n| no_user_agent      | `boolean`  |          |                             `false`                             | do not send User-Agent header in DNS over HTTPS                                                              |\n| no_single_inflight | `boolean`  |          |                             `false`                             | do not suppress multiple same outstanding queries                                                            |\n\nExample:\n\n```toml\n[config]\nlisten = ['[::1]:53', '127.0.0.1:53']\ncustom_ecs = ['1.2.3.4', '1:2::3:4']\nno_user_agent = true\n```\n\n### Upstream DNS\n\n#### Traditional DNS\n\n| Key                |    Type    | Required | Default | Description                                                                                         |\n| :----------------- | :--------: | :------: | :-----: | :-------------------------------------------------------------------------------------------------- |\n| host               | `string[]` |    ✔️    |         | ip addresses                                                                                        |\n| port               |  `uint16`  |          |  `53`   | port to use                                                                                         |\n| bootstrap          | `boolean`  |          | `false` | mark this is a bootstrap DNS server, only used to resolve names for DNS over HTTPS and DNS over TLS |\n| weight             |   `uint`   |          |   `1`   | weight used for weighted round robin, should \u003e 0                                                    |\n| domain             | `string[]` |          |         | mark this DNS server only used to resolve specified domain names                                    |\n| suffix             | `string[]` |          |         | mark this DNS server only used to resolve domain names with specified suffixes                      |\n| custom_ecs         | `string[]` |          |         | custom EDNS Subnet to override                                                                      |\n| fallback_no_ecs    | `boolean`  |          | `false` | fallback to no_ecs=`true` when DNS request got no answer                                            |\n| no_ecs             | `boolean`  |          | `false` | disable EDNS Subnet and remove EDNS Subnet from DNS request                                         |\n| no_single_inflight | `boolean`  |          | `false` | do not suppress multiple same outstanding queries                                                   |\n\nExample:\n\n```toml\n[[traditional]]\nhost = ['8.8.4.4', '8.8.8.8']\n\n[[traditional]]\nhost = ['1.1.1.1', '1.0.0.1']\nbootstrap = true\n\n[[traditional]]\nhost = ['9.9.9.9']\nsuffix = [\n  'example.com',\n]\n```\n\n#### DNS over TLS (DoT)\n\n| Key                |    Type    | Required | Default | Description                                                                    |\n| :----------------- | :--------: | :------: | :-----: | :----------------------------------------------------------------------------- |\n| host               | `string[]` |    ✔️    |         | ip addresses or host names                                                     |\n| port               |  `uint16`  |          |  `853`  | port to use                                                                    |\n| hostname           |  `string`  |          |         | hostname for ip addresses                                                      |\n| weight             |   `uint`   |          |   `1`   | weight used for weighted round robin, should \u003e 0                               |\n| domain             | `string[]` |          |         | mark this DNS server only used to resolve specified domain names               |\n| suffix             | `string[]` |          |         | mark this DNS server only used to resolve domain names with specified suffixes |\n| custom_ecs         | `string[]` |          |         | custom EDNS Subnet to override                                                 |\n| fallback_no_ecs    | `boolean`  |          | `false` | fallback to no_ecs=`true` when DNS request got no answer                       |\n| no_ecs             | `boolean`  |          | `false` | disable EDNS Subnet and remove EDNS Subnet from DNS request                    |\n| no_single_inflight | `boolean`  |          | `false` | do not suppress multiple same outstanding queries                              |\n\nExample:\n\n```toml\n[[tls]]\nhost = ['dns.google']\n\n[[tls]]\nhost = ['1.1.1.1']\nhostname = 'cloudflare-dns.com'\ndomain = [\n  'example.com',\n]\n```\n\n\u003e Note: If you want to specify hostname in host field, you must specify a traditional DNS server that marked with `bootstrap = true`.\n\n#### DNS over HTTPS (DoH)\n\n| Key                |    Type    | Required |                             Default                             | Description                                                                    |\n| :----------------- | :--------: | :------: | :-------------------------------------------------------------: | :----------------------------------------------------------------------------- |\n| host               | `string[]` |    ✔️    |                                                                 | ip addresses or host names                                                     |\n| port               |  `uint16`  |          |                              `443`                              | port to use                                                                    |\n| hostname           |  `string`  |          |                                                                 | hostname for ip addresses                                                      |\n| path               |  `string`  |          |                         `'/dns-query'`                          | HTTP URI path to use                                                           |\n| google             | `boolean`  |          |                             `false`                             | use google's DoH query structure                                               |\n| cookie             | `boolean`  |          |                             `false`                             | enable cookie support for this server                                          |\n| weight             |   `uint`   |          |                               `1`                               | weight used for weighted round robin, should \u003e 0                               |\n| domain             | `string[]` |          |                                                                 | mark this DNS server only used to resolve specified domain names               |\n| suffix             | `string[]` |          |                                                                 | mark this DNS server only used to resolve domain names with specified suffixes |\n| custom_ecs         | `string[]` |          |                                                                 | custom EDNS Subnet to override                                                 |\n| fallback_no_ecs    | `boolean`  |          |                             `false`                             | fallback to no_ecs=`true` when DNS request got no answer                       |\n| no_ecs             | `boolean`  |          |                             `false`                             | disable EDNS Subnet and remove EDNS Subnet from DNS request                    |\n| user_agent         |  `string`  |          | `'secure-dns/VERSION https://github.com/jinliming2/secure-dns'` | User-Agent field for DNS over HTTPS                                            |\n| no_user_agent      | `boolean`  |          |                             `false`                             | do not send User-Agent header in DNS over HTTPS                                |\n| no_single_inflight | `boolean`  |          |                             `false`                             | do not suppress multiple same outstanding queries                              |\n\nExample:\n\n```toml\n[[https]]\nhost = ['dns.google']\n\n[[https]]\nhost = ['8.8.4.4', '8.8.8.8']\nhostname = 'dns.google'\npath = '/resolve'\ngoogle = true\n\n[[https]]\nhost = ['1.1.1.1']\nhostname = 'cloudflare-dns.com'\ndomain = [\n  'example.com',\n]\n```\n\n\u003e Note: If you want to specify hostname in host field, you must specify a traditional DNS server that marked with `bootstrap = true`.\n\n### Custom Hosts\n\nExample:\n\n```toml\n[hosts.'example.com']\nA = [\n  '127.0.0.1',\n  '192.168.1.1',\n]\nAAAA = ['::1']\nTXT = ['this matches example.com']\n\n[hosts.'*.example.com']\nA = ['0.0.0.0']\nTXT = ['this matches example.com a.example.com a.b.example.com a.b.c.example.com ...']\n\n[hosts.'*.blocked.domain']\n# Answered with no record\n```\n\n#### Import domain list from file\n\nWhen defining hosts, you can use the `=#` or `$#` prefix followed by a relative or absolute file path to import the domain list from the specified file. The file path is related to the TOML config file path.\n\nThe domain list file is a plain text file that contains domains in each line, split by the `\\n` character. Lines starting with the `#` character are ignored.\n\n`=#` means to use the domain list to resolve specified domain names.\n\n`$#` means to use the domain list to resolve domain names with specified suffixes.\n\nExample:\n\n```toml\n[hosts.'$#./domains.txt']\nA = [ '127.0.0.1' ]\n\n[hosts.'=#./domains.txt']\n\n[hosts.'$#/etc/secure-dns/domains.txt']\n\n[hosts.'=#/mnt/txt']\n```\n\n## License\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fjinliming2%2Fsecure-dns.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fjinliming2%2Fsecure-dns?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinliming2%2Fsecure-dns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinliming2%2Fsecure-dns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinliming2%2Fsecure-dns/lists"}