Isolating cloudflared?

What is the name of the domain?

example.com

What is the issue you’re encountering

Wanting to isolate cloudflared, giving it access to my apache server only?

What steps have you taken to resolve the issue?

Okay, I have a cloudflared tunnel running on the same Debian machine as my apache server. I’m feeling quite nervous about this, as it appears anyone with the right access may see everything on my home network.

Somewhere there is a guide that will show me how to isolate cloudflared, and give it access only to my apache server instances, and prevent it accessing anything else on my network. Only thing is, I can’t find it, and ChatGPT seems to be quite confused (confusing) on the matter.

Anyone know where I can find the pertinent info, or maybe have tips to offer themselves?

Thx,
M.

How are you configuring Cloudflare’s? To connect to a network or to connect to hostname/port?

Hi, cscharff.

I installed the cloudflared that you configure remotely from the Cloudflare site, on the same machine as my apache server, and it’s set to expose https service from that machine via a domain name I have DNS setup for at Cloudflare.

It worries me that the tunnel will expose http traffic as well, even though there is no tunnel configured for that protocol. From what I understand, anyone with access to the remote configuration dashboard at Cloudflare, can setup tunnels to my cloudflared endpoint any way they like, and expose any and everything on my home network. Not want.

Thanks,
M.

If you don’t trust people to have access to your Cloudflare account, don’t grant them access. If you don’t trust Cloudflare :logo: then cloudflared is likely not the tool for you / you should set monitors for the configuration to alert you to changes made and kill cloudflared if detected.

1 Like

If the origin doesn’t listen on 80 it would die in transit and if you have configured the edge to update to https it would never get anywhere because it would be redirected.

This systemd unit file is designed to manage a cloudflared service within an isolated network namespace (isolated_ns) on a Linux system. It creates a virtualized network environment where the cloudflared tunnel service runs, with strict controls on the network traffic allowed to and from the service. Here’s a breakdown:

Network Isolation: The unit file sets up a virtual network namespace (isolated_ns) to run the cloudflared service in isolation from the rest of the system. This prevents the service from interacting with or accessing any parts of the host system except those explicitly allowed.

Network Setup: It configures virtual network interfaces (veth pair) to connect the isolated network namespace to the host’s network. The cloudflared service in the isolated network is configured with limited access to specific IP addresses and ports, and certain traffic types are restricted.

Security: Through iptables and ip6tables rules, the unit carefully controls inbound and outbound traffic, limiting communication to only what’s necessary for the service to function (e.g., communication with DNS, the web server, and the gateway).

New systemd unit file:

sudo nano /etc/systemd/system/cloudflared.service

[Unit]
Description=cloudflared
After=network-online.target
Wants=network-online.target

[Service]
TimeoutStartSec=0
Type=notify

Environment=LAN_IP_RANGE=192.168.0.0/24   # Adjust to reflect your LAN's IP range
Environment=WEBSERVER_IP=192.168.0.101    # Adjust to reflect your web server's IP
Environment=GATEWAY_IP=192.168.0.1        # Adjust to reflect your gateway's IP
Environment=DNSSERVER_IP=192.168.0.1      # Adjust to reflect your DNS server's IP

# Initialization:

# Create network isolated_ns.
ExecStartPre=ip netns add isolated_ns

# Create the veth pair (veth0 and veth1) in the root network isolated_ns.
ExecStartPre=ip link add veth_host type veth peer name veth_ns

# Move veth1 into the network namespace isolated_ns.
ExecStartPre=ip link set veth_ns netns isolated_ns

# Bring up the interfaces
ExecStartPre=ip addr add 192.168.100.1/24 dev veth_host
ExecStartPre=ip link set veth_host up

ExecStartPre=ip netns exec isolated_ns ip addr add 192.168.100.2/24 dev veth_ns
ExecStartPre=ip netns exec isolated_ns ip link set veth_ns up

# Set the Gateway and DNS server within the isolated_ns
ExecStartPre=ip netns exec isolated_ns ip route add default via 192.168.100.1
ExecStartPre=ip netns exec isolated_ns sh -c "echo 'nameserver $DNSSERVER_IP' > /etc/resolv.conf"

