Technitium DNS Server 自建家庭网络环境DNS
Technitium DNS Server介绍
Technitium DNS Server是一个开源的权威和递归 DNS 服务器,可用于自托管 DNS 服务器以实现隐私和安全。它开箱即用且无需或仅需最小的配置,并提供用户友好的网页控制台,可使用任何现代网页浏览器访问。
没有人真正关心域名解析,因为它在幕后自动工作,并且理解起来很复杂。大多数计算机软件使用操作系统的 DNS 解析器,通常使用 UDP 协议查询配置的 ISP 的 DNS 服务器。这种方式对大多数人来说运行良好,但是,您的 ISP 可以看到并控制您可以访问的网站,即使该网站采用 HTTPS 安全措施。不仅如此,一些 ISP 甚至可以在您使用不同的 DNS 提供商(如 Google DNS 或 Cloudflare DNS)时重定向、阻止或注入您访问的网站的内容。配置 Technitium DNS 服务器使用 DNS-over-TLS、DNS-over-HTTPS 或 DNS-over-QUIC 加密 DNS 协议与转发器,这些隐私和安全问题可以非常有效地得到缓解。
无论是家庭网络还是组织的网络,运行本地 DNS 服务器可以让您更深入了解您的网络,并通过使用 DNS 日志和统计数据更好地理解它。它提高了整体性能,因为大多数查询都是从 DNS 缓存中提供的,使网站在无需等待频繁的 DNS 解析的情况下加载得更快。它还为您提供了对网络的额外控制,允许您在整个网络中阻止域名,并允许您使用加密 DNS 协议安全地路由您的 DNS 流量。

可用于家庭网络中的特性
现代化的WebUI,提供清晰明了的Dashboard。
支持DOT、DOH、DOQ等多种现代化的加密DNS请求。
支持过期缓存和缓存预取,尽可能加速家庭环境中的DNS请求速度。
支持通过UI查看缓存内容,方便判断缓存是否出错。
支持广告拦截,支持添加误报白名单,支持添加自定义黑名单。
支持APP(插件),允许用户下载插件增强DNS服务器功能。
内置DNS Client,可以无需本地终端发起DNS请求即可验证多种DNS服务器请求结果。
支持DHCP&DNS All in one,类似dnsmasq。
支持详细日志查看,但需配合APP插件。
支持Dns over HTTP,可轻松通过反向代理自建DOH。
其他优势
缺点
WebUI界面无中文支持,且作者明确表示不会支持多语言。
部分设置没有ADGH那么清晰直观,例如故障转移设置和加密DNS域名Bootstrap DNS设置完全依靠Zone模块设置实现。
自身没有分流功能,分流有国内用户写过插件,但是评价为不如设置个MosDNS或者SmartDNS做上游。
安装
无论是容器还是普通安装资源基本需求都为1核心512MiB内存2G磁盘,其中如果缓存较多需要适量增加内存和磁盘大小,留存日志的情况下建议增加硬盘空间,个人实践留存七天全量日志4G左右磁盘空间足以。
文章仅介绍Linux下的安装方式,建议根据官方安装步骤进行,下载链接为 安装版 便携版
防火墙需求
若终端到服务器存在防火墙,或者服务器本身安装有防火墙,请按照现网环境需求放通以下端口:
5380/tcp:用以提供Webui HTTP登入方式
53443/tcp:用以提供Webui HTTPS登入方式
53/udp:传统UDP服务器监听端口
53/tcp:TCP服务器监听端口
853/udp:DNS-over-QUIC监听端口
853/tcp:DNS-over-TLS监听端口
443/udp:DNS-over-HTTP3监听端口
443/tcp:DNS-over-HTTPS监听端口
80/tcp:DNS-over-HTTP监听端口,或提供上述加密协议证书申请挑战
67/udp:DHCP服务器端口
普通安装
在树莓派或者主流Linux上运行以下脚本以在线安装Technitium服务器,需要注意的是树莓派仅支持amrv7以上芯片设备。
curl -sSL https://download.technitium.com/dns/install.sh | sudo bash安装完毕后会提示使用http://dns_server_ip:5380/来访问面板,此时在浏览器上输入对应的url即可。
docker方式安装
docker安装参考该网站,使用官方一键安装脚本即可。
如果非root用户要使用docker,要么使用sudo命令提权,要么将该用户加入docker组,后者请参考该文章,不重复造轮子了。
docker方式更推荐使用compose编排工具部署,作者在github托管了docker-compose.yaml,直接使用默认最小化配置部署即可,配置如下所示:
services:
dns-server:
container_name: dns-server
hostname: dns-server
image: technitium/dns-server:latest
# For DHCP deployments, use "host" network mode and remove all the port mappings, including the ports array by commenting them
# network_mode: "host"
ports:
- "5380:5380/tcp" #DNS web console (HTTP)
# - "53443:53443/tcp" #DNS web console (HTTPS)
- "53:53/udp" #DNS service
- "53:53/tcp" #DNS service
# - "853:853/udp" #DNS-over-QUIC service
# - "853:853/tcp" #DNS-over-TLS service
# - "443:443/udp" #DNS-over-HTTPS service (HTTP/3)
# - "443:443/tcp" #DNS-over-HTTPS service (HTTP/1.1, HTTP/2)
# - "80:80/tcp" #DNS-over-HTTP service (use with reverse proxy or certbot certificate renewal)
# - "8053:8053/tcp" #DNS-over-HTTP service (use with reverse proxy)
# - "67:67/udp" #DHCP service
environment:
- DNS_SERVER_DOMAIN=dns-server #The primary domain name used by this DNS Server to identify itself.
# - DNS_SERVER_ADMIN_PASSWORD=password #DNS web console admin user password.
# - DNS_SERVER_ADMIN_PASSWORD_FILE=password.txt #The path to a file that contains a plain text password for the DNS web console admin user.
# - DNS_SERVER_PREFER_IPV6=false #DNS Server will use IPv6 for querying whenever possible with this option enabled.
# - DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES=172.17.0.1,127.0.0.1 #Comma separated list of network interface IP addresses that you want the web service to listen on for requests. The "172.17.0.1" address is the built-in Docker bridge. The "[::]" is the default value if not specified. Note! This must be used only with "host" network mode.
# - DNS_SERVER_WEB_SERVICE_HTTP_PORT=5380 #The TCP port number for the DNS web console over HTTP protocol.
# - DNS_SERVER_WEB_SERVICE_HTTPS_PORT=53443 #The TCP port number for the DNS web console over HTTPS protocol.
# - DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS=false #Enables HTTPS for the DNS web console.
# - DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT=false #Enables self signed TLS certificate for the DNS web console.
# - DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP=false #Enables DNS server optional protocol DNS-over-HTTP on TCP port 8053 to be used with a TLS terminating reverse proxy like nginx.
# - DNS_SERVER_RECURSION=AllowOnlyForPrivateNetworks #Recursion options: Allow, Deny, AllowOnlyForPrivateNetworks, UseSpecifiedNetworkACL.
# - DNS_SERVER_RECURSION_NETWORK_ACL=192.168.10.0/24, !192.168.10.2 #Comma separated list of IP addresses or network addresses to allow access. Add ! character at the start to deny access, e.g. !192.168.10.0/24 will deny entire subnet. The ACL is processed in the same order its listed. If no networks match, the default policy is to deny all except loopback. Valid only for `UseSpecifiedNetworkACL` recursion option.
# - DNS_SERVER_RECURSION_DENIED_NETWORKS=1.1.1.0/24 #Comma separated list of IP addresses or network addresses to deny recursion. Valid only for `UseSpecifiedNetworkACL` recursion option. This option is obsolete and DNS_SERVER_RECURSION_NETWORK_ACL should be used instead.
# - DNS_SERVER_RECURSION_ALLOWED_NETWORKS=127.0.0.1, 192.168.1.0/24 #Comma separated list of IP addresses or network addresses to allow recursion. Valid only for `UseSpecifiedNetworkACL` recursion option. This option is obsolete and DNS_SERVER_RECURSION_NETWORK_ACL should be used instead.
# - DNS_SERVER_ENABLE_BLOCKING=false #Sets the DNS server to block domain names using Blocked Zone and Block List Zone.
# - DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT=false #Specifies if the DNS Server should respond with TXT records containing a blocked domain report for TXT type requests.
# - DNS_SERVER_BLOCK_LIST_URLS= #A comma separated list of block list URLs.
# - DNS_SERVER_FORWARDERS=1.1.1.1, 8.8.8.8 #Comma separated list of forwarder addresses.
# - DNS_SERVER_FORWARDER_PROTOCOL=Tcp #Forwarder protocol options: Udp, Tcp, Tls, Https, HttpsJson.
# - DNS_SERVER_LOG_USING_LOCAL_TIME=true #Enable this option to use local time instead of UTC for logging.
volumes:
- config:/etc/dns
restart: unless-stopped
sysctls:
- net.ipv4.ip_local_port_range=1024 65000
volumes:
config:有host模式需求得到将ports内容注释后取消# network_mode: "host"中的#即可。
将该文件上传至~/docker/technitiumdns目录后,使用docker compose up -d便会自动拉取image并在后台运行容器,随后便可使用http://dns_server_ip:5380/来访问面板了。
PVE平台LXC容器部署
如果家中有虚拟化平台,则可以使用一键脚本在平台上部署LXC容器并安装Technitium DNS Server。
通过远程SSH或者PVE平台自带的SHELL连入PVE底层。

在底层中使用bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/ct/technitiumdns.sh)"命令下载自动安装脚本并运行。

选择YES并回车,提示是否使用默认配置,在此我们选择Advanced并回车。

默认选择debian12系统,如果想使用debian11或者ubuntu可自行更换,使用上下键选择,使用空格键确认,出现*说明该选项已被选中。在没有偏好的情况下,如果资源比较吃紧可以选择debian11,不推荐ubuntu。


是否选择无特权容器,实测无特权运行正常,建议无特权以保证最小权限原则。

是否设置root密码,建议不设置,并且后续设定中选择不开启SSH以减小攻击面,如果有问题需要进入底层排查通过PVE平台的SHELL进入即可。

设置容器ID,保持默认即可,有特殊需求可自行更改。

设置容器主机名,根据自身需要填写。

设置磁盘大小,如果留存日志请至少给容器4GiB磁盘以防磁盘爆满,当然容器的磁盘是可以随意扩容的,可以一开始给小一点,后续快满了再逐步增加。

分配CPU数量,默认1核即可满足要求。

分配内存大小,家庭512MiB足够使用,因为还会默认分配512MiB Swap。

网络接口默认分配vmbr0,该接口是pve安装后的默认网桥口,无特殊需求不动即可。

IP地址默认为DHCP分配,建议设置一个静态地址,并在DHCP服务器上做IP/MAC绑定关系,注意IP地址必须带掩码如/24。

根据现网状态设置网关。

选择是否开启ipv6,可以开启但是没有必要,无特殊需求建议关闭减少攻击面。
DNS默认跟随PVE系统DNS,也可自定义为其他的如223.5.5.5或119.29.29.29,该DNS是容器本身的DNS解析服务器,与Technitium DNS Server无关。

其他没提到的配置回车保持默认即可,最后确认后便会进入安装过程,安装时需保证到Github网络畅通。

安装完毕后会提示使用http://dns_server_ip:5380/进入管理界面,至此LXC应用容器安装完毕。

用户设置
设置管理员密码
WebUI登入后需要设置一个管理员密码,建议随意输入一个,在后续的设置中会设定另一位管理员并禁用默认管理员。
如果需要使用默认管理员请设置复杂密码以防止被爆破。

新建用户
点击栏目Administration-Users,点击Add User按钮,分别输入展示用户名、用户名和密码,注意展示用户名可以用中文,但是用户名必须为数字英文与部分符号组合。

用户提权
点击新建的用户test,在Add Group中点击Administrators,然后点击Save即可给用户提权至管理员。
其中Session Timeout为可选配置,在内网环境可以设置为最大值604800,表示七天后会话才会过期,不需要频繁输入密码。

