dnscrypt-proxy on Android with Universal-init.d
Device root access is required.
This method is tried and tested with Android 6 - 9 (LineageOS 13 - 16); mostly on a Samsung Galaxy S5 (klte).
Summary
This guide describes how to configure an Android device so that all DNS requests (on both cellular and WiFi) are encrypted between the device and the DNS server using the DNSCrypt protocol and dnscrypt-proxy client. Universal-init.d is used so it will run automatically when the device boots. dnscrypt-proxy is not installed as an Adroid zip package; it is copied directly to the device.
Requirements
To use this guide, you must have a working Android system with root (su
) access. A custom ROM is not required;
however, root is.
Prerequisites
To use this guide, you need a computer with adb
installed and
developer mode enabled on the device. USB debugging permission must be granted to the computer.
Why do this?
- Privacy
- Stops your carrier from being able to monitor your DNS traffic
- Stop your carrier from DNS hijacking
- Block requests to unwanted hosts at the device level
- Block traffic to hosts that leak information or compromise privacy
- Choice
- Android (normally) does not allow custom DNS servers on cellular connections!
- Performance
- If using fast DNS servers close to your location
- Block trackers and ads
Installation
Install Universal-init.d
Universal-init.d is an Android application that emulates the behavior of the init.d kernel mechanism. It allows us to run custom scripts at boot, which will be used to start dnscrypt-proxy automatically and add iptables rules to redirect DNS requests through dnscrypt-proxy.
If you can't or don't want to use Universal-init.d, that is okay as long as you can get the dnscrypt-proxy script to run using some other method (either manually or with some other software to run it on every boot).
Install Universal-init.d from the Play store or other source (apk).
Turn Init.d support on, test and reboot.
Re-open Universal-init.d and make sure that it says "Your Kernet has init.d Support".
Install dnscrypt-proxy binary
Download the dnscrypt-proxy-android release for your architecture and extract the files to a temporary location.
The dnscrypt-proxy
binary will be placed in /system/xbin
.
Connect your device to the computer and enable USB file transfer.
Copy the dnscrypt files to a temporary location on the device's external memory card or internal shared stored.
Unmount storage, turn off file transfer and set back to charging only.
Connect to a shell on your device using adb
. Once you have a shell, run su
to switch to root.
# from your computer
adb shell
# once on the device
su
Now re-mount the system partition to be writable:
mount -o remount,rw /system
Copy dnscrypt-proxy to /system/xbin
(replace /sdcard/dnscrypt-proxy
with the location where the files were copied in the above step):
cp /sdcard/dnscrypt-proxy /system/xbin/.
Install dnscrypt-proxy configuration files
The config files will be kept in /data/local/dnscrypt-proxy
From the root, shell, create the directory:
mkdir /data/local/dnscrypt-proxy
Copy dnscrypt-proxy.toml
to config path:
cp /sdcard/dnscrypt-proxy.toml /data/local/dnscrypt-proxy/.
chmod +x /data/local/dnscrypt-proxy
Enable dnscrypt-proxy at boot
The following init script runs dnscrypt-proxy
and redirects outbound DNS requests to go through dnscrypt-proxy
.
Copy this init script to /etc/init.d/99dnscrypt
, or run vim /etc/init.d/99dnscrypt
from the adb root shell, paste the contents, and save.
#!/system/bin/sh
DNSCRYPT_PROXY="/system/xbin/dnscrypt-proxy"
CONFFILE="/data/local/dnscrypt-proxy/dnscrypt-proxy.toml"
PIDFILE="/data/local/tmp/dnscrypt-proxy.pid"
APPEND="-A"
WAITFORDAEMON=10
STOP=0
nohup="nohup"
_log() {
log -p i -t dnscrypt-init -- $1
echo "$1" 1>&2
}
_wait_for_pid() {
cnt=0
while true ; do
sleep 1
if test -s "$PIDFILE" ; then
pid=$(cat "$PIDFILE")
if kill -0 $pid 2>/dev/null ; then
return 0
fi
fi
[ "`expr $cnt % 3`" != 2 ] || _log "."
cnt=`expr $cnt + 1`
if [ $cnt -gt $WAITFORDAEMON ] ; then
break
fi
done
return 1
}
## Begin
if [ "$1" = "--debug" ] ; then
nohup=""
_log "Attempting to run dnscrypt-proxy in foreground"
fi
if [ "$1" = "--stop" ] ; then
STOP=1
APPEND="-D"
_log "Stopping dnscrypt-proxy"
else
_log "Starting dnscrypt-proxy"
fi
if [ -s "$PIDFILE" ] ; then
# if dnscrypt-proxy is running, kill
kill $(cat "$PIDFILE")
rm -f "$PIDFILE"
fi
if [ $STOP -eq 0 ] ; then
cmd="""$DNSCRYPT_PROXY"" -config ""$CONFFILE"" -pidfile=""$PIDFILE"""
if [ "$nohup" != "" ] ; then
$nohup $cmd >/dev/null 2>&1 &
_wait_for_pid
if [ $? -ne 0 ] ; then
# delete iptable rule
APPEND="-D"
_log "failed to start dnscrypt-proxy"
_log "Try running '$0 --debug' or enable logging and check the logs for errors"
exit 1
fi
else
$cmd
fi
fi
iptables -t nat $APPEND OUTPUT -p tcp --dport 53 -j DNAT --to-destination 127.0.0.1:533
iptables -t nat $APPEND OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:533
Make the script executable:
chmod +x /etc/init.d/99dnscrypt
With Universal-init.d enabled, this script will execute at boot and start dnscrypt-proxy
and redirect DNS requests through it.
From a shell, running this file directly will also start or restart the process.
Testing & Troubleshooting
Starting & Restarting
To start or restart dnscrypt-proxy, run the following command from a root shell:
/etc/init.d/99dnscrypt
Note: This can be run from adb
or from a terminal emulator on the device (as long as you can run su
from the terminal).
From a shell on your device, you can see if it is running at any time:
# ps -A | grep dnscrypt
root 8849 1 810176 8644 futex_wait_queue_me aa97632c S dnscrypt-proxy
Testing DNS resolution
/system/xbin/dnscrypt-proxy -resolve example.com
Debugging
If dnscrypt-proxy fails to run or cannot resolve anything, run it in debug mode (which runs dnscrypt-proxy in the foreground):
/etc/init.d/99dnscrypt --debug
Output from dnscrypt-proxy will be written to the console so you can identify why it may be failing to work.
Stopping
If there are problems with dnscrypt or you need to fall back to regular system DNS, use:
/etc/init.d/99dnscrypt --stop
Document History
Version 1.0 (2019/04/05): Initial version