Hello,
I've already gained some experience with iptables configuration, but
now I'm facing a serious problem, where I investigated more than two
full working days without coming closer to any solution. Therefore
any help would be highly appreciated ...
The problem is: the address translation in the OUTPUT nat table is not
working! The application: a pc pool - all students a
working on a central server via ltsp. On this server any internet web
access should be redirected to a transparent proxy, which is running
on the same server.
A smooth solution would be to user the -t nat OUTPUT chain in order to
redirect an access to the external destination port 80 to port 3128
(squid, running on the same server).
My configuration is:
SuSE Linux 9.1
Kernel Version 2.6
IpTables V1.2.9
In order to be able to demonstrate the problem, I have reduced my
complex iptables script to a very few lines:
----------------------- begin of iptables script -----------------------
#!/bin/sh
################################################## ########################
R=/usr/sbin/iptables
EXTIP="192.168.1.6"
EXTIF="eth0"
# Delete all Rules
$R -F INPUT
$R -F FORWARD
$R -F OUTPUT
$R -t nat -F OUTPUT
# Default: Drop Packages, if not explicitly allowed
$R -P INPUT DROP
$R -P FORWARD DROP
$R -P OUTPUT DROP
#$R -t nat -P OUTPUT DROP
# local Packages are allowed
#$R -A INPUT -i lo -j ACCEPT
#$R -A OUTPUT -o lo -j ACCEPT
# HTTP
# allow response Packets from HTTP servers
$R -A INPUT -i "$EXTIF" -p tcp --dport 1024:65535 --sport 80 ! --syn -j
ACCEPT
# HTTP-Proxies
$R -A OUTPUT -p tcp --dport 80 -j ACCEPT
#!!!!!!! the following statement is not executed properly !!!!!!!!!
$R -t nat -A OUTPUT -o "$EXTIF" -p tcp --dport 80 -j REDIRECT --to-ports
3128
# Let Requests to Proxy pass
#$R -A INPUT -p tcp -d 127.0.0.1 --dport 3128 -j ACCEPT
#$R -A INPUT -p tcp --dport 3128 -j ACCEPT
# Unsuccessful Packet Protocols
#$R -A INPUT -s 0.0.0.0/0 -j LOG --log-level notice --log-prefix
"INPUT (default): "
#$R -A OUTPUT -s 0.0.0.0/0 -j LOG --log-level notice --log-prefix
"OUTPUT (default): "
$R -A INPUT -p tcp -s 0.0.0.0/0 -j LOG --log-prefix "INPUT LOG: "
$R -A OUTPUT -p tcp -s 0.0.0.0/0 -j LOG --log-prefix "OUTPUT LOG: "
$R -t nat -A OUTPUT -p tcp -s 0.0.0.0/0 -j LOG --log-prefix "OUTPUT NAT
LOG: "
$R -t nat -A POSTROUTING -p tcp -s 0.0.0.0/0 -j LOG --log-prefix
"POSTROUTING NAT LOG: "
$R -A FORWARD -s 0.0.0.0/0 -j LOG --log-level notice --log-prefix
"FORWARD (default): "
$R -A INPUT -s 0.0.0.0/0 -j DROP
$R -A OUTPUT -s 0.0.0.0/0 -j DROP
$R -A FORWARD -s 0.0.0.0/0 -j DROP
$R -t nat -A POSTROUTING -s 0.0.0.0/0 -j DROP
# Check Prerouting NAT
$R -t nat -A PREROUTING -i "$EXTIF" -p tcp --dport 80 -j REDIRECT
--to-port 3128
echo 1 > /proc/sys/net/ipv4/ip_forward
################################################## ########################
----------------------- end of iptables script -------------------------
lsmod delivers after starting the firewall
Module Size Used by
ipt_LOG 5632 5
ipt_REDIRECT 2176 2
iptable_nat 21548 2 ipt_REDIRECT
ip_conntrack 30768 2 ipt_REDIRECT,iptable_nat
iptable_filter 2816 1
ip_tables 17152 4
ipt_LOG,ipt_REDIRECT,iptable_nat,iptable_filter
In the firewall script above I have installed a redirect in the
PREROUTING chain and I have locked the INPUT chain in order to be able
to analyse, if the redirect is working by checking the log entries of
the INPUT chain:
telnet 192.168.1.6 80 from an external host delivers:
May 17 22:45:08 daisayah kernel: INPUT LOG: IN=eth0 OUT=
MAC=08:00:46:b6:e4:48:00:00:f0:6e:ee:45:08:00 SRC=192.168.1.5
DST=192.168.1.6 LEN=60 TOS=0x08 PREC=0x00 TTL=64 ID=895 DF PROTO=TCP
SPT=1026 DPT=3128 WINDOW=5840 RES=0x00 SYN URGP=0
It can be seen clearly, that the incoming destination port 80 has been
redirected to 3128 by the input chain.
If I start a web access from the considered server to the outer world
the POSTROUTING log delivers:
May 17 22:42:53 daisayah kernel: POSTROUTING NAT LOG: IN= OUT=lo
SRC=192.168.1.6 DST=192.168.1.6 LEN=60 TOS=0x10 PREC=0x00 TTL=64
ID=27310 DF PROTO=TCP SPT=32779 DPT=80 WINDOW=32767 RES=0x00 SYN URGP=0
^^^^^^
This means, that the outgoing port 80 (from localhost) is NOT redirected
to 3128 as requested in the OUTPUT nat table.
If I remove the line (commenting it out)
$R -A OUTPUT -p tcp --dport 80 -j ACCEPT
the same log is resulting already in the OUTPUT chain (destination port 80).
And now the strange thing: under SuSE 9.0 (iptables 1.2.8) the OUTPUT
nat redirect to port 3128 works perfectly an in the logs the destination
port is occurrind.
So: Is the current Linux Kernel or iptables version buggy? or did some
specification change???
Thanks for any hints,
Thomas
thomas(@)mes.tu-darmstadtNOSPAM.de
(remove brackets and anti-spam marker before direct mail reply)
|