Using CloudNS For DNS Resolution – Integrity, Authenticity, Confidentiality

CloudNS is a DNS host that supports a few cool security features. I’ve set it up, and it’s working for me on Linux Ubuntu 13.04. I think its security features give it the potential to be the preferred choice for those looking for that higher level of security and privacy.

* DNSCrypt Support
We only allow connections to our service using DNSCrypt, this 
provides confidentially and message integrity to our DNS 
resolver, and makes it harder for an adversery watching the 
traffic of our resolver to identify the origin of a DNS query as
all the traffic is mixed together.

* DNSSEC Validation
Our server does complete trust validation of DNSSEC enabled 
names, protecting you from upstream dns poisoning attacks or 
other DNS tampering.

* Namecoin resolution
Namecoin is an alternative, decentralized DNS system, that is 
able to prevent domain name censorship. Our DNS server does local
namecoin resolution of .bit domain names making it an easy way to
start exploring namecoin websites.

* Hosted in Australia
Our DNS Server is hosted in Australia, making it a faster 
alternative to other open public DNS resolvers for Australian 
residents.

* No domain manipulation or logging
We will not tamper with any domain queries, unlike some 
public providers who hijack domain resolution for domains that
fail to resolve. Our servers do not log any data from connecting 
users including DNS queries and IP addresses that make 
connections.

I think those are some really interesting features. For one thing, it forces DNSCrypt and validates with DNSSEC, and it appears to be the only resolver to do both of these things. And it’s also hosted outside of the US, which has its own implications for security.

So I went ahead and set up CloudNS using the following command (and setting this in rc.local) after configuring DNSCrypt from this guide. You can check Cloudns.com.au for the updated information, but as of today (Aug 8th, 2013) this command works for me.

dnscrypt-proxy --user=dnscrypt
--daemonize --resolver-address=113.20.6.2:443 --provider-name=2.dnscrypt-cert.cloudns.com.au --provider-key=1971:7C1A:C550:6C09:F09B:ACB1:1AF7:C349:6425:2676:247F:B738:1C5A:243A:C1CC:89F4

To use the secondary server as well the command is:

dnscrypt-proxy --user=dnscrypt --daemonize --resolver-address=113.20.8.17:443 --provider-name=2.dnscrypt-cert-2.cloudns.com.au --provider-key=67A4:323E:581F:79B9:BC54:825F:54FE:1025:8B4F:37EB:0D07:0BCE:4010:6195:D94F:E330

So the three big improvements for me are DNSSEC, DNSCrypt, and Australia hosting.

DNSSEC

DNSSEC is an extension of DNS that aims to provide authentication and integrity of DNS results; it ensures that you know who the result is from and that no one else has tampered with it. DNS responses are authenticated but they are not encrypted, so DNSSEC does not prevent someone between you and the resolver from viewing the request.

DNSCrypt

DNSCrypt provides encryption of DNS requests, which provides confidentiality of the requests, meaning that an attacker between you and the resolver can not view the traffic between you and your DNS resolver.

Stacking DNSSEC and DNSCrypt works out very well, as you end up covering your bases and achieving confidentiality, integrity, and authentication.

Hosting In Australia

While I’m not particularly familiar with Australia’s laws, hosting outside of the US definitely provides a bit more peace of mind. Just yesterday we learned that Lavabit (the email provider chosen by Edward Snowden) has shut down due to the US government trying to compromise their ability to protect their users. The truth is that hosting in the US just makes a service less trustworthy at this point, and hosting outside is a big plus. This, combined with Namecoin and their pledge to not log, is really somewhat comforting.

So, while I can’t absolutely recommend it at this point (I haven’t been using it long enough) I think there’s a lot of potential here.

Hardening DNSCrypt

DNSCrypt is a DNS Resolver that encrypts the DNS requests between you and the first level DNS resolver. I have a guide for setting it up here. This guide will be about restricting the process and user account, making DNSCrypt more resilient to attack – I will continue to update this guide, I have a few more ideas.

One of the nice features of DNSCrypt is that it actually takes security into account. I wish this weren’t something to be shocked by, but, *gasp* it actually uses compiler security flags. Specifically, it uses the following flags:

-fPIC -fPIE -fstack-protector-all -fno-strict-overflow -fwrapv **

-fPIC and -fPIE tell the compiler to create a relocatable binary, completing the implementation of ASLR. It’s a mitigation technique we rarely seen used, despite it being somewhat critical, and it having been around for years. So right off the bat they’re doing more than most.

-fstack-protector-all (unlike the oft used -fstack-protector, which only protects functions using char arrays/strings) tells the compiler to protect every function with a stack canary. If an overflow occurs the canary may be overwritten, and the function will fail.

-fno-strict-overflow and -fwrapv are essentially the same (in other words, I don’t know the difference) and they tell GCC to not make assumptions about overflows, basically to not assume that overflows won’t occur. Compilers make the assumption that overflows won’t happen when they generate the optimized assembly, so they can build optimizations with that assumption – this prevents that, which is safer.

So these are nice, and we like them. But DNSCrypt also does a bit more.

You can create a new DNSCrypt user with no write rights, and it will chroot itself into that user, and drop rights. This is great, since a chroot’d process with no ability to write is difficult to break out of. And running as a separate user means no X11 access, it gets its own home folder, and it’s generally more isolated from the system – all good things!

But it means some other stuff too. Because it does all of the above we as users can take that protection further – beyond where typical programs allow us to. I think this demonstrates what a strong security model really can do when built from the ground up.

So, on to what we can do.

First thing’s first, we’re going to want some information on our DNSCrypt user.

run ‘id dnscrypt’

You should get something similar to:

id dnscrypt
uid=109(dnscrypt) gid=123(dnscrypt) groups=123(dnscrypt)

We’re going to need this.

IPTables On User

Note that if you’re using UFW this may cause issues, using UFW/GUFW with iptables isn’t recommended, and your mileage may vary  – to remove your UFW rules run ‘iptables -F’. 

Normally I’m not fond of outbound filtering, but because DNSCrypt separates itself into another user, it’s actually not such a bad idea. It means that DNSCrypt can’t just switch its outbound connection to another program under the same user account, and it means that the ports we limit will be limited to that user account specifically. This assumes you are using DNSCrypt under a user called ‘dnscrypt’.

So it’s a lot more worthwhile to set up outbound filtering here.

DNSCrypt should only need outbound access to port 443, with UDP. So we can restrict it to just port 443 and UDP with the following IPTables rules:

iptables -A OUTPUT -m owner --uid-owner dnscrypt -p udp  --dport 443 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner dnscrypt -j DROP

Basically, the first rule allows outbound access to the DNSCrypt user over port 443 and UDP, and the second rule denies everything. If the first rule is hit, and it passes, the second rule doesn’t have to come into play.

***

DNSCrypt is now restricted to UDP over port 443, and all processes running under the dnscrypt user are as well. If you followed the tip then no new connections can be made to your system except over port 53 (you can have dnscrypt use another port, in which case you’ll switch that port to whatever that one is. I have yet to figure the details of this out, I’ll edit it in when I do.)

Trusted Path Execution

If you care about security you’re already running Grsecurity, but if not, see my guide here.

Grsecurity has an option called Trusted Path Execution that allows us to limit a group, preventing it from executing files owned and only writable by root – since our program doesn’t run as root, and can’t write anywhere, it means it won’t be able to execute anything at all.

So check the TPE box and add the GID for untrusted users, in this case 123.

Now this protection is superfluous, DNSCrypt shouldn’t be able to write to the filesystem, so it shouldn’t be able to execute any payloads off of the file system, but it’s still good to have as the protection is now implemented by the user account itself, and doesn’t rely on the program to drop rights properly, or a perfect implementation of chroot.

Chroot Restrictions

While you’re compiling your Grsecurity kernel, you can also go ahead and turn on every single chroot restriction without worry – DNSCrypt works fine with them all. DNSCrypt already can’t write to its chroot, so  as far as I know there’s no known bypass as is, but you can safely enable all of these restrictions. Although some of the protections are a bit redundant due to the aforementioned write restrictions, there are a few that are quite nice, such as:

CONFIG_GRKERNSEC_CHROOT_FINDTASK

CONFIG_GRKERNSEC_CHROOT_CAPS

More restrictions on our exposed service.

Apparmor

Apparmor is an LSM (Linux Security Module) program that restricts a process. If Apparmor is the LSM used on your distribution (Ubuntu derivatives) you can find my profile here. Apparmor will restrict file access, what programs can be executed, what libraries can be loaded, etc. An attacker who winds up in a program that is confined with apparmor must either find a flaw in apparmor, or the profile, or they have to use a local escalation attack. If you’re using everything listed above this is going to be a lot of work for them.

Users of other LSM such as SELinux will need to build their own profiles. This shouldn’t be hard, DNSCrypt needs little file access to work.

Conclusion

Given the situation where an attacker finds himself compromosing the DNSCrypt-Proxy on a system that has done all of the above, they’re going to be pretty pissed off. There is still room for improvement, (seccomp filters) but right now an attacker is going to have to do a lot to get an exploit to be reliable.

For a program like DNSCrypt this level of security is great. It already chroots itself to a directory that it can’t write to, and they use compiler security, so you know they’re taking this stuff seriously. That’s what allows us to spend our time securing it further. If DNSCrypt did not so gracefully run as another user, and if it weren’t built to drop its rights to the extent that it does, then our apparmor profile would be more convoluted, TPE may not be possible, and an outbound Firewall would have been a useless attempt at security through obscurity. But because it’s built from the ground up to be this way we can reinforce it well.

Notes/ Tips

Much of this can be done to any process/ service with a bit of a change, but it’s nice to be able to do this to a process like DNSCrypt.

**

Keep in mind that you can add your own files to the makefile, such as “-march=native”, optimizing for your CPU. I can’t guarantee that this will play nice, or that it won’t add in unsafe compiler optimization! But you may end up using something like AES instructions since this deal swith crypto, and math, and this could speed things up.

***

Tip: The following commands will set your firewall so that:

1) If a connection is new, is over the loopback interface, is udp, and uses port 53, we accept it (allows dns resolution)
2) If a connection is already established from an outbound connection then we allow an inbound connection.
3)All other connections that do not meet the above criteria are blocked.

iptables -A INPUT -i lo  -m state --state NEW -p udp --dport 53 -j ACCEPT

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A INPUT -m  state --state NEW,INVALID -j REJECT

Apparmor Profile For DNSCrypt

DNSCrypt is a program that provides encryption for DNS requests. I have a guide for setting it up here and a guide for locking it down further here.

This is a short apparmor profile for the program. I’ve removed all abstractions, and it works for me.

# Last Modified: Sat Jul 6 02:21:04 2013
# This Apparmor profile is provided by insanitybit.com , and if there are updates that # is where you will find them. Report
# issues or changes there please!

#include <tunables/global>

/usr/local/sbin/dnscrypt-proxy {

network inet stream,
network inet6 stream,
network inet dgram,
network inet6 dgram,

capability block_suspend,
capability net_admin,
capability net_bind_service,
capability setgid,
capability setuid,
capability sys_chroot,

/usr/local/lib/libsodium.so* mr,

/bin/false r,
/dev/null rw,
/dev/urandom r,
/etc/ld.so.cache r,
/etc/localtime r,
/etc/nsswitch.conf r,
/etc/passwd r,
/lib/*-linux-gnu*/libc-*.so mr,
/lib/*-linux-gnu*/libm-*.so mr,
/lib/*-linux-gnu*/libnsl-*.so mr,
/lib/*-linux-gnu*/libnss_compat-*.so mr,
/lib/*-linux-gnu*/libnss_files-*.so mr,
/lib/*-linux-gnu*/libnss_nis-*.so mr,

/usr/lib/libsodium.so* mr,
/usr/local/lib/libsodium.so* mr,

/usr/lib/libdns.so* mr,

}

The dnscrypt-proxy service can run as a separate user, and chroot itself into the directory and drop rights. It also makes use of compiler security flags, so it’s PIE enabled, uses full RELRO, and stack protection. It’s pretty cool, but I like to be sure, so enforcing an apparmor profile is always nice.

With this apparmor profile enabled an attacker who compromises DNSCrypt will have absolutely no write access to the file system, and incredibly limited read access. The most viable option at this point is for them to go for a local kernel exploit.

Enjoy.

Setting Up DNSCrypt By OpenDNS On An Ubuntu 13.04 System

So I’ve just spent the time getting DNSCrypt working on my system. It was a bit of a pain but now that I got it done it shouldn’t be hard to recreate. I thought I’d write up a short guide explaining how to get it done.

Note that all double “-“s are turned into single ones. This is a WordPress issue. You’ll have to manually type them in, sorry.

Step 1: Setting Up A DNSCrypt User

sudo adduser --system --quiet --home /run/dnscrypt --shell /bin/false --group --disabled-password --disabled-login dnscrypt

That’s all one command. This is so that DNSCrypt can run as another user with no rights, and chroot itself into the directory.

Step 2: Install DNSCrypt

Find the right DNSCrypt version for you at this link:

http://download.dnscrypt.org/dnscrypt-proxy/

You’re going to have to unzip it and compile it. Traverse to the folder you’ve just unzippzed and run the following commands:

  • ./configure
  • make
  • make install

I personally have to run “make install” twice. No clue why.

Step 3: Configure DNS

Change your DNS settings to 127.0.0.1 in your network manager. Click the “wifi” area in the top right corner wifi and go to “edit connections”.  Select the network, and hit ‘Edit…’ then go to IPV4 Settings.

Make sure the Method is “Automatic (DHCP) Addresses Only” and set DNS Servers to 127.0.0.1

Step 4: Run DNSCrypt

Run the following command

dnscrypt-proxy --daemonize --user=dnscrypt

Step 5:

You can add the above command to /etc/rc.local so that it runs at bootup. You should also add the following command:

mkdir /run/dnscrypt

That way there’s a folder to move to.

That should be all it takes. Let me know how it works.

 

edit: You may need to install libsodium in newer versions, info here:

https://github.com/jedisct1/libsodium