NextDNS, Cloudflare Access and Zero Trust

My local network is my home playground. 3 years ago, I have set up a local server that acts as:

  • a router.
  • a custom DNS with ads blocking capabilities.
  • a nginx server that proxy request to a NAS server.
  • Unifi controller.

The main idea was to be able to stop ads or any tracking systems built-in into softwares or devices plugged on the network.

This setup has a major drawback, when I am on the move, well, nothing works… So to make it works, I build a relay server on VPC (Scaleway) to host a copy of the DNS server, but also to proxy requests to my internal server (and services). Also, this setup allows passing the Let’s Encrypt certificate validation system.

The relay server was connected to a WireGuard VPN, beta version, even before WireGuard was built into the Linux kernel ;)

Setup Before

So on my local network, the VPN was not connected, the WireGuard client allows to disable the VPN when connected to a specific WIFI SSID.

The true is that over time, servers are not maintained, sometimes servers crash: Adblock servers disappears => break the ad lists => break the DNS.

So, time to rechallenge this setup with 2021 tools and try to maintain less. Over the last 2 years, 2 tools have picked up my interest:

  • NextDNS.io: A DNS server as a service with Ads blocking and many other nice features.
  • Cloudflare for Teams: the solution integrated different products, cloudflared tunnel and Cloudflare Access. The tunnel part relies on a custom WireGuard implementation with proxy capabilities.

So, I have migrated to NextDNS on my mobiles devices using Apple Profile system and update my local DNS to use NextDNS. This was pretty easy, get pretty good results and this is more reliable as I don’t have to maintain the AdBlock list by myself.

The next step was to remove my VPC server and set up the cloudflared tunnel. As with any new Cloudflare product, the setup experience is not great.

I finally get the correct tunnel configuration by using Cloudflare certificates to my local Nginx server and NAS. Certificates are generated by Cloudflare and are valid for 10 years…

To make it works properly, I have to use the originServerName property so the server name can be detected by nginx.

The configuration looks like:

tunnel: REDACTED
credentials-file: /root/.cloudflared/REDACTED.json

ingress:
    - hostname: ssh.HOSTNAME.com
      service: ssh://localhost:22

    - hostname: netdata.HOSTNAME.com
      service: https://172.16.1.1:4443
      originRequest:
        originServerName: netdata.REDACTED.com

    - hostname: plusnet.HOSTNAME.com
      service: https://172.16.1.1:4444
      originRequest:
        originServerName: plusnet.HOSTNAME.com

    - hostname: nas.HOSTNAME.com
      service: https://172.16.1.52:5001
      originRequest:
        originServerName: nas.HOSTNAME.com

    - service: http_status:404

When the tunnel is created, a CNAME entry is also created on Cloudflare network. From that point, a CNAME entry needs to be defined for each service in your DNS zone, having a wildcard does not seems to work. Not ideal, but do the work for now.

At this stage, we also need to configure Cloudflare Access to protect applications access. Because, with the tunnel and DNS update, my very important apps are now exposed to the world!

So, Cloudflare for Teams allows to define different auth providers, I just used the default one using the email with pin. However, I failed to make it works. So I went with using Auth0, the service offers a free plan as long you don’t have 7000 active users - more than enough for a family… On Auth0, I have created a Cloudflare Access application, configure the different token, app id, callback URLs, etc … once done, I have disabled the sign-up option to avoid anyone creating an account.

The next pain was to attach all the strings together: application configuration, access policies, and the App Launcher. To make thing works, I have created a Family Members group which includes Auth0 as Login Methods. Once done, I have included the new group on each app. And voila!

Now anytime, I am reaching a service, Cloudflare Access checks if my browser has valid credentials if not the Auth0 login screen will be displayed for authentification.

Setup After

So, I finally have a similar setup, but now I don’t need a VPC server, that saved me some bucks - 500EUR spent over the last 3 years. NextDNS will probably cost me 72EUR for the next 3 years. Cloudflare and Auth0 are free.

Of course, the trade-off is that you need to trust the different services. All are incorporated in the US. So, this can be an issue for some, however, the US are not part of my threat model, so I am ok for now with that.

The traffic from the local network goes through the web. So, this is far from ideal, I have to investigate more on Cloudflare for Teams options - which also provides advanced tunnelling and DNS.

The next thing in my test and learn process is https://tailscale.com/. This can also be a good alternative to Cloudflare for Teams and can solve 2 things: traffic cannot be read by the service and traffic optimization based on the location. However, the current pricing plan is not suitable for a family.