LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   iptables, port forward problem... (https://www.linuxquestions.org/questions/linux-security-4/iptables-port-forward-problem-132556/)

wildwolf 01-07-2004 07:31 PM

iptables, port forward problem...
 
Hi there.

I'm trying my absolutely brain out to get port forwarding working with iptables. I had thought I had it working in the past (as in a year or three ago) but I wanted to run an internal webserver through an external IP, and thought it would be a simple couple of lines in my script and found out that wasn't the case.

I've spent all day (3-4 hours of trying various techniques I've stumbled across on the net or thought of on my own) and nothing seems to allow this to work.

I'm at the point where I'm not sure it's that I'm just ignorant, or that there's something else in the system that's preventing it.

I'd be happy with just a simple, example script now, that will allow NAT/iptables firewall support that does one simple port foward: port 80.

My network is setup as thus:
eth0 DHCP controlled, script does a fine job of getting the IP.
eth1 192.168.1.1
Machine to forward port 80 traffic to: 192.168.1.2

Script I'm attempting to use, but failing with (Note* I do have a script that's a whole lot more complex that I normally use, but wanted to use this almost "bare bones" older version that does the NAT part just fine so that I'm ensuring that some complex settings are not the problem holding the port forwarding back):

<start of file>
#!/bin/sh
#
# rc.firewall-2.4
FWVER=0.63
#
# Initial SIMPLE IP Masquerade test for 2.4.x kernels
# using IPTABLES.
#
# Once IP Masquerading has been tested, with this simple
# ruleset, it is highly recommended to use a stronger
# IPTABLES ruleset either given later in this HOWTO or
# from another reputable resource.
#
#
#
# Log:
# 0.63 - Added support for the IRC IPTABLES module
# 0.62 - Fixed a typo on the MASQ enable line that used eth0
# instead of $EXTIF
# 0.61 - Changed the firewall to use variables for the internal
# and external interfaces.
# 0.60 - 0.50 had a mistake where the ruleset had a rule to DROP
# all forwarded packets but it didn't have a rule to ACCEPT
# any packets to be forwarded either
# - Load the ip_nat_ftp and ip_conntrack_ftp modules by default
# 0.50 - Initial draft
#

echo -e "\n\nLoading simple rc.firewall version $FWVER..\n"


# The location of the 'iptables' program
#
# If your Linux distribution came with a copy of iptables, most
# likely it is located in /sbin. If you manually compiled
# iptables, the default location is in /usr/local/sbin
#
# ** Please use the "whereis iptables" command to figure out
# ** where your copy is and change the path below to reflect
# ** your setup
#
IPTABLES=/sbin/iptables
#IPTABLES=/usr/local/sbin/iptables


#Setting the EXTERNAL and INTERNAL interfaces for the network
#
# Each IP Masquerade network needs to have at least one
# external and one internal network. The external network
# is where the natting will occur and the internal network
# should preferably be addressed with a RFC1918 private address
# scheme.
#
# For this example, "eth0" is external and "eth1" is internal"
#
# NOTE: If this doesnt EXACTLY fit your configuration, you must
# change the EXTIF or INTIF variables above. For example:
#
# EXTIF="ppp0"
#
# if you are a modem user.
#
EXTIF="eth0"
INTIF="eth1"
echo " External Interface: $EXTIF"
echo " Internal Interface: $INTIF"


#======================================================================
#== No editing beyond this line is required for initial MASQ testing ==


echo -en " loading modules: "

# Need to verify that all modules have all required dependencies
#
echo " - Verifying that all kernel modules are ok"
/sbin/depmod -a

# With the new IPTABLES code, the core MASQ functionality is now either
# modular or compiled into the kernel. This HOWTO shows ALL IPTABLES
# options as MODULES. If your kernel is compiled correctly, there is
# NO need to load the kernel modules manually.
#
# NOTE: The following items are listed ONLY for informational reasons.
# There is no reason to manual load these modules unless your
# kernel is either mis-configured or you intentionally disabled
# the kernel module autoloader.
#

# Upon the commands of starting up IP Masq on the server, the
# following kernel modules will be automatically loaded:
#
# NOTE: Only load the IP MASQ modules you need. All current IP MASQ
# modules are shown below but are commented out from loading.
# ===============================================================

#Load the main body of the IPTABLES module - "iptable"
# - Loaded automatically when the "iptables" command is invoked
#
# - Loaded manually to clean up kernel auto-loading timing issues
#
echo -en "ip_tables, "
/sbin/insmod ip_tables


#Load the IPTABLES filtering module - "iptable_filter"
# - Loaded automatically when filter policies are activated


#Load the stateful connection tracking framework - "ip_conntrack"
#
# The conntrack module in itself does nothing without other specific
# conntrack modules being loaded afterwards such as the "ip_conntrack_ftp"
# module
#
# - This module is loaded automatically when MASQ functionality is
# enabled
#
# - Loaded manually to clean up kernel auto-loading timing issues
#
echo -en "ip_conntrack, "
/sbin/insmod ip_conntrack


#Load the FTP tracking mechanism for full FTP tracking
#
# Enabled by default -- insert a "#" on the next line to deactivate
#
echo -en "ip_conntrack_ftp, "
/sbin/insmod ip_conntrack_ftp


#Load the IRC tracking mechanism for full IRC tracking
#
# Enabled by default -- insert a "#" on the next line to deactivate
#
echo -en "ip_conntrack_irc, "
/sbin/insmod ip_conntrack_irc


#Load the general IPTABLES NAT code - "iptable_nat"
# - Loaded automatically when MASQ functionality is turned on
#
# - Loaded manually to clean up kernel auto-loading timing issues
#
echo -en "iptable_nat, "
/sbin/insmod iptable_nat


#Loads the FTP NAT functionality into the core IPTABLES code
# Required to support non-PASV FTP.
#
# Enabled by default -- insert a "#" on the next line to deactivate
#
echo -en "ip_nat_ftp, "
/sbin/insmod ip_nat_ftp


# Just to be complete, here is a list of the remaining kernel modules
# and their function. Please note that several modules should be only
# loaded by the correct master kernel module for proper operation.
# --------------------------------------------------------------------
#
# ipt_mark - this target marks a given packet for future action.
# This automatically loads the ipt_MARK module
#
# ipt_tcpmss - this target allows to manipulate the TCP MSS
# option for braindead remote firewalls.
# This automatically loads the ipt_TCPMSS module
#
# ipt_limit - this target allows for packets to be limited to
# to many hits per sec/min/hr
#
# ipt_multiport - this match allows for targets within a range
# of port numbers vs. listing each port individually
#
# ipt_state - this match allows to catch packets with various
# IP and TCP flags set/unset
#
# ipt_unclean - this match allows to catch packets that have invalid
# IP/TCP flags set
#
# iptable_filter - this module allows for packets to be DROPped,
# REJECTed, or LOGged. This module automatically
# loads the following modules:
#
# ipt_LOG - this target allows for packets to be
# logged
#
# ipt_REJECT - this target DROPs the packet and returns
# a configurable ICMP packet back to the
# sender.
#
# iptable_mangle - this target allows for packets to be manipulated
# for things like the TCPMSS option, etc.

echo ". Done loading modules."



#CRITICAL: Enable IP forwarding since it is disabled by default since
#
# Redhat Users: you may try changing the options in
# /etc/sysconfig/network from:
#
# FORWARD_IPV4=false
# to
# FORWARD_IPV4=true
#
echo " enabling forwarding.."
echo "1" > /proc/sys/net/ipv4/ip_forward


# Dynamic IP users:
#
# If you get your IP address dynamically from SLIP, PPP, or DHCP,
# enable this following option. This enables dynamic-address hacking
# which makes the life with Diald and similar programs much easier.
#
echo " enabling DynamicAddr.."
echo "1" > /proc/sys/net/ipv4/ip_dynaddr


# Enable simple IP forwarding and Masquerading
#
# NOTE: In IPTABLES speak, IP Masquerading is a form of SourceNAT or SNAT.
#
# NOTE #2: The following is an example for an internal LAN address in the
# 192.168.0.x network with a 255.255.255.0 or a "24" bit subnet mask
# connecting to the Internet on external interface "eth0". This
# example will MASQ internal traffic out to the Internet but not
# allow non-initiated traffic into your internal network.
#
#
# ** Please change the above network numbers, subnet mask, and your
# *** Internet connection interface name to match your setup
#


#Clearing any previous configuration
#
# Unless specified, the defaults for INPUT and OUTPUT is ACCEPT
# The default for FORWARD is DROP
#
echo " clearing any existing rules and setting default policy.."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -F INPUT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -F OUTPUT
$IPTABLES -P FORWARD DROP
$IPTABLES -F FORWARD
$IPTABLES -t nat -F

#echo "Enabling PORTFW Redirection on the external LAN.."
#
# This will forward ALL port 80 traffic from the external IP address
# to port 80 on the 192.168.0.10 machine
#
# Be SURE that when you add these new rules to your rc.firewall, you
# add them before a direct or implict DROP or REJECT.
#
$IPTABLES -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.2:80
$IPTABLES -A FORWARD -i eth0 -o eth1 -p tcp -d 192.168.1.2 --dport 80 -j ACCEPT
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

