Skip to content

feat(dns): add DNS over HTTPS (DoH) support via blocky#200

Merged
vnepogodin merged 6 commits intoCachyOS:developfrom
awlx:feat/doh-support
Mar 28, 2026
Merged

feat(dns): add DNS over HTTPS (DoH) support via blocky#200
vnepogodin merged 6 commits intoCachyOS:developfrom
awlx:feat/doh-support

Conversation

@awlx
Copy link
Copy Markdown
Contributor

@awlx awlx commented Mar 25, 2026

Adds DNS over HTTPS (DoH) support using blocky as a lightweight local DNS proxy. When DoH is enabled, blocky handles resolution over HTTPS and NetworkManager points to 127.0.0.1.

Built on top of #196 (custom DNS server support).

What changed

DNS over HTTPS (DoH)

  • Added DoH toggle for each server that supports it (Cloudflare, Google, Quad9, AdGuard, FFMUC, etc.)
  • DoH and DoT are mutually exclusive — enabling one disables the other
  • Uses blocky as local DNS proxy on 127.0.0.1:53
  • Bootstrap DNS uses DoT-encrypted queries (tcp-tls:hostname with ips: list) when the server supports DoT, falls back to plaintext IPs otherwise
  • Both IPv4 and IPv6 bootstrap addresses are included (quoted for YAML safety)
  • blocky installed from CachyOS repo via pacman with pkexec GUI password prompt
  • Upstream strategy set to strict for predictable resolution order
  • Reset clears blocky (stops service, disables it) and restores DHCP
  • CLI gets --doh flag on dns set subcommand
  • State preserved across restarts: reads blocky config to detect active DoH server

Custom DNS with DoH

  • Added DoH URL input field to the custom DNS server form
  • Custom servers can use DoH with their own URL, using the configured IPv4/IPv6 addresses and DoT hostname for bootstrap resolution
  • CLI dns set-custom gets --doh and --doh-url flags
  • Empty bootstrap IPs are filtered to prevent blocky config errors

NetworkManager hardening

  • Set ipv4.ignore-auto-dns yes and ipv6.ignore-auto-dns yes when setting DNS (both DoT and DoH) to prevent DHCP-provided DNS servers from leaking alongside the configured encrypted servers
  • Reset restores ignore-auto-dns no for both protocols
  • Blocky restarts after NM (not before) to avoid bootstrap failures during network transition

Why blocky over dnscrypt-proxy

  • Simple YAML config — easy to generate programmatically, single file
  • Native DoH + DoT upstream support — covers the two most requested protocols
  • Bootstrap DNS with DoTtcp-tls: upstream with ips: for encrypted bootstrap, dnscrypt-proxy only supports plaintext bootstrap
  • Lightweight — single Go binary, ~15 MB, ~20 MB RAM, no databases or temp files
  • DoQ coming soon0xERR0R/blocky#2013 adds DNS over QUIC upstream support; once shipped, adding DoQ here is a one-line config change
  • dnscrypt-proxy is heavier, uses TOML + server stamps (harder to generate), and its primary focus is DNSCrypt protocol which is less widely adopted than DoH

More details on blocky: https://0xerr0r.github.io/blocky/latest/

Testing

Tested on CachyOS with NetworkManager 1.52, systemd-resolved, and blocky 0.29.0:

  • cachyos-hello dns set -c "Starlink" -s cloudflare --doh — sets Cloudflare with DoH enabled
  • cachyos-hello dns set-custom -c "Starlink" --ipv4 "45.90.28.220,45.90.30.220" --doh --doh-url "https://dns.nextdns.io/eb9cb4" --dot-hostname "eb9cb4.dns.nextdns.io" — custom NextDNS DoH with DoT bootstrap
  • cachyos-hello dns set-custom -c "Starlink" --ipv4 "45.90.28.220" --doh --doh-url "https://dns.nextdns.io/eb9cb4" — custom DoH without DoT hostname (plaintext bootstrap)
  • cachyos-hello dns list-servers — shows DoH URLs alongside DoT hostnames
  • cachyos-hello dns reset -c "Starlink" — resets DNS, stops blocky, restores DHCP
  • GUI: select server → check DoH → Apply; verified blocky running, config written, DNS resolving via dig @127.0.0.1
  • Verified DoT bootstrap: tcp-tls:cloudflare-dns.com with IPs when DoT available
  • Verified resolvectl query --cache=no shows encrypted transport: yes for DoT
  • Verified ignore-auto-dns prevents DHCP DNS leaks on both IPv4 and IPv6
  • Verified state persists across app restarts (blocky config read back)
  • Verified switching between DoH ↔ DoT ↔ reset works cleanly

