Setting up a firewall using Linux 2.4.x/2.6.x: a solution (and how iptables works)
Hello all,
Here is a solution using iptables in order to have a fully functional firewall. I'll first put in the commands themselves, and will explain in later posts why and how it works.
The setup is the following:
* the machine acts as a router for a local network with IP network/mask of 192.168.1.0/24, on eth0 ;
* the interface is ppp0, its address is dynamic.
Here goes, supposing that your iptables rules are blank:
#
# The central part of it - conntrack, ie stateful firewalling
#
iptables -N connstate
iptables -A connstate -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A connstate -m state --state INVALID -j DROP
iptables -A connstate -m state --state NEW -p tcp ! --syn -m limit --limit 2/sec -j LOG --log-prefix "NEWNOTSYN: "
iptables -A connstate -m state --state NEW -p tcp ! --syn -j REJECT --reject-with tcp-reset
iptables -A connstate -m state --state NEW -j RETURN
iptables -A connstate -j LOG --log-level CRIT --log-prefix "CONNTRACK BARF: "
iptables -A connstate -j DROP
#
# For all three filter chains: drop everything by default - first chain to go through is
# connstate
#
for i in INPUT OUTPUT FORWARD; do
iptables -P $i DROP
iptables -A $i -j connstate
done
#
# Deal with the loopback special case
#
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
#
# First, let's allow anything from the local machine to the local network
#
iptables -N local_to_eth0
iptables -A local_to_eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j local_to_eth0
#
# Also allow anything from the local machine to the Internet
#
iptables -N local_to_ppp0
iptables -A local_to_ppp0 -j ACCEPT
iptables -A OUTPUT -o ppp0 -j local_to_ppp0
#
# Now, only allow some protocols (here, let's say SSH and ping only) from the local
# network to the local machine
#
iptables -N eth0_to_local
iptables -A eth0_to_local -p tcp --dport 22 -j ACCEPT
iptables -A eth0_to_local -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i eth0 -j eth0_to_local
#
# For the Internet, first thing is to masquerade our local network... Private IP
# addresses cannot be routed on the Internet!
#
iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
#
# Now, packets that come from our local network and go to the Internet: accept
# everything
#
iptables -N eth0_to_ppp0
iptables -A eth0_to_ppp0 -j ACCEPT
iptables -A FORWARD -i eth0 -o ppp0 -j eth0_to_ppp0
#
# END
#
Hello all,
Here is a solution using iptables in order to have a fully functional firewall. I'll first put in the commands themselves, and will explain in later posts why and how it works.
The setup is the following:
* the machine acts as a router for a local network with IP network/mask of 192.168.1.0/24, on eth0 ;
* the interface is ppp0, its address is dynamic.
Here goes, supposing that your iptables rules are blank:
#
# The central part of it - conntrack, ie stateful firewalling
#
iptables -N connstate
iptables -A connstate -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A connstate -m state --state INVALID -j DROP
iptables -A connstate -m state --state NEW -p tcp ! --syn -m limit --limit 2/sec -j LOG --log-prefix "NEWNOTSYN: "
iptables -A connstate -m state --state NEW -p tcp ! --syn -j REJECT --reject-with tcp-reset
iptables -A connstate -m state --state NEW -j RETURN
iptables -A connstate -j LOG --log-level CRIT --log-prefix "CONNTRACK BARF: "
iptables -A connstate -j DROP
#
# For all three filter chains: drop everything by default - first chain to go through is
# connstate
#
for i in INPUT OUTPUT FORWARD; do
iptables -P $i DROP
iptables -A $i -j connstate
done
#
# Deal with the loopback special case
#
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
#
# First, let's allow anything from the local machine to the local network
#
iptables -N local_to_eth0
iptables -A local_to_eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j local_to_eth0
#
# Also allow anything from the local machine to the Internet
#
iptables -N local_to_ppp0
iptables -A local_to_ppp0 -j ACCEPT
iptables -A OUTPUT -o ppp0 -j local_to_ppp0
#
# Now, only allow some protocols (here, let's say SSH and ping only) from the local
# network to the local machine
#
iptables -N eth0_to_local
iptables -A eth0_to_local -p tcp --dport 22 -j ACCEPT
iptables -A eth0_to_local -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i eth0 -j eth0_to_local
#
# For the Internet, first thing is to masquerade our local network... Private IP
# addresses cannot be routed on the Internet!
#
iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
#
# Now, packets that come from our local network and go to the Internet: accept
# everything
#
iptables -N eth0_to_ppp0
iptables -A eth0_to_ppp0 -j ACCEPT
iptables -A FORWARD -i eth0 -o ppp0 -j eth0_to_ppp0
#
# END
#