# Allow localhost access inside the isolated_ns
ExecStartPre=ip netns exec isolated_ns ip link set lo up
ExecStartPre=ip netns exec isolated_ns ip route add 127.0.0.0/8 dev lo


# 1. Inside the isolated_ns (Isolated Network isolated_ns).

# Allow outgoing traffic to the DNS server on port 53
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d $DNSSERVER_IP -p tcp --dport 53 -j ACCEPT
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d $DNSSERVER_IP -p udp --dport 53 -j ACCEPT

# Allow outgoing traffic to the local host's Web server on port 80 and 443
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d $WEBSERVER_IP -p tcp --dport 80 -j ACCEPT
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d $WEBSERVER_IP -p tcp --dport 443 -j ACCEPT

# Allow outgoing traffic to localhost (127.0.0.1)
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT

# Allow incoming traffic from localhost (127.0.0.1)
ExecStartPre=ip netns exec isolated_ns iptables -A INPUT -s 127.0.0.1 -j ACCEPT

# Allow return traffic for related and established connections (response to queries)
ExecStartPre=ip netns exec isolated_ns iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Block outgoing traffic to the local LAN (192.168.0.0/24) except for the 192.168.0.1 and DNS server
ExecStartPre=ip netns exec isolated_ns iptables -A OUTPUT -d $LAN_IP_RANGE -j REJECT

# Block incoming traffic from the local LAN (192.168.0.0/24) except for the 192.168.0.1 and DNS server
ExecStartPre=ip netns exec isolated_ns iptables -A INPUT -s $LAN_IP_RANGE -j REJECT


# 2. On the Host (Outside the isolated_ns).

# Enable IP forwarding on the host
ExecStartPre=sysctl -w net.ipv4.ip_forward=1

# Set up NAT for traffic from the isolated_ns (192.168.100.0/24) through the host (eth0)
ExecStartPre=iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE

# Allow forwarding from the isolated_ns to the Gateway on ports 7844, 443 and 53
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -p tcp --dport 7844 -j ACCEPT
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -p udp --dport 7844 -j ACCEPT
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -p tcp --dport 443 -j ACCEPT
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -p tcp --dport 53 -j ACCEPT
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -p udp --dport 53 -j ACCEPT

# Allow return traffic from the internet to the isolated_ns on ports 7844 and 443 (return traffic)
ExecStartPre=iptables -A FORWARD -i eth0 -o veth_host -m state --state RELATED,ESTABLISHED -j ACCEPT

# Drop all other incoming traffic to the isolated_ns
ExecStartPre=iptables -A FORWARD -i eth0 -o veth_host -j REJECT

# Drop all other outgoing traffic from the isolated_ns
ExecStartPre=iptables -A FORWARD -i veth_host -o eth0 -j REJECT

# Isolate cloudflared to prevent it using IPv6 traffic in, out or forward.
#ExecStartPre=ip netns exec isolated_ns ip6tables -P INPUT DROP
#ExecStartPre=ip netns exec isolated_ns ip6tables -P OUTPUT DROP
#ExecStartPre=ip netns exec isolated_ns ip6tables -P FORWARD DROP


# Run the cloudflared tunnel service in isolation
ExecStart=ip netns exec isolated_ns cloudflared tunnel run --token eyJhIjoiZDI0MWMxYzYzMWI0OWZmM2QiLCJ0IjoiODI2ZjY3YzAtMTJhMi00MOak00WlRBdFlqZzBZUzAwTlRsakxUazBZVGN0TVRJM1lXVXhaVEV3TldObSJ9I4ZWQ3M2VlMzdkNWZjMDjNmOGY5OGMzYjRhIiwicyjQ3LWJhNTUtNI6Ik1qUTB    # Adjust to reflect your tunnel's token (munged)


# De-initialization

# 1. Inside the isolated_ns (Isolated Network isolated_ns).

# Remove the rule allowing outgoing traffic to the DNS server on port 53
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d $DNSSERVER_IP -p tcp --dport 53 -j ACCEPT
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d $DNSSERVER_IP -p udp --dport 53 -j ACCEPT

