<!doctypehtml><html class=client-nojs dir=ltr lang=en><meta charset=utf-8><title>
   Simple stateful firewall - ArchWiki
  </title><script>document.documentElement.className="client-js";RLCONF={"wgBreakFrames":!1,"wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgDefaultDateFormat":"dmy","wgMonthNames":["","January","February","March","April","May","June","July","August","September","October","November","December"],"wgRequestId":"ce64e42834e4735c808fc81a","wgCSPNonce":!1,"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":!1,"wgNamespaceNumber":0,"wgPageName":"Simple_stateful_firewall","wgTitle":"Simple stateful firewall","wgCurRevisionId":697156,"wgRevisionId":697156,"wgArticleId":2287,"wgIsArticle":!0,"wgIsRedirect":!1,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["Pages or sections flagged with Template:Expansion","Firewalls"],"wgPageContentLanguage":"en","wgPageContentModel":"wikitext","wgRelevantPageName":"Simple_stateful_firewall","wgRelevantArticleId":2287,"wgIsProbablyEditable":!1,"wgRelevantPageIsProbablyEditable":!1,"wgRestrictionEdit":[],
"wgRestrictionMove":[],"wgRedirectedFrom":"Simple_Stateful_Firewall","wgInternalRedirectTargetUrl":"/title/Simple_stateful_firewall"};RLSTATE={"site.styles":"ready","noscript":"ready","user.styles":"ready","user":"ready","user.options":"loading","skins.vector.styles.legacy":"ready","zzz.ext.archLinux.styles":"ready"};RLPAGEMODULES=["mediawiki.action.view.redirect","site","mediawiki.page.ready","mediawiki.toc","skins.vector.legacy.js"];</script><script>(RLQ=window.RLQ||[]).push(function(){mw.loader.implement("user.options@1hzgi",function($,jQuery,require,module){/*@nomin*/mw.user.tokens.set({"patrolToken":"+\\","watchToken":"+\\","csrfToken":"+\\"});
});});</script><link href=/load.php?lang=en&modules=skins.vector.styles.legacy%7Czzz.ext.archLinux.styles&only=styles&skin=vector rel=stylesheet><script async src=/load.php?lang=en&modules=startup&only=scripts&raw=1&skin=vector></script><meta name=ResourceLoaderDynamicStyles><link href=/load.php?lang=en&modules=site.styles&only=styles&skin=vector rel=stylesheet><meta content="MediaWiki 1.36.2"name=generator><meta content=no-referrer-when-downgrade name=referrer><link rel="shortcut icon"href=/favicon.ico><link title="ArchWiki (en)"href=/opensearch_desc.php rel=search type=application/opensearchdescription+xml><link href=https://wiki.archlinux.org/api.php?action=rsd rel=EditURI type=application/rsd+xml><link href=http://www.gnu.org/copyleft/fdl.html rel=license><link title="ArchWiki Atom feed"href=/index.php?title=Special:RecentChanges&feed=atom rel=alternate type=application/atom+xml><link href=https://wiki.archlinux.org/title/Simple_stateful_firewall rel=canonical><body class="mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Simple_stateful_firewall rootpage-Simple_stateful_firewall skin-vector action-view skin-vector-legacy"><div class=noprint id=archnavbar><div id=archnavbarlogo><p><a href=https://www.archlinux.org/ id=logo> </a></div><div id=archnavbarmenu><ul id=archnavbarlist><li id=anb-home><a href=https://www.archlinux.org/> Home </a><li id=anb-packages><a href=https://www.archlinux.org/packages/> Packages </a><li id=anb-forums><a href=https://bbs.archlinux.org/> Forums </a><li class=anb-selected id=anb-wiki><a href=https://wiki.archlinux.org/> Wiki </a><li id=anb-bugs><a href=https://bugs.archlinux.org/> Bugs </a><li id=anb-security><a href=https://security.archlinux.org/> Security </a><li id=anb-aur><a href=https://aur.archlinux.org/> AUR </a><li id=anb-download><a href=https://www.archlinux.org/download/> Download </a></ul></div></div><div class=noprint id=mw-page-base></div><div class=noprint id=mw-head-base></div><div class=mw-body id=content role=main><a id=top> </a><div class=mw-body-content id=siteNotice></div><div class="mw-indicators mw-body-content"></div><h1 class=firstHeading id=firstHeading>Simple stateful firewall</h1><div class=mw-body-content id=bodyContent><div class=noprint id=siteSub>From ArchWiki</div><div id=contentSub><span class=mw-redirectedfrom> (Redirected from <a title="Simple Stateful Firewall"class=mw-redirect href=/index.php?title=Simple_Stateful_Firewall&redirect=no> Simple Stateful Firewall </a> ) </span></div><div id=contentSub2></div><div id=jump-to-nav></div><a class=mw-jump-link href=#mw-head> Jump to navigation </a><a class=mw-jump-link href=#searchInput> Jump to search </a><div class=mw-content-ltr dir=ltr id=mw-content-text lang=en><div class=mw-parser-output><div class=archwiki-template-meta-related-articles-start><p>Related articles<ul><li><a class=mw-redirect href=/title/Firewalls title=Firewalls> Firewalls </a><li><a title="Internet sharing"href=/title/Internet_sharing> Internet sharing </a><li><a href=/title/Nftables#Simple_stateful_firewall title=Nftables> Nftables#Simple stateful firewall </a><li><a href=/title/Router title=Router> Router </a><li><a title="Uncomplicated Firewall"href=/title/Uncomplicated_Firewall> Uncomplicated Firewall </a></ul></div><p>This page explains how to set up a <a title="wikipedia:Stateful firewall"class=extiw href=https://en.wikipedia.org/wiki/Stateful_firewall> stateful firewall </a> using <a href=/title/Iptables title=Iptables> iptables </a> . It also explains what the rules mean and why they are needed. For simplicity, it is split into two major sections. The first section deals with a firewall for a single machine, the second sets up a NAT gateway in addition to the firewall from the first section.<div class="archwiki-template-box archwiki-template-box-warning"><strong> Warning: </strong> The rules below are given in the order they are executed and should only be followed while logged in locally. If you are logged into a remote machine, you may be locked out of the machine while setting up the rules. To get around this problem in a remote setup, the <a href=#Resulting_iptables.rules_file> example config file </a> can be used.</div><div aria-labelledby=mw-toc-heading class=toc id=toc role=navigation><input class=toctogglecheckbox id=toctogglecheckbox role=button style=display:none type=checkbox><div class=toctitle dir=ltr lang=en><h2 id=mw-toc-heading>Contents</h2><span class=toctogglespan> <label class=toctogglelabel for=toctogglecheckbox></label> </span></div><ul><li class="toclevel-1 tocsection-1"><a href=#Prerequisites> <span class=tocnumber> 1 </span> <span class=toctext> Prerequisites </span> </a><li class="toclevel-1 tocsection-2"><a href=#Firewall_for_a_single_machine> <span class=tocnumber> 2 </span> <span class=toctext> Firewall for a single machine </span> </a> <ul><li class="toclevel-2 tocsection-3"><a href=#Creating_necessary_chains> <span class=tocnumber> 2.1 </span> <span class=toctext> Creating necessary chains </span> </a><li class="toclevel-2 tocsection-4"><a href=#The_FORWARD_chain> <span class=tocnumber> 2.2 </span> <span class=toctext> The FORWARD chain </span> </a><li class="toclevel-2 tocsection-5"><a href=#The_OUTPUT_chain> <span class=tocnumber> 2.3 </span> <span class=toctext> The OUTPUT chain </span> </a><li class="toclevel-2 tocsection-6"><a href=#The_INPUT_chain> <span class=tocnumber> 2.4 </span> <span class=toctext> The INPUT chain </span> </a><li class="toclevel-2 tocsection-7"><a href=#Resulting_iptables.rules_file> <span class=tocnumber> 2.5 </span> <span class=toctext> Resulting iptables.rules file </span> </a><li class="toclevel-2 tocsection-8"><a href=#The_TCP_and_UDP_chains> <span class=tocnumber> 2.6 </span> <span class=toctext> The TCP and UDP chains </span> </a> <ul><li class="toclevel-3 tocsection-9"><a href=#Opening_ports_to_incoming_connections> <span class=tocnumber> 2.6.1 </span> <span class=toctext> Opening ports to incoming connections </span> </a><li class="toclevel-3 tocsection-10"><a href=#Port_knocking> <span class=tocnumber> 2.6.2 </span> <span class=toctext> Port knocking </span> </a></ul><li class="toclevel-2 tocsection-11"><a href=#Protection_against_spoofing_attacks> <span class=tocnumber> 2.7 </span> <span class=toctext> Protection against spoofing attacks </span> </a><li class="toclevel-2 tocsection-12"><a href=#"Hide"_your_computer> <span class=tocnumber> 2.8 </span> <span class=toctext> "Hide" your computer </span> </a> <ul><li class="toclevel-3 tocsection-13"><a href=#Block_ping_request> <span class=tocnumber> 2.8.1 </span> <span class=toctext> Block ping request </span> </a><li class="toclevel-3 tocsection-14"><a href=#Tricking_port_scanners> <span class=tocnumber> 2.8.2 </span> <span class=toctext> Tricking port scanners </span> </a> <ul><li class="toclevel-4 tocsection-15"><a href=#SYN_scans> <span class=tocnumber> 2.8.2.1 </span> <span class=toctext> SYN scans </span> </a><li class="toclevel-4 tocsection-16"><a href=#UDP_scans> <span class=tocnumber> 2.8.2.2 </span> <span class=toctext> UDP scans </span> </a><li class="toclevel-4 tocsection-17"><a href=#Restore_the_Final_Rule> <span class=tocnumber> 2.8.2.3 </span> <span class=toctext> Restore the Final Rule </span> </a></ul></ul><li class="toclevel-2 tocsection-18"><a href=#Protection_against_other_attacks> <span class=tocnumber> 2.9 </span> <span class=toctext> Protection against other attacks </span> </a> <ul><li class="toclevel-3 tocsection-19"><a href=#Bruteforce_attacks> <span class=tocnumber> 2.9.1 </span> <span class=toctext> Bruteforce attacks </span> </a></ul><li class="toclevel-2 tocsection-20"><a href=#IPv6> <span class=tocnumber> 2.10 </span> <span class=toctext> IPv6 </span> </a><li class="toclevel-2 tocsection-21"><a href=#Saving_the_rules> <span class=tocnumber> 2.11 </span> <span class=toctext> Saving the rules </span> </a><li class="toclevel-2 tocsection-22"><a href=#Resulting_ip6tables.rules_file> <span class=tocnumber> 2.12 </span> <span class=toctext> Resulting ip6tables.rules file </span> </a></ul><li class="toclevel-1 tocsection-23"><a href=#Setting_up_a_NAT_gateway> <span class=tocnumber> 3 </span> <span class=toctext> Setting up a NAT gateway </span> </a> <ul><li class="toclevel-2 tocsection-24"><a href=#Setting_up_the_filter_table> <span class=tocnumber> 3.1 </span> <span class=toctext> Setting up the filter table </span> </a> <ul><li class="toclevel-3 tocsection-25"><a href=#Creating_necessary_chains_2> <span class=tocnumber> 3.1.1 </span> <span class=toctext> Creating necessary chains </span> </a><li class="toclevel-3 tocsection-26"><a href=#Setting_up_the_FORWARD_chain> <span class=tocnumber> 3.1.2 </span> <span class=toctext> Setting up the FORWARD chain </span> </a><li class="toclevel-3 tocsection-27"><a href=#Setting_up_the_fw-interfaces_and_fw-open_chains> <span class=tocnumber> 3.1.3 </span> <span class=toctext> Setting up the fw-interfaces and fw-open chains </span> </a></ul><li class="toclevel-2 tocsection-28"><a href=#Setting_up_the_nat_table> <span class=tocnumber> 3.2 </span> <span class=toctext> Setting up the nat table </span> </a> <ul><li class="toclevel-3 tocsection-29"><a href=#Setting_up_the_POSTROUTING_chain> <span class=tocnumber> 3.2.1 </span> <span class=toctext> Setting up the POSTROUTING chain </span> </a><li class="toclevel-3 tocsection-30"><a href=#Setting_up_the_PREROUTING_chain> <span class=tocnumber> 3.2.2 </span> <span class=toctext> Setting up the PREROUTING chain </span> </a></ul><li class="toclevel-2 tocsection-31"><a href=#Saving_the_rules_2> <span class=tocnumber> 3.3 </span> <span class=toctext> Saving the rules </span> </a></ul><li class="toclevel-1 tocsection-32"><a href=#See_Also> <span class=tocnumber> 4 </span> <span class=toctext> See Also </span> </a></ul></div><h2><span class=mw-headline id=Prerequisites> Prerequisites </span></h2><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong> Your kernel needs to be compiled with iptables support. All stock Arch Linux kernels have iptables support.</div><p>First, install the userland utilities <span class="plainlinks archwiki-template-pkg"> <a class="external text"href=https://archlinux.org/packages/?name=iptables rel=nofollow> iptables </a> </span> or verify that they are already installed.<p>This article assumes that there are currently no iptables rules set. To check the current ruleset and verify that there are currently no rules run the following:<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em;"># iptables-save</pre><pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em;"># Generated by iptables-save v1.4.19.1 on Thu Aug  1 19:28:53 2013
*filter
:INPUT ACCEPT [50:3763]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [30:3472]
COMMIT
# Completed on Thu Aug  1 19:28:53 2013
</pre><p>or<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em;"># iptables -nvL --line-numbers</pre><pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em;">Chain INPUT (policy ACCEPT 156 packets, 12541 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 82 packets, 8672 bytes)
num   pkts bytes target     prot opt in     out     source               destination
</pre><p>If there are rules, you may be able to reset the rules by loading a default rule set:<pre># iptables-restore < /etc/iptables/empty.rules
</pre><p>Otherwise, see <a href=/title/Iptables#Resetting_rules title=Iptables> Iptables#Resetting rules </a> .<h2><span class=mw-headline id=Firewall_for_a_single_machine> Firewall for a single machine </span></h2><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong> Because iptables processes rules in linear order, from top to bottom within a chain, it is advised to put frequently-hit rules near the start of the chain. Of course there is a limit, depending on the logic that is being implemented. Also, rules have an associated runtime cost, so rules should not be reordered solely based upon empirical observations of the byte/packet counters.</div><h3><span class=mw-headline id=Creating_necessary_chains> Creating necessary chains </span></h3><p>For this basic setup, we will create two user-defined chains that we will use to open up ports in the firewall.<pre># iptables -N TCP
# iptables -N UDP
</pre><p>The chains can of course have arbitrary names. We pick these just to match the protocols we want handle with them in the later rules, which are specified with the protocol options, e.g. <code>
        -p tcp
       </code> , always.<h3><span class=mw-headline id=The_FORWARD_chain> The FORWARD chain </span></h3><p>If you want to set up your machine as a NAT gateway, please look at <a href=#Setting_up_a_NAT_gateway> #Setting up a NAT gateway </a> . For a single machine, however, we simply set the policy of the <b> FORWARD </b> chain to <b> DROP </b> and move on:<pre># iptables -P FORWARD DROP