Related issues

Future: DNS over QUIC (DoQ)

DoQ support can be added with minimal changes once blocky ships 0xERR0R/blocky#2013. The implementation would be a new doq:// upstream URL in the blocky config — no architectural changes needed.

Copy link
Copy Markdown
Member

@vnepogodin vnepogodin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good overall, besides AUR package

Comment thread src/actions.rs Outdated
@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 25, 2026

Found a bug after applying the DoH config and restarting Hello it picks it up as custom servers. Fixing that at the moment :).

@awlx awlx force-pushed the feat/doh-support branch from 77b3aea to b8cc490 Compare March 25, 2026 14:38
@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 25, 2026

Ok, it's now fixed and tested all kinds of scenarios:

  • Switching between DoH and DoT and no encryption for pre-configured servers
  • Tested Plaintext DNS and DoH and DoT for custom servers, tested DoH without DoT bootstrap for custom servers
  • Tested restarting of Hello and it correctly sees all the configured things reading from blocky or NetworkManager

@awlx awlx force-pushed the feat/doh-support branch 2 times, most recently from 51b7e89 to 2bfe65b Compare March 25, 2026 15:02
@awlx awlx requested review from ptr1337 and vnepogodin March 25, 2026 17:24
@ptr1337 ptr1337 requested a review from Copilot March 25, 2026 17:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds DNS-over-HTTPS (DoH) support by introducing a local blocky DNS proxy (127.0.0.1:53) and wiring it into both the GUI DNS page and the CLI, alongside existing DoT/custom DNS functionality.