# Remove the rule allowing outgoing traffic to the local host's Web server on port 80 and 443
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d $WEBSERVER_IP -p tcp --dport 80 -j ACCEPT
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d $WEBSERVER_IP -p tcp --dport 443 -j ACCEPT

# Remove the rule allowing outgoing traffic to localhost (127.0.0.1)
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d 127.0.0.1 -j ACCEPT

# Remove the rule allowing incoming traffic from localhost (127.0.0.1)
ExecStop=ip netns exec isolated_ns iptables -D INPUT -s 127.0.0.1 -j ACCEPT

# Remove the rule allowing return traffic for related and established connections
ExecStop=ip netns exec isolated_ns iptables -D INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Remove the rule blocking outgoing traffic to the local LAN (192.168.0.0/24)
ExecStop=ip netns exec isolated_ns iptables -D OUTPUT -d $LAN_IP_RANGE -j REJECT

# Remove the rule blocking incoming traffic from the local LAN (192.168.0.0/24)
ExecStop=ip netns exec isolated_ns iptables -D INPUT -s $LAN_IP_RANGE -j REJECT


# 2. On the Host (Outside the isolated_ns).

# Disable IP forwarding on the host
ExecStop=sysctl -w net.ipv4.ip_forward=0

# Remove the NAT rule for traffic from the isolated_ns through the host
ExecStop=iptables -t nat -D POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE

# Remove forwarding from the isolated_ns to the Gateway on ports 7844, 443 and 53
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -p tcp --dport 7844 -j ACCEPT
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -p udp --dport 7844 -j ACCEPT
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -p tcp --dport 443 -j ACCEPT
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -p tcp --dport 53 -j ACCEPT
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -p udp --dport 53 -j ACCEPT

# Remove the rule allowing return traffic from the internet to the isolated_ns
ExecStop=iptables -D FORWARD -i eth0 -o veth_host -m state --state RELATED,ESTABLISHED -j ACCEPT

# Remove the rule rejecting incoming traffic to the isolated_ns
ExecStop=iptables -D FORWARD -i eth0 -o veth_host -j REJECT

# Remove the rule rejecting outgoing traffic from the isolated_ns
ExecStop=iptables -D FORWARD -i veth_host -o eth0 -j REJECT

# Remove the default route and DNS configuration from the isolated_ns
ExecStop=ip netns exec isolated_ns ip route del default via 192.168.100.1
ExecStop=ip netns exec isolated_ns sh -c "echo '' > /etc/resolv.conf"

# Delete the loopback interface route (optional cleanup)
ExecStop=ip netns exec isolated_ns ip route del 127.0.0.0/8 dev lo

# Bring down the veth interfaces
ExecStop=ip link set veth_host down
ExecStop=ip netns exec isolated_ns ip link set veth_ns down

# Delete the veth pair
ExecStop=ip link delete veth_host

# Delete the network namespace isolated_ns
ExecStop=ip netns del isolated_ns


Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

New update systemd unit file:

sudo nano /etc/systemd/system/cloudflared-update.service

[Unit]
Description=Update cloudflared
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/bin/bash -c '/usr/bin/ip netns exec isolated_ns /usr/bin/cloudflared update; code=$?; if [ $code -eq 11 ]; then systemctl restart cloudflared; exit 0; fi; exit $code'

The original timer system unit file (/etc/systemd/system/cloudflared-update.timer) needs no changes.

Summary:

This systemd unit ensures that the cloudflared tunnel runs in a highly controlled and isolated network environment, minimizing potential security risks. The service is confined to a specific network namespace with access limited to only the essential services and traffic types, effectively preventing unintended or malicious communication with other parts of the host system.

Some commands to help in debugging:

sudo nano /etc/systemd/system/cloudflared-update.service

sudo nano /etc/systemd/system/cloudflared.service

sudo systemctl daemon-reload

sudo ip netns add isolated_ns

sudo ip netns del isolated_ns

sudo systemctl enable cloudflared.service

sudo systemctl disable cloudflared.service

sudo systemctl start cloudflared.service

sudo systemctl stop cloudflared.service

sudo systemctl status cloudflared.service

journalctl -u cloudflared.service -b | grep -i error

HTH,
M.

1 Like