Skip to content

wg-quick: fix dns cleaning on MacOS#22

Open
nesstord wants to merge 1 commit intoWireGuard:masterfrom
nesstord:master
Open

wg-quick: fix dns cleaning on MacOS#22
nesstord wants to merge 1 commit intoWireGuard:masterfrom
nesstord:master

Conversation

@nesstord
Copy link

@nesstord nesstord commented Nov 14, 2023

I found out that sometimes on MacOS calling wg-quick to shut down Wireguard doesn't return the original DNS servers that are specified in the network services.

To see why that happens, I added a file output on the line 327 in the function monitor_daemon and wrote a little script that tries to detect and log the problem.

# wireguard-tools/src/wg-quick/darwin.bash # ... monitor_daemon() { echo "[+] Backgrounding route monitor" >&2	(trap 'del_routes; del_dns; exit 0' INT TERM EXIT #exec >/dev/null 2>&1 exec >> /Users/user/wg-quick.log 2>&1 exec 19< <(exec route -n monitor) local event bpid=$BASHPID mpid=$!	[[ ${#DNS[@]} -gt 0 ]] && trap set_dns ALRM # ... }
# test_dns.bash #!/usr/bin/env bash LOG_FILE=/Users/user/wg-quick.log echo "[$(date -u)] start test" >> $LOG_FILE declare -A found_services get_response="" { read -r _ && while read -r service; do	[[ $service == "*"* ]] && service="${service:1}"	get_response="$(networksetup -getdnsservers "$service")"	[[ $get_response == *" "* ]] && get_response="Empty"	[[ -n $get_response ]] && found_services["$service"]="$get_response" echo "[$(date -u)] $service: $get_response" >> $LOG_FILE done; } < <(networksetup -listallnetworkservices) for (( i = 0; ; i++ )); do echo "[$(date -u)] loop $i" >> $LOG_FILE echo "[$(date -u)] up" >> $LOG_FILE wg-quick up "$1" > /dev/null 2>&1 sleep $(( RANDOM % 30 )) echo "[$(date -u)] down" >> $LOG_FILE wg-quick down "$1" > /dev/null 2>&1 sleep 3 # wait for graceful shutdown for service in "${!found_services[@]}"; do get_response="$(networksetup -getdnsservers "$service")" [[ $get_response == *" "* ]] && get_response="Empty" [[ $get_response != "${found_services["$service"]}" ]] || continue msg="dns error on loop $i, service $service, expected ${found_services["$service"]}, got $get_response" echo "$msg" osascript -e "display notification \"$msg\" with title \"Found\"" exit done done

I ran the script using
sudo ./test_dns.bash ~/wg0.conf

In this case, the problem occurred on the 82 try.

// /Users/user/wg-quick.log [Mon Nov 13 11:08:09 UTC 2023] start test [Mon Nov 13 11:08:09 UTC 2023] Thunderbolt Bridge: Empty [Mon Nov 13 11:08:09 UTC 2023] Wi-Fi: Empty [Mon Nov 13 11:08:09 UTC 2023] iPhone USB: Empty [Mon Nov 13 11:08:09 UTC 2023] loop 0 [Mon Nov 13 11:08:09 UTC 2023] up ... [Mon Nov 13 11:36:23 UTC 2023] loop 81 [Mon Nov 13 11:36:23 UTC 2023] up [#] networksetup -setdnsservers iPhone USB 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Thunderbolt Bridge Empty [#] networksetup -setdnsservers iPhone USB 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Thunderbolt Bridge Empty [Mon Nov 13 11:36:48 UTC 2023] down [#] networksetup -setdnsservers iPhone USB Empty [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi Empty [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge Empty [#] networksetup -setsearchdomains Thunderbolt Bridge Empty [Mon Nov 13 11:36:51 UTC 2023] loop 82 [Mon Nov 13 11:36:51 UTC 2023] up [#] networksetup -setdnsservers iPhone USB 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Thunderbolt Bridge Empty [Mon Nov 13 11:36:55 UTC 2023] down [#] networksetup -setdnsservers iPhone USB Empty [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi Empty [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge Empty [#] networksetup -setsearchdomains Thunderbolt Bridge Empty [#] networksetup -setdnsservers iPhone USB 8.8.8.8 8.8.4.4 // !!! set_dns is called after del_dns !!! [#] networksetup -setsearchdomains iPhone USB Empty [#] networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Wi-Fi Empty [#] networksetup -setdnsservers Thunderbolt Bridge 8.8.8.8 8.8.4.4 [#] networksetup -setsearchdomains Thunderbolt Bridge Empty 

As you see, sometimes set_dns is called after del_dns. I decided to implement a very simple fix that doesn't change the original logic: I added a flag that will stop the execution of set_dns if the monitor_daemon subprocess has finished. You can check out the changes in the commit.

I've been using this fix for about a week, and the bug hasn't occurred since then.
It could be used as a temporary solution until the proper fix is implemented.

@zx2c4-bot zx2c4-bot force-pushed the master branch 2 times, most recently from 4574b8e to 0b7d982 Compare June 19, 2025 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant