返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
系统配置

One-click setup of DoH on Linux systems to address DNS resolution pollution

DNS resolution polluted? Just switch to DoH. Cloudflare's tool is laughably simple; just use it directly with the domestic DNS upstream. One line of configuration, and it's done—not that difficult.

曦远 (DealiAxy)约 18 分钟
目录9 个章节

Preface

Recently, my swag service suddenly failed to renew the certificate.

After diagnosing, I found that it was unable to resolve the acme-v02.api.letsencrypt.org domain name.

Tried switching several DNS servers, but none worked; it should be due to DNS pollution or hijacking.

At this point, I realized that without DoH/DoT, there's probably no solution.🤣

This article records a simple method to implement DoH/DoT on the server.

DoH/DoT

A brief primer: DNS is a protocol that resolves website names to IP addresses.

Standard DNS transmits data in plaintext, making it vulnerable to tampering or hijacking.

DoH (DNS over HTTPS) uses encrypted HTTPS traffic (port 443). It appears similar to normal web browsing, making it less susceptible to DNS pollution or interception.

In addition, there is DoT (DNS over TLS) and ODoH (Oblivious DoH, with enhanced privacy). These are all more secure methods for domain name resolution.

cloudflared

https://github.com/cloudflare/cloudflared

This is an official open-source Cloudflare Tunnel client from Cloudflare, developed in the Go language, and it's very easy to install and deploy.

Introduction

This client can not only connect to Tunnel to achieve intranet penetration but also implement DoH proxy.

This article uses this tool to implement DoH configuration.

Installation

The official Ubuntu Server software repository does not include this tool.

You need to add the Cloudflare official APT repository.

# 1. Add GPG key
`curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg > /dev/null`
# 2. Add Software Repository
`echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared jammy main" | sudo tee /etc/apt/sources.list.d/cloudflared.list`
# 3. Update and Install
sudo apt update
sudo apt install cloudflared

You can also download and install the DEB package directly.

# 1. Download the latest cloudflared deb package
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
# 2. Installation
sudo dpkg -i cloudflared-linux-amd64.deb
# 3. Verify

cloudflared --version
### Testing

After installation, run:

```bash
sudo cloudflared proxy-dns --address 127.0.0.1 --port 5053

Test it with:

dig @127.0.0.1 -p 5053 acme-v02.api.letsencrypt.org

If it returns a resolution result, then it's successful.

By default, this uses Cloudflare's official DoH.

If it doesn't work, you can switch to a domestic DoH service.

For example, Alibaba's:

For example, Tencent's:

Example

sudo cloudflared proxy-dns --address 127.0.0.1 --port 5053 \
  --upstream https://223.5.5.5/dns-query \
  --upstream https://223.6.6.6/dns-query

If testing with tools like dig or nslookup shows no issues, you can proceed to the next step.

Add Service

Create a systemd service to run cloudflared continuously.

sudo nano /etc/systemd/system/cloudflared-dns.service

Content:

[Unit]
Description=Cloudflared DNS over HTTPS proxy
After=network.target

[Service]
ExecStart=/usr/local/bin/cloudflared proxy-dns --address 127.0.0.1 --port 5053 \
  --upstream https://223.5.5.5/dns-query \
  --upstream https://223.6.6.6/dns-query \
  --upstream https://doh.pub/dns-query \
  --upstream https://dns.pub/dns-query
Restart=always
User=nobody
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Apply & Start

sudo systemctl daemon-reexec
sudo systemctl enable --now cloudflared-dns

Configuring DNS

Using a drop-in configuration method to set up DNS

Do not directly modify /etc/systemd/resolved.conf

sudo mkdir -p /etc/systemd/resolved.conf.d
sudo nano /etc/systemd/resolved.conf.d/dns.conf

Content:

[Resolve]
DNS=127.0.0.1:5053
FallbackDNS=223.5.5.5 223.6.6.6
DNSSEC=no

Restart the service

sudo systemctl restart systemd-resolved

Check the effect

resolvectl status

You can see the following output

$ resolvectl status
Global
           Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
    resolv.conf mode: stub
         DNS Servers: 127.0.0.1:5053
Fallback DNS Servers: 223.5.5.5 223.6.6.6

At this point, it's done, and Docker containers will also use this system DNS by default

Now, when you go to renew the certificate with swag, it will succeed ✌️

One-Click Script

Following the usual practice, I had AI grandpa write a one-click script for configuring DoH

By default, it uses the method of downloading and installing the deb package from the official GitHub repository

You can execute it directly

bash -c "$(curl -fsSL https://gist.github.com/Deali-Axy/8b2ad8e5a601f2c43f6e7debdfb0aa29/raw/3c57dbce7dc0e224ad4ad35606f15cbc34d4810e/install-doh.sh)"

Script Source Code

#!/usr/bin/env bash
set -e

echo "[1/6] Installing cloudflared..."
if ! command -v cloudflared >/dev/null 2>&1; then
  wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -O /tmp/cloudflared.deb
  sudo dpkg -i /tmp/cloudflared.deb || sudo apt-get install -f -y
  rm -f /tmp/cloudflared.deb
else
  echo "cloudflared is already installed, skipping."
fi

CLOUDFLARED_BIN=$(command -v cloudflared)
echo "cloudflared path: $CLOUDFLARED_BIN"

echo "[2/6] Creating systemd service..."
sudo tee /etc/systemd/system/cloudflared-dns.service >/dev/null <<EOF
[Unit]
Description=Cloudflared DNS over HTTPS proxy
After=network.target

[Service]
ExecStart=${CLOUDFLARED_BIN} proxy-dns --address 127.0.0.1 --port 5053 \
  --upstream https://223.5.5.5/dns-query \
  --upstream https://223.6.6.6/dns-query \
  --upstream https://doh.pub/dns-query \
  --upstream https://dns.pub/dns-query
Restart=always
User=nobody
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
EOF

echo "[3/6] Reloading systemd and enabling service..."
sudo systemctl daemon-reexec
sudo systemctl enable --now cloudflared-dns

echo "[4/6] Configuring systemd-resolved..."
sudo mkdir -p /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/dns.conf >/dev/null <<EOF
[Resolve]
DNS=127.0.0.1:5053
FallbackDNS=223.5.5.5 223.6.6.6
DNSSEC=no
EOF

echo "[5/6] Restarting systemd-resolved..."
sudo systemctl restart systemd-resolved

echo "[6/6] Checking DNS configuration..."
resolvectl status | grep "DNS Servers"

echo "✅ Installation complete! The system DNS is now using DoH."

Save the above code as install-doh.sh

Run

chmod +x install-doh.sh
./install-doh.sh

The script will automatically:

  1. Download and install cloudflared
  2. Write the systemd service file and start it
  3. Configure systemd-resolved
  4. Automatically restart the relevant services and verify the setup

_EOF_

One-click setup of DoH on Linux systems to address DNS resolution pollution

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

给VMware里的Linux虚拟机配置静态ip

前言 最近用VMware的时候是使用桥接方式,不知道是路由的问题还是其他,路由器里面没有显示虚拟机的连接,虽然虚拟机和主机都在路由器里分配了不同的IP地址,但是每次resume之后虚拟机的IP地址总是变,很麻烦。 VMware设置 把下面这个勾去掉。 然后点击Nat Settings。 记录网关。 虚拟机设置。把网络改成这个VMnet8。 Linux系统中配置静态IP Debian nano /e

2025-10-27 · 系统配置 · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…