Surfing the web a bit safer

Maybe people will think of me as Captain Obvious if I say that the web is not a safe environment. At the same time, and paradoxically, most of us do not take many practical actions to fight against the ever increasing attack on personal private privacy. Today I'll share with you one of my tactics to make life harder for the army of evil (aka adware/spyware industry).

The most common practice I observe is the use of VPNs in combination with TOR. While there is nothing wrong with this setup it is one that has some caveats. VPNs have usually an additional cost and TOR is usually useful to to protect against a subset of the internet traffic (usually http/https). Don't get me wrong, I completely endorse both.

In this post I will try to address a common threat that is usually ignored by most of us. The Domain Name System (DNS) resolution. DNS is a protocol that is used to make our life easier. Without DNS if I wanted to use Google I would need to use instead http://142.250.200.68 or https://[2a00:1450:4003:803::2004]/ in the ipv6 case

dig www.google.com  
;; ANSWER SECTION:
www.google.com.        152 IN  A   142.250.200.68

dig AAAA www.google.com  
;; ANSWER SECTION:
www.google.com.        27  IN  AAAA    2a00:1450:4003:803::2004  

I guess we can agree here that if we need to remember these IPs any time we need to communicate our life would be very close to hell. But it would not be only our life that would be hell developers as well. To understand why lets repeat the last command several times

dig AAAA www.google.com  
;; ANSWER SECTION:
www.google.com.        26  IN  AAAA    2a00:1450:4003:80d::2004  
;; ANSWER SECTION:
www.google.com.        237 IN  AAAA    2a00:1450:4003:80c::2004  
;; ANSWER SECTION:
www.google.com.        230 IN  AAAA    2a00:1450:4003:80e::2004  

If you pay attention the you noticed that www.google.com resolved to a different IP each time we ask for a resolution. Why is that? Because google need to distribute (or balance) the requests to different endpoints to be able to shard traffic to deal with the ridiculous amount of requests per second.

But yes we are digressing from the main topic. The idea here is that any time we go to the internet we don't use IPs, we use names. But why do I need to know this? You may ask. Well because usually when you establish a wifi connection there will be another protocol called DHCP which stands for Dynamic Host Configuration Protocol that will tell to your computer/smartphone who are the DNS servers that will be responsible for the name resolution.

In short you don't control the servers that will resolve the names for you. And this is where things start to become shady. Most of the time this is not properly an issue because we are on a trusted environment, usually our home network, it turns out that sometimes we are not. When you go to an hotel or a restaurant how do you know that the DNS Servers that where negotiated during the DHCP phase are not misbehaving? Short answer? You don't. Actually most of the times the DNS server is actually logging the requests and these are then sold to companies that use this for advertising purposes (and actually this is also true in your home with your ISP). But this is the most common, not the most nefarious. If you aren't lucky you happen to stumbled with a evil hacker that hijacked your connection to the router. In this case you are not actually connecting to a legitimate DNS server but with a nasty one. This is done usually with a technique called dns spoofing. I hope we can agree that by not controlling the name resolution you can be in trouble.

So the question is: How can I protect against this? Well if you're not tech savvy using a VPN will solve this out. The reason why is because with a VPN you tunnel all the traffic via the VPN servers and usually VPN connections will also set the name servers for you.

If you don't have a VPN there is a way to circumvent this DNS spoofing problem. How? Well basically by having your personal DNS server and rewriting /etc/resolv.conf with the loopback address.

How? You may ask! Well it turns out that this is a much more simple task than you may thing. Lets write down the steps

  • Run your personal dns server
  • Connect to wifi
  • Rewrite the /etc/resolv.conf file to use 127.0.0.1 as the server for local resolution

For the first point there are alot of solutions out there. In my personal setup I decided to use AdGuard. You can use their docker image and easily boot a container up. Or if you are a bit more security focused you can build your own docker image from scratch as well.

To make this a bit easier I created a Makefile to automate this a little bit. It looks like this

adguard-run:  
    @echo "Kill all dnsmasq processes"
    @killall dnsmasq | true
    @echo "systemd-resolved"
    @systemctl stop systemd-resolved
    @docker run \
    --restart unless-stopped\
    -v adguard-work:/opt/adguardhome/work\
    -v adguard-conf:/opt/adguardhome/conf\
    -p 53:53/tcp -p 53:53/udp\
    -p 80:80/tcp -p 443:443/tcp -p 443:443/udp -p 3000:3000/tcp\
    -p 853:853/tcp\
    -p 784:784/udp -p 853:853/udp -p 8853:8853/udp\
    -p 5443:5443/tcp -p 5443:5443/udp\
    -d adguard/adguardhome

set-resolv:  
    @echo "Down ${net_device}"
    @ifconfig ${net_device} down
    @echo "Set random mac address"
    @ifconfig ${net_device} hw ether $$(./setmacaddr.sh)
    @echo "Up wlp2s0"
    @ifconfig ${net_device} up
    @echo "Set ipv4 only"
    @sysctl -w net.ipv6.conf.all.disable_ipv6=1
    @echo "Override resolve.conf"
    @cp resolv.conf /etc/resolv.conf

So this Makefile has essentially two functionalities. One that starts the adguard server the other that set the local environment to be able to use the server.

The command that starts the local dns server is called adguard-run and it will do the following

  • Kill dnsmask and systemd-resolved to avoid conflicts with adguard
  • Start AdGuard in a container

After this is done we can establish a wifi connection with set-resolv. This will do the following:

  • Shutting down current wifi connection
  • Set fake mac address
  • Start wifi connection
  • Disable ipv6
  • Rewrite /etc/resolv.conf file

There is one step that we didn't discuss and is optional. The step in which we fake the mac address. The reason why I add this is because in untrusted environments the MAC address can be used for fingerprinting and tracking. MAC addresses use a concept called Organizationally unique identifier or OUI for short. Which means that part of the MAC address identifies the hardware manufactor and type of device. By using this information we can discover if the MAC address is pointing to a smartphone or a laptop. So in case you are the only guy in the bar with a laptop you are pretty easy to identify based on MAC. Tracking is also possible because if you don't randomize your MAC address you'll be using the same over several connections. How do we randomize then? Well inside the setmacaddr.sh script. Which is described below

#!/bin/bash
hexdump -n 6 -ve '1/1 "%.2x "' /dev/random |\  
awk -v a="2,6,a,e" -v r="$RANDOM" '  
    BEGIN {
        srand(r);
    }
    NR==1 {
        split(a, b, ",");
        r=int(rand() * 4 + 1);
        printf("%s%s:%s:%s:%s:%s:%s\n", substr($1, 0, 1), b[r], $2, $3, $4, $5, $6);
    }
'  

In short that will create random fake mac addresses any time is called, for example

./setmacaddr.sh 
9a:bb:4a:23:f3:38  
./setmacaddr.sh
52:ee:33:77:55:a8