[PR #2274] Fix systemd-resolved CPU spikes caused by Kill Switch DNS leak protection on Linux #2737

Open
opened 2026-10-14 21:04:23 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amnezia-client/pull/2274
Author: @ilsme
Created: 2/24/2026
Status: 🔄 Open

Base: dev ← Head: pr/linux-resolved-cpu


📝 Commits (1)

  • 0f3578a fix: avoid systemd-resolved CPU spikes with Kill Switch DNS leak protection enabled

📊 Changes

3 files changed (+56 additions, -4 deletions)

View changed files

📝 client/platforms/linux/daemon/dnsutilslinux.cpp (+45 -0)
📝 client/platforms/linux/daemon/dnsutilslinux.h (+2 -0)
📝 service/server/router_linux.cpp (+9 -4)

📄 Description

Problem

Repro is with Kill Switch enabled (default).

In this mode, Linux firewall enables 310.blockDNS and allows DNS only via 320.allowDNS to configured DNS servers on VPN interfaces (updateDNSServers, rules from getDNSRules).

So DNS to router/uplink (for example 192.168.50.1:53 on wlo1) is rejected by iptables. Kill Switch path that enables this: KillSwitch::enableKillSwitch.

If systemd-resolved has DefaultRoute=yes on both uplink and tunnel links, it still tries uplink DNS, gets ECONNREFUSED, and enters a frequent non-blocking retry loop (epoll/syscall wakeups), causing high CPU usage.

Disabling Kill Switch avoids this path but weakens DNS leak protection.

Related: #1532

Fix

  • During VPN DNS apply, set DefaultRoute=no on non-tunnel uplink link.
  • Keep DefaultRoute=yes on tunnel link.
  • Restore previous per-link DefaultRoute state on teardown (best-effort).
  • Use resolvectl flush-caches instead of restarting systemd-resolved.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amnezia-client/pull/2274 **Author:** [@ilsme](https://github.com/ilsme) **Created:** 2/24/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `pr/linux-resolved-cpu` --- ### 📝 Commits (1) - [`0f3578a`](https://github.com/amnezia-vpn/amnezia-client/commit/0f3578a390d2c7ecbfe71c332358d20977fee67b) fix: avoid systemd-resolved CPU spikes with Kill Switch DNS leak protection enabled ### 📊 Changes **3 files changed** (+56 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `client/platforms/linux/daemon/dnsutilslinux.cpp` (+45 -0) 📝 `client/platforms/linux/daemon/dnsutilslinux.h` (+2 -0) 📝 `service/server/router_linux.cpp` (+9 -4) </details> ### 📄 Description ## Problem Repro is with Kill Switch enabled (default). In this mode, Linux firewall enables [`310.blockDNS`](https://github.com/ilsme/amnezia-client/blob/pr/linux-resolved-cpu/client/platforms/linux/daemon/linuxfirewall.cpp#L250-L252) and allows DNS only via [`320.allowDNS`](https://github.com/ilsme/amnezia-client/blob/pr/linux-resolved-cpu/client/platforms/linux/daemon/linuxfirewall.cpp#L248) to configured DNS servers on VPN interfaces ([`updateDNSServers`](https://github.com/ilsme/amnezia-client/blob/pr/linux-resolved-cpu/client/platforms/linux/daemon/linuxfirewall.cpp#L446-L453), rules from [`getDNSRules`](https://github.com/ilsme/amnezia-client/blob/pr/linux-resolved-cpu/client/platforms/linux/daemon/linuxfirewall.cpp#L190-L200)). So DNS to router/uplink (for example `192.168.50.1:53` on `wlo1`) is rejected by iptables. Kill Switch path that enables this: [`KillSwitch::enableKillSwitch`](https://github.com/ilsme/amnezia-client/blob/pr/linux-resolved-cpu/service/server/killswitch.cpp#L326-L347). If `systemd-resolved` has `DefaultRoute=yes` on both uplink and tunnel links, it still tries uplink DNS, gets `ECONNREFUSED`, and enters a frequent non-blocking retry loop (epoll/syscall wakeups), causing high CPU usage. Disabling Kill Switch avoids this path but weakens DNS leak protection. Related: #1532 ## Fix - During VPN DNS apply, set `DefaultRoute=no` on non-tunnel uplink link. - Keep `DefaultRoute=yes` on tunnel link. - Restore previous per-link `DefaultRoute` state on teardown (best-effort). - Use `resolvectl flush-caches` instead of restarting `systemd-resolved`. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#2737
No description provided.