禁用默认管理员
必须切换另一位管理员才可禁用默认管理员账户,这是一种防呆设计,免得有人把默认管理员禁用了导致无法管理。别问,问就是我当年尝试过,幸亏有这个设计不然我就得重装了。
右上角点击用户名称,选择Logout登出系统,随后使用新建用户登入。
进去后重新进入Administration-Users,如果看不到Settings和Administration,请登入回管理员账户,你肯定是忘记保存了导致提权失败,普通用户是无法更改设置的。
选择admin账户,勾选Disable User Account,然后点击Save,此时admin账户已禁用。

DNS服务器基本设置
关闭DNSSEC
如果上游使用境外的DNS,大部分都是支持此功能的,那这个选项可以打开。
如果上游有大陆境内DNS或者上游有其他自建DNS,需要关闭这个选项,不然DNSSEC验证失败会无法得到解析结果。
该设定再Settings-General中,取消勾选该选项,然后在最底栏选择Save settings。

确认DNS服务器接受内网请求
在Settings-Recursion中确认Allow Recursion Only For Private Networks (default)被勾选,该选项是默认的,只有勾选该选项才能接受来源为私有网络的DNS请求。

Proxy设置
如果需要通过代理连接,可以在Settings-Proxy & Forwards更改代理设置。
支持需要鉴权的HTTP和SOCKS代理。
但是需要注意的是如果设定了代理,Technitium DNS Server所有网络请求都会走代理出去,所以推荐网关部署透明代理,不要使用自带的代理设置,不会有人家里部署了DNS服务器却没有软路由吧。
而且如果上游是另一台内网DNS,千万不要设置代理,不然我不好说代理软件会不会被内网DNS请求打崩。

上游递归服务器设置
家用一般使用递归服务器更多,普通的需求在Settings-Proxy & Forwards更改Forwarders即可实现。

境外DNS推荐
由于Technitium DNS Server是一款境外开发的软件,默认提供的DNS模板大多为境外DNS。常用的有:
谷歌 DNS
DNS-over-TLS:dns.google (8.8.8.8:853)、dns.google (8.8.4.4:853)
DNS-over-HTTPS:https://dns.google/dns-query (8.8.8.8)、https://dns.google/dns-query (8.8.4.4)
CloudFlare DNS
DNS-over-TLS:cloudflare-dns.com (1.1.1.1:853)、cloudflare-dns.com (1.0.0.1:853)
DNS-over-HTTPS:https://cloudflare-dns.com/dns-query (1.1.1.1)、https://cloudflare-dns.com/dns-query (1.0.0.1)
Quad9 DNS
DNS-over-TLS:dns.quad9.net (9.9.9.9:853)、dns.quad9.net (149.112.112.112:853)
DNS-over-HTTPS:https://dns.quad9.net/dns-query (9.9.9.9)、https://dns.quad9.net/dns-query (149.112.112.112)
Cisco Open DNS
DNS-over-TLS:dns.opendns.com (208.67.222.222:853)、dns.opendns.com (208.67.220.220:853)
DNS-over-HTTPS:https://doh.opendns.com/dns-query (146.112.41.2)
在大陆境内不推荐使用境外的QUIC、HTTP3、传统UDP类型DNS,大陆境内出境UDP流量经常受到干扰,并且即时在代理环境下,部分代理对于UDP支持欠佳,体验不一定比TCP类型的DNS更好。
境内DNS推荐
如果在大陆境内使用推荐使用以下三个加密DNS:
阿里AliDNS
DNS-over-TLS:dns.alidns.com (223.5.5.5:853)、dns.alidns.com (223.6.6.6:853)
DNS-over-HTTPS:https://dns.alidns.com (223.5.5.5)、https://dns.alidns.com (223.6.6.6)
DNS-over-QUIC:dns.alidns.com (223.5.5.5:853)、dns.alidns.com (223.6.6.6:853)
腾讯DNSpod
DNS-over-TLS:dot.pub (1.12.12.21:853)、dot.pub (120.53.53.53:853)
DNS-over-HTTPS:https://dot.pub (1.12.12.21)、https://dot.pub (120.53.53.53)
360安全DNS
DNS-over-TLS:dot.360.cn (112.65.69.15:853)、dot.360.cn (101.199.254.118:853)、dot.360.cn (123.6.48.18:853)
DNS-over-HTTPS:https://doh.360.cn (112.65.69.15)、https://doh.360.cn (101.199.254.118)、https://doh.360.cn (123.6.48.18)
其中阿里和腾讯有QoS策略,阿里为动态限速(一开始说要针对每个来源公网IP做20qps的限速被喷了,现在限速是黑盒,无法确认具体限速策略),腾讯为针对目标域名的20qps限速(应该还同时是针对每个来源公网IP的),360暂未宣布限速,但是用不用仁者见仁智者见智吧。
注意事项
在Forwards设置中必须使用同类型DNS服务器
Forwards选项中必须填入同一个类型的DNS,不可同时填入DoH、DoT、DoQ,因为在Forwarder Protocol选项中指定了上游服务器的协议,当然后续在进阶设置中有其他方式实现同时请求DoH、DoT、DoQ的功能。
与ADGH的不同
大家也许发现了这款DNS软件和ADGH的不同之处,在ADGH中如果要添加域名形式的DNS,只需要使用tls://dot.pub或者https://doh.pub并且在Bootstrap DNS中提供IP形式的DNS即可依靠Bootstrap DNS实现针对域名形式DNS服务器的域名解析。但是Technitium DNS Server却必须在域名后面指定IP,如果不指定IP在中国大陆是无法解析加密DNS域名的,这也许对初上手的用户会造成一定的困扰。
其实Technitium针对未知的域名会使用根服务器进行递归,然而在中国无法进行针对根服务器的递归,会被GFW阻断。

