By Kurt Seifried [email protected]
Introduction
Firewalling is the practice of filtering network traffic, typically at the
point where your network connects to another (e.g. the Internet, a customers
LAN, etc.) network, that may be untrusted (in the case of the Internet) or
perhaps even trusted (another floor of your building). Like firewalls in a large
building, a network firewall can prevent and even block the spread of an attack
if one segment is compromised successfully, like their namesake firewalls can
stop your network from being further compromised.There is a good FAQ on Internet
firewalls at: https://www.interhack.net/pubs/fwfaq/. A list of port numbers
and what they are is available https://seifried.org/security/ports/
Firewall software for Linux
Linux has gone through a series of firewalls. The most recent is IPTables
(sometimes referred to as NETFILTER), preceding that was ipchains, and preceding
this was ipfwadm, as well there are a number of other firewalls such as IPF and
SINUS firewall (some of which only work on 2.0 and 2.2 series kernels so are
largely obsolete). I would recommend using a 2.4 kernel with IPTables if
possible since it offers stateful packet inspection, which makes firewalling
protocols such as DNS and FTP properly a lot easier. Linux also supports IPMASQ
(IP Masquerading) as part of it's firewall capabilities, an advanced form of NAT
(Network Address Translation). IPMASQ allows you to hook up a network of
computers to the Internet but proxy their connections at the IP level. Thus all
traffic appears to be coming and going to one machine (the Linux IPMASQ box)
which affords a high degree of protection to the internal network. As an added
bonus the clients on the internal network require NO proxy configuration; as
long as the Linux IPMASQ server is configured correctly, and the clients use it
as their default gateway, things will work quite well.
Both ipchains and ipfwadm provide the following basic capabilities:
- blocking/passing of data based on source/destination IP address and port
- masquerading of connections based on source/destination IP address and
port
In addition to which ipchains supports:
- port forwarding
- creation of chains, for more intricate rules and conditions, speedier rule
parsing and easier management
- quality of service (QOS) routing, useful on low speed connections or
otherwise saturated connections
- specification of IP/port/interface as well as inverse specification (using
the !, i.e. "everything but")
The Firewall-HOWTO and "man <command>" (ipchains, ipfwadm or IPTables)
page both cover in great detail the mechanics for setting up rules, but don't
really cover the strategy for firewalling safely. Your first basic choice (well
actually it's not so basic) to make is whether to go with default deny or
default allow policies, followed by which services and hosts you wish to allow
and block.
When deciding policy you should ideally choose a policy that will default to
denying everything unless specifically allowed through (that is if there is a
failure it will hopefully be minimized via default policies) or a policy that
allows everything and blocks certain services/hosts. I typically use a policy of
default denial as it can accommodate mistakes and changes more safely then a
policy that defaults to allowing data through.
Case in point, you have a server secured via firewalling, currently running
Apache, you install WU-FTPD on it for internal use (so people can upload files)
at 3 am, you forget to change the firewall rules. If you have chosen a policy of
default allowal, anyone on the Internet can access the ftp server, and silly
you, you installed an old version which allowed someone to compromise the
machine. If on the other hand you go with a policy of default denial, they would
not have access to the ftp server, and neither would your users, but you would
find out quite quickly. Annoyed users are much easier to appease then fixing a
network that has been compromised.
Firewall concepts
Some of the problems with firewalling and what you can do ensure they don't
affect you to much.
Firewalling is typically seen as simple and effective security measure, but
nothing could be farther from the truth.
IPTables
Firewalling for Linux 2.4 and 2.5. Provides stateful filtering unlike
IPChains and IPFWADM. Combined with Linux advanced routing you can do many
interesting and several downright bizarre things.
IPTables (sometimes referred to as NETFILTER) is the current generation of
packet firewalling for Linux. It is stateful, and easily extended, providing
very powerful firewall capabilities to Linux. IPTables includes numerous new
features, from advanced logging to the ability to do string matching. Backwards
compatibility for ipfwadm and ipchains rules is provided with modules, allowing
you to easily upgrade to IPTables with minimal effort. Unfortunately the
majority of IPTables documents are not incredibly great, and the more advanced
features can be difficult to use correctly.
Although the HOWTO's are far from perfect I can't really do justice to
recreating the IPTables HOWTO's so instead I will just point you to them:
https://netfilter.samba.org/unreliable-guides/packet-filtering-HOWTO/packet-filtering-HOWTO.linuxdoc.html.
This is the most basic document, and will get you up and running.
https://netfilter.samba.org/documentation/HOWTO//NAT-HOWTO.html
This document cover NAT (Network Address Translation, sometimes referred to
as IPMASQ in Linux).
https://netfilter.samba.org/documentation/HOWTO//netfilter-extensions-HOWTO.html
This document covers extensions available in IPTables.
https://netfilter.samba.org/documentation/index.html
This lists all the documents available in various languages.
A very basic example
For those of you that just want to get on with it here is a simple iptables
firewall script I use that is suitable for machines with one interface:
#
# First set some default policies
#
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
#
# Then block the reserved network 10.* on the external interface eth0
#
-A INPUT -s 10.0.0.0/255.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j DROP
#
# Then we allow SSH, SMTP and DNS
#
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 22:22 -j ACCEPT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 25:25 -j ACCEPT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p udp -m udp --dport 53:53 -j ACCEPT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 53:53 -j ACCEPT
#
# Now we block all incoming traffic to ports between 1 and 1024. For your system
#
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p tcp -m tcp --dport 1:1024 -j REJECT
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -p udp -m udp --dport 1:1024 -j REJECT
Some more tricks with IPTables
Invalid packets
One of the nicest things about IPTables is that it is stateful, and there are
several options for state: NEW, ESTABLISHED, RELATED and INVALID. INVALID is
especially interesting as it will:
"A packet which could not be identified for some reason: this
includes running out of memory and ICMP errors which don't correspond to any
known connection. Generally these packets should be dropped."
Putting this rule first in your list may be a wise decision since it will
prevent mangled packets from traversing your chains and additionally it may help
with survivability of your server if someone attacks it.
-A INPUT -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 -m state --state INVALID -j DROP
Listing Tables
Typically most of us will use:
iptables -L -v -n
However this will not show all the tables (most importantly it misses the
pretrouting and postrouting tables, used for NAT among other things).
To list current NAT tables:
iptables -t nat -L -v -n
Dropping every second or third packet
This is guarenteed to drive network administrators a bit nutty, and amuse
attackers to ne end. Using the "nth" rule (not supported by default in most
kernels) you can drop every "nth" packet:
iptables -A INPUT -p tcp --dport 80 -m nth --every 2 -j DROP
This rule would drop every second packet coming in to port 80 (the webserver
usually).
IPChains
Firewalling for Linux 2.2 and present in 2.4 for backwards compatibility as
well. Does not provide stateful filtering, but provides chains, making it easier
to manage then ipfwadm.
IPChains contains several new features as compared to ipfwadm; you can
create chains of rules (hence the name) and link them together, making
administration of firewalls far easier. IPChains supports more targets then
ipfwadm; you can point a rule at: ACCEPT, DENY, REJECT, MASQ, REDIRECT, or
RETURN or a user defined chain. As such it is very powerful, for example I could
redirect all packets bound for port 80 (www traffic) going through my gateway
machine to be redirected to local port 3128, the Squid proxy server. You can
also use this in conjunction with quality of service routing, the example given
in ipfwadm's documentation is that of prioritizing traffic going over a PPP
link, you can give telnet traffic a much higher priority then say ftp, reducing
latency problems caused by a saturated link. Typically I create an
/etc/rc.d/init.d/ipchains-sh (or wherever appropriate) and call it immediately
before the networking is brought up, this leaves a NO time in which the server
is vulnerable.
The following script is appropriate for a gateway with 2 interfaces running,
the reason I have used the DENY instead of REJECT target is so that the packet
is dropped and not responded to in any way, this slows down network scans (as
they wait for the packet to timeout instead of receiving a response) and gives
away less information. I would also advise against logging data unless you have
a significant amount of drive space available, for each packet I send (several
bytes) many bytes of drive space is used up to create a log entry, making it
easy to overwhelm syslog and/or your drive space on a fast connection.
#!/bin/bash
#
# This script sets up firewall rules appropriate for a server with 2 interfaces
# running as a gateway
# This script needs to be edited if you plan to use it.
# We assume the internal machines call all talk to the gateway, so no rules block
# internal traffic
#
# A couple of variables
#
# ETH0 is the IP address on ETH0 (the external interface)
# ETH0NET is the network
# ETH0NETMASK is the network mask
# TRUSTEDHOST1 is a trusted host (for webmin/ssh)
# TRUSTEDHOST2 is a trusted host (for webmin/ssh)
# ETH1IP is the IP address on ETH1 (internal interface)
# ETH1NET is the network
# ETH1NETMASK is the network mask
#
ETH0IP=1.1.1.1
ETH0NET=1.1.1.0
ETH0NETMASK=24
TRUSTEDHOST1=1.5.1.1
TRUSTEDHOST2=1.5.1.2
ETH1IP=10.0.0.1
ETH1NET=10.0.0.0
ETH1NETMASK=24
#
PATH=/sbin
# FLUSH ALL RULES
ipchains -F input
ipchains -F output
ipchains -F forward
# ANTI-SPOOFING
ipchains -A input -p all -j DENY -s 10.0.0.0/8 -i eth0 -d 0.0.0.0/0
ipchains -A input -p all -j DENY -s 127.0.0.0/8 -i eth0 -d 0.0.0.0/0
ipchains -A input -p all -j DENY -s 192.168.0.0/16 -i eth0 -d 0.0.0.0/0
ipchains -A input -p all -j DENY -s 172.16.0.0/16 -i eth0 -d 0.0.0.0/0
ipchains -A input -p all -j DENY -s $ETH0IP -i eth0 -d 0.0.0.0/0
# ICMP FIRST
ipchains -A input -p icmp -j ACCEPT -s $ETH0NET/$ETH0NETMASK -i eth0 -d 0.0.0.0/0
ipchains -A input -p icmp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0
# SSH
ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST1 -i eth0 -d 0.0.0.0/0 22
ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST2 -i eth0 -d 0.0.0.0/0 22
# BLOCKING 1:1023
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1:1023
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1:1023
# BLOCKING OTHER THINGS
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1109
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1524
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 1600
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2003
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2049
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 2105
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3001
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3001
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3128:3130
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3128:3130
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3306
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 3306
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 4444
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6000:6100
ipchains -A input -p udp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6000:6100
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 6667
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 7000
# WEBMIN
ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST1 -i eth0 -d 0.0.0.0/0 10000
ipchains -A input -p tcp -j ACCEPT -s $TRUSTEDHOST2 -i eth0 -d 0.0.0.0/0 10000
ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -i eth0 -d 0.0.0.0/0 10000
# FORWARD RULES
ipchains -P forward DENY
ipchains -A forward -p all -j MASQ -s $ETH1NET/$ETH1NETMASK -d 0.0.0.0/0
Firewall scripts
Some scripts for Red Hat Linux in rpm format: https://www.webideal.de/rh-isdn/downloads/.
ipfwadm2ipchains
A simple script that converts ipfwadm rules to ipchains rules, making
migration a snap. The script is available at: https://users.dhp.com/~whisper/ipfwadm2ipchains/
IPFWADM
Firewalling for Linux 2.0, no longer present. Not recommended.
If you are still using ipfwadm it is time to upgrade from 2.0 to a 2.2
kernel. Seriously, stop reading and upgrade to at least a 2.2 kernel or
preferably a 2.4 kernel.
Ipfwadm is a solid packet filter for Linux, although it lacks a lot of
features available in IPChains. Ipfwadm only supports 3 targets for a packet:
accept, deny or reject, whereas ipchains rules can be targeted at 6 built-in
targets, or a user defined target. Ipfwadm is really only appropriate for a
simple IP-level firewall, IP masquerading and if you plan to use FreeS/WAN
(which currently does not support kernel 2.2.x). The basic options are: specify
a direction (in, out, or both, useful with the interface flag), input rules,
output rules, forwarding rules (say you have multiple interfaces, also covers
the masquerading rules) and masquerade rules which control the behavior of
masquerading (timeouts, etc). You can insert, append and delete rules, set
default policies, and list all the rules. Other then that it is very similar to
ipchains, with some minor variations. The following is a script appropriate for
a server bridging 2 networks (10.0.0.x on eth0, 10.0.0.1 and 192.168.0.x on
eth1, 192.168.0.1) with a mail server running.
#!/bin/bash
#
# Flush all the rule sets first
#
ipfwadm -f -I
ipfwadm -f -O
ipfwadm -f -F
#
# Allow forwarding between the two networks and otherwise deny it for security
#
ipfwadm -F -a accept -P all -S 10.0.0.0/24 -i eth0 -D 192.168.0.0/24
ipfwadm -F -a accept -P all -S 192.168.0.0/24 -i eth1 -D 10.0.0.0/24
ipfwadm -F -p deny
#
# And of course we have to allow those packets in
#
ipfwadm -I -a accept -P tcp -S 10.0.0.0/24 -i eth0 -D 192.168.0.0/24
ipfwadm -I -a accept -P tcp -S 192.168.0.0/24 -i eth1 -D 10.0.0.0/24
#
# Let them access the mail server port on the server but nothing else
#
ipfwadm -I -a accept -P tcp -S 10.0.0.0/24 -i eth0 -D 10.0.0.1 25
ipfwadm -I -a accept -P tcp -S 192.168.0.0/24 -i eth0 -D 192.168.0.1 25
ipfwadm -I -p deny
Rule creation / scripts
Kfirewall
From the site:
Kfirewall is an GUI application for X, using the KDE/QT widgets.
You need to have KDE installed on your system, and qt-devel-1.44 installed.
You can find the KDE packages at ftp://ftp.kde.org/
Firewall piercing
Sometimes you will be stuck behind a firewall that is not properly set up, or
otherwise stopping you from accessing data you need to. Other times users will
simply want to climb over any walls you put on the network, and the best way to
defend is to understand the attack. There is actually a mini-HOWTO on this; https://www.linuxdoc.org/HOWTO/mini/Firewall-Piercing.html. In
addition to this is an add-on for the IP Masquerading code that allows certain
types of VPN's through, you can get it at: ftp://ftp.rubyriver.com/pub/jhardin/masquerade/ip_masq_vpn.html.