Link to home
Start Free TrialLog in
Avatar of ttro
ttro

asked on

Iptables Portforwarding problem

I set up a Firewall RedHat 8.0 with iptables 1.2.6a
here are it's configuration :

iptables -L -n
----------------------------------------
Chain INPUT (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:22
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:110
DROP       all  --  0.0.0.0/0            0.0.0.0/0          

Chain FORWARD (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            192.168.2.2        
ACCEPT     all  --  192.168.2.0/24      !192.168.2.0/24    
ACCEPT     all  -- !192.168.2.0/24       192.168.2.0/24    
DROP       all  --  0.0.0.0/0            0.0.0.0/0          

Chain OUTPUT (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state NEW,RELATED,ESTABLISHED


iptables -L -n -t nat
----------------------------------------
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination        
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:80 to:192.168.2.2:80
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:110 to:192.168.2.3:110

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination        
MASQUERADE  all  --  192.168.2.0/24       0.0.0.0/0          

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        



I wanted to forward port 80 and port 110 to internal server but it doesn't work ... always connection refused :'(

did I do something wrong ??

Avatar of stone_soup
stone_soup

Hi, This worked for me:

# this is the prerouting dnat
iptables -A PREROUTING -t nat -p TCP -d [externalIP] --dport [externalPort] -j DNAT --to-destination [internalIP]:[InternalPort]

# This allows packets from external->internal
iptables -A FORWARD -i [externalInterface eg ppp0] -o [internalInterface eg eth1] -p tcp -d [internalIP] --dport [internalPort] -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# This allows packets from internal->external
iptables -A FORWARD -i [internalInterface eg eth1] -o [externalInterface eg ppp0] -p tcp -s [internalIP] --sport [internalPort] -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# This enables access to the 'public' server from the internal network
iptables -t nat -A POSTROUTING -d [internalIP] -s [NETWORK e.g. 192.168.1.0] -p tcp --dport [internalPort] -j SNAT --to [internalIP]
Avatar of ttro

ASKER

yes thanks for thaht that's what i previouslmy done but it still don't work :'(

thanks anyway
Can you post the result of iptables -L -v ?
Avatar of ttro

ASKER

yes of course :)

iptables -L -v
--------------------------------------------
Chain INPUT (policy DROP 1 packets, 40 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere          
   36  5984 ACCEPT     all  --  any    any     anywhere             anywhere           state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere           tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere           tcp dpt:http
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere           tcp dpt:pop3
    0     0 DROP       all  --  any    any     anywhere             anywhere          

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     all  --  eth0   any     192.168.2.0/24      !192.168.2.0/24    
    0     0 ACCEPT     all  --  eth1   any    !192.168.2.0/24       192.168.2.0/24    
    0     0 DROP       all  --  any    any     anywhere             anywhere          

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        
   38  8020 ACCEPT     all  --  any    any     anywhere             anywhere           state NEW,RELATED,ESTABLISHED
My mistake, the interesting table is the nat one :)

Actually what I want to see is if there are any interfaces specified in the masquerade and in the forwarding rules. I think they should be. Also the counters could be intersting since they can give you an ideea where the packets go or don't go.

BTW, since the default policy is DROP you don't need the rule.
Avatar of ttro

ASKER

ok you're right the lines where drop
must be indulgent this is my first iptables script :p

i always use ipchains until now ;)

so here is my script if it can be any help ...

#################################################################
# Internal and External Devices
dev_world=eth0
dev_int=eth1

# Firewall IP
addr_int=192.168.2.200
addr_ext=194.242.168.110

# Internal Net
net_int=192.168.2.0/24

# DMZ servers
http_server=192.168.2.2
pop_server=192.168.2.3

echo -e "Loading Firewall Setting..."

#################################################################
# Load Modules
depmod -a
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe iptable_nat
modprobe ipt_MASQUERADE

#################################################################
# Delete all Rules in Filtertable
echo -e "Flush all old rulez..."
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat
#################################################################
# Setting Default Rulez
echo -e "Default Rulez Drop."
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

#################################################################
# Point to chains
iptables -A INPUT -i lo -j ACCEPT
echo -e "Setting nuew rulez..."
iptables -A FORWARD -d ! $net_int -i $dev_world -s $net_int -j ACCEPT
iptables -A FORWARD -d $net_int -i $dev_int -s ! $net_int -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -p tcp -d $http_server --dport 80 -j ACCEPT
#iptables -A FORWARD -j DROP

iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

#################################################################
# Chain Rules
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
#iptables -A INPUT -j DROP

################################################################
# NAT Rules
# Standard Routing
iptables -A POSTROUTING -t nat -o $dev_world -j MASQUERADE -s $net_int

# Port Forwarding
iptables -A PREROUTING -t nat -p tcp --dport 80 -d $addr_ext -j DNAT --to-destination $http_server:80
#iptables -A PREROUTING -t nat -p tcp --dport 110 -i $dev_world -j DNAT --to-destination $pop_server:110
################################################################
# Enable IP-Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
Avatar of ttro

ASKER

ok you're right the lines where drop
must be indulgent this is my first iptables script :p

i always use ipchains until now ;)

so here is my script if it can be any help ...

#################################################################
# Internal and External Devices
dev_world=eth0
dev_int=eth1

# Firewall IP
addr_int=192.168.2.200
addr_ext=194.242.168.110

# Internal Net
net_int=192.168.2.0/24

# DMZ servers
http_server=192.168.2.2
pop_server=192.168.2.3

echo -e "Loading Firewall Setting..."

#################################################################
# Load Modules
depmod -a
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe iptable_nat
modprobe ipt_MASQUERADE

#################################################################
# Delete all Rules in Filtertable
echo -e "Flush all old rulez..."
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat
#################################################################
# Setting Default Rulez
echo -e "Default Rulez Drop."
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

#################################################################
# Point to chains
iptables -A INPUT -i lo -j ACCEPT
echo -e "Setting nuew rulez..."
iptables -A FORWARD -d ! $net_int -i $dev_world -s $net_int -j ACCEPT
iptables -A FORWARD -d $net_int -i $dev_int -s ! $net_int -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -p tcp -d $http_server --dport 80 -j ACCEPT
#iptables -A FORWARD -j DROP

iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

#################################################################
# Chain Rules
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
#iptables -A INPUT -j DROP

################################################################
# NAT Rules
# Standard Routing
iptables -A POSTROUTING -t nat -o $dev_world -j MASQUERADE -s $net_int

# Port Forwarding
iptables -A PREROUTING -t nat -p tcp --dport 80 -d $addr_ext -j DNAT --to-destination $http_server:80
#iptables -A PREROUTING -t nat -p tcp --dport 110 -i $dev_world -j DNAT --to-destination $pop_server:110
################################################################
# Enable IP-Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
You are drop'ing anything towards 192.168.2.0/24 network when coming from eth0 so I guess you're not testing from the outside :-)
If you are testing from behind eth1, you are not testing from a machine within the 192.168.2.0/24 network are you? (you drop that too)