</pre><h3><span class=mw-headline id=The_OUTPUT_chain> The OUTPUT chain </span></h3><p>The OUTPUT chain can be a powerful tool for filtering outbound traffic, especially for servers and other devices which do not run web browsers or peer-to-peer tools that need to connect to arbitrary destinations on the internet. However, properly setting up an OUTPUT chain requires information about the intended use of the system. A secure set of rules for a desktop system, laptop system, cloud server and home/on-prem server would all be very different.<p>In this simple example, we will allow all outbound traffic by setting the default policy for the <b> OUTPUT </b> chain to <b> ACCEPT </b> . This is less secure, but is highly compatible with many systems.<pre># iptables -P OUTPUT ACCEPT
</pre><h3><span class=mw-headline id=The_INPUT_chain> The INPUT chain </span></h3><p>Similar to the previous chains, we set the default policy for the <b> INPUT </b> chain to <b> DROP </b> in case something somehow slips by our rules. Dropping all traffic and specifying what is allowed is the best way to make a secure firewall.<div class="archwiki-template-box archwiki-template-box-warning"><strong> Warning: </strong> If you are logged in via SSH, the following will immediately disconnect the SSH session. To avoid it: (1) add the first INPUT chain rule below (it will keep the session open), (2) add a regular rule to allow inbound SSH (to be able to reconnect in case of a connection drop) and (3) set the policy.</div><pre># iptables -P INPUT DROP
</pre><p>Every packet that is received by any network interface will pass the <b> INPUT </b> chain first, if it is destined for this machine. In this chain, we make sure that only the packets that we want are accepted.<p>The first rule added to the INPUT chain will allow traffic that belongs to established connections, or new valid traffic that is related to these connections such as ICMP errors, or echo replies (the packets a host returns when pinged). ICMP stands for Internet Control Message Protocol. Some ICMP messages are very important and help to manage congestion and MTU, and are accepted by this rule:<pre># iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</pre><p>The connection state <code>
        ESTABLISHED
       </code> implies that either another rule previously allowed the initial ( <code>
        --ctstate NEW
       </code> ) connection attempt or the connection was already active (for example an active remote SSH connection).<p>The second rule will accept all traffic from the "loopback" (lo) interface, which is necessary for many applications and services.<pre># iptables -A INPUT -i lo -j ACCEPT