在24年年底我在reddit上发布过一篇贴文,询问作者是否有实现ADGH类似功能的Feature,在25年年初作者在13.4版本更新了该功能,支持在Zone中添加针对加密DNS域名的FWD记录,以实现Bootstrap DNS类似功能,该设置将会在后续进阶设置中提到。
即便如此本人也更推荐如果在对端服务器IP确定的情况下,使用域名+指定IP的方式或者使用纯IP的方式连接,因为在这两种方式下将会绕过针对DNS服务器域名的解析行为,直接发起连接有利于降低解析延迟。
确实不想使用域名形式?
如果不想使用域名形式的加密DNS服务器,可以填入以下格式:
DNS-over-TLS:8.8.8.8:853、8.8.4.4:853
DNS-over-HTTPS:https://8.8.8.8/dns-query、https://8.8.4.4/dns-query
但是必须由服务器端支持,如果服务端不支持IP证书,那加密传输将会失败。
例如之前腾讯DNSpod宣布将取消IP形式加密DNS的接入,不清楚什么时候落实,所以能用域名方式指定将会更稳定。
验证DNS服务器基本设置
在进行完毕上述设置后,该DNS服务器应当已正常运作,通过自带的DNS Client可以验证服务器是否正常。
如果要验证服务器本身,请在Server中选择this-server,域名填写www.baidu.com,记录选择A记录,服务器类型选择传统UDP,点击Resolve即可验证。
需要注意的是,服务器类型不可选错,如果选错了必定会导致解析失败。

DNS服务器进阶设置
利用条件转发解析DNS服务器域名
上文中我们提到可以利用Zone中的条件转发实现加密DNS服务器域名解析。
我们需要在Zone中点击Add Zone。

Zone中需要指定被条件转发的域名,Type选择Conditional Forwarder Zone,Protocol选择DNS-over-UDP (default),Forwarder填写223.5.5.5或者119.29.29.29,只要是IP形式的递归DNS都可以,务必取消Enable DNSSEC Validation勾选。


点击Add添加完毕后会进入对应的Zone,可以针对该域名的Zone增加其他解析记录,如再新增一条FWD记录。

此时使用DNS Client即可验证,尝试解析bilibili.com,可以看到解析成功。

观察Cache,可以看到dot.360.cn成功由223.5.5.5解析。

观察Zone记录调用情况,可以看到两条FWD记录被成功调用。

多种上游加密DNS解析
可通过在Zone中设定根Zone的条件转发实现多个上游加密DNS解析。
在Zone中选择Add Zone,Zone需要填写.,意味着修改根Zone,Forwarder勾选Use "This Server",DNSSEC取消勾选Enable DNSSEC Validation。