echo " FWD: Allow all connections OUT and only existing and related ones IN"
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT
$IPTABLES -A FORWARD -j LOG

echo " Enabling SNAT (MASQUERADE) functionality on $EXTIF"
$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

echo -e "\nrc.firewall-2.4 v$FWVER done.\n"

<end of file>

If anybody can figure out what in the heck is wrong...or what will make this work, then please, I beg you, enlighten me.

wildwolf 01-07-2004 10:29 PM

Ok, I'm getting closer to what I really want.

I can port forward port 80 straight through to the internal machine. Would be nice to port foward a different port, so I could still run a webserver on the external/NAT machine as well.

I've been using this to do the straight port forward for port 80:

# Port Forwarding
## forward from external interface
$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP --sport 8050: \
--dport 80 -j DNAT --to 192.168.1.2:80
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp -d 192.168.1.2 \
--sport 80: --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p tcp -s 192.168.1.2 \
--sport 80 --dport 80: -m state --state ESTABLISHED -j ACCEPT

## forward from internal interface
$IPTABLES -t nat -A PREROUTING -i $INTIF -p tcp -s $INTNET -d \
$EXTIP --sport 80: --dport 80 -j DNAT --to 192.168.1.2:80
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s $INTNET \
-d 192.168.1.2 --sport 80: --dport 8050 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s 192.168.1.2 \
-d $INTNET --sport 80 --dport 80: -m state --state ESTABLISHED -j ACCEPT

$IPTABLES -t nat -A POSTROUTING -o $INTIF -p tcp -s $INTNET -d \
192.168.1.2 --sport 80: --dport 80 -j SNAT --to-source 192.168.1.1


However, if I change the "80" to "8050" and start the internal webserver to use port 8050, then I get nothing.

Anybody have any suggestions?

wildwolf 01-07-2004 10:39 PM

Ok, must be something it doesn't like about port 8050, because if I use 713, it forwards through just fine.

At least this answer is up here now, in case somebody else has any trouble, it might help them.....