</pre><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong> You can add more trusted interfaces here such as "eth1" if you do not want/need the traffic filtered by the firewall, but be warned that if you have a NAT setup that redirects any kind of traffic to this interface from anywhere else in the network (let us say a router), it will get through, regardless of any other settings you may have.</div><p>The third rule will drop all traffic with an "INVALID" state match. Traffic can fall into four "state" categories: NEW, ESTABLISHED, RELATED or INVALID and this is what makes this a "stateful" firewall rather than a less secure "stateless" one. States are tracked using the "nf_conntrack_*" kernel modules which are loaded automatically by the kernel as you add rules.<div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong><ul><li>This rule will drop all packets with invalid headers or checksums, invalid TCP flags, invalid ICMP messages (such as a port unreachable when we did not send anything to the host), and out of sequence packets which can be caused by sequence prediction or other similar attacks. The "DROP" target will drop a packet without any response, contrary to REJECT which politely refuses the packet. We use DROP because there is no proper "REJECT" response to packets that are INVALID, and we do not want to acknowledge that we received these packets.<li>ICMPv6 Neighbor Discovery packets remain untracked, and will always be classified "INVALID" though they are not corrupted or the like. Keep this in mind, and accept them before this rule! Run <code>
          iptables -A INPUT -p 41 -j ACCEPT
         </code> as root.</ul></div><pre># iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
</pre><p>The next rule will accept all new incoming ICMP echo requests, also known as pings. Only the first packet will count as NEW, the others will be handled by the RELATED, ESTABLISHED rule. Since the computer is not a router, no other ICMP traffic with state NEW needs to be allowed.<pre># iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
</pre><p>Now we attach the TCP and UDP chains to the INPUT chain to handle all new incoming connections. Once a connection is accepted by either TCP or UDP chain, it is handled by the RELATED/ESTABLISHED traffic rule. The TCP and UDP chains will either accept new incoming connections, or politely reject them. New TCP connections must be started with SYN packets.<pre># iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
# iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
</pre><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong><code>
        NEW
       </code> does not necessarily imply <code>
        --syn
       </code> . However, packets that match " <code>
        NEW
       </code> but not <code>
        --syn
       </code> " are rarely malicious and should not just be dropped. Instead, they are simply rejected with a TCP RESET by the next rule. Also, <code>
        --syn
       </code> is not equivalent to <code>
        --tcp-flags SYN SYN
       </code> . See <span class="plainlinks archwiki-template-man"title="$ man 8 iptables-extensions"> <a class="external text"href=https://man.archlinux.org/man/iptables-extensions.8 rel=nofollow> iptables-extensions(8) </a> </span> for details.</div><p>We reject TCP connections with TCP RESET packets and UDP streams with ICMP port unreachable messages if the ports are not opened. This imitates default Linux behavior (RFC compliant), and it allows the sender to quickly close the connection and clean up.<pre># iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
# iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
</pre><p>For other protocols, we add a final rule to the INPUT chain to reject all remaining incoming traffic with icmp protocol unreachable messages. This imitates Linux's default behavior.<pre># iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
</pre><h3><span class=mw-headline id=Resulting_iptables.rules_file> Resulting iptables.rules file </span></h3><p>Example of <code>
        iptables.rules
       </code> file after running all the commands from above:<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em;">/etc/iptables/iptables.rules</pre><pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em;"># Generated by iptables-save v1.4.18 on Sun Mar 17 14:21:12 2013
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
COMMIT
# Completed on Sun Mar 17 14:21:12 2013
</pre><p>This file can be generated and saved with:<pre># iptables-save -f /etc/iptables/iptables.rules
</pre><p>and can be used to continue with the following sections. If you are setting up the firewall remotely via SSH, append the following rule to allow new SSH connections before continuing (adjust port as required):<pre># iptables -A TCP -p tcp --dport 22 -j ACCEPT
</pre><h3><span class=mw-headline id=The_TCP_and_UDP_chains> The TCP and UDP chains </span></h3><p>The TCP and UDP chains contain rules for accepting new incoming TCP connections and UDP streams to specific ports.<div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong> This is where you need to add rules to accept incoming connections, such as SSH, HTTP or other services that you want to access remotely.</div><h4><span class=mw-headline id=Opening_ports_to_incoming_connections> Opening ports to incoming connections </span></h4><p>To accept incoming TCP connections on port 80 for a web server:<pre># iptables -A TCP -p tcp --dport 80 -j ACCEPT
</pre><p>To accept incoming TCP connections on port 443 for a web server (HTTPS):<pre># iptables -A TCP -p tcp --dport 443 -j ACCEPT
</pre><p>To allow remote SSH connections (on port 22):<pre># iptables -A TCP -p tcp --dport 22 -j ACCEPT
</pre><p>To accept incoming TCP/UDP requests for a <a title="DNS server"class=mw-redirect href=/title/DNS_server> DNS server </a> (port 53):<pre># iptables -A TCP -p tcp --dport 53 -j ACCEPT
# iptables -A UDP -p udp --dport 53 -j ACCEPT
</pre><p>See <span class="plainlinks archwiki-template-man"title="$ man 8 iptables"> <a class="external text"href=https://man.archlinux.org/man/iptables.8 rel=nofollow> iptables(8) </a> </span> for more advanced rules, like matching multiple ports.<h4><span class=mw-headline id=Port_knocking> Port knocking </span></h4><p>Port knocking is a method to externally open ports that, by default, the firewall keeps closed. It works by requiring connection attempts to a series of predefined closed ports. When the correct sequence of port "knocks" (connection attempts) is received, the firewall opens certain port(s) to allow a connection. See <a title="Port knocking"href=/title/Port_knocking> Port knocking </a> for more information.<h3><span class=mw-headline id=Protection_against_spoofing_attacks> Protection against spoofing attacks </span></h3><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong><code>
        rp_filter
       </code> is currently set to <code>
        2
       </code> by default in <code>
        /usr/lib/sysctl.d/50-default.conf
       </code> , so the following step is not necessary.</div><p>Blocking reserved local addresses incoming from the internet or local network is normally done through setting <code>
        rp_filter
       </code> (Reverse Path Filter) in sysctl to 1. To do so, add the following line to your <code>
        /etc/sysctl.d/90-firewall.conf
       </code> file (see <a href=/title/Sysctl title=Sysctl> sysctl </a> for details) to enable source address verification which is built into Linux kernel itself. The verification by the kernel will handle spoofing better than individual iptables rules for each case.<pre>net.ipv4.conf.all.rp_filter=1
</pre><p>This can be done with netfilter instead if statistics (and better logging) are desired:<pre># iptables -t raw -I PREROUTING -m rpfilter --invert -j DROP
</pre><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong> There is no reason to enable this in both places. The netfilter method is the modern choice and works with IPv6 too.</div><p>For niche setups where asynchronous routing is used, the <code>
        rp_filter=2
       </code> sysctl option needs to be used instead. Passing the <code>
        --loose
       </code> switch to the <code>
        rpfilter
       </code> module will accomplish the same thing with netfilter.<h3><span id=.22Hide.22_your_computer> </span> <span id='"Hide"_your_computer'class=mw-headline> "Hide" your computer </span></h3><p>If you are running a desktop machine, it might be a good idea to block some incoming requests.<h4><span class=mw-headline id=Block_ping_request> Block ping request </span></h4><p>A 'Ping' request is an ICMP packet sent to the destination address to ensure connectivity between the devices. If your network works well, you can safely block all ping requests. It is important to note that this <i> does not </i> actually hide your computer — any packet sent to you is rejected, so you will still show up in a simple nmap "ping scan" of an IP range.<p>This is rudimentary "protection" and makes life difficult when debugging issues in the future. This should only be done for educational purposes.<p>To block echo requests, add the following line to your <code>
        /etc/sysctl.d/90-firewall.conf
       </code> file (see <a href=/title/Sysctl title=Sysctl> sysctl </a> for details):<pre>net.ipv4.icmp_echo_ignore_all = 1
</pre><p>More information is in the iptables man page, or reading the docs and examples on the webpage <a class="external free"href=http://www.snowman.net/projects/ipt_recent/ rel=nofollow> http://www.snowman.net/projects/ipt_recent/ </a><h4><span class=mw-headline id=Tricking_port_scanners> Tricking port scanners </span></h4><div class="archwiki-template-box archwiki-template-box-note"><strong> Note: </strong><ul><li>This opens you up to a form of <a title="wikipedia:Denial-of-service attack"class=extiw href=https://en.wikipedia.org/wiki/Denial-of-service_attack> DoS </a> . An attack can send packets with spoofed IPs and get them blocked from connecting to your services.<li>This trick may block a legitimate IP address if some packets from this address to the destination port are regarded as INVALID by module conntrack. To avoid blacklisting, a workaround is to allow all packets directed to that particular destination port.</ul></div><p>Port scans are used by attackers to identify open ports on your computer. This allows them to identify and fingerprint your running services and possibly launch exploits against them.<p>The INVALID state rule will take care of every type of port scan except UDP, ACK and SYN scans (-sU, -sA and -sS in nmap respectively).<p><i> ACK scans </i> are not used to identify open ports, but to identify ports filtered by a firewall. Due to the SYN check for all TCP connections with the state NEW, every single packet sent by an ACK scan will be correctly rejected by a TCP RESET packet. Some firewalls drop these packets instead, and this allows an attacker to map out the firewall rules.<p>The recent module can be used to trick the remaining two types of port scans. The recent module is used to add hosts to a "recent" list which can be used to fingerprint and stop certain types of attacks. Current recent lists can be viewed in <code>
        /proc/net/xt_recent/
       </code> .<h5><span class=mw-headline id=SYN_scans> SYN scans </span></h5><p>In a SYN scan, the port scanner sends a SYN (synchronization) packet to every port to initiate a TCP connection. Closed ports return a TCP RESET packet, or get dropped by a strict firewall, while open ports return a SYN ACK packet.<p>The <code>
        recent
       </code> module can be used to keep track of hosts with rejected connection attempts and return a TCP RESET for any SYN packet they send to open ports as if the port was closed. If an open port is the first to be scanned, a SYN ACK will still be returned, so running applications such as ssh on non-standard ports is required for this to work consistently.<p>First, insert a rule at the top of the TCP chain. This rule responds with a TCP RESET to any host that got onto the <code>
        TCP-PORTSCAN
       </code> list in the past sixty seconds. The <code>
        --update
       </code> switch causes the recent list to be updated, meaning the 60 second counter is reset.<pre># iptables -I TCP -p tcp -m recent --update --rsource --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset
</pre><p>Next, the rule for rejecting TCP packets need to be modified to add hosts with rejected packets to the <code>
        TCP-PORTSCAN
       </code> list.<pre># iptables -D INPUT -p tcp -j REJECT --reject-with tcp-reset
# iptables -A INPUT -p tcp -m recent --set --rsource --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset
</pre><h5><span class=mw-headline id=UDP_scans> UDP scans </span></h5><p>UDP port scans are similar to TCP SYN scans except that UDP is a "connectionless" protocol. There are no handshakes or acknowledgements. Instead, the scanner sends UDP packets to each UDP port. Closed ports should return ICMP port unreachable messages, and open ports do not return a response. Since UDP is not a "reliable" protocol, the scanner has no way of knowing if packets were lost, and has to do multiple checks for each port that does not return a response.<p>The Linux kernel sends out ICMP port unreachable messages very slowly, so a full UDP scan against a Linux machine would take over 10 hours. However, common ports could still be identified, so applying the same countermeasures against UDP scans as SYN scans is a good idea.<p>First, add a rule to reject packets from hosts on the <code>
        UDP-PORTSCAN
       </code> list to the top of the UDP chain.<pre># iptables -I UDP -p udp -m recent --update --rsource --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable
</pre><p>Next, modify the reject packets rule for UDP:<pre># iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
# iptables -A INPUT -p udp -m recent --set --rsource --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable
</pre><h5><span class=mw-headline id=Restore_the_Final_Rule> Restore the Final Rule </span></h5><p>If either or both of the portscanning tricks above were used, the final default rule is no longer the last rule in the INPUT chain. It needs to be the last rule, or it would intercept the <i> trick port scanner </i> rules you just added, rendering them useless. Simply delete (-D) the rule, then add it again using append (-A), which will place it at the end of the chain.<pre># iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
</pre><h3><span class=mw-headline id=Protection_against_other_attacks> Protection against other attacks </span></h3><p>See the <a href=/title/Sysctl#TCP/IP_stack_hardening title=Sysctl> sysctl#TCP/IP stack hardening </a> for relevant kernel parameters.<h4><span class=mw-headline id=Bruteforce_attacks> Bruteforce attacks </span></h4><p>Unfortunately, bruteforce attacks on services accessible via an external IP address are common. One reason for this is that the attacks are easy to perform with the many tools available. Fortunately, there are a number of ways to protect the services against them. One is the use of appropriate <code>
        iptables
       </code> rules which activate and blacklist an IP after a set number of packets attempt to initiate a connection. Another is the use of specialised daemons that monitor the logfiles for failed attempts and blacklist accordingly.<div class="archwiki-template-box archwiki-template-box-warning"><strong> Warning: </strong> Using an IP blacklist will stop trivial attacks but it relies on an additional daemon and successful logging (the partition containing <code>
        /var
       </code> can become full, especially if an attacker is pounding on the server). Additionally, with the knowledge of your IP address, the attacker can send packets with a spoofed source header and get you locked out of the server. <a title="SSH keys"href=/title/SSH_keys> SSH keys </a> provide an elegant solution to the problem of brute forcing without these problems.</div><p>Two packages that ban IPs after too many password failures are <a href=/title/Fail2ban title=Fail2ban> Fail2ban </a> or, for <code>
        sshd
       </code> in particular, <a href=/title/Sshguard title=Sshguard> Sshguard </a> . These two applications update iptables rules to reject temporarily or permanently future connections from attackers.<p>The following rules give an example configuration to mitigate SSH bruteforce attacks using <code>
        iptables
       </code> .<pre># iptables -N IN_SSH
# iptables -N LOG_AND_DROP
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j LOG_AND_DROP
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j LOG_AND_DROP 
# iptables -A IN_SSH -m recent --name sshbf --set -j ACCEPT
# iptables -A LOG_AND_DROP -j LOG --log-prefix "iptables deny: " --log-level 7
# iptables -A LOG_AND_DROP -j DROP
</pre><p>Most of the rules should be self-explanatory: the first one allows for a maximum of three connection packets in ten seconds and drops further attempts from this IP. The next rule adds a quirk by allowing a maximum of four hits in 30 minutes. This is done because some bruteforce attacks are actually performed slow and not in a burst of attempts. The rules employ a number of additional options. To read more about them, check the original reference for this example in <a class="external text"href=https://compilefailure.blogspot.com/2011/04/better-ssh-brute-force-prevention-with.html rel=nofollow> compilefailure.blogspot.com </a> . The LOG_AND_DROP chain is used for logging dropped connections.<p>The above rules can be used to protect any service, though the SSH daemon is probably the most often required one.<p>In terms of order, one must ensure that <code>
        -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH
       </code> is at the right position in the iptables sequence: it should come before the TCP chain is attached to INPUT in order to catch new SSH connections first. If all the previous steps of this wiki have been completed, the following positioning works:<pre>...
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
<b>-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j IN_SSH</b>
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
...
</pre><div class="archwiki-template-box archwiki-template-box-tip"><strong> Tip: </strong> For self-testing the rules after setup, the actual blacklisting can slow the test, making it difficult to fine-tune parameters. One can watch the incoming attempts via <code>
        cat /proc/net/xt_recent/sshbf
       </code> . To unblock the own IP during testing, root is needed <code>
        echo / > /proc/net/xt_recent/sshbf
       </code></div><h3><span class=mw-headline id=IPv6> IPv6 </span></h3><p>If you do not use IPv6, you can consider <a title="Disabling IPv6"class=mw-redirect href=/title/Disabling_IPv6> disabling it </a> , otherwise follow these steps to enable the IPv6 firewall rules.<p>Copy the IPv4 rules used in this example as a base, and change any IPs from IPv4 format to IPv6 format:<pre># cp /etc/iptables/iptables.rules /etc/iptables/ip6tables.rules
</pre><p>A few of the rules in this example have to be adapted for use with IPv6. The ICMP protocol has been updated in IPv6, replacing the ICMP protocol for use with IPv4. Hence, the reject error return codes <code>
        --reject-with icmp-port-unreachable
       </code> and <code>
        --reject-with icmp-proto-unreachable
       </code> have to be converted to ICMPv6 codes.<p>The available ICMPv6 error codes are listed in <a class=extiw href=https://tools.ietf.org/html/rfc4443#section-3.1 title=rfc:4443> RFC 4443 </a> , which specifies that connection attempts blocked by a firewall rule should use <code>
        --reject-with icmp6-adm-prohibited
       </code> . Doing so will basically inform the remote system that the connection was rejected by a firewall, rather than a listening service.<p>If it is preferred not to explicitly inform about the existence of a firewall filter, the packet may also be rejected without the message:<pre> -A INPUT -j REJECT
