Linux Iptables Firewall Shell Script For Standalone Server

A shell script on iptables rules for a webserver (no need to use APF or CSF) just run this script from /etc/rc.local and you are done. Save following script as /root/scripts/fw.start:

#!/bin/bash
# A Linux Shell Script with common rules for IPTABLES Firewall.
# By default this script only open port 80, 22, 53 (input)
# All outgoing traffic is allowed (default - output)
# -------------------------------------------------------------------------
# Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
 
IPT="/sbin/iptables"
SPAMLIST="blockedip"
SPAMDROPMSG="BLOCKED IP DROP"
 
echo "Starting IPv4 Wall..."
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
modprobe ip_conntrack
 
[ -f /root/scripts/blocked.ips.txt ] && BADIPS=$(egrep -v -E "^#|^$" /root/scripts/blocked.ips.txt)
 
PUB_IF="eth0"
 
#unlimited 
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
 
# DROP all incomming traffic
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
 
if [ -f /root/scripts/blocked.ips.txt ];
then
# create a new iptables list
$IPT -N $SPAMLIST
 
for ipblock in $BADIPS
do
   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
   $IPT -A $SPAMLIST -s $ipblock -j DROP
done
 
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
fi
 
# Block sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW  -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Drop Sync"
$IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP
 
# Block Fragments
$IPT -A INPUT -i ${PUB_IF} -f  -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets"
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
 
# Block bad stuff
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan"
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
 
$IPT  -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
 
# Allow full outgoing connection but no incomming stuff
$IPT -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
 
# Allow ssh 
$IPT -A INPUT -p tcp --destination-port 22 -j ACCEPT
 
# allow incomming ICMP ping pong stuff
$IPT -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# Allow port 53 tcp/udp (DNS Server)
$IPT -A INPUT -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
$IPT -A INPUT -p tcp --destination-port 53 -m state --state NEW,ESTABLISHED,RELATED  -j ACCEPT
$IPT -A OUTPUT -p tcp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# Open port 80
$IPT -A INPUT -p tcp --destination-port 80 -j ACCEPT
##### Add your rules below ######
 
##### END your rules ############
 
# Do not log smb/windows sharing packets - too much logging
$IPT -A INPUT -p tcp -i eth0 --dport 137:139 -j REJECT
$IPT -A INPUT -p udp -i eth0 --dport 137:139 -j REJECT
 
# log everything else and drop
$IPT -A INPUT -j LOG
$IPT -A FORWARD -j LOG
$IPT -A INPUT -j DROP
 
exit 0

How do I install and use this script?

Type the following command as root server:
# mkdir /root/scripts
# cd /root/scripts
# wget http://bash.cyberciti.biz/dl/381.sh.zip
# wget http://bash.cyberciti.biz/dl/151.sh.zip
# unzip 381.sh.zip
# unzip 151.sh.zip
# mv 381.sh start.fw
# mv 151.sh stop.fw
# chmod +x *.fw

Now edit firewall as per your requirements:
# vi /root/scripts/start.fw
Install firewall:
# echo '/root/scripts/start.fw' >> /etc/rc.local

How do I start firewall from a shell prompt?

# /root/scripts/start.fw

How do I stop firewall from a shell prompt?

# /root/scripts/stop.fw

Get the latest tutorials on SysAdmin, Linux/Unix, Open Source, and DevOps topics:
CategoryList of Unix and Linux commands
File Management cat
Firewall Alpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilities dig host ip nmap
OpenVPN CentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Manager apk apt
Processes Management bg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searching grep whereis which
User Information groups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPN Alpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
14 comments… add one
  • EoghanM Oct 8, 2016 @ 22:56

    I executed this on a VPS that luckily was due to expire.

    Unfortunately it errored on line 24 as modprobe wasn’t installed on the server (very old installation).

    I think the commands up til line 24 must have enabled full firewall blocking, and because of the failure, the line which opened up the SSH port 22 never got executed, so now I’m completely locked out of the server.

    Could you edit your instructions to have the following be the first thing people are told to execute:

    `/root/scripts/start.fw || /root/scripts/stop.fw`

    Then it will disable the firewall again if there’s any failure enabling it.

    With thanks

  • António Dec 21, 2013 @ 13:16

    Thanks for the script but what rules should I add below port 80?

  • ruud berry Sep 26, 2013 @ 20:49

    Why DROP, REJECT is better..

  • John B. Mar 31, 2012 @ 17:17

    This is about the time we should learn how to appreciate one another. We should all learn to live in LOVE,harmony and appreciation. Whoever wrote this script from the bottom of my heart I say thank you in a million fold.
    John B.

  • Dlugi Feb 2, 2011 @ 13:01

    Something is wrong with Your script, because DNS resolving doesnt work… so for example using Your script I cant login to Roundcube mail.

    Please correct this.

    • Canis Lupus Feb 5, 2011 @ 7:09

      This aint a charity mate, you didn’t even say thankyou to this guy who spent HIS time to create this script and distribute it openly, so at least show some appreciation and common-sense.

      He doesn’t have to fix anything, if you’re managing a firewall, least you can do is learn how it works or even read a log to find out why it’s not letting you… however it should work fine.

    • lactose Jan 11, 2012 @ 23:00

      in addition..the script does not allow mail. you have to open whatever port you use for that

  • hp1 Dec 9, 2009 @ 22:29

    I think this is a very good script, but one mistake left inside:
    egrep -v -E
    Do you mean -e ? Option called -E doesn’t exist in my egrep version :)

  • harold Oct 30, 2009 @ 12:24

    Never mind I found it, I was using another adapter so I changed the script to use eth1

  • harold Oct 30, 2009 @ 12:05

    When I start the script ssh is not working anymore and nothing else is working, totally firewalled. What might be the problem

  • Chaplu Oct 14, 2009 @ 14:32

    not helping at all

    i tried, but still getting ddos

  • wi77iam Oct 6, 2009 @ 15:45

    Nice script, how would you open ftp with tls?

    • gilligoon Apr 13, 2013 @ 18:15

      port 20-21

  • WAHIL Apr 24, 2009 @ 21:52

    It seems really good. I’ll try it very soon. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.