31

I have a home network with Linux pc's, which all had iptables running. I think it is easier to put my LAN behind a Linux gateway/firewall, so I've put a pc (with fedora,no gui) between my router and LAN and configured iptables. No problem here, INPUT only allows dns an http (and some local stuff), forwarding works fine: LAN connects to internet.

But my question is: does FORWARD allows all from the outside, or only the ports I configured with INPUT? Do FORWARD and INPUT work together or are they separate?

This is my iptables:

*nat
:PREROUTING ACCEPT [16:1336]
:INPUT ACCEPT [14:840]
:OUTPUT ACCEPT [30:2116]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o p1p1 -j MASQUERADE
COMMIT
# Completed on Tue Oct 16 09:55:31 2012
# Generated by iptables-save v1.4.14 on Tue Oct 16 09:55:31 2012
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [91:9888]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p UDP --dport 53 -j ACCEPT
-A INPUT -p TCP --dport 53 -j ACCEPT
-A INPUT -s 192.168.1.0/24 -i p1p1 -p tcp -m multiport --dports 20,21 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.2.0/24 -i p3p1 -p tcp -m multiport --dports 20,21 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.1.0/24 -i p1p1 -p tcp -m tcp --dport 5000:5100 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.2.0/24 -i p3p1 -p tcp -m tcp --dport 5000:5100 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i p1p1 -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.2.0/24 -i p3p1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.1.0/24 -i p1p1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i p1p1 -p tcp -m multiport --dports 20,21,443 -j DROP
-A INPUT -i p1p1 -p tcp --dport 5000:5100 -j DROP
-A INPUT -i p1p1 -p icmp -m icmp --icmp-type 8 -j DROP
-A FORWARD -s 192.168.2.0/24 -j ACCEPT
-A FORWARD -d 192.168.2.0/24 -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A OUTPUT -j LOG --log-prefix "denied out: "

COMMIT

p1p1 (.1.x) is my external nic, p3p1 (.2.x) is internal.

  • From the iptables tag: IPTABLES SUPPORT IS OFF-TOPIC. [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) Support questions may be asked on https://superuser.com. Use this tag only for questions on programming with iptables. Questions about configuring iptables should be asked on Server Fault (https://serverfault.com/). Please delete this. I’m voting to close this question because – Rob May 30 '23 at 11:29

2 Answers2

100

RedHat has a great doc about iptables (a little bit long), but the subject to cover is complex and there are so many different use cases that I don't see how to avoid it.

iptables kernel routing

Here is the chapter about FORWARD and NAT Rules. As it states:

For example, if you want to forward incoming HTTP requests to your dedicated Apache HTTP Server at 172.31.0.23, use the following command as the root user:

~]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 172.31.0.23:80

Here is what happens:

  • your linux gateway receives a packet from your router. The packet header has:
    • source: x.x.x.x:y (sender IP from the internet & source port used for packet transmission)
    • destination: 192.168.1.1:80 (assuming your linux gateway IP on external NIC, ie p1p1)
  • your linux gateway applies the PREROUTING chain to find a match. Assuming that you have typed what's above, the packet matches the rule and then calls (jumps -j) to the DNAT function (Destination Network Address Translation) which changes the destination of the packet header from the initial 192.168.1.1:80 to 172.31.0.23:80.
  • then, the packet arrives to the Routing Decision. The packet destination is now 172.31.0.23:80.
    • Your linux gateway asks itself: Is it for me (192.168.1.1:80) ? No, so I won't send it to the INPUT chain.
    • => I'll send it to the FORWARD chain.
  • since you have set the rules to FORWARD all on your local network (table filter chain FORWARD), the packet should be forwarded correctly to your local Apache HTTP Server (for example).

Hope it'll help to understand a little bit more how internal routing works with iptables.

Samuel Phan
  • 4,218
  • 2
  • 17
  • 18
77

INPUT, FORWARD, and OUTPUT are separate. A packet will only hit one of the three chains.

If the destination is to this server, it hits the INPUT chain. If its source is from this server, it hits OUTPUT. If its source and destination are both other machines—it's being routed through the server—then it hits the FORWARD chain.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 1
    So, if I understand correctly, I have INPUT secured (sort of), but FORWARD lets everything through the way it is now? I hoped traffic was first filtered by INPUT, and then forwarded. –  Oct 18 '12 at 00:07
  • Traffic from the outside, that is. –  Oct 18 '12 at 00:23
  • @Ray Right. A packet going through your box hits only FORWARDED. It doesn't do INPUT → FORWARDED → OUTPUT. – John Kugelman Oct 18 '12 at 00:39
  • Allright, thank you for your answer. Is there a way with nat-rules I can route certain ports to my LAN? For example, block all, open port 53 for my whole LAN? I am not an expert at this, I know how to set up a firewall, but routing is different stuff. –  Oct 18 '12 at 08:43
  • I'm looking into bridging, see what I can do with that. –  Oct 18 '12 at 09:23
  • @Ray You can post that as a new question, and serverfault.com would be a better fit, more network experts there I'd imagine. – John Kugelman Oct 18 '12 at 15:00
  • 1
    Ok, I'll try it there. Read a lot about bridging, it cannot do what I want. Think I have to dive into the realm of DNAT and SNAT.... John, thanks for thinking with me! –  Oct 18 '12 at 15:27