Anyway try adding;

iptables -t <table> -A <chain> -j LOG --log-prefix '<table:chain> === Oh no === '

To all chains, then check the log to see if you fall of a chain (Drop'ed since default is drop)

/b
Add both the interface and the IP of the interface to the rerouting rules.
Also I think you should use -i dev_int and not -o dev_world in the masquerade rule (but I'm not sure about this one at this time, i't 1:35 AM here :)
Avatar of ttro

ASKER

no "iptables v1.2.6a: Can't use -i with POSTROUTING" ;)

and i had both ip and interface
but no change i try to follow a packet to see where he is drop ...

thank you for your help isn't it time to sleep ;)

is there a tool to generate a packet to try the ruleset ?

PS : where are in the same time zone ;)
Avatar of ttro

ASKER

no "iptables v1.2.6a: Can't use -i with POSTROUTING" ;)

and i had both ip and interface
but no change i try to follow a packet to see where he is drop ...

thank you for your help isn't it time to sleep ;)

is there a tool to generate a packet to try the ruleset ?

PS : where are in the same time zone ;)
Ok, back to work.

The setup seems to work (at least for me) but with one small difference: the target for masquerading is -j SNAT and  not -j MASQUERADE.

If it still doesn't work, please post the result of iptables -L -vn and iptables -L -vn -t nat.

