Translation(s): English - Italiano

WARNING: nftables is the default firewall framework since Debian 10 Buster. This page is outdated.


A network firewall is a set of rules to allow or deny passage of network traffic, through one or more network devices. A network firewall may also perform more complex tasks, such as network address translation, bandwidth adjustment, provide encrypted tunnels and much more related to network traffic.

Prior to version 5 (Lenny), a default Debian installation, did not have a default firewall enabled. But provides the needed tools to configure it manually.

Basic firewall software

Network traffic has different components, layers and protocols. For more references, check out the links section.

The most known type of firewall, and the most initially implemented, are sets of rules based on netfilter software, based on a set of kernel modules and some user space tools.

Basic software for network traffic manipulation

The default Debian installation comes with the program iptables(8), configured to allow all traffic. This section briefly explains the different programs to handle network traffic manually, as well as two sample scripts.

You need to be root, or use sudo, to launch these programs.

You may find the iptables-persistent package useful.

Using iptables for IPv4 traffic

This is not an iptables manual, only a short introduction about the use of the program. For more extended explanations, see iptables(8)

Basic invocation to define rules is:

% iptables [-t table] -[AD] chain  rule-specification [options]

Tables and chains

All rules, are stored on different tables.

The default table is filter, which maintain the INPUT, OUTPUT and FORWARD chains, used for incoming, outgoing and redirected traffic respectively.

Other present tables are mangle, nat and raw. You can also create and delete custom tables.

Rules and program invocation may refer to a specific table using the -t table_name switch (or --table table_name).

If no table is specified, the default table is used (the filter table).

To list the ruleset of any table, the -L switch is used. For example:

% iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

As you can see, the default policy in a default installation is to ACCEPT all traffic. There are no rules on any chain.

Each of the default tables, contain different chains, to store rules for different points, in the kernel networking subsystem.

You can list other tables using -t, for example, to see the nat (Network Address Translation) table:

% iptables -L -t nat
target     prot opt source               destination         

target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Matching and order

When a packet is inspected through the rulesets, matches are searched from top to bottom of tables and chains.

Into the rules, matches are searched from left to right, of the rule syntax used.

When a packet does not match a rule, the search jumps to the next rule. If no rules matches, then the default policy is applied to the packet.

If the packet matches any rule definition, then the target defined on the rule is applied (ACCEPT, REJECT, DROP, LOG, etc), and the following rules of the same chain are skipped.

It is very important to keep this in mind when designing a ruleset, to reach the desired functionality and because of its impact on performance, in large rulesets.

Policies and Targets

Default policy is to ACCEPT all traffic, but the most common practice, is to change policies to DROP all traffic but the allowed.

You have to be careful and sure that your rules are right, before put a policy to DROP, or you will lose connectivity.

See the troubleshooting section for tips about this issue.

Program switches

Most commonly used switches are:

There are other switches, to handle chains, tables, clear rules, counters and other elements. See iptables(8) man page.


The iptables program has an extensive collection of modules, to use different criteria to evaluate packets.

There are modules for protocols, logging, states of the conection, etc. All compiled-in modules, are neatly explained in the man page.

Modules may have parameters (-m module_name --parameter_name parameter_arguments).

An example rule, using the state module, to drop incoming traffic with INVALID state (a parameter of the state module), defined in the headers of the packet, would be:

% iptables -I INPUT -m state --state INVALID -j DROP

Example scripts


You can put this scripts at any place that run at boot time or network initialization.

Common places are:


Before the exit 0. Will be launched at boot time.

# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.

set -e

# Launch my netfilter rules
if [ -e '/etc/' ]
    /bin/sh '/etc/'

exit 0


This is a more reasonable and standard place for networking related stuff.

For example, if eth0 is your main or uniq interface, using DHCP:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto  lo
iface lo inet loopback

# WAN cablemodem
allow-hotplug eth0
iface         eth0 inet dhcp
              pre-up    /bin/sh /etc/firewall/
              post-down /bin/sh /etc/firewall/

SystemD | firewall.service

Most Debian distributions now include systemd. In order to bring up the iptable rules using systemd at start:

Create a new file using any reasonable file text editor(I called mine firewall.service)

# vim.tiny /etc/systemd/system/firewall.service

Then add the following:

Description=Add Firewall Rules to iptables

#ExecStart=/etc/firewall/  #For IPV6


Then enable the service:

# systemctl enable firewall.service

Example: Basic standalone machine firewall

You can use this script in any stand-alone machine (for example a personal desktop) that does not need ports open to any place. Or see the final commented line, to open specific ports.

A simple script like the one below, will provide your host with a reasonable amount of security. Be aware that the following script drops all packets which do not match an allow rule, so normal network error messages will not be seen. All allow rules have been commented out to protect the uninitiated.

# A very basic IPtables / Netfilter script /etc/firewall/


# Flush the tables to apply changes
iptables -F

# Default policy to drop 'everything' but our output to internet
iptables -P FORWARD DROP
iptables -P INPUT   DROP
iptables -P OUTPUT  ACCEPT

# Allow established connections (the responses to our outgoing traffic)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow local programs that use loopback (Unix sockets)
iptables -A INPUT -s -d -i lo -j ACCEPT

# Uncomment this line to allow incoming SSH/SCP conections to this machine,
# for traffic from (you can use also use a network definition as
# source like
# iptables -A INPUT -s -p tcp --dport 22 -m state --state NEW -j ACCEPT

Example: Basic gateway machine firewall

# This is a more complex setup, for a home firewall: 
# * One interface plug to the ISP conection (eth0). Using DHCP.
# * One interface plug to the local LAN switch (eth1). Using
# * Traffic open from the LAN to the SSH in the firewall.
# * Traffic open and translated, from the local LAN to internet.
# * Traffic open from internet, to a local web server.
# * Logging of dropped traffic, using a specific ''log level'' to configure a separate file in syslog/rsyslog.



# Flush previous rules, delete chains and reset counters
iptables -F
iptables -X
iptables -Z
iptables -t nat -F

# Default policies
iptables -P INPUT   DROP
iptables -P OUTPUT  DROP
iptables -P FORWARD DROP

echo -n '1' > /proc/sys/net/ipv4/ip_forward
echo -n '0' > /proc/sys/net/ipv4/conf/all/accept_source_route
echo -n '0' > /proc/sys/net/ipv4/conf/all/accept_redirects
echo -n '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo -n '1' > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

# Enable loopback traffic
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Enable statefull rules (after that, only need to allow NEW conections)
iptables -A INPUT   -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop invalid state packets
iptables -A INPUT   -m conntrack --ctstate INVALID -j DROP
iptables -A OUTPUT  -m conntrack --ctstate INVALID -j DROP
iptables -A FORWARD -m conntrack --ctstate INVALID -j DROP


# Incoming ssh from the LAN
iptables -A INPUT -i eth1 -s \
                  -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT


# Enable al outgoing traffic to internet
iptables -A OUTPUT -o eth0 -d      -j ACCEPT 

# Enable access traffic, from the firewall to the LAN network
iptables -A OUTPUT -o eth1 -d -j ACCEPT


# We have dynamic IP (DHCP), so we've to masquerade 
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables        -A FORWARD     -o eth0 -i eth1 -s \
                               -m conntrack --ctstate NEW -j ACCEPT

# Redirect HTTP (tcp/80) to the web server (
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
                              -j DNAT --to-destination

iptables        -A FORWARD    -i eth0 -p tcp --dport 80 \
                              -o eth1 -d    \
                              -m conntrack --ctstate NEW -j ACCEPT


iptables -A INPUT   -j LOG --log-level DEBUG --log-prefix '[FW INPUT]:    '
iptables -A OUTPUT  -j LOG --log-level DEBUG --log-prefix '[FW OUTPUT]:   '
iptables -A FORWARD -j LOG --log-level DEBUG --log-prefix '[FW FORWARD ]: '

Using ip6tables for IPv6 traffic

Because of growth, Internet is slowly switching to IPv6, that has a much larger address space than IPv4, and Debian is IPv6 capable.

If you have IPv6 addresses, networks and conections in your firewall, you've to be careful and configure your rulesets for each protocol.

To configure and manage IPv6 rulesets, you need to use ip6tables(8), which is provided by the default Debian install, in the package iptables.

The usage and functionality, is very similar to iptables, but oriented to IPv6 traffic.

For more references, see: ip6tables(8)


# A very basic IP6tables / Netfilter6 script

# Flush the tables to apply changes
ip6tables -F

ip6tables -P INPUT DROP #If it doesn't match a rule Drop it
ip6tables -P OUTPUT ACCEPT #If it doesn't match a rule

ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -m state --state ESTABLISHED,RELATED -A INPUT -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT

Using ebtables for ARP traffic

Ebtables (package ebtables) is used to set up, maintain, and inspect the tables of Ethernet frame rules in the Linux kernel. It is analogous to iptables, but operates at the MAC (ARP) layer, rather than the IP layer.

If you need to filter or translate ARP traffic (at link layer), your firewall has bridged interfaces (for example a transparent bridge between a OpenVPN tunneled VLAN and a local VLAN, or bridged interfaces for virtualization), ebtables(8) is your friend.

The design is very similar to netfilter's iptables.

It manages rulesets in tables with chains and targets, using user space tools, but this time it's not in the default Debian installation, and you need to add it:

% aptitude update
% aptitude install ebtables

For a more detailed explanation of its usage, look at the inevitable man page, and visit the official website (see links section).

There are documents that explain howto integrate ebtables and iptables, using the iptables module physdev.

Application firewalls

To go more up, and manipulate the Layer 7 of the OSI model, and be able to define rules at application level, you need other tools.

For example... you open the port 80 to your users, but you don't want them to be able to download .exe files from internet. You need an application firewall or proxy.

The default kernel in Debian does not have layer 7 patches, but you can install user space proxys to manage this kind of filters.

There are options like squid, dans guardian, zorp, etc.

See also the links section for the l7-filter project.

Troubleshooting software and tips

Some helpful (and must-have) tools are:

It's very easy to lose connectivity when initially configuring a firewall. And it's easier the more complex the firewall is.

A basic skill for troubleshoot a firewall problem, is to know the points where the traffic passes, is turned, routed, can be rejected, etc. And to know how to monitor that points, and what is happening.

The most effective is to analyze the traffic from end to end, from the initial request, the DNS, the interfaces by which must pass, the translations that have to do, the rejected traffic logs, the routing rules, etc.

A common hack when doing ruleset designing, is to put a cron task, that flush rules every few minutes, in case you will make a mistake (working in remote).

Graphic applications and frontends

There are some tools, to configure firewalls using frontends and helpers.

Some of them are:

Search firewall in

There are also command line "high level" tools, to avoid the "low level" syntax, or to simplify certain tasks. Anyway, the real power is in the large number of modules and options for basic command line programs, that often is not covered by frontends.

Networking information :

Ebtables :

Netfilter (iptables/ip6tables) :

Layer 7 :


This page was completely changed by -- ?PoisonBit 2009-05-10 18:35:50. It has user oriented content. May be you want to improve it, and link from/to related pages. May be you want to create a developer oriented page about firewalls.

CategorySystemAdministration | CategorySystemSecurity | CategoryRedundant: merge with DebianFirewall