0

I have a set of services where I'd like to set IP based ACLs (whitelist) for one, but not for the other. The issues seems to show up as the services run on the same port internally (port 80) but I use different ports on the gateway to access them.

Port 8088 on Gateway -> Port 80 on 10.0.0.A (with IP whitelist)
Port 80 on Gateway -> Port 80 on 10.0.0.B

And I can get this to work with everything open with the following rules:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j DNAT --to 10.0.0.A:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 10.0.0.B
iptables -A FORWARD -p tcp -i eth0 --dport 80 -j ACCEPT

The issue is that the FORWARD ACCEPT rule covers both of these nat rules, as they seem to be based on the destination port (--dport 80), instead of the incoming port on the gateway (80 vs 8088).

I can't figure out how to rewrite the FORWARD rule into 2 separate rules so that I can have different behaviour for connections coming into the gateway on 80 vs 8088.

Additional info:

lsb_release -d
Description:    Debian GNU/Linux 7.5 (wheezy)
iptables --version
iptables v1.4.14

1st Solution Attempt I have been able to spin off a chain and perform the routing there, but I am unable to add the ACL (reject) line due to the following error message:

x_tables: ip_tables: REJECT target: only valid in filter table, not nat

Here's what I put in:

iptables -t nat -N Whitelist
iptables -t nat -A Whitelist -p tcp -j DNAT --to 10.0.0.A:80
iptables -t nat -A Whitelist -s <whatsmyip.org> -j RETURN
iptables -t nat -A Whitelist -j REJECT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j Whitelist

Everything works fine until line 4, where the REJECT inside nat fails. If I comment the REJECT line out, I can confirm that the remainder of the logic works and the port becomes open to the wild because nothing is rejected.

Next Solution Attempt Seem to be tripping up on the original issue while working with a properly setup separate chain. The PREROUTING rule changing the port right off the top still seems to cause an issue with the non-nat ACL attempt. The ACL rules have no effect and the port is open to the wild.

iptables -N Whitelist
iptables -A Whitelist -s <whatsmyip.org> -j RETURN
iptables -A Whitelist -j REJECT
iptables -A INPUT -i eth0 -p tcp --dport 8088 -j Whitelist
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j DNAT --to 10.0.0.A:80

Solution Attempt #3 I tried setting up the whitelist first, then attempting port redirection after resolution of the whitelist. While the rules load, it does not have the intended effect as traffic does not reach it's intended destination from the whitelisted IP. Although I'm not actually 100% sure what the behaviour actually is. I can't tell if the traffic is being rejected in iptables, or maybe the connection is being accepted and pushed through to the destination on port 8088 without the port change? I'm not sure how to verify if the port redirect is actually being done. Here's the rules for this attempt:

iptables -N Whitelist
iptables -A Whitelist -s <whatsmyip.org> -j RETURN
iptables -A Whitelist -j REJECT
iptables -A INPUT -i eth0 -p tcp --dport 8088 -j Whitelist
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j DNAT --to 10.0.0.A
iptables -t nat -A OUTPUT -p tcp --dport 8088 -j REDIRECT --to-ports 80

Current status Unresolved. Unsure if I should see if I can figure out another way to redirect the port after the whitelist, or if there's an easy way to determine where the current solution is failing (is it forwarding through 8088 without the 80 redirect, or is it simply being blocked?)

1

Change

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j DNAT --to 10.0.0.A:80

to jump to a user-user defined chain that implements your acls. E.g.,

iptables -t nat -N foo
iptables -t nat -A foo --source 192.168.0.0/24 -j RETURN
iptables -t nat -A foo -j REJECT

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j foo

Edit:

iptables -N foo
iptables -A foo --source 192.168.0.0/24 -j RETURN
iptables -A foo -j REJECT
iptables -A INPUT -i eth0 -p tcp --dport 8088 -j foo

You design your packet filtering completely ignoring any NAT you are doing.

  • I am able to spin off a chain and perform the routing I wish, but I am unable to add the ACL (reject) line to the end. As such, it remains open to the wild regardless of if the IP matches. Once I figure out the different formatting in comments I'll edit the rules/chain I've got and add the error message – Doug Jan 18 '17 at 16:05
  • turns out this site doesn't support threaded discussions very well. I've modified the question itself with your recommended implementation and the error seen. – Doug Jan 18 '17 at 16:26
  • nat is the wrong table. It should be the filter table. I'll edit my answer. – Mark Wagner Jan 18 '17 at 19:03
  • Thanks for the update, I moved the whitelist/ACL rules to INPUT, but it seems that the NAT-PREROUTING port change is still tripping it up. From what I can tell in the docs you provided, the requirement of changing the port (in nat prerouting) causes other rules using --dport to trigger on the new port (80) instead of the original port (8088), therefore bypassing the ACLs in INPUT entirely. Is there a way to change the port it routes to on the destination after the INPUT whitelist and nat PREROUTING rules? – Doug Jan 19 '17 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.