image with Bitel's logo, secure DNS and text.

Bitel, an internet provider in Peru, drops DNS traffic to other servers.

This is a direct attack on Net Neutrality, privacy, freedom, and security.

In this example, I’ll use CloudFlare DNS as destination.

The problem

I exclusively use CloudFlare DNS on my personal laptop (MacBook Pro) so I set up my settings to use it on Wi-Fi and Ethernet.

I use security.cloudflare-dns.com or more exactly:

  • 1.1.1.2
  • 1.0.0.2
  • 2606:4700:4700::1112
  • 2606:4700:4700::1002

I have a little command to set up on my laptop:

networksetup -setdnsservers Wi-Fi 1.1.1.2 1.0.0.2 2606:4700:4700::1112 2606:4700:4700::1002

When I connect my laptop with my smartphone (hotspot) with my sim Bitel, I have a timeout and nothing more.

I tried a lot of tests and nothing is working… wait, no DNS traffic but TCP (directly using the IP address) is working to my webservers.

Net Neutrality, privacy and freedom

Net Neutrality is the principle that Internet service providers (ISPs) must treat all Internet communications equally, and not discriminate or charge differently based on user, content, website, platform, application, type of equipment, source address, a destination address, or method of communication.[4][5]

With net neutrality, ISPs may not intentionally block, slow down, or charge money for specific online content.

Without net neutrality, ISPs may prioritize certain types of traffic, meter others, or potentially block traffic from specific services, while charging consumers for various tiers of service.

We have the right to untrust our internet provider and use external DNS servers like CloudFlare or others depending on our need and trust.

I never trusted Bitel to be my DNS provider and now, I untrust it a lot more.

Security:

Yes, it’s also about security because Bitel is intentionally blocking other DNS so I can’t use CloudFlare for Families or any other solution using DNS like OpenDNS Family Shield to protect my child.

For example, 1.1.1.2/1.0.0.2 is blocking malware so it’s good for any personal computer to use it.

Bypass:

The only way to bypass easily this problem without security issues is by using DNS-over-TLS.

Install and configure Stubby

brew install stubby

This is a quick and working config: /usr/local/etc/stubby/stubby.yml

resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private : 1
round_robin_upstreams: 1
idle_timeout: 9000
listen_addresses:
  - 127.0.0.1
  - 0::1
upstream_recursive_servers:
  - address_data: 1.1.1.2
    tls_auth_name: "security.cloudflare-dns.com"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  - address_data: 1.0.0.2
    tls_auth_name: "security.cloudflare-dns.com"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  - address_data: 2606:4700:4700::1112
    tls_auth_name: "security.cloudflare-dns.com"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
  - address_data: 2606:4700:4700::1002
    tls_auth_name: "security.cloudflare-dns.com"
#    tls_pubkey_pinset:
#      - digest: "sha256"
#        value: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=

I commented on the pinset in this blog post because CloudFlare can change the certificate and you need to compute the new pinset using:

openssl s_client -connect 1.1.1.2:853 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

It’s time to start stubby:

  • to have launchd start stubby now and restart at startup:
    sudo brew services start stubby
    
  • if you don’t want/need a background service you can just run:
    sudo stubby -C /usr/local/etc/stubby/stubby.yml
    

Now, it’s time to set up the system to use it:

networksetup -setdnsservers Wi-Fi 127.0.0.1 ::1

Verify

You can open any website and look if you can see it or use your shell with my custom function that permits you to know which DNS server (IP and Organization) I use:

function whatsmydns() {
    local ip=$(ping whoami.akamai.net -c 1 | awk '/from/ {print $4}' | cut -d ':' -f1)
    echo $ip
    whois $ip | awk '/Organization/'
}

In my case, I need to see CloudFlare for the organization.

My evidence