0

I'm trying to forward ports 80, 443, 32400 to a machine internal to my network. So traffic from EXTIP:80 should go to SERVERIP:80 and responses back out through EXTIP:80, it would also be helpful if these changes persisted restarts of the router. The router has two IPs EXTIP and INTIP. It is connected directly to the modem without NAT. The router manages NAT for the internal servers.

I've tried any number of iptable changes around the internet, and there's usually side effects like I can no longer SSH into the router or outbound traffic stops working. The router is also running ufw and fail2ban

  • You mentioned ufw. do you need a ufw solution or are you happy with an iptables? It would be helpful, I think, if you could explain at least some of your "I've tried any number of iptables changes...". Do you have any special rules in your firewall that we need to be aware of, or are you comfortable mapping a solution offered here to your own situation? – roaima Sep 12 '16 at 19:56
  • I'm willing to manipulate a solution to my conditions. The only condition I can think of is that the EXTIP is a router, so my rules need to allow incoming traffic from outbound requests to go to the appropriate client. An iptable rule that maps all TCP:80 to SERVERIP will break internet for all other clients. – Drew Sep 13 '16 at 22:07
0

I haven't tested it, but I would try something like this:

iptables -t nat -A PREROUTING --protocol tcp --destination EXTIP --destination-port 80 -j DNAT --to-destination SERVERIP

Similarly for the other ports. Might that help?

  • This works okay for TCP traffic. However, it will redirect all traffic to that IP now including all HTTP traffic for all clients. So I can't access the internet from within the intranet once applying this rule. – Drew Sep 13 '16 at 16:58
  • Right, I should have included a destination address flag too. I've edited my reply now. (I said it was untested! :-)) Concerning TCP only: as you want to redirect ports 80 and 443 I assumed this was about HTTP traffic only. And HTTP typically is TCP only. But I don't think there is anything that would prevent you from redirecting UDP traffic in a similar rule. – Göran Uddeborg Sep 14 '16 at 21:00
  • hmm, this didn't seem to work. If I understand this correctly... Traffic onto EXTIP on port 80 is redirected to SERVERIP. Maybe it needs another rule to forward traffic from SERVERIP:80 back to SOURCE? – Drew Sep 15 '16 at 2:28
0

This sounds like a relatively straightforward set of rules.

  1. Allow anything on loopback
  2. Allow anything in that is the "other half" of an outbound request
  3. Allow anything out (from router to INT, router to EXT, or INT to EXT)
  4. Allow port 22 in from INT (inferred from your explanation)
  5. Allow port 80 in from EXT, and forward it on to the internal server
  6. Allow port 443 in from EXT, and forward it on to the internal server
  7. Allow port 32400 in from EXT, and forward it on to the internal server

Here is my suggestion. Untested because I don't have a two interface VM available just now.

# Definitions
INTIF=eth1             # Internal interface
EXTIF=eth0             # External interface
SERVERIP=192.168.1.12  # Internal webserver address

# Prepare to wipe the ruleset, so default to allowing everything
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# Erase the rulesets
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
iptables -t nat -F PREROUTING
iptables -t nat -F POSTROUTING

# Allow anything on loopback
iptables -i lo -j ACCEPT

# Allow anything in that is the "other half" of an outbound request
iptables -A INPUT -m state --state ESTABLISHED,RELATED

# Allow anything out (from router to INT, router to EXT, or INT to EXT)
iptables -A OUTPUT -j ACCEPT

# Allow port 22 in from INT (inferred from your explanation)
# Strictly, this is only required if you apply additional restrictions
# in the next rule, but I'm going to leave it here anyway
iptables -A INPUT -i $INTIF -p tcp --dport 22 -j ACCEPT

# Allow everything through from INT
# This allows internal access to the router too. You could add some extra
# rules here that disallow access to both the router's own IP addresses
iptables -A INPUT -i $INTIF -j ACCEPT

# Allow port 80 in from EXT, and forward it on to the internal server
# Allow port 443 in from EXT, and forward it on to the internal server
# Allow port 32400 in from EXT, and forward it on to the internal server
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport 80 -j DNAT --to-destination $SERVERIP
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport 443 -j DNAT --to-destination $SERVERIP
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport 32400 -j DNAT --to-destination $SERVERIP

# Set the default action to discard all traffic
iptables -P INPUT DENY
iptables -P OUTPUT DENY

# Enable forwarding
echo 1 >/proc/sys/net/ipv4/ip_forward
  • love how you say ~100 lines of iptables is straightforward :p I'm trying this out – Drew Sep 15 '16 at 2:28
  • Are there special requirements to run this? I'm getting several iptables errors when putting this in a shell script and executing it: iptables: No chain/target/match by that name. – Drew Sep 15 '16 at 2:38
  • @Drew for the PREROUTING lines? Fixed. Unfortunately, like I said at the top I've not been able to test this so it's quite possible you'll get some sillies. For your other comment, this suggestion is less than 20 lines of code. My usual preference would be to use shorewall or some other high-level tool that layers on top of iptables, but I'm not familiar with ufw so can't offer you a solution directly for that. – roaima Sep 15 '16 at 11:18
  • shorewall sounds useful, I'll look into that – Drew Sep 15 '16 at 16:50

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.