...other than that, sorry for wasting space. :(

Noerr 01-08-2004 08:37 AM

to be short the catch in port forwarding is to let packets go through forward also
##ie. setup portforwarding
iptables -t nat -I PREROUTING -p tcp -d your.public.ip --dport 8050 -j DNAT --to 192.168.1.10:80
## now let packtes go to your local net
iptables -I FORWARD -p tcp -d 192.168.1.10 --dport 80 -j ACCEPT

and off you go with public port 8050 getting forwarded to internal 192.168.1.10 machine on port 80

wildwolf 01-08-2004 12:17 PM

Been there, tried that, didn't work. Even tried your code, didn't work either.

No need to try any more, the code I posted works fine for me on port 713.

peter_robb 01-09-2004 07:34 AM

Just remove any references to --sport in the -t nat PREROUTING rule for -i $EXTIF & the FORWARD rules

Any source port is ok coming in on $EXTIF, just the destination port must be 80

wildwolf 01-09-2004 11:25 PM

Tried that. Specifically:
Code:

$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP \
    --dport 8050 -j DNAT --to 192.168.1.5:80
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp -d 192.168.1.5 \
    --dport 8050 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p tcp -s 192.168.1.5 \
    --dport 8050: -m state --state ESTABLISHED -j ACCEPT

## forward from internal interface
$IPTABLES -t nat -A PREROUTING -i $INTIF -p tcp -s $INTNET -d \
    $EXTIP --dport 8050 -j DNAT --to 192.168.1.5:80
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s $INTNET \
    -d 192.168.1.5  --dport 8050 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s 192.168.1.5 \
    -d $INTNET --dport 8050: -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -o $INTIF -p tcp -s $INTNET -d \
    192.168.1.5 --dport 8050 -j SNAT --to-source 192.168.1.1

and that didn't work either. I removed the source ports, as you said, and changed the destination port to 8050, and wanted to forward it to port 80 on the internal machine. I evne tried running the internal webserver on port 8050 (and yes I changed the lines above to 192.168.1.5:8050) and that didn't work either.

Like I have, with port 713 works. If I try port 8050, it does not. That's the only way so far I can get it to work, which makes me wonder if there's something further up in my iptables that's screwed up?

peter_robb 01-11-2004 11:47 AM

If you are forwarding http requests, they all have "--dport 80"
so a typical line would look like ..

$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP --dport 80 -j DNAT --to 192.168.1.5:8050

And drop the last 3 rules relating to forwarding from the internal interface
So long as you allow general internal traffic to pass to the internet, you don't need a specific rule...

wildwolf 01-11-2004 01:27 PM

They all won't have --dport 80, as I want them coming in on port 8050 because the requests will go to an internal server running an http server.

Port 80 will still be used on the linux machine that is doing the forwarding/firewalling for its own http server.

Thus, anything I try like so:
$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP --dport 8050 -j DNAT --to 192.168.1.5:80

or
$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP --dport 8050 -j DNAT --to 192.168.1.5:8050

has been failing me. The only thing that has worked is using a lower numbered port (thus the 713). I just would like to know if there's something that would cause 8050 to not work, and allow 713 to work.

peter_robb 01-12-2004 03:59 AM

Ok, that's quite a different scenario from your 1st post..

Where does it show you it has failed?
Do the http server logs show connection packets?

--quote--
I can port forward port 80 straight through to the internal machine. Would be nice to port foward a different port, so I could still run a webserver on the external/NAT machine as well.
---
However, if I change the "80" to "8050" and start the internal webserver to use port 8050, then I get nothing.


One problem with http requests is the http header... eg
If I enter www.mydomain.org into a browser, it sends packets on port 80 automatically, so the http header just says GET http://www.mydomain.org

If I however enter www.mydomain.org:8050 into the browser, the http header says GET http://www.mydomain.org:8050.
Your http server will need to be set to respond to this URL correctly... with the :8050 in the name..

wildwolf 01-12-2004 06:56 AM

Quote:

Ok, that's quite a different scenario from your 1st post..

Where does it show you it has failed?
Do the http server logs show connection packets?

--quote--
I can port forward port 80 straight through to the internal machine. Would be nice to port foward a different port, so I could still run a webserver on the external/NAT machine as well.
---
However, if I change the "80" to "8050" and start the internal webserver to use port 8050, then I get nothing.

One problem with http requests is the http header... eg
If I enter www.mydomain.org into a browser, it sends packets on port 80 automatically, so the http header just says GET http://www.mydomain.org

If I however enter www.mydomain.org:8050 into the browser, the http header says GET http://www.mydomain.org:8050.
Your http server will need to be set to respond to this URL correctly... with the :8050 in the name..
I know that the http server would need to be set to port 8050 in this scenario. I do that (thus, how do you think I get it to correctly work on port 713?)

It doesn't show me that it has failed in the http server logs. The server gets nothing. The firewall does not let anything through on port 8050, nor does it log it (and I do not know why it does not).

Also, I apologize. I have figured out a "working solution" that I did not post, partially at least.

I have it working for port 713 with the following code:
Code:

# Port Forwarding port forward the internal httpd server on port 713
## forward from external interface
$IPTABLES -t nat -A PREROUTING -i $EXTIF -p tcp -d $EXTIP --sport 713: \
    --dport 713 -j DNAT --to 192.168.1.5:713
$IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp -d 192.168.1.5 \
    --sport 713: --dport 713 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p tcp -s 192.168.1.5 \
    --sport 713 --dport 713: -m state --state ESTABLISHED -j ACCEPT

## forward from internal interface
$IPTABLES -t nat -A PREROUTING -i $INTIF -p tcp -s $INTNET -d \
    $EXTIP --sport 713: --dport 713 -j DNAT --to 192.168.1.5:713
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s $INTNET \
    -d 192.168.1.5 --sport 713: --dport 713 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i $INTIF -o $INTIF -p tcp -s 192.168.1.5 \
    -d $INTNET --sport 713 --dport 713: -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -o $INTIF -p tcp -s $INTNET -d \
    192.168.1.5 --sport 713: --dport 713 -j SNAT --to-source 192.168.1.1

Howveer, if I change all instances of 713 to 8050 in those lines, in theory, it should work on port 8050, right? Well it doesn't. At least for me it doesn't. And, yes, I change the internal webserver to respond to port 8050 when attempting this code.

Anyways, thanks for the help.

peter_robb 01-12-2004 07:38 AM

Ok, how about adding some -j LOG entries to track the packets through..
After the script has run, try adding these by the command line and watch /var/log/messages...

iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 8050 -j LOG --log-prefix "8050-nat "
iptables -I FORWARD -i eth0 -p tcp --dport 80 -j LOG --log-prefix "80-fwd "
iptables -I FORWARD -i eth0 -p tcp --dport 8050 -j LOG --log-prefix "8050-fwd "
(The -I places them as 1st rule)

Will you also pls send a "sanitised" version of the rules from iptables-save
This will list them on your screen, all the active rules, in their running order...
(Mask any sensitive external numbers, eg x.x.x.x)
I want to be sure all the rules are loading and what iptables has done to them.


All times are GMT -5. The time now is 04:49 AM.