Picture it, Sicily, 1937… OK, maybe not that. Picture it, you have a custom network service that you want to get at via Cloudflare WARP logged in to Cloudflare Zero Trust, but it isn’t the kind of thing that easily fits into the Public Hostname way of doing stuff (for example, it may run on a bunch of random port numbers and not work in a web browser). You also don’t want the service to be visible on the LAN where it is hosted.
So how do you go about satisfying all these requirements? With some hocus-pocus on the host machine and some careful setup in Zero Trust.
The setup we’ll use in this example
So we’re going to assume a bunch of things:
- The host machine will be Ubuntu 22.04.
- You want the service to be available only to selected Zero Trust users in your organization.
- It can’t be set up as an Application in Zero Trust.
- We’ll select an arbitrary private IP address not used anywhere else for this service:
10.0.0.1(adjust to taste).
- The service can be configured to listen on a specified IP address, the one we selected above.
On the host machine
So the basic idea is to add an IP address to the local loopback network interface (
lo), so it is only visible to processes on the host machine (It’s a bit of a kluge, and I didn’t know this was possible until I tried). The command to do this would be
ip address add 10.0.0.1/32 dev lo
Since we don’t want to have to log in to run this command after every reboot, we’ll set up a
systemd service to run it at boot time. Start by creating /etc/systemd/system/customstart.service, using the command sudo nano /etc/systemd/system/customstart.service. Put this in it:
[Unit] After=network.target [Service] ExecStart=/usr/local/bin/customstart.sh [Install] WantedBy=default.target
Next, we create /usr/local/bin/customstart.sh (
sudo nano /usr/local/bin/customstart.sh) and put this in it:
#!/bin/bash ip addr add 10.0.0.1/32 dev lo
Once that’s done, we set permissions because Security Is Important:
sudo chmod 644 /etc/systemd/system/customstart.service sudo chmod 700 /usr/local/bin/customstart.sh
Now we can enable out new “service” to run customstart.sh at boot time:
sudo systemctl enable customstart.service
Now you can happily reboot the host machine an the custom IP will be added to the loopback interface at boot time. You can also do other stuff in customstart.sh, maybe set up firewall rules and/or start your custom service. But because Security Is Important, starting or running a custom service type thing as root is a Bad Thing, using
@reboot in a non-root user’s
crontab is a better idea and setting it up as a systemd service that runs as a non-root user is an even better idea.
While you are on the host machine, install/configure your service to only bind to
10.0.0.1. If your service can’t do this, you will need to do clever
iptables stuff to limit your service to only be accessible on the
lo interface. For a Minecraft server (though Minecraft servers can bind to a specific IP address by setting
server.properties, so this is just an example), you would want something like:
iptables -A INPUT -i lo -p tcp --dport 25565 -j ACCEPT iptables -A INPUT -p tcp --dport 25565 -j DROP
Zero Trust tunnel setup
You will need to set up a cloudflared tunnel connecting the host machine to your Zero Trust organization. Some things that are different from the general documentation for that:
- You can skip the Public Hostname stuff.
- In Private Network, add 10.0.0.1/32 as the only entry.
WARP client profile
You may want to set up a Profile in WARP Client (under Settings in the Zero Trust dashboard) that has Split Tunneling set to Include instead of Exclude and only have
10.0.0.1/32 in the Include list, you can then assign this profile to users who must only see your service and nothing else. For other users, just make sure that
10.0.0.1/32 is either covered by Include mode split tunneling, or not blocked by Exclude mode split tunneling.
Zero Trust policies
In Gateway -> Policies on the Zero Trust dashboard, you need to set up policies controlling who can access your
10.0.0.1/32 “network”. In general (for the paranoid, like me, because Security Is Important), it’s a good idea to have an Allow rule specifying the destination IP and specific user accounts allowed to access it. Directly after that, add a Block rule specifying the destination IP and Everyone.
So, with these little tricks, a bit of hocus-pocus on the host machine and three basic things in Zero Trust, you have your service available to selected people in a secure way.
Users will just need to have the WARP client installed on their device and log in to your Zero Trust organization with it, then they can access the service on 10.0.0.1.