# Iptables router. External IP from inside

## Rust710

My firewall script, built from a combination of Gentoo home router guide, Red Hat/CentOS scripts and other things I've stumbled apon over the last few months.

```

#!/bin/sh

export LAN=eth0

export WAN=eth1

iptables -F

iptables -t nat -F

iptables -P INPUT ACCEPT

iptables -P OUTPUT ACCEPT

iptables -P FORWARD DROP

-iptables -N GENTOO-Firewall-1-INPUT

iptables -F GENTOO-Firewall-1-INPUT

iptables -A INPUT -i ${WAN} -j GENTOO-Firewall-1-INPUT # Filter if from WAN

iptables -A GENTOO-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT p tcp -m state --state NEW -m tcp --dport 110  -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 6697  -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9000 -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 8000  -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 143  -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 6667 -j ACCEPT

iptables -A GENTOO-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

iptables -I INPUT 1 -i ${LAN} -j ACCEPT

iptables -I INPUT 1 -i lo -j ACCEPT

iptables -A INPUT -p UDP --dport bootps -i ! ${LAN} -j REJECT

iptables -A INPUT -p UDP --dport domain -i ! ${LAN} -j REJECT

iptables -A INPUT -p TCP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP

iptables -A INPUT -p UDP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP

#iptables -I FORWARD -i ${LAN} -d 192.168.0.0/255.255.0.0 -j DROP

iptables -A FORWARD -i ${LAN} -s 192.168.0.0/255.255.0.0 -j ACCEPT

iptables -A FORWARD -i ${WAN} -d 192.168.0.0/255.255.0.0 -j ACCEPT

iptables -t nat -A POSTROUTING -o ${WAN} -j MASQUERADE

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 22 -j DNAT --to 192.168.8.100:22

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 443 -j DNAT --to 192.168.8.100:443

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 81 -j DNAT --to 192.168.8.100:80

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 10000 -j DNAT --to 192.168.8.100:10000

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 8080 -j DNAT --to 192.168.8.100:8080

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 5000 -j DNAT --to 192.168.8.100:5000

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 2750 -j DNAT --to 192.168.8.101:2750

iptables -t nat -A PREROUTING -p tcp -i ${WAN} --dport 4000 -j REDIRECT --to-ports 22

```

What works:

As a router it works perfectly. All internal clients can access the internet.

The forwarded ports are reachable from the internet.

The opened ports work from the outside.

What doesn't work:

If an internal client on the internal network tries to connect to any of the forwarded ports from the external or internal IP, the connection fails.

Which is my question. I need to be able to connect to my external ip(or my hostname.whatever) and have it forwarded to the internal servers. I have done some looking and even found this post, but the solution used there didn't help.

----------

## Raffi

The easiest answer here is to have your internal machines go directly to the service and not through the firewall's forwarding. You can do this by either running your own internal dns that gives local addresses to the internal machines or by setting up a host file on the internal machines that point inside.

Things get more complicated if you have multiple services going to multiple machines but all using the same external name. If that case, I'd suggest adding aliases for the outside machines to the external dns and using different names for each service.

----------

## Rust710

I finally found out a way to get this to work.

```

iptables -t nat -A PREROUTING -p tcp -d ${WANIP} --dport ${FWD_PORT} -j DNAT --to ${INTERNAL_IP}:${FWD_PORT}

iptables -t nat -A POSTROUTING -p tcp --dport ${FWD_PORT} -s ${LAN_CLIENTS} -d ${INTERNAL_IP} -j SNAT --to-source ${WANIP}

```

For some reason beyond me at the moment, this works for all lan clients EXCEPT for the router. And if you access the ${INTERNAL_IP}:${FWD_PORT} from the router, it will also appear to the service on ${INTERNAL_IP}:${FWD_PORT} that you are connecting from ${WANIP} when connecting from the router. I'm sure some changes to IP tables would fix this, but in my situation it won't have much gain for me, so I doubt I will bother.

----------

## splooge

Good job!

If I may make a recommendation,

Best practice is to not allow private rfc1918 addresses to connect to the external interface.  This is to prevent spoofing.  If you're anal, your best bet would be to lock this down, run a DNS server on your internal lan that resolves internal clients host names, and recurses out to your ISP's dns for the rest.

You can lock it down by adding a rule like so:

iptables -A INPUT -i {EXT_IF} -s {INT_NET} -j DROP

good luck.

----------

## Rust710

So your recommending:

```

iptables -t nat -A PREROUTING -p tcp -d ${LANIP} --dport ${FWD_PORT} -j DNAT --to ${INTERNAL_IP}:${FWD_PORT}

iptables -t nat -A POSTROUTING -p tcp --dport ${FWD_PORT} -s ${LAN_CLIENTS} -d ${INTERNAL_IP} -j SNAT --to-source ${LANIP} 

iptables -t nat -A PREROUTING -p tcp --dport ${FWD_PORT} -i ${WAN} -j DNAT --to ${INTERNAL_IP}:${FWD_PORT}

```

For each forwarded port and:

```

iptables -A INPUT -i ${WAN} -s ${LAN_CLIENTS} -j DROP #Perhaps REJECT would be better?

```

On a slightly related note: I have a dyndns name(somethinghere.ath.cx), can I convince my DNS server to redirect that name and not the rest of .ath.cx, and make the rest of .ath.cx still work too?

----------