There are a couple of packages you can use to test the firewall: ipsorcery (one with a GUI), TCPinject (I don't know the URLs for these) and maybe Packet Excalibur (http://www.securitybugware.org/excalibur)
Avatar of ttro

ASKER

Ok so I don't see how i can use -j SNAT to route the outgoing packet for web server to incoming requester :(

here are the content of the 2 tables :

iptables -L -vn
---------------------------------------------------
Chain INPUT (policy DROP 3987 packets, 814K bytes)
 pkts bytes target     prot opt in     out     source               destination        
   28  2892 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0          
  290 41508 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          tcp dpt:22
    0     0 ACCEPT     tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0          tcp dpt:80
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0          tcp dpt:110
   10  1282 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     all  --  eth0   *      !192.168.2.0/24       192.168.2.0/24    
    0     0 ACCEPT     all  --  eth1   *       192.168.2.0/24      !192.168.2.0/24    
    4   184 ACCEPT     tcp  --  *      eth1    0.0.0.0/0            192.168.2.2        tcp dpt:80
    2    96 ACCEPT     tcp  --  *      eth1    0.0.0.0/0            192.168.2.3        tcp dpt:110

Chain OUTPUT (policy DROP 2 packets, 368 bytes)
 pkts bytes target     prot opt in     out     source               destination        
  282 34351 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0          state NEW,RELATED,ESTABLISHED

iptables -L -vn -t nat
--------------------------------------------------------
Chain PREROUTING (policy ACCEPT 14132 packets, 2027K bytes)
 pkts bytes target     prot opt in     out     source               destination        
    3   140 DNAT       tcp  --  *      *       0.0.0.0/0            194.242.168.110    tcp dpt:80 to:192.168.2.2:80
    2    96 DNAT       tcp  --  *      *       0.0.0.0/0            194.242.168.110    tcp dpt:110 to:192.168.2.3:110

Chain POSTROUTING (policy ACCEPT 91 packets, 5054 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    3   198 MASQUERADE  all  --  *      eth1    192.168.2.0/24       0.0.0.0/0          

Chain OUTPUT (policy ACCEPT 42 packets, 2804 bytes)
 pkts bytes target     prot opt in     out     source               destination        

so as you can see the packet really go to the webserver (I've check the log) but never come back :( but i've logged all the drop chain and the problem is that it never drop !

so i'll try to test it with TCPinject ...

let u know the result ;)
try moving dnat rules to the output chain instead.
/b
sorry,
here is why:

--- FROM NAT-HOWTO ---

The three chains are called
  PREROUTING (for Destination NAT, as packets first come in),
  POSTROUTING (for Source NAT, as packets leave), and OUTPUT (for
  Destination NAT of locally-generated packets).


  The following diagram would illustrate it quite well if I had any
  artistic talent:



             _____                                     _____
            /     \                                   /     \
          PREROUTING -->[Routing ]----------------->POSTROUTING----->
            \D-NAT/     [Decision]                    \S-NAT/
                            |                            ^
                            |                          __|__
                            |                         /     \
                            |                        | OUTPUT|
                            |                         \D-NAT/
                            |                            ^
                            |                            |
                            --------> Local Process ------


----

(Hope the above shows up OK on the page)

/bummer
it didn't :-)
You can get NAT-HOWTO yourself and look there if you want.

/bummer
oh, sorry again ;-)
I forgot what you were trying to accomplish.. disregard my last (2) postings.


If you are trying to reach a.b.c.d, and this destination gets rewritten to e.f.g.h, then returning packets will come from e.f.g.h and not a.b.c.d. That could a) confuse any other firewall between client and webserver, or b) returning packets (from webserver) will be routed directly to your client depending on webserver routing table (is your firewall the webservers default gateway?).
How is routing setup in the webserver? The path to your client should either be via your firewall, or your firewall should SNAT packets so that returning packets go back through your firewall, otherwise your stateful inspection will not regard the session as established, thus following packets that don't have SYN flag will be dropped in the nat:output chain.
I think ;-)

/b



well today I'm dizzy ;-)
nat:output in prev post should be "filter:output" ... you probably guessed that anyway :-)
ASKER CERTIFIED SOLUTION
Avatar of Mihai Barbos
Mihai Barbos
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you run "tcpdump -i eth1 -n" while you make a test you may be able to identify what really happens.
Also adding LOG rules at specific places could help you tell what chains are really passed. (see output from dmesg command)
If you LOG packets last in each chain you will know when/if a packet fall of a chain. If that chain has policy DROP that may give you a clue of what rule needs altering.
Also output from tcpdump may help telling if NAT occurs when you expect it to.

/b
Avatar of ttro

ASKER

thanks that's it it work perfectily :p

now i'll adjust some settings and it'll be goos :p

THANK you very much man you've really help me ;)
You're welcome. Thanks for the points and have a nice forwarding ;)