随后添加FWD记录即可,注意添加完的FWD记录是默认0优先级的,即最高优先级,会和this-server进行并发查询。

自动故障转移
自动故障转移可以实现高优先级服务器宕机后,使用低优先级服务器进行递归的操作。
其实该步骤和上一步是一样的,只不过添加FWD记录的时候需要调整Priority,默认优先级为0为最高,255为最低,可酌情调整。
APP插件
通过APP插件可以实现多种功能以增强DNS服务器,优化用户体验。
安装插件
在线安装
点击Apps选择App Store,挑选想要的插件点击安装即可。


离线安装
作者提供了APP列表供使用者进行离线安装,如果DNS出现问题导致无法连接互联网,可以通过该列表找到插件安装包。以安装DNS Rebinding Protection为例,找到下载URL,通过浏览器访问下载可得到zip压缩包。

在Apps中选择Install,App Name建议填入APP列表中的名字,App Zip File选择下载的安装包,点击Install即可安装。



插件推荐
DNS Rebinding Protection
该插件将过滤上游DNS返回的私有IP地址范围回应,如果家中有Plex不建议安装,可能导致局域网登入出现问题。
本地托管的DNS域名解析返回的私有IP地址将不会被过滤。
Drop Requests
可以丢弃特定的DNS请求,例如可以丢弃HTTPS、AAAA、PTR记录请求。
{
"enableBlocking": true,
"dropMalformedRequests": false,
"allowedNetworks": [
],
"blockedNetworks": [
],
"blockedQuestions": [
{
"type": "HTTPS"
},
{
"type": "PTR"
}
]
}Filter AAAA
可以过滤AAAA记录请求,需要注意的是只有在一个域名同时有A记录和AAAA记录时,此插件才会作用,如果仅有AAAA记录仍然正常返回,推荐针对境外域名解析用的服务器使用此插件。
Query Logs (Sqlite)
必装插件,安装此插件后Logs中的Query Logs才能正常查看。
黑名单、白名单
兼容ADGH格式的黑名单、白名单,有一定的去广告和反追踪作用。
在Settings-Blocking中Allow / Block List URLs可以添加黑、白名单
去广告合并规则:https://raw.githubusercontent.com/217heidai/adblockfilters/main/rules/adblockdns.txt
秋风广告:https://raw.githubusercontent.com/TG-Twilight/AWAvenue-Ads-Rule/main/AWAvenue-Ads-Rule.txt
Anti-AD白名单:https://raw.githubusercontent.com/privacy-protection-tools/dead-horse/master/anti-ad-white-list.txt
缓存预取
缓存预取默认开启,默认情况下将在域名过期前针对热门域名进行预取,具体的设置在Settings-Cache中。
一般不需要动推荐设置,可以稍微调低Auto Prefetch Eligibility值降低热门域名的判定标准以更积极地调动预取。
随机化DNS查询
在Settings-Recursion-Recursive Resolver中可开启三种随机化DNS查询。
实测开启后基本没有兼容性问题,而且可以增强查询的隐私性。
备份和恢复设置
在Settings中最下方右下角有两个选项,Backup Settings用以备份设置,Restore Settings用以恢复设置。


刷新缓存
如果缓存出错,可以通过Setting最下方左下角的Flush Cache刷新缓存。

日志查询与相关设置
日志查询
在Logs-Query Logs中可以查询DNS请求日志,使用的前提是安装Query Logs插件,家用一般安装Sqlite版本即可,大型项目可以使用Mysql版本。
直接点击Query按键会按照默认参数输出日志,需要注意的是Protocol是本服务器提供给客户端的解析方式,而不是使用的上游服务器的协议,暂时不支持在该日志中查询域名是由哪个上游解析的,此信息需要去缓存中查找。
并且Domain中如果需要模糊查询,需要使用通配符匹配,例如我想查找bilibili.com的子域名,需要使用*.bilibili.com来查询,只输入bilibili.com是没有结果的。

设置
默认留存365天日志,家用情况建议改为七天,且建议开启Log All Queries、Use Local Time选项。

