Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE] AFWall+ 3.6 and OpenVPN Connect fails Android 11+ Private DNS #1355

Open
resolutecake opened this issue Sep 20, 2023 · 2 comments
Open
Labels

Comments

@resolutecake
Copy link

resolutecake commented Sep 20, 2023

Describe the bug
When on Android 11+ using OpenVPN Connect with Private DNS set to other than Off or Automatic and AFWall+ is enabled, DNS fails to function until the VPN is disconnected
— root cause is a race timing issue
— works for some fast local VPNs, but not for those slower public ones

Symptoms:
—a The exclamation mark superimposed on the statusbar LTE or Wi-Fi icon should go away within 1 second, it stays put
—b Within 11 seconds: pling and notification:
Network has no internet access
Private DNS server cannot be accessed
—c the Private DNS menu selection has text below: Couldn’t connect
—d Android apps fails with ERR_NAME_NOT_RESOLVED

GETAROUND:
Ensure that unencrypted DNS is always allowed for root inside the vpn tunnel:

Use a custom script ./data/dnsgoogle
(should work for all DNS providers)
Write file /data/dnsgoogle:

#!/system/bin/sh
# License: ISC
# /data/data/com.termux/files/usr/bin/nano /data/dnsgoogle
# Android 11+ Private DNS dns.google to work with AFWall+ 3.6
# if not present: statusbar has bars-with-question-mark, pling, Private DNS: Can’t Connect
# and Android apps errors: ERR_NAME_NOT_RESOLVED
# Only required for Private DNS Setting other than Off or Automatic
unset RULE CHAIN
# Allow regular DNS udp/53 inside vpn AT ALL TIMES
RULE=(--match owner --uid-owner 0 --out-interface tun0 --protocol udp --destination-port 53 --jump ACCEPT)
CHAIN=OUTPUT
if ! iptables --check $CHAIN "${RULE[@]}"; then
  iptables --insert $CHAIN "${RULE[@]}"
fi
unset RULE CHAIN

ls -l /data/dnsgoogle
-rwxr-xr-x 1 u0_a252 u0_a252 764 Sep 19 16:14 /data/dnsgoogle
— executable by root

root user access must be allowed in AFWall+ for any interface to be used

Firewall Logs
N/A

Smartphone (please complete the following information):
Pixel 3 Android 12 October 5, 2021 SP1A.210812.016.C2

Additional context
Likely, AFWall+ is busy rebuilding its configuration and while that is ongoing traffic is blocked. DNS resolution of Private DNS server like dns.google is not retried

For Android settings Private DNS: Off or Automatic, regular unencrypted DNS is used on troubles. Only the option with a set provider is full privacy

The most optimal DNS is:
DNS-over-HTTP/3 DoH3 udp port 443 packet-loss resilient, Android 11+
DoQ

DNS-over-TLS (DoT) incurs overhead for every DNS request: tcp port 853
https://security.googleblog.com/2022/07/dns-over-http3-in-android.html

There are others:
DNS-over-TLS (DoT) tcp port 853
DoQ udp port 8853 packet-loss resilient
DNS-over-HTTPS (DoH) tcp port 443
DNS-over-HTTP/3 DoH3 udp port 443 packet-loss resilient, Android 11+
https://help.nextdns.io/t/x2hmvas/what-is-dns-over-tls-dot-dns-over-quic-doq-and-dns-over-https-doh-doh3

@resolutecake
Copy link
Author

resolutecake commented Sep 20, 2023

Additionally, due to AFWall+ 3.6 design, initial packets may be delayed by up to 15 s due to temporary blocking of vpn and dns while AFWall+ is working. Because AFWall+ also blocks your apps, it’s difficult to benefit from the instant DNS

The following updated script enhances that:
— vpn is never blocked either, if you can design a good rule for your vpn
— regular DNS and Private DNS is never blocked, for how dns.google works, likely also others
— no need to unblock root in AFWall+, which is known to cause excessive traffick from Google apps

#!/system/bin/sh
# License: ISC
# /data/data/com.termux/files/usr/bin/nano /data/dnsgoogle
# Android 11+ Private DNS dns.google to work with AFWall+ 3.6
# if not present: statusbar has bars-with-question-mark, pling, Private DNS: Couldn’t Connect
# and Android apps errors: ERR_NAME_NOT_RESOLVED
# Only required for Private DNS Setting other than Off or Automatic
# Version: 230920 03:39
#
# UID for VPN Android app
VPNUID=10249
CHAIN=GDNS
CHAIN0=OUTPUT
#
unset RULE
iptables --new $CHAIN 2>/dev/null || :
RULE=($CHAIN0 --match owner --uid-owner 0 --out-interface tun0 --jump $CHAIN)
R="-A OUTPUT -o tun0 -m owner --uid-owner 0 -j $CHAIN"
# ensure at top
if [ "$(iptables --list-rules $CHAIN0 1)" != "$R" ] ;then
  iptables --delete "${RULE[@]}" 2>/dev/null || :
  iptables --insert "${RULE[@]}"
fi
#
# ensure vpn is never blocked 230920 02:31
# second position to be ahead of afwall rule
P=2
RULE=(--match owner --uid-owner $VPNUID --jump ACCEPT)
R="-A $CHAIN0 -m owner --uid-owner $VPNUID -j ACCEPT"
if [ "$(iptables --list-rules $CHAIN0 $P)" != "$R" ] ;then
  iptables --delete $CHAIN0 "${RULE[@]}" 2>/dev/null || :
  iptables --insert $CHAIN0 $P "${RULE[@]}"
fi
#
# Allow regular DNS udp/53 inside vpn AT ALL TIMES
RULE=(--protocol udp --destination-port 53 --jump ACCEPT)
if ! iptables --check $CHAIN "${RULE[@]}" 2>/dev/null; then
  iptables --insert $CHAIN "${RULE[@]}"
fi
# DoH3 udp/443
RULE=(--protocol udp --destination-port 443 --jump ACCEPT)
if ! iptables --check $CHAIN "${RULE[@]}" 2>/dev/null; then
  iptables --insert $CHAIN "${RULE[@]}"
fi
# DoT tcp/853
RULE=(--protocol tcp --destination-port 853 --jump ACCEPT)
if ! iptables --check $CHAIN "${RULE[@]}" 2>/dev/null; then
  iptables --insert $CHAIN "${RULE[@]}"
fi
unset RULE CHAIN CHAIN0 R P
echo at end of dnsgoogle

The resulting iptables:

for a in $(seq 1 3); do iptables --list-rules OUTPUT $a; done && iptables --list-rules GDNS
-A OUTPUT -o tun0 -m owner --uid-owner 0 -j GDNS
-A OUTPUT -m owner --uid-owner 10249 -j ACCEPT
-A OUTPUT -j afwall
-N GDNS
-A GDNS -p tcp -m tcp --dport 853 -j ACCEPT
-A GDNS -p udp -m udp --dport 443 -j ACCEPT
-A GDNS -p udp -m udp --dport 53 -j ACCEPT

@resolutecake
Copy link
Author

resolutecake commented Sep 22, 2023

This works on all my Androids

The requirements on AFWall+ to avoid
— up to 15 s network outages caused by AFWall+ and
— temporary DNS failures and permanent failure of Private DNS until the next network change
is for AFWall+ to never block, for no matter how short the time period:
— The VPN Android App in use
— Inside the vpn tunnel, DNS access by user 0 root over udp/53 udp/443 tcp/853

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant