User Tools

Site Tools


iptables_firewall

Iptables Firewall

Iptables is tool used to configure firewall rules. There are various firewall programs available in most Linux OSs which sit on top of and use iptable commands. However I prefer to use a simple bash .sh script to set my custom firewall rules.

Iptables Setup on Debian Squeeze

apt-get install iptables

Iptable command line options/switches:

 -A => Append this rule to the WhatEver Chain 
 -s => Source Address 
 -d => Destination Address 
 -p => Protocol 
 --dport => Destination Port 
 -j => Jump. If everything in this rule matches then 'jump' to ACCEPT 
 -I => Insert at position 1 of the ACCEPT Chain
 -P => Set Policy e.g. iptables -P INPUT DROP

Rules of Iptables:

As it is a table of rules, the first rule has precedence. If the first rule dis-allows everything then nothing else afterwards will matter.

  • INIVIDUAL REJECTS FIRST
  • THEN OPEN IT UP
  • BLOCK ALL
 List iptable rules:
 **iptables -n -L** (-n prevents slow reverse DNS lookup)<br>
 Reject all from an IP Address:
 **iptables -A INPUT -s 136.xxx.xxx.xxx -d 136.xxx.xxx.xxx -j REJECT<br>**
 Allow in SSH:
 **iptables -A INPUT -d 136.xxx.xxx.xxx -p tcp --dport 22 -j ACCEPT<br>**
 //If Logging - Insert Seperate Line *BEFORE* the ACCEPT / REJECT / DROP//
 **iptables -A INPUT -d 136.xxx.xxx.xxx -p tcp --dport 3306 -j LOG**
 **iptables -A INPUT -d 136.xxx.xxx.xxx -p tcp --dport 3306 -j ACCEPT**
 Block All:
 **iptables -A INPUT -j REJECT**

My Firewall Config Script

 vi /root/firewall.sh
 #!/bin/sh
 ### Flush any Existing iptable Rules and start afresh ###
 iptables -F INPUT
 iptables -F OUTPUT
 iptables -F FORWARD
 iptables -F POSTROUTING -t nat
 iptables -F PREROUTING -t nat
 ### Set our own simple iptable rules ###
 iptables -A INPUT -p tcp --dport 80 -j ACCEPT    <nowiki>//</nowiki>apache
 iptables -A INPUT -p tcp --dport 443 -j ACCEPT    <nowiki>//</nowiki>apache ssl
 iptables -A INPUT -p tcp --dport 53 -j ACCEPT    <nowiki>//</nowiki>dns - udp for large queries
 iptables -A INPUT -p udp --dport 53 -j ACCEPT    <nowiki>//</nowiki>dns - udp for small queries
 iptables -A INPUT -p tcp --dport 953 -j ACCEPT    <nowiki>//</nowiki>dns internal
 iptables -A INPUT -p tcp --dport 1080 -j ACCEPT    <nowiki>//</nowiki>dante socks server
 iptables -A INPUT -d 136.201.1.250 -p tcp --dport 22 -j ACCEPT      <nowiki>//</nowiki>sshd
 iptables -A INPUT -d 136.201.1.250 -p tcp --dport 3306 -j ACCEPT    <nowiki>//</nowiki>mysql
 iptables -A INPUT -d 136.201.1.250 -p tcp --dport 8000 -j ACCEPT    <nowiki>//</nowiki>apache on phi
 iptables -A INPUT -s 136.201.1.250 -p tcp --dport 8080 -j ACCEPT   <nowiki>//</nowiki>jboss for ejc
 iptables -A INPUT -d 136.201.1.250 -p tcp --dport 993 -j ACCEPT    <nowiki>//</nowiki>imaps
 iptables -A INPUT -s 127.0.0.1 -p tcp --dport 111 -j ACCEPT       <nowiki>//</nowiki>to speed up mail via courier. Identified via logging
 iptables -A INPUT -d 136.201.1.250 -p tcp --dport 139 -j ACCEPT   <nowiki>//</nowiki>samba
 iptables -A INPUT -s 127.0.0.1 -p tcp --dport 143 -j ACCEPT    <nowiki>//</nowiki>squirrelmail
 iptables -A INPUT -p tcp --dport 4949 -j ACCEPT   <nowiki>//</nowiki>munin stats
 iptables -A INPUT -p tcp --dport 25 -j ACCEPT    <nowiki>//</nowiki>incoming mail
 iptables -A INPUT -p tcp --dport 3128 -j ACCEPT  <nowiki>//</nowiki>squid
 iptables -A INPUT -p udp --dport 161 -j ACCEPT  <nowiki>//</nowiki>snmpd
 iptables -A INPUT -p icmp -j ACCEPT  <nowiki>//</nowiki>Allow ICMP Ping packets.
 iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
 iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
 iptables -A INPUT -m state --state RELATED -j ACCEPT
 iptables -A INPUT -j REJECT   <nowiki>//</nowiki>Close up firewall. All else blocked.
 #################################
 
 ##########PORT FORWARDING########
 iptables -t nat -A PREROUTING -p tcp -d 136.201.1.250 --dport 8000 -j DNAT --to 136.201.146.211:80
 iptables -t nat -A POSTROUTING -d 136.201.146.211 -j MASQUERADE
 #################################

Control / Use Firewall Script

As its a simple bash file, it just needs to be executed. It is OK to run this at any time. Any existing connections will not be dropped.

 chmod 755 /root/firewall.sh
 /root/firewall.sh

Update Firewall

It's a simple case of editing the firewall.sh script and re-running it.

 vi /root/firewall.sh
 /add or adjust as necessary
 /root/firewall.sh

Stop Firewall

iptables does not run as a daemon, so instead of stopping it, we “flush” any iptable rules:

 iptables -F INPUT
 iptables -F OUTPUT
 iptables -F FORWARD
 iptables -F POSTROUTING -t nat
 iptables -F PREROUTING -t nat

Calling the Firewall script on boot

When the computer is rebooted, the firewall rules are flushed. As we have all the iptable rules in firewall.sh, all we need to do is to execute this bash script when the computer boots up. There are a number of different ways of doing this.

1. Simplest Method of Executing Firewall Script on boot

 vi /etc/rc.local
 #add in:
 /root/firewall.sh

2. Init.d firewall script

I used just to place the firewall.sh script in /etc/init.d/ and then symlink it into /etc/rcX.d (or use sysv-rc-conf to set runlevels 2,3,4,5). In debian squeeze with dependancy based boot this can cause a lot of errors when installing subsequent packages (see sample below).

Errors recieved with firewall script in /etc/init.d/
 Error:
 Setting up postfix (2.7.1-1) ...
 insserv: warning: script 'firewall' missing LSB tags and overrides
 insserv: There is a loop between service munin-node and firewall if stopped
 insserv:  loop involving service firewall at depth 2
 insserv:  loop involving service munin-node at depth 1
 insserv: Stopping firewall depends on munin-node and therefore on system facility `$all' which can not be true!
 insserv: exiting now without changing boot order!
 update-rc.d: error: insserv rejected the script header
 dpkg: error processing postfix (--configure):
  subprocess installed post-installation script returned error exit status 1
 configured to not write apport reports
                                      Errors were encountered while processing:
 postfix
 E: Sub-process /usr/bin/dpkg returned an error code (1)

Things have changed in Debian Squeeze. Upgrading from etch or lenny to squeeze could cause any firewall.sh (or other) script to cause errors. This is due to the new dependency based boot in squeeze. Instead of using update-rc.d, you should use insserv firewall.sh Also, with dependency based boot with insserv LSB headers are required in all /etc/init.d/ scripts.

LSB Headers for Firewall script
 #! /bin/sh
 ### BEGIN INIT INFO
 # Provides:          custom firewall
 # Required-Start:    $remote_fs $syslog $network
 # Required-Stop:     $remote_fs $syslog $network
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
 # Short-Description: firewall initscript
 # Description:       Custom Firewall
 ### END INIT INFO
This was obtained from /etc/init.d/skeleton and shorewall and apf-firewall deb files.
Init.d Firewall script complete
 mv /root/firewall.sh /etc/init.d/firewall.sh
 cd /etc/init.d/
 vi firewall.sh
 <nowiki>//</nowiki>add in the following lines to the start:
 #! /bin/sh
 ### BEGIN INIT INFO
 # Provides:          custom firewall
 # Required-Start:    $remote_fs $syslog $network
 # Required-Stop:     $remote_fs $syslog $network
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
 # Short-Description: firewall initscript
 # Description:       Custom Firewall
 ### END INIT INFO
 
 ### Flush any Existing iptable Rules and start afresh ###
 iptables -F INPUT
 iptables -F OUTPUT
 iptables -F FORWARD
 iptables -F POSTROUTING -t nat
 iptables -F PREROUTING -t nat
 ### Set our own simple iptable rules ###
 iptables -A INPUT -p tcp --dport 80 -j ACCEPT    <nowiki>//</nowiki>apache
 iptables -A INPUT -p tcp --dport 443 -j ACCEPT    <nowiki>//</nowiki>apache ssl
 iptables -A INPUT -p tcp --dport 53 -j ACCEPT    <nowiki>//</nowiki>dns - udp for large queries
 iptables -A INPUT -p udp --dport 53 -j ACCEPT    <nowiki>//</nowiki>dns - udp for small queries 
 ....
insserv v's update-rc.d

Update-rc.d required you to choose a position between 0 and 99 and it created symlinks. insserv does the same, however it does so cleaner. It also requires the correct LSB headers such as “Required-Start” and “Required-Stop” which set when it should be run. In the above firewall.sh with LSB headers we can see that it will be started after the network and any filesystems are up. $all can also be used, where the firewall will be called when all other init.d scripts have been run. See: http://wiki.debian.org/LSBInitScripts

 insserv -n firewall.sh  (-n = dry run)
 insserv firewall.sh (do it. -v = verbose if you want to see it doing stuff)
 check if you like by looking in rc3.d

Ref's for init.d, update-rc.d, and insserv: <br> http://wiki.debian.org/LSBInitScripts <br> http://www.debianuserforums.org/viewtopic.php?f=46&t=555 <br> http://adminhowtos.com/index.php?topic=9.0 <br> http://wiki.pcprobleemloos.nl/using_lxc_linux_containers_on_debian_squeeze/vm-net <br> http://pastebin.com/gYBHx5cP <br>

Port Forwarding & NAT - Network Address Translation - V.Basic:

 iptables -t nat -A PREROUTING -p tcp -d 136.201.xxx.xxx --dport 443 -j DNAT --to 136.201.xxx.xxx:22
 The Above will do on its Own. The above allows someone to ssh into the box on port 443 incase port 22 is blocked by User ISP.
 **NB** Set ipForwarding in /etc/networking/options !!!!!!!!!!
 If Forwarding from another Network:
 iptables -A FORWARD -p tcp -d 136.201.xxx.xxx --dport 22 -j ACCEPT
 Web Port Forwarding: http://www.hackorama.com/network/portfwd.shtml

NB: Must allow IN Traffic and Connections the server started/ initiated (http://rimuhosting.com/howto/firewall.jsp):

 iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
 iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
 iptables -A INPUT -m state --state RELATED -j ACCEPT

Iptables Forward with NAT

This is already covered on this wiki here iptables_forward

Using iptables directly

Of course iptable commands can be entered live and will take effect immediately (instead of editing the firewall.sh script and re-running it).

Remove / Delete an individual /single Iptable Rule

 iptables -D INPUT -s 127.0.0.1 -p tcp --dport 111 -j ACCEPT
 <nowiki>//</nowiki> -D = delete appropriate rule. If you dont know the exact syntax of the rule to delete do the following:
 iptables -L
 <nowiki>//</nowiki>count down the number of lines until you reach the rule you wish to delete
 iptables -D INPUT 4
 <nowiki>//</nowiki>format = iptables -D CHAIN #Rule_No

Other pieces of information to remember:

iptables -P INPUT DROP (Setting the Default Policy)<br>
iptables -A INPUT * * * -j ACCEPT | REJECT (send back 'connection refused') | DROP (keep quiet)

 iptables -A INPUT -s 5.10.83.0/24 -p tcp --dport 80 -j REJECT
 # Drop all from that IP Address range. I.e. block from 5.10.83.0 to 5.10.83.255

fail2ban - Debian Etch/Ubuntu

Fail2ban is a simple Debian etch package which uses iptables to dynamically add rules which blocks ips after various incorrect Authentication/Password attempts. To install:

 apt-get install fail2ban
 #configuration file is in /etc/fail2ban.conf
 #fail and ban logs are saved in /var/log/fail2ban.log and /var/log/faillog

It monitors incorrect attempts in /var/log/auth.log for ssh attempts by default. The defaults are: 5 attempts before a rule is added blocking the client ip (on port 22) for 10minutes. Its a very very very nice package -)

Problems with fail2ban and ssh attempts on ubuntu

fail2ban was only banning ssh attempts where the user was “unknown”. It was not stopping brute force attempts at root for example. The failregex for the sshd.conf had to be changed.

 vi /etc/fail2ban/filter.d/sshd.conf
 #change the failregex line to:
 failregex = (?:Failed password [[-/\w+]]+) .*(?: from|FROM) <HOST>

It could be done a lot better, but the above works. Also see: <br> http://debaday.debian.net/2007/04/ <br> http://debaday.debian.net/2007/04/29/fail2ban-an-enemy-of-script-kiddies/

fail2ban blocking apache2 htaccess attempts

Working on Debian Bullseye

vi /etc/fail2ban/jail.d/defaults-debian.conf
#below the entry for ssh, enter

[apache-auth]
enabled = true
port     = http,https
logpath  = /var/log/apache2/error_vhostname.log

/etc/init.d/fail2ban restart

Make incorrect attempts. Monitor using "iptables -L" to see the entries after the failed attempts.

Firewall on Centos / RH

Archive

old debian sarge The init (start/stop) script for iptables is new within sarge - using if-up and if-down. The old init script is still available to load and save iptables rules. Do the following to set-up the iptables init script (details obtained from http://www.howtoforge.com/linux_iptables_sarge):

 gunzip /usr/share/doc/iptables/examples/oldinitdscript.gz -c > /etc/init.d/iptables
 chmod +x /etc/init.d/iptables
 mkdir /var/lib/iptables
 chmod 700 /var/lib/iptables

Control of Iptables (inactive is a blank file with no rules):

 /etc/init.d/iptables save active
 /etc/init.d/iptables load active | inactive

Saving ALL IPTABLE Rules

It seems that the method for saving & loading iptable rules from /etc/init.d/iptables load|save active|inactive does not save NAT rules.

The command for saving iptable rules manually is:

 root:~# iptables-save > rules-saved
There is also command called iptables-restore. It is:
 root:~# iptables-restore rules-saved
iptables_firewall.txt · Last modified: 2022/07/23 00:14 by admin