Cloudflare Zero Trust tunnel client does not support FreeBSD out of the box and Cloudflare does not provide FreeBSD binaries either. This means that we need to build the binary ourselves, and configure tunnel in a roundabout way: automatic tunnel setup does not work either. Lastly, we want to enable it in a way to survive the TrueNAS OS upgrades, let alone reboots.

Building the cloudflared binary

  1. Create a temporary jail named temp, enable DHCP, BPF, and VNET, and login:
    [email protected][~]# iocage create -r 13.1-RELEASE -n temp
    temp successfully created!
    [email protected][~]# iocage set dhcp=1 temp
    dhcp: 0 -> 1
    [email protected][~]# iocage set bpf=1 temp
    bpf: 0 -> 1
    [email protected][~]# iocage set vnet=1 temp
    vnet: 0 -> 1
    [email protected][~]# iocage console -f temp
    [email protected]:~#
  2. Now we are in the jail. Fetch and extract ports:
    portsnap fetch
    portsnap extract
  3. Build cloudflared:
    cd /usr/ports/net/cloudflared/
    env FORCE_PKG_REGISTER=1 make install clean
  4. You will be presented with a series of configuration dialogs, accept everything by default, except disable dtrace (for some reason it does not build, and we’re not going to be debugging the cloudflared anyway):


  5. Once the build process is complete, we are interested in two files: /usr/local/bin/cloudflared daemon and /usr/local/etc/rc.d/cloudflared rc script.
  6. Copy them out to some persistent location, for example, a dedicated dataset on your main pool, e.g. /mnt/pool1/cloudflared/.... We will symlink them into the correct positions later.
  7. At this point we no longer need the temp jail. Log out, stop, and destroy it:
    [email protected]:/usr/ports/net/cloudflared# exit
    [email protected][~]# iocage stop temp
    [email protected][~]# iocage destroy temp

Creating the tunnel

cloudflared service install ... does not work, so we will create a tunnel manually, and then migrate it to mange from the ZeroTrust dashboard.

  1. On the main TrueNAS instance symlink those two files to the expected locations:
    ln -s /mnt/pool1/cloudflared/usr/local/etc/cloudflared /usr/local/etc/cloudflared
    ln -s /mnt/pool1/cloudflared/usr/local/etc/rc.d/cloudflared /usr/local/etc/rc.d/cloudflared
  2. Also create a folder to hold cloudflare configuration data, and symlink it to the main host as well:
    mkdir -p /mnt/pool1/cloudflared/usr/local/etc/cloudflared
    ln -s /mnt/pool1/cloudflared/usr/local/etc/cloudflared /usr/local/etc/cloudflared
  3. Now login to cloudflare and follow the instructions:
    cloudflared tunnel login
  4. As a result, the cert.pem file will be created, move it to the configuration folder:
    mv /root/.cloudflared/cert.pem  /usr/local/etc/cloudflared
  5. Proceed with the tunnel creation per Cloudflare documentation1.
  6. Disable the TLS verification in the advanced properties of the tunnel if your TrueNAS instance uses self-signed certificate

Configuring persistence

  1. Create the file in your cloudflared dataset on the persistent pool with the commands necessary to configure the symlinks, cloudflared daemon and to start it.

    service cloudflared stop
    echo "Linking /usr/local/etc/cloudflared/"
    ln -sF /mnt/pool1/cloudflared/usr/local/etc/cloudflared /usr/local/etc/cloudflared
    echo "Linking /usr/local/bin/cloudflared"
    ln -sf /mnt/pool1/cloudflared/usr/local/bin/cloudflared /usr/local/bin/cloudflared
    echo "Linking /usr/local/etc/rc.d/cloudflared"
    ln -sf /mnt/pool1/cloudflared/usr/local/etc/rc.d/cloudflared /usr/local/etc/rc.d/cloudflared
    echo "Configuring the rc service"
    sysrc cloudflared_enable="YES"
    sysrc cloudflared_mode="tunnel run"
    service cloudflared start
  2. In Tasks, add an entry under Init/Shutdown Scripts section to call the script in POSTINIT`