Thursday, November 12, 2015

Bypassing UDP/443 Blocks for Dnscrypt-Proxy

I've long been a fan of dnscrypt-proxy. It solves what is perhaps the internet's biggest security issue-- the domain name system. DNS requests are sent in plain text and are easily intercepted and altered. Cache poisoning, MITM attacks, and attacks from Nazi system administrators are all possible and quite simple thanks to the aging protocol. And that is why everyone ought to be encrypting their DNS requests via something like dnscrypt-proxy.

Recently, I've noticed a sick trend gaining traction. Dnscrypt uses UDP port 443 for resolution requests, and it seems that a lot of ISP's are blocking this port and/or forcing their customers to fall back to plain-text DNS. Although theoretically the program can operate over TCP as well, it's sort of a pain because I keep strict outbound iptables policies on my systems. I don't like giving dnscrypt more outgoing ports than it needs, not to mention TCP is slower.

What really ticked me was when I figured out why dnscrypt was not working on Digital Ocean's servers whatsoever... Yeah, you guessed it-- they're blocking outbound requests on UDP/443. Well done, D.O.! Rather than surrender to such insanity, I turned to Google for help, and found a post on twitter (can't find it at the moment) explaining that Digital Ocean is indeed doing what I suspected, and in response, a couple of the dnscrypt servers are now listening on UDP 5353 as well.

This hack worked perfectly, and within a few minutes I had an encrypted DNS server working on one of my D.O. nodes again! This is especially important to me because I am also administering some OpenVPN servers, and I like to provide security to the clients by serving DNS to them through dnscrypt-proxy combined with unbound for caching.

If you are experiencing similar issues from ISP blocks, than give this a try. Depending on how you installed dnscrpypt, you will have a configuration file somewhere that designates which nameservers you are using. I typically use this script for installation, so mine is located at /etc/init.d/dnscrypt-proxy .

Open the file and make a couple modifications, and you'll be back in buisiness:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          dnscrypt-proxy
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: dnscrypt-proxy
# Description:       dnscrypt-proxy secure DNS client
### END INIT INFO

# Authors: https://github.com/simonclausen/dnscrypt-autoinstall/graphs/contributors
# Project site: https://github.com/simonclausen/dnscrypt-autoinstall

PATH=/usr/sbin:/usr/bin:/sbin:/bin
DAEMON=/usr/local/sbin/dnscrypt-proxy
NAME=dnscrypt-proxy
PORT=5353
ADDRESS1=77.66.84.233:$PORT
ADDRESS2=176.56.237.171:$PORT
PNAME1=2.dnscrypt-cert.resolver2.dnscrypt.eu
PNAME2=2.dnscrypt-cert.resolver1.dnscrypt.eu
PKEY1=3748:5585:E3B9:D088:FD25:AD36:B037:01F5:520C:D648:9E9A:DD52:1457:4955:9F0A:9955
PKEY2=67C0:0F2C:21C5:5481:45DD:7CB4:6A27:1AF2:EB96:9931:40A3:09B6:2B8D:1653:1185:9C66

case "$1" in
  start)
    echo "Starting $NAME"
    $DAEMON --daemonize --ephemeral-keys --user=dnscrypt --local-address=127.0.0.1 --resolver-address=$ADDRESS1 --provider-name=$PNAME1 --provider-key=$PKEY1
    $DAEMON --daemonize --ephemeral-keys --user=dnscrypt --local-address=127.0.0.2 --resolver-address=$ADDRESS2 --provider-name=$PNAME2 --provider-key=$PKEY2
    ;;
  stop)
    echo "Stopping $NAME"
    pkill -f $DAEMON
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "Usage: /etc/init.d/dnscrypt-proxy {start|stop|restart}"
    exit 1
    ;;
esac

exit 0


There are only a couple nameserves listening on port 5353, so make sure you use one that is, such as 'dnscrypt.eu' . Now just restart the daemon:

service dnscrypt-proxy restart

OR

 /etc/init.d/dnscrypt-proxy restart

... and enjoy encrypted, untamperable DNS again!

By the way,  this blog is sort of moving to my new website, https://chev.tech. That's it for today.

No comments:

Post a Comment