What's new

Port Forwarding - CIDR List Whitelist - scripting

Movian

New Around Here
Hey, a little pre amble for context of the issue I am trying to figure out, the question itself is later on but I wanted to ensure all relevant information was included.

so I have been setting up a small web host with a couple sites running in docker containers and an Nginx Proxy Manager (NPM) container to manage certificates and domain port forwarding on the internal level.

currently I have a port forward on 443 that points to the NPM container and this is working fine.

I am also using Cloud Flare for security and IP privacy.

I had trouble setting up the Cloud Flare Tunnel with my specific configuration, I know I can setup a single IP or CIDR with the port forward....
However both asus stock firmware and merlin only allow that one CIDR.

I want to provide a list of about 20 CIDRs allowed so that cloud flare connections are allowed in, but if someone tries to access the server by the direct IP (say adding the ip and domain to hosts file)
they will not gain access, thus forcing all connections through Cloud flare.

So with some research and full disclosure with some AI coding assistance for script templating, with me updating and finalizing the script.

I have a script that creates IP table rules, by downloading the list of CIDRs from cloud flare and using those.

However after running the script, the IPtables generate and they appear correct...

However I am unable to access any of the sites via domain...

but if I manually add back the port forwarding rule in the GUI with no IP restrictions... then everything starts working again.

if anyone has any insight or suggestions I would appreciate it

I attached my current script as a .txt as I was having trouble posting including it in the post.. I also created a firewall-start script that calls this script and I also plan when the script is working to setup a cron job once every 24 hours
so that any cloudflare IP changes are implemented automatically.
 

Attachments

I can't comment on your particular use case, but to the script itself;

1. -t nat commands should be called from nat-start, not firewall-start.
2. Your script is generating the same four -I FORWARD lines over and over again.
3. I don't understand why you have the -s 192.168.2.138 --sport 443 lines. They appear to be pointless, unless this is an nginx thing.
4. The -d 192.168.2.138 --dport 443 also appear to be redundant as there's already an existing rule that covers DNAT connections.
5. Likewise, the --sport 443 -j MASQUERADE lines appear to be redundant as there's an existing rule that covers that.
6. Do you really need to forward both UDP and TCP for port 443? Wouldn't TCP alone be sufficient?

N.B. Trying to access the internet using commands like curl in nat-start or firewall-start can be problematic because the internet connection may not have been fully established during boot up.
 
Last edited:
I had iterated over these a few times and as mentioned did use AI to generate a base script template, (Apologies for the slop)

I will try stripping out the mentioned items and see if that will resolve.

no I don't need UDP just TCP as these are just serving up HTTPS web sites.

Will try this out this evening and let you know how I get on with those changes.
 
It would seem more efficient to create an ipset for IPv4 addresses and another for IPv6 addresses and only have to create a single rule each type, versus an individual iptables rule for each CIDR in the downloaded file. Then you can update the ipset contents on a regular basis without destroying the rules.

Untested example (don't have an iptables router):
Bash:
INTERNAL_IP="192.168.2.138"
PORT="443"
WAN_IF="eth0"  

ipset -L -n cloudflarev4 || ipset -q create cloudflarev4 hash:net
ipset -L -n cloudflarev6 || ipset -q create cloudflarev6 hash:net family inet6

iptables -t nat -A PREROUTING -i $WAN_IF -p tcp -m set --match-set cloudflarev4 src --dport $PORT -j DNAT --to-destination $INTERNAL_IP:$PORT
ip6tables -I INPUT -p tcp -m set --match-set cloudflarev6 src --dport $PORT -j ACCEPT
Then you can run a cron job to download and update the ipset on a periodic basis:
Bash:
ipset flush cloudflarev4 || ipset -q create cloudflarev4 hash:net
awk '{print "add cloudflarev4 " $1}' "$IPV4_FILE" | ipset restore -!
ipset flush cloudflarev6 || ipset -q create cloudflarev6 hash:net family inet6
awk '{print "add cloudflarev6 " $1}' "$IPV6_FILE" | ipset restore -!
 
Last edited:

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top