nslookup 'DoH-on-alpine-linux-using-cloudflared' 127.0.0.1

Posted on May 9, 2021
tl;dr: Insecure nslookups are a thing of the past! You need the libc6-compat package to run cloudflared.

Hey Victor,

Can you make a dirty, probably worst-practice guide on how local clients can utilize DNS over HTTPS with automated malware blocking using cloudflared on an Alpine Linux box?

  Hold my insecure queries, I’m going in!  

Getting started

Please read https://developers.cloudflare.com/1.1.1.1/dns-over-https/cloudflared-proxy for the official instructions.

Here’s a simple step by step guide:
Step 0. Create an Alpine Linux VM.
My specs are:

  • 1 CPU
  • 6 GB disk
  • 512MB RAM

Installing cloudflared

Step 1. I start off by adding my regular Alpine Base packages - you probably have this in a template already.
This is not required, but like I said, this blog is a notepad for me, meaning I can just copy/paste everything here and the environment’s running just as I want it.

apk add -U bash shadow git wget curl htop nano qemu-guest-agent # install stuff
rc-update add qemu-guest-agent # and run qemu guest agent on boot

Step 2. Reboot

Step 3. Install cloudflared

mkdir -pv /etc/cloudflared # make a directory for cloudflared if you don't already have one.
cd /etc/cloudflared # we'll do everything here
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.tgz #get the latest cloudflared Linux binary
tar zxvf cloudflared-stable-linux-amd64.tgz # extract it
./cloudflared -version # try it!

cloudflared: not found

Huh?! But I see it and it is executable!

Step 4. Ah, that’s right! For cloudflared to run on alpine, we need to install the libc6-compat pkg..

apk add -U libc6-compat

Step 5. Make sure cloudflared is working

./cloudflared -version # make sure it works
cloudflared version 2021.4.0 (built 2021-04-07-2048 UTC)

Cool, it works!

Step 6. Run cloudflared’s DNS Proxy service using the following command:
cloudflared proxy-dns --address 0.0.0.0

Try resolving something from your client.
nslookup ssh.nu <your_server_IP>

Running cloudflared proxy-dns on boot?

I couldn’t find an openrc init file for cloudflared during my 15 seconds of googling, and I want to run the service at boot.
First, we need a config file, let’s save the following as /etc/cloudflared/config.yml.

proxy-dns: true
proxy-dns-address: 0.0.0.0
proxy-dns-upstream:
 - https://security.cloudflare-dns.com/dns-query

I’m using Cloudflare’s malware blocking resolver (aka 1.1.1.2).

Let’s create the init file, saved as /etc/init.d/cloudflared. This is actually just copied from /etc/init.d/httpd with some paths and args changed.

#!/sbin/openrc-run

name="cloudflared"
command="/etc/cloudflared/cloudflared"
command_args="--config /etc/cloudflared/config.yml"

depend() {
	need net localmount
        after firewall
}

Give it executable permissions

chmod +x /etc/init.d/cloudflared

And let’s run cloudflared on boot:

rc-update add cloudflared

Awesome! It actually works!
But wait a minute… After reboot, DNS resolving works, but I can no longer SSH to my server?!

Upon trying to log in to the server via console, I saw that it was stuck with a message:

getrandom indicates that the entropy pool has not been initialized. Rather than continue with poor entropy, this process will block until entropy is available.

a

Me trying to fix stuff…

Googling some, I found a proposed solution, to install the rng-tools package.
You guessed right, it didn’t help at all.

Me being me, I tried to do a dirty hack, adding a & to the end of the

command_args="--config /etc/cloudflared/config.yml"

line in /etc/init.d/cloudflared file, but it didn’t work either.

What did work, however, was another really dirty change in the /etc/init.d/cloudflared.
Change the depend function to make it run after sshd has started!:

depend() {
	need net localmount sshd
}

And tada, it works!
b

This of course works fine for setting up Cloudflare Tunnels as well.

Oh, and also, this works wonders if you use Cloudflare for Teams and want to use the resolvers for a location, just change the proxy-dns-upstream to reflect the value in your location’s “DNS over HTTPS” field.

If you want to run the very same setup, you can find my setup in my GitHub repository.
But please, as with everything on this blog, do not run this in production.