Step 1: Create a Cloudflare Tunnel
Instead of traditional port forwarding, a Cloudflare Tunnel creates a secure outbound connection from your network to Cloudflare, meaning you can close port 443 on your pfSense WAN entirely.
- Launch the Tunnel:
- In the Cloudflare Zero Trust dashboard, go to Networks > Tunnels > Create a tunnel.
- Run Connector:
- Run the provided command on your Unraid server (ideally as a Docker container).
- Public Hostname:
- Map
jlab.remote-tech.usto the internal IP and port of your Jupyter instance (e.g.,http://192.x.x.x:XXXX)
- Map
Step 2: Add Access Policies
Once the tunnel is active, you must add an Access Application to require authentication.
- Add Application:
- Go to Access > Applications > Add an application.
- Domain:
- Enter
jlab.remote-tech.us.
- Enter
- Policy:
- Create a policy (e.g., “Allow Me”) that allows only your specific email address.
- Auth Method:
- You can use a “One-time PIN” sent to your email or link an identity provider like Google or GitHub
Step 3: Tighten HAProxy (If not using Tunnels)
If you prefer to keep using HAProxy instead of a tunnel,
you should restrict it to only allow Cloudflare IP addresses to prevent bots from hitting your WAN IP directly.
- Create Alias:
- In pfSense, go to Firewall > Aliases and create an alias called
Cloudflare_IPsusing the URL Tablehttps://www.cloudflare.com/ips-v4.
- In pfSense, go to Firewall > Aliases and create an alias called
- Apply ACL:
- In your HAProxy Frontend, add an ACL:
- Name:
is_cloudflare - Expression:
Source IP matches IP or Alias - Value:
Cloudflare_IPs.
- Name:
- In your HAProxy Frontend, add an ACL:
- Action:
- Add an Action to
http-request denyif!is_cloudflare.
- Add an Action to
By doing this, any bot scanning AT&T’s network that tries to hit your IP directly will be instantly rejected by your firewall or HAProxy, stopping the “abusive” activity from reaching your backend apps
Will it affect internal traffic?
The firewall alias and HAProxy changes will not affect your internal traffic as long as you have configured your network with Split-DNS. In a Split-DNS setup, internal devices resolve your domains (like jlab.remote-tech.us) to your local HAProxy IP instead of your public WAN IP, effectively staying within the LAN
- External Access:
- When you apply a “Cloudflare-only” rule to your WAN or HAProxy frontend,
it strictly filters traffic coming from the internet.
- When you apply a “Cloudflare-only” rule to your WAN or HAProxy frontend,
- Internal Access:
- If your internal devices point to the LAN IP of your pfSense/HAProxy,
they bypass the WAN interface’s firewall rules entirely.
- If your internal devices point to the LAN IP of your pfSense/HAProxy,
- The Caveat:
- If you use NAT Reflection (hairpinning) to access your sites via your WAN IP from inside the network, the Cloudflare-only rule will block you because your internal traffic will look like it’s coming from your local subnet, not a Cloudflare IP.
- Solution:
- Use a Host Override in pfSense (Services > DNS Resolver) to point your domains directly to your HAProxy’s internal LAN IP.
Using hairpinning (NAT Reflection) means your internal traffic technically “loops out” to the WAN interface before coming back in, which will cause your internal devices to be blocked if you apply a strict Cloudflare-only filter.
To maintain internal access while securing your public-facing apps from “abusive” traffic, you need to transition from hairpinning to a Split-DNS strategy.
1. Configure Split-DNS (Bypass Hairpinning)
By setting up DNS Host Overrides in pfSense, your internal devices will talk directly to your HAProxy’s LAN IP, bypassing the WAN firewall rules entirely.
- Navigate to:
Services > DNS Resolver. - Host Overrides: Click Add for each domain (e.g.,
jlab.remote-tech.us).- Host:
jlab - Domain:
remote-tech.us - IP: The Internal LAN IP of your HAProxy (often your pfSense IP).
- Host:
- Result: When you are at home, your domain resolves to
192.x.x.x. When you are away, it resolves to Cloudflare’s public IP
Restrict HAProxy to Cloudflare + LAN
Once Split-DNS is working, you can safely restrict your HAProxy Frontend to only allow your trusted sources.
- Create Alias: Use a URL Table (IPs) alias for Cloudflare:
https://www.cloudflare.com/ips-v4. - HAProxy ACLs:
is_cloudflare: Source IP matches IP or Alias →Cloudflare_IPs.is_local: Source IP matches IP or Alias →192.x.x.x/x(Your LAN).
- Action:
http-request denyif!is_cloudflareAND!is_local. - Impact: This kills the “abusive” traffic at your front door. Only legitimate traffic from Cloudflare or your own home network can reach your backends
Move to Cloudflare Zero Trust (Best Method)
If you set up the Cloudflare Tunnel as discussed, you won’t need hairpinning or open ports at all.
- Tunnel Bypass: You can configure Cloudflare Zero Trust policies to “bypass” authentication for your internal IP range, so you don’t have to log in when you’re sitting on your couch, but everyone else in the world does.
Note: After setting Host Overrides, you may need to flush your DNS cache on your devices or restart the unbound service in pfSense to see the change immediately.
Using a tunnel is the best way to stop the “abusive” traffic flags because it allows you to completely close port 443 on your router. Below is a docker-compose.yml optimized for Unraid:
version: '3.9'
services:
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: always
# On Unraid, storing in appdata is standard
volumes:
- /mnt/user/appdata/cloudflared:/home/nonroot/.cloudflared/
environment:
- TUNNEL_TOKEN=YOUR_TUNNEL_TOKEN_HERE
command: tunnel --no-autoupdate run
Setup Steps on Unraid
- Get your Token:
- In the Cloudflare Zero Trust dashboard, create a “Cloudflare Tunnel” (Networks > Tunnels).
- Select “Docker” as your environment to see your unique token.
- Deploy:
- Create a new stack in the Unraid Docker Compose Manager with the code above.
- Configure in Cloudflare:
- Once the container says “Connected” in your dashboard, add your “Public Hostnames” (e.g.,
jlab.remote-tech.us) and point them to your internal HAProxy or direct service IPs.
- Once the container says “Connected” in your dashboard, add your “Public Hostnames” (e.g.,
- Close Ports:
- Once you verify everything works via the tunnel, you can delete your Port 443 forward in pfSense.
- This immediately stops all external bots from being able to hit your IP