</pre><p>The above will reject with the default return error of <code>
        --reject-with icmp6-port-unreachable
       </code> . You should note though, that identifying a firewall is a basic feature of port scanning applications and most will identify it regardless.<div class="noprint archwiki-template-message"><p><a class=image href=/title/File:Tango-view-fullscreen.png> <img alt=Tango-view-fullscreen.png decoding=async height=48 src=/images/3/38/Tango-view-fullscreen.png width=48> </a> <b> This article or section needs expansion. </b> <a class=image href=/title/File:Tango-view-fullscreen.png> <img alt=Tango-view-fullscreen.png decoding=async height=48 src=/images/3/38/Tango-view-fullscreen.png width=48> </a><div><b> Reason: </b> Which ICMPv6 peculiarities should be added to bring the rules at par with the IPv4 rules this article uses? (Discuss in <a title="Talk:Simple stateful firewall"href=/title/Talk:Simple_stateful_firewall#ICMP_blocking> Talk:Simple_stateful_firewall#ICMP blocking </a> )</div></div><p>In the next step make sure the protocol and extension are changed to be IPv6 appropriate for the rule regarding all new incoming ICMP echo requests (pings):<pre># ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT
</pre><p>Netfilter conntrack does not appear to track ICMPv6 Neighbor Discovery Protocol (the IPv6 equivalent of ARP), so we need to allow ICMPv6 traffic regardless of state for all directly attached subnets. The following should be inserted after dropping <code>
        --ctstate INVALID
       </code> , but before any other DROP or REJECT targets, along with a corresponding line for each directly attached subnet:<pre># ip6tables -A INPUT -s fe80::/10 -p ipv6-icmp -j ACCEPT
</pre><p>If you want to enable <a class=extiw href=https://en.wikipedia.org/wiki/DHCPv6 title=wikipedia:DHCPv6> DHCPv6 </a> , you need to accept incoming connections on <a class="external text"href=https://unix.stackexchange.com/a/452905 rel=nofollow> UDP port 546 </a> :<pre># ip6tables -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT
</pre><p>Since there is no kernel reverse path filter for IPv6, you may want to enable one in <i> ip6tables </i> with the following:<pre># ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT
# ip6tables -t raw -A PREROUTING -j DROP
</pre><h3><span class=mw-headline id=Saving_the_rules> Saving the rules </span></h3><p>The rule sets are now finished and should be saved to a file so that they can be loaded on every boot.<p>Save the IPv4 and IPv6 rules with these commands:<pre># iptables-save -f /etc/iptables/iptables.rules
# ip6tables-save -f /etc/iptables/ip6tables.rules
</pre><h3><span class=mw-headline id=Resulting_ip6tables.rules_file> Resulting ip6tables.rules file </span></h3><p>Example of <code>
        ip6tables.rules
       </code> file after running all the commands from above:<pre style="margin-bottom: 0; border-bottom:none; padding-bottom:0.8em;">/etc/iptables/ip6tables.rules</pre><pre style="margin-top: 0; border-top-style:dashed; padding-top: 0.8em;"># Generated by ip6tables-save v1.8.2 on Sat Apr 20 10:53:41 2019
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -s fe80::/10 -p ipv6-icmp -j ACCEPT
-A INPUT -p udp --sport 547 --dport 546 -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp6-adm-prohibited
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp6-adm-prohibited
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 128 -m conntrack --ctstate NEW -j ACCEPT
COMMIT
# Completed on Sat Apr 20 10:53:41 2019
</pre><p>Then <a class=mw-redirect href=/title/Enable title=Enable> enable </a> and <a class=mw-redirect href=/title/Start title=Start> start </a> <code>
        iptables.service
       </code> and the <code>
        ip6tables.service
       </code> . Check the status of the services to make sure the rules are loaded correctly.<h2><span class=mw-headline id=Setting_up_a_NAT_gateway> Setting up a NAT gateway </span></h2><p>This section of the guide deals with NAT gateways. It is assumed that you already read the <a href=#Firewall_for_a_single_machine> first part of the guide </a> and set up the <b> INPUT </b> , <b> OUTPUT </b> , <b> TCP </b> and <b> UDP </b> chains like described above. All rules so far have been created in the <b> filter </b> table. In this section, we will also have to use the <b> nat </b> table.<h3><span class=mw-headline id=Setting_up_the_filter_table> Setting up the filter table </span></h3><h4><span class=mw-headline id=Creating_necessary_chains_2> Creating necessary chains </span></h4><p>In our setup, we will create two new chains in the filter table, <b> fw-interfaces </b> and <b> fw-open </b> , using the following commands:<pre># iptables -N fw-interfaces
# iptables -N fw-open
</pre><h4><span class=mw-headline id=Setting_up_the_FORWARD_chain> Setting up the FORWARD chain </span></h4><p>Setting up the <b> FORWARD </b> chain is similar to the <b> INPUT </b> chain in the first section.<p>Now we set up a rule with the <b> conntrack </b> match, identical to the one in the <b> INPUT </b> chain:<pre># iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
</pre><p>The next step is to enable forwarding for trusted interfaces and to make all packets pass the <b> fw-open </b> chain.<pre># iptables -A FORWARD -j fw-interfaces 
# iptables -A FORWARD -j fw-open 
</pre><p>The remaining packets are denied with an <b> ICMP </b> message:<pre># iptables -A FORWARD -j REJECT --reject-with icmp-host-unreachable
# iptables -P FORWARD DROP
</pre><h4><span class=mw-headline id=Setting_up_the_fw-interfaces_and_fw-open_chains> Setting up the fw-interfaces and fw-open chains </span></h4><p>The meaning of the <b> fw-interfaces </b> and <b> fw-open </b> chains is explained later, when we deal with the <b> POSTROUTING </b> and <b> PREROUTING </b> chains in the <b> nat </b> table, respectively.<h3><span class=mw-headline id=Setting_up_the_nat_table> Setting up the nat table </span></h3><p>All over this section, we assume that the outgoing interface (the one with the public internet IP) is <b> ppp0 </b> . Keep in mind that you have to change the name in all following rules if your outgoing interface has another name.<h4><span class=mw-headline id=Setting_up_the_POSTROUTING_chain> Setting up the POSTROUTING chain </span></h4><p>Now, we have to define who is allowed to connect to the internet. Let us assume we have the subnet <b> 192.168.0.0/24 </b> (which means all addresses that are of the form 192.168.0.*) on <b> eth0 </b> . We first need to accept the machines on this interface in the FORWARD table, that is why we created the <b> fw-interfaces </b> chain above:<pre># iptables -A fw-interfaces -i eth0 -j ACCEPT
</pre><p>Now, we have to alter all outgoing packets so that they have our public IP address as the source address, instead of the local LAN address. To do this, we use the <b> MASQUERADE </b> target:<pre># iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
</pre><p>Do not forget the <b> -o ppp0 </b> parameter above. If you omit it, your network will be screwed up.<p>Let us assume we have another subnet, <b> 10.3.0.0/16 </b> (which means all addresses 10.3.*.*), on the interface <b> eth1 </b> . We add the same rules as above again:<pre># iptables -A fw-interfaces -i eth1 -j ACCEPT
# iptables -t nat -A POSTROUTING -s 10.3.0.0/16 -o ppp0 -j MASQUERADE
</pre><p>The last step is to <a title="Internet sharing"href=/title/Internet_sharing#Enable_packet_forwarding> enable packet forwarding </a> (if it is not already enabled).<p>Machines from these subnets can now use your new NAT machine as their gateway. Note that you may want to set up a DNS and <a class=mw-redirect href=/title/DHCP title=DHCP> DHCP </a> server like <a href=/title/Dnsmasq title=Dnsmasq> dnsmasq </a> or a combination of <a href=/title/BIND title=BIND> BIND </a> and <a href=/title/Dhcpd title=Dhcpd> dhcpd </a> to simplify network settings DNS resolution on the client machines. This is not the topic of this guide.<h4><span class=mw-headline id=Setting_up_the_PREROUTING_chain> Setting up the PREROUTING chain </span></h4><p>Sometimes, we want to change the address of an incoming packet from the gateway to a LAN machine. To do this, we use the <b> fw-open </b> chain defined above, as well as the <b> PREROUTING </b> chain in the <b> nat </b> table in the following two simple examples.<p>First, we want to change all incoming SSH packets (port 22) to the ssh server of the machine <b> 192.168.0.5 </b> :<pre># iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT --to 192.168.0.5
# iptables -A fw-open -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT
</pre><p>The second example will show you how to change packets to a different port than the incoming port. We want to change any incoming connection on port <b> 8000 </b> to our web server on <b> 192.168.0.6 </b> , port <b> 80 </b> :<pre># iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to 192.168.0.6:80
# iptables -A fw-open -d 192.168.0.6 -p tcp --dport 80 -j ACCEPT
</pre><p>The same setup also works with udp packets.<h3><span class=mw-headline id=Saving_the_rules_2> Saving the rules </span></h3><p>Save the rules:<pre># iptables-save -f /etc/iptables/iptables.rules
</pre><p>This assumes that you have followed the steps <a href=#Saving_the_rules> above </a> to enable the <b> iptables </b> systemd service.<h2><span class=mw-headline id=See_Also> See Also </span></h2><ul><li><a class="external text"href=https://www.webhostingtalk.com/showthread.php?t=456571 rel=nofollow> Methods to block SSH attacks </a><li><a class="external text"href=https://www.ducea.com/2006/06/28/using-iptables-to-block-brute-force-attacks/ rel=nofollow> Using iptables to block brute force attacks </a><li><a class="external text"href=https://linuxconfig.org/collection-of-basic-linux-firewall-iptables-rules rel=nofollow> 20 Iptables Examples For New SysAdmins </a><li><a class="external text"href=https://www.thegeekstuff.com/2011/06/iptables-rules-examples/ rel=nofollow> 25 Most Frequently Used Linux IPTables Rules Examples </a></ul></div><div class=printfooter>Retrieved from " <a dir=ltr href=https://wiki.archlinux.org/index.php?title=Simple_stateful_firewall&oldid=697156> https://wiki.archlinux.org/index.php?title=Simple_stateful_firewall&oldid=697156 </a> "</div></div><div class=catlinks data-mw=interface id=catlinks><div class=mw-normal-catlinks id=mw-normal-catlinks><a href=/title/Special:Categories title=Special:Categories> Category </a> : <ul><li><a href=/title/Category:Firewalls title=Category:Firewalls> Firewalls </a></ul></div><div class="mw-hidden-catlinks mw-hidden-cats-hidden"id=mw-hidden-catlinks>Hidden category: <ul><li><a title="Category:Pages or sections flagged with Template:Expansion"href=/title/Category:Pages_or_sections_flagged_with_Template:Expansion> Pages or sections flagged with Template:Expansion </a></ul></div></div></div></div><div id=mw-navigation><h2>Navigation menu</h2><div id=mw-head><nav class="mw-portlet mw-portlet-personal vector-menu"aria-labelledby=p-personal-label id=p-personal role=navigation><h3 class=vector-menu-heading id=p-personal-label><span> Personal tools </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li id=pt-createaccount><a title="You are encouraged to create an account and log in; however, it is not mandatory"href=/index.php?title=Special:CreateAccount&returnto=Simple+stateful+firewall> Create account </a><li id=pt-login><a title="You are encouraged to log in; however, it is not mandatory [o]"accesskey=o href=/index.php?title=Special:UserLogin&returnto=Simple+stateful+firewall> Log in </a></ul></div></nav><div id=left-navigation><nav class="mw-portlet mw-portlet-namespaces vector-menu vector-menu-tabs"aria-labelledby=p-namespaces-label id=p-namespaces role=navigation><h3 class=vector-menu-heading id=p-namespaces-label><span> Namespaces </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li class=selected id=ca-nstab-main><a title="View the content page [c]"accesskey=c href=/title/Simple_stateful_firewall> Page </a><li id=ca-talk><a title="Discussion about the content page [t]"accesskey=t href=/title/Talk:Simple_stateful_firewall rel=discussion> Discussion </a></ul></div></nav><nav class="mw-portlet mw-portlet-variants emptyPortlet vector-menu vector-menu-dropdown"aria-labelledby=p-variants-label id=p-variants role=navigation><input aria-labelledby=p-variants-label class=vector-menu-checkbox type=checkbox><h3 class=vector-menu-heading id=p-variants-label><span> Variants </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list></ul></div></nav></div><div id=right-navigation><nav class="mw-portlet mw-portlet-views vector-menu vector-menu-tabs"aria-labelledby=p-views-label id=p-views role=navigation><h3 class=vector-menu-heading id=p-views-label><span> Views </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li class=selected id=ca-view><a href=/title/Simple_stateful_firewall> Read </a><li id=ca-viewsource><a title="This page is protected.
You can view its source [e]"accesskey=e href=/index.php?title=Simple_stateful_firewall&action=edit> View source </a><li id=ca-history><a title="Past revisions of this page [h]"accesskey=h href=/index.php?title=Simple_stateful_firewall&action=history> View history </a></ul></div></nav><nav class="mw-portlet mw-portlet-cactions emptyPortlet vector-menu vector-menu-dropdown"aria-labelledby=p-cactions-label id=p-cactions role=navigation><input aria-labelledby=p-cactions-label class=vector-menu-checkbox type=checkbox><h3 class=vector-menu-heading id=p-cactions-label><span> More </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list></ul></div></nav><div id=p-search role=search><h3><label for=searchInput>Search</label></h3><form action=/index.php id=searchform><div data-search-loc=header-navigation id=simpleSearch><input placeholder="Search ArchWiki"title="Search ArchWiki [f]"accesskey=f autocapitalize=sentences id=searchInput name=search type=search><input name=title type=hidden value=Special:Search><input class="searchButton mw-fallbackSearchButton"title="Search the pages for this text"id=mw-searchButton name=fulltext type=submit value=Search><input title="Go to a page with this exact name if it exists"class=searchButton id=searchButton name=go type=submit value=Go></div></form></div></div></div><div id=mw-panel><div id=p-logo role=banner><a title="Visit the main page"class=mw-wiki-logo href=/title/Main_page> </a></div><nav class="mw-portlet mw-portlet-navigation vector-menu vector-menu-portal portal"aria-labelledby=p-navigation-label id=p-navigation role=navigation><h3 class=vector-menu-heading id=p-navigation-label><span> Navigation </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li id=n-mainpage-description><a title="Visit the main page [z]"accesskey=z href=/title/Main_page> Main page </a><li id=n-Table-of-contents><a href=/title/Table_of_contents> Table of contents </a><li id=n-portal><a title="Various ways Archers can contribute to the community"href=/title/Getting_involved> Getting involved </a><li id=n-currentevents><a title="The latest lowdown on the wiki"href=/title/ArchWiki:News> Wiki news </a><li id=n-randompage><a title="Load a random page [x]"accesskey=x href=/title/Special:Random> Random page </a></ul></div></nav><nav class="mw-portlet mw-portlet-Interaction vector-menu vector-menu-portal portal"aria-labelledby=p-Interaction-label id=p-Interaction role=navigation><h3 class=vector-menu-heading id=p-Interaction-label><span> Interaction </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li id=n-help><a title="Wiki navigation, reading, and editing help"href=/title/Category:Help> Help </a><li id=n-Contributing><a href=/title/ArchWiki:Contributing> Contributing </a><li id=n-recentchanges><a title="A list of recent changes in the wiki [r]"accesskey=r href=/title/Special:RecentChanges> Recent changes </a><li id=n-Recent-talks><a href=https://wiki.archlinux.org/index.php?title=Special:RecentChanges&namespace=all-discussions rel=nofollow> Recent talks </a><li id=n-newpages><a href=/title/Special:NewPages> New pages </a><li id=n-Statistics><a href=/title/ArchWiki:Statistics> Statistics </a><li id=n-Requests><a href=/title/ArchWiki_talk:Requests> Requests </a></ul></div></nav><nav class="mw-portlet mw-portlet-tb vector-menu vector-menu-portal portal"aria-labelledby=p-tb-label id=p-tb role=navigation><h3 class=vector-menu-heading id=p-tb-label><span> Tools </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li id=t-whatlinkshere><a title="A list of all wiki pages that link here [j]"accesskey=j href=/title/Special:WhatLinksHere/Simple_stateful_firewall> What links here </a><li id=t-recentchangeslinked><a title="Recent changes in pages linked from this page [k]"accesskey=k href=/title/Special:RecentChangesLinked/Simple_stateful_firewall rel=nofollow> Related changes </a><li id=t-specialpages><a title="A list of all special pages [q]"accesskey=q href=/title/Special:SpecialPages> Special pages </a><li id=t-print><a title="Printable version of this page [p]"accesskey=p href=javascript:print(); rel=alternate> Printable version </a><li id=t-permalink><a title="Permanent link to this revision of the page"href=/index.php?title=Simple_stateful_firewall&oldid=697156> Permanent link </a><li id=t-info><a title="More information about this page"href=/index.php?title=Simple_stateful_firewall&action=info> Page information </a></ul></div></nav><nav class="mw-portlet mw-portlet-lang vector-menu vector-menu-portal portal"aria-labelledby=p-lang-label id=p-lang role=navigation><h3 class=vector-menu-heading id=p-lang-label><span> In other languages </span></h3><div class=vector-menu-content><ul class=vector-menu-content-list><li class="interlanguage-link interwiki-es"><a title="Simple stateful firewall – español"class=interlanguage-link-target href=https://wiki.archlinux.org/title/Simple_stateful_firewall_(Español) hreflang=es lang=es> Español </a><li class="interlanguage-link interwiki-ja"><a title="シンプルなステートフルファイアウォール – 日本語"class=interlanguage-link-target href=https://wiki.archlinux.jp/index.php/%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%95%E3%83%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB hreflang=ja lang=ja> 日本語 </a><li class="interlanguage-link interwiki-ru"><a title="Simple stateful firewall – русский"class=interlanguage-link-target href=https://wiki.archlinux.org/title/Simple_stateful_firewall_(Русский) hreflang=ru lang=ru> Русский </a><li class="interlanguage-link interwiki-zh-hans"><a title="Simple stateful firewall – 中文（简体）‎"class=interlanguage-link-target href=https://wiki.archlinux.org/title/Simple_stateful_firewall_(简体中文) hreflang=zh-Hans lang=zh-Hans> 中文（简体）‎ </a></ul></div></nav></div></div><footer class=mw-footer id=footer role=contentinfo><ul id=footer-info><li id=footer-info-lastmod>This page was last edited on 23 September 2021, at 12:29.<li id=footer-info-copyright>Content is available under <a class=external href=http://www.gnu.org/copyleft/fdl.html rel=nofollow> GNU Free Documentation License 1.3 or later </a> unless otherwise noted.</ul><ul id=footer-places><li id=footer-places-privacy><a class=extiw href=https://terms.archlinux.org/docs/privacy-policy/ title=archlinux-service-agreements:privacy-policy> Privacy policy </a><li id=footer-places-about><a href=/title/ArchWiki:About title=ArchWiki:About> About ArchWiki </a><li id=footer-places-disclaimer><a title="ArchWiki:General disclaimer"href=/title/ArchWiki:General_disclaimer> Disclaimers </a></ul></footer><script>(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgPageParseReport":{"limitreport":{"cputime":"0.166","walltime":"0.175","ppvisitednodes":{"value":662,"limit":1000000},"postexpandincludesize":{"value":10977,"limit":2097152},"templateargumentsize":{"value":7504,"limit":2097152},"expansiondepth":{"value":7,"limit":40},"expensivefunctioncount":{"value":0,"limit":100},"unstrip-depth":{"value":0,"limit":20},"unstrip-size":{"value":606,"limit":5000000},"timingprofile":["100.00%   82.024      1 -total"," 17.10%   14.023      9 Template:Note"," 16.83%   13.804      1 Template:Related_articles_start"," 12.05%    9.883      1 Template:Expansion","  8.96%    7.351      1 Template:Pkg","  8.83%    7.240     41 Template:Ic","  7.73%    6.340      4 Template:Hc","  7.22%    5.921      2 Template:Man","  6.54%    5.363      1 Template:Tip","  5.91%    4.850      1 Template:META_Related_articles_start"]},"cachereport":{"timestamp":"20211031154827","ttl":86400,"transientcontent":false}}});mw.config.set({"wgBackendResponseTime":140});});</script>