Trying to forward web traffic through firewall w/ IPTABLES
Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Trying to forward web traffic through firewall w/ IPTABLES
Please help! I've tried reading the IPTABLES man page and scoured Google, but with no luck. I'm having trouble getting port forwarding to work...I'd like requests that come in to my firewall on port 80 to be forwarded to the private web host on port 8080.
I'm certain that two or three extra lines in /etc/sysconfig/iptables will enable the functionality, but I've been unable to find the magic incantations.
I have a pretty generic home office configuration. I'm running Red Hat 8 and iptables on the firewall. The firewall has its own static IP address on an external Internet ethernet interface. It also has an internal interface to the private non-routable network (10.x.x.x). I'm using Network Address Translation to mask the private hosts behind the firewall. This is all working well.
Now I've added a web server to my private network behind the firewall. Here's an ASCII diagram of the network:
*filter
# define the user-defined 'firewall' chain
-N firewall
# accept all mail connections on any interface for Sendmail/PostFix
# from any interface
# (note: 'mail' is defined in /etc/services, which iptables accepts)
-A firewall -p tcp -m tcp --dport mail -j ACCEPT
# accept all SSH connections from any interface
-A firewall -p tcp -m tcp --dport ssh -j ACCEPT
# accept all IMAPS connections on any interface (but not IMAP)
-A firewall -p tcp -m tcp --dport imaps -j ACCEPT
# accept all established and related connections from any interface
-A firewall -m state --state ESTABLISHED,RELATED -j ACCEPT
# accept all new connections as long as they are not from eth0
# (ie, accept everything except from the Internet-facing interface)
-A firewall -m state --state NEW -i ! eth0 -j ACCEPT
# block everything else (eg, block the Internet-facing interface)
-A firewall -j DROP
# jump to that chain from the INPUT and FORWARD chains
-A INPUT -j firewall
-A FORWARD -j firewall
COMMIT
*nat
# change source addresses to EXTERNAL_IP_ADDR
-A POSTROUTING -o eth0 -j SNAT --to <my_external_ip_addr>
COMMIT
Thanks for the response. It's still not working for me though. I added that line to my /etc/sysconfig/iptables file, but now I can't restore iptables:
Code:
# /etc/init.d/iptables restart
Flushing all current rules and user defined chains: [ OK ]
Clearing all current rules and user defined chains: [ OK ]
Applying iptables firewall rules: iptables-restore v1.2.6a: Unknown arg `--dport'
Try `iptables-restore -h' or 'iptables-restore --help' for more information.
[FAILED]
Does it matter where/how you add the PREROUTING line? Does it matter that my "filter" chain drops all connections other than mail, ssh, and imaps? BTW, I have added the new line just above the other *nat* line like so (in red):
Code:
*filter
# define the user-defined 'firewall' chain
-N firewall
# accept all mail connections on any interface for Sendmail/PostFix
# from any interface
# (note: 'mail' is defined in /etc/services, which iptables accepts)
-A firewall -p tcp -m tcp --dport mail -j ACCEPT
# accept all SSH connections from any interface
-A firewall -p tcp -m tcp --dport ssh -j ACCEPT
# accept all IMAPS connections on any interface (but not IMAP)
-A firewall -p tcp -m tcp --dport imaps -j ACCEPT
# accept all established and related connections from any interface
-A firewall -m state --state ESTABLISHED,RELATED -j ACCEPT
# accept all new connections as long as they are not from eth0
# (ie, accept everything except from the Internet-facing interface)
-A firewall -m state --state NEW -i ! eth0 -j ACCEPT
# block everything else (eg, block the Internet-facing interface)
-A firewall -j DROP
# jump to that chain from the INPUT and FORWARD chains
-A INPUT -j firewall
-A FORWARD -j firewall
COMMIT
*nat
# route HTTP port 80 requests inside the firewall to the
# internal web server at 8080
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2:8080
# change source addresses to EXTERNAL_IP_ADDR
-A POSTROUTING -o eth0 -j SNAT --to <my_external_ip_addr>
COMMIT
Again...many, many thanks for any help you can offer.
# (ie, accept everything except from the Internet-facing interface)
-A firewall -m state --state NEW -i ! eth0 -j ACCEPT
Just wondered about this....how's anyone going to connect from outside of your network to any of the servers you are running? Maybe this is the problem.
how's anyone going to connect from outside of your network to any of the servers you are running? Maybe this is the problem.
Thanks, I think you're right. Unfortunately iptables still fails to load, so I can't test it yet (I'm still hoping someone has a solution for the load failure problem).
In the meantime I'll add a line like so to my "filter" chain to allow HTTP traffic.
Code:
.
.
# accept all HTTP connections on any interface
-A firewall -p tcp -m tcp --dport http -j ACCEPT
.
.
Once again, many thanks for any help. Sorry for all the newbie questions.
Now I run the following script, and it sets everything up nicely...
Code:
#!/bin/bash
# iptablesconf
echo 'Running iptables firewall configuration script'
# turn on IP forwarding
# this can be configured in /etc/sysctl.conf
echo 1 > /proc/sys/net/ipv4/ip_forward
# flush the existing rules
echo '*** Flushing existing iptables rules from memory ***'
iptables --flush
# define some handy variables
EXTERNAL_STATIC_IP_ADDR=...
echo Setting EXTERNAL_STATIC_IP_ADDR=$EXTERNAL_STATIC_IP_ADDR
EXTERNAL_INTERFACE=eth0
echo Setting EXTERNAL_INTERFACE=$EXTERNAL_INTERFACE
INTERNAL_STATIC_IP_ADDR=10.0.0.1
echo Setting INTERNAL_STATIC_IP_ADDR=$INTERNAL_STATIC_IP_ADDR
INTERNAL_INTERFACE=eth1
echo Setting INTERNAL_INTERFACE=$INTERNAL_INTERFACE
HTTP_SERVER_IP_ADDR=10.0.0.2
echo Setting HTTP_SERVER_IP_ADDR=$HTTP_SERVER_IP_ADDR
echo '*** Beginning NAT configuration ***'
# Forward packets coming in from the outside on port 80 to the internal HTTP server on port 8080
echo 'Forwarding packets from outside for port 80 to the HTTP server port 8080'
iptables -t nat -A PREROUTING -p tcp -d $EXTERNAL_STATIC_IP_ADDR --dport 80 -j DNAT --to-destination $HTTP_SERVER_IP_ADDR:8080
# Make it work from the firewall itself
echo 'Forwarding port 80 packets from the firewall itself to the HTTP server port 8080'
iptables -t nat -A OUTPUT -p tcp -d $EXTERNAL_STATIC_IP_ADDR --dport 80 -j DNAT --to-destination $HTTP_SERVER_IP_ADDR:8080
# Make responses on the internal network go through the firewall
echo 'Making responses from the internal HTTP server pass back through the firewall'
iptables -t nat -A POSTROUTING -p tcp -d $HTTP_SERVER_IP_ADDR --dport 8080 -j SNAT --to-source $INTERNAL_STATIC_IP_ADDR
# Allow forwarded packets
echo 'Allowing packets destined for the HTTP server on port 8080 to be forwarded'
iptables -A FORWARD -p tcp -d $HTTP_SERVER_IP_ADDR --dport 8080 -j ACCEPT -m state --state NEW,ESTABLISHED,RELATED
# change source addresses to EXTERNAL_STATIC_IP_ADDR
echo 'Modifying the source address of packets to appear to be from the firewall itself'
iptables -t nat -A POSTROUTING -o $EXTERNAL_INTERFACE -j SNAT --to $EXTERNAL_STATIC_IP_ADDR
# define the user-defined 'firewall' chain
echo '*** Creating user-defined "firewall" chain ***'
iptables -N firewall
# accept all mail connections on any interface for Sendmail/PostFix
# from any interface
# (note: 'mail' is defined in /etc/services, which iptables accepts)
echo 'Accepting incoming internal/external SMTP tcp traffic to pass through the firewall'
iptables -A firewall -p tcp -m tcp --dport mail -j ACCEPT
# accept all IMAPS connections on any interface (but not IMAP)
# (note: 'imaps' is defined in /etc/services, which iptables accepts)
echo 'Accepting incoming internal/external IMAPS (secure IMAP) tcp traffic to pass through the firewall'
iptables -A firewall -p tcp -m tcp --dport imaps -j ACCEPT
# accept all SSH connections from any interface
# (note: 'ssh' is defined in /etc/services, which iptables accepts)
echo 'Accepting incoming internal/external SSH tcp traffic to pass through the firewall'
iptables -A firewall -p tcp -m tcp --dport ssh -j ACCEPT
# accept all HTTP connections on any interface
# (note: 'http' is defined in /etc/services, which iptables accepts)
echo 'Accepting incoming internal/external HTTP (but not HTTPS) tcp traffic to pass through the firewall'
iptables -A firewall -p tcp -m tcp --dport http -j ACCEPT
# accept all established and related connections from any interface
echo 'Accepting incoming internal/external ESTABLISHED and RELATED (any protocol) connections to pass through the firewall'
iptables -A firewall -m state --state ESTABLISHED,RELATED -j ACCEPT
# accept all new connections as long as they are not from EXTERNAL_INTERFACE
# (ie, accept everything except from the Internet-facing interface)
echo 'Accepting incoming internal-only NEW (any protocol) connections to pass through the firewall'
iptables -A firewall -m state --state NEW -i ! $EXTERNAL_INTERFACE -j ACCEPT
# block everything else (eg, block the Internet-facing interface)
echo 'Dropping all other connection attempts (any protocol)'
iptables -A firewall -j DROP
# if we get to here, jump to the named chain (INPUT and FORWARD chains)
echo 'Jumping any remaining unmatched packets to the INPUT and FORWARD built-in chains, in case they care'
iptables -A INPUT -j firewall
iptables -A FORWARD -j firewall
# turn on IP forwarding
# THIS IS DONE IN CONFIGURATION FILE /etc/sysctl.conf !!!
#echo 1 > /proc/sys/net/ipv4/ip_forward
# show the user the final results of what was accomplished
echo 'Finished -- Outputting verbose result of table manipulation'
echo ""
iptables -L -v -n
# now remind the user to regenerate the iptables initialization file
echo "Don't forget to save the iptables to the iptables initialization file"
echo 'with this command:'
echo "iptables-save > /etc/sysconfig/iptables"
root@bastion:/etc/sysconfig
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.