Changes:

  • Add DoH toggle/support for preset providers and custom servers (GUI + CLI), using blocky as a local proxy.
  • Generate/read blocky YAML config to persist and detect active DoH server across restarts.
  • Adjust NetworkManager DNS application/reset logic and extend i18n keys for new UI/CLI strings.

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/pages/dns.rs GUI: add DoH toggle, custom DNS fields (including DoH URL), and apply logic for DoH via blocky
src/dns.rs Add DoH URL map, blocky config generation + parsing helpers, and CLI arg extensions
src/cli_handler.rs CLI: add --doh/custom DoH handling and show DoH URLs in list-servers
src/actions.rs Implement blocky install/config/start flow, DoH NM wiring, and new DNS parsing helpers
i18n/*/cachyos_hello.ftl Add new strings for DoH + custom DNS UI/CLI messages

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli_handler.rs Outdated
Comment thread i18n/zh-CN/cachyos_hello.ftl Outdated
Comment thread src/actions.rs Outdated
Comment thread src/actions.rs Outdated
Comment thread src/cli_handler.rs
Comment thread src/dns.rs
Comment thread src/actions.rs
Comment thread src/actions.rs
Comment thread src/cli_handler.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/pages/dns.rs
Comment thread src/pages/dns.rs
Comment thread src/pages/dns.rs
Comment thread src/pages/dns.rs
Comment thread src/cli_handler.rs
Comment thread src/dns.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

src/actions.rs:175

  • conn_name.replace('\'', "'\\'") does not correctly escape single quotes for use inside a single-quoted shell string (and can break the nmcli command / enable injection). Use the standard bash single-quote escape sequence ('\'') or a shared shell-escape helper, consistent with the escaping used for escaped_config above.
    src/actions.rs:265
  • conn_name.replace('\'', "'\\'") is also used here and has the same incorrect single-quote escaping issue, which can break the command string passed to bash -c. Please switch to the correct bash-safe escaping ('\'') or a shared escape helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/actions.rs
Comment thread src/pages/dns.rs
Comment thread src/dns.rs
Comment thread src/pages/dns.rs
Comment thread src/dns.rs
@awlx awlx force-pushed the feat/doh-support branch 2 times, most recently from d627cc8 to 8682824 Compare March 25, 2026 18:53
@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 26, 2026

@ptr1337 @vnepogodin all the relevant Copilot suggestions should now be addressed. I tested all the combinations again and it works for me :).

As a follow-up (don't want to over do this PR), I wonder if when pressing "reset" the selection should jump to "DHCP (automatic)" so people clearly see that none of the DNS servers is used. Same for the defaults on first start.

I can add a separate PR for that if it's something you are interested in, otherwise this now works :).

@vnepogodin
Copy link
Copy Markdown
Member

Will review in the coming days.

Yeah "reset" should reset to the previous state without CachyOS Hello modifications

@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 26, 2026

Yep, it does that already. I just thought of also making that visually more clear. But as said, it's probably something for a follow-up PR for now the behavior is the same as before :).

Copy link
Copy Markdown
Member

@vnepogodin vnepogodin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall

Comment thread i18n/af/cachyos_hello.ftl Outdated
Comment thread src/actions.rs Outdated
Comment thread src/actions.rs Outdated
@awlx awlx requested a review from vnepogodin March 27, 2026 15:51
@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 27, 2026

Fixed all issues :).

@vnepogodin
Copy link
Copy Markdown
Member

Fixed all issues :).

async await #196 )

@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 27, 2026

I think #196 will auto-close once this is merged as it's building on top.

@vnepogodin
Copy link
Copy Markdown
Member

Would prefer merging those separately via squash.

I can also remove from PR later if you want

@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 27, 2026

Will remove the translations tomorrow morning from the other PR then :). And rebase based on it so it merges cleanly.

@awlx
Copy link
Copy Markdown
Contributor Author

awlx commented Mar 28, 2026

Rebased on top of #196

@awlx awlx force-pushed the feat/doh-support branch from 561c30d to ac6afbd Compare March 28, 2026 07:49
awlx added 6 commits March 28, 2026 13:35
Add a 'Custom' option to the DNS server dropdown allowing users to
specify their own DNS server addresses and DoT hostname, addressing
use cases like NextDNS or other custom resolvers.

Changes:
- Add 'Custom' entry to DNS server combo box with IPv4, IPv6, and
  DoT hostname input fields
- Use NetworkManager's native 'address#hostname' notation to persist
  DoT hostnames across restarts
- Read back DoT state and hostname from NM on startup
- Add SNI hostname validation (RFC-compliant DNS labels)
- Add 'set-custom' CLI subcommand for custom DNS from command line
- Fix preset servers to include DoT hostname in addr#hostname format
- Add i18n strings for custom DNS to all 31 locales

Closes: CachyOS#144
The fallback mechanism automatically serves English when a translation
string is missing, so copying English strings to other locales is
unnecessary.
Add DoH support to the DNS settings page using blocky as a local DNS proxy.
When DoH is enabled, blocky is installed (blocky-bin from AUR), configured
with the selected server's DoH URL, and started as a systemd service.
NetworkManager is pointed to 127.0.0.1 for resolution.

Changes:
- Add DoH URL map for 14 DNS servers that support DNS over HTTPS
- Add blocky config generation with DoT-encrypted bootstrap DNS when the
  server supports it, falling back to plaintext IPs otherwise
- Add DoH checkbox to DNS settings GUI (mutually exclusive with DoT)
- Add --doh flag to 'dns set' CLI subcommand (conflicts_with dot)
- Add --doh and --doh-url flags to 'dns set-custom' for custom DoH
  servers, using the custom IPv4/IPv6 addresses and DoT hostname for
  bootstrap resolution
- Add DoH URL input field to the custom DNS server form
- Auto-install blocky-bin via paru with pkexec for GUI password prompt
- Stop and disable blocky on DNS reset or when switching to DoT/plain
- Show DoH support in 'dns list-servers' output
- Add i18n strings for DoH to all 31 locales

Built on top of CachyOS#196 (custom DNS server support).

Note: DNS over QUIC (DoQ) can be added once blocky ships with
0xERR0R/blocky#2013 (DoQ upstream support)

Addresses: CachyOS#156, CachyOS#144
- Remove untranslated English strings from all non-English i18n files;
  the fallback mechanism serves English automatically
- Use install_needed_packages for blocky installation in change_dns_server_doh
- Use utils::get_tweak_toggle_cmd in stop_blocky (consistent with install_winboat)
- Fix read_active_doh_url to strip YAML quotes so preset server detection works
@vnepogodin vnepogodin merged commit 9630283 into CachyOS:develop Mar 28, 2026
1 check failed
@vnepogodin
Copy link
Copy Markdown
Member

Many thanks

awlx added a commit to awlx/CachyOS-Welcome that referenced this pull request Mar 29, 2026
Add a 'DHCP (automatic)' entry to the DNS server dropdown so users can
clearly see when no custom DNS is configured. Selecting it and clicking
Apply resets DNS to automatic (same as the Reset button).

Changes:
- Add 'DHCP (automatic)' as the last entry in the DNS server combo box
- Show it as selected when no DNS servers are manually configured
- Clicking Apply with DHCP selected calls reset_dns_server()
- Reset button now jumps the combo to 'DHCP (automatic)' and unchecks
  DoT/DoH
- Disable DoT/DoH checkboxes and latency buttons when DHCP is selected
- Add dhcp-automatic i18n string to en locale

Follow-up to CachyOS#200 (DoH support) as discussed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Add DoH/DoT disable option and custom server support in DNS Changer DNS selection improvements

4 participants