Skip to content

Instantly share code, notes, and snippets.

@heartnet
Created April 15, 2011 12:33
Show Gist options
  • Save heartnet/921615 to your computer and use it in GitHub Desktop.
Save heartnet/921615 to your computer and use it in GitHub Desktop.
iptables.sh
#!/bin/bash
# @(#) iptables.sh - Script for configuring firewall with iptables
# Based on: http://centossrv.com/
#
# Configuration part
#
##############################
## Set external interface
EXTERNAL_IF="eth0"
## Define full path of functions
PATH_FUNCTIONS="/root/scripts/lib/iptables_functions"
## Define full path of blacklist
PATH_BLACKLIST="/root/scripts/misc/blacklist"
## Define full path of whitelist
PATH_WHITELIST="/root/scripts/misc/whitelist"
## Define full path of allowed host or network to use proxy
PATH_ALLOW_PROXY_LIST="/root/scripts/misc/allow_proxy_list"
## Define full path of init script of iptables
PATH_INIT_SCRIPT="/etc/init.d/iptables"
## Define syslog priority of iptables
SYSLOG_PRIORITY="debug"
## Define country which is allowed to access
COUNTRY_ACCEPT=("JP")
## Define country of which packets are forcibly dropped
COUNTRY_DROP=("CN" "TW" "KR" "KP")
## set PATH
export PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin
#
# Main routines
#
##############################
## Obtain netmask from target interface
LOCALNET_MASK=`ifconfig ${EXTERNAL_IF} | sed -e 's/^.*Mask:\([^ ]*\)$/\1/p' -e d`
## Obtain network address from target interface
LOCALNET_ADDR=`netstat -rn | grep ${EXTERNAL_IF} | grep ${LOCALNET_MASK} | cut -f1 -d' '`
LOCALNET=${LOCALNET_ADDR}/${LOCALNET_MASK}
## Reset all rules
iptables -F
iptables -X
iptables -Z
## Stop running iptables
${PATH_INIT_SCRIPT} stop
## Default policy
## (These policies will be applied to rules which do not match any rules.)
iptables -P INPUT DROP # All discard incoming packets
iptables -P OUTPUT ACCEPT # All permit outgoing packets
iptables -P FORWARD ACCEPT # All permit forwarding packets
#iptables -P FORWARD DROP # All discard forwarding packets
## Permit all packets from loopback interface
iptables -A INPUT -i lo -j ACCEPT
## Permit all packets from private network
iptables -A INPUT -s ${LOCALNET} -j ACCEPT
## Permit all packets via private network interface card
iptables -A INPUT ! -i ${EXTERNAL_IF} -j ACCEPT
## Permit all return packets from private network
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## Enable SYN Cookies
## (*) for TCP SYN Flood attack
sysctl -w net.ipv4.tcp_syncookies=1 >/dev/null
sed -i '/net.ipv4.tcp_syncookies/d' /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >>/etc/sysctl.conf
## Do not reply to broadcast ping packets
## (*) for Smurf attack
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 >/dev/null
sed -i '/net.ipv4.icmp_echo_ignore_broadcasts/d' /etc/sysctl.conf
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >>/etc/sysctl.conf
## Deny all ICMP Redirect packets
sed -i '/net.ipv4.conf.*.accept_redirects/d' /etc/sysctl.conf
for DEV in `ls /proc/sys/net/ipv4/conf/`
do
sysctl -w net.ipv4.conf.${DEV}.accept_redirects=0 >/dev/null
echo "net.ipv4.conf.${DEV}.accept_redirects=0" >>/etc/sysctl.conf
done
## Deny all Source-Routed packets
sed -i '/net.ipv4.conf.*.accept_source_route/d' /etc/sysctl.conf
for DEV in `ls /proc/sys/net/ipv4/conf/`
do
sysctl -w net.ipv4.conf.${DEV}.accept_source_route=0 >/dev/null
echo "net.ipv4.conf.${DEV}.accept_source_route=0" >>/etc/sysctl.conf
done
## Discard all packets of new sessions which do not start from SYN flag
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
## Deny all packets of new sessions which start from SYN/ACK flag
iptables -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
## Discard all fragmented packets after logging
iptables -A INPUT -f -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [FRAGMENT] : "
iptables -A INPUT -f -j DROP
## Discard all packets which are related to NetBIOS from external network without logging
## (*) for not logging unnecessary packets
iptables -A INPUT ! -s ${LOCALNET} -p tcp -m multiport --dports 135,137,138,139,445 -j DROP
iptables -A INPUT ! -s ${LOCALNET} -p udp -m multiport --dports 135,137,138,139,445 -j DROP
iptables -A OUTPUT ! -d ${LOCALNET} -p tcp -m multiport --sports 135,137,138,139,445 -j DROP
iptables -A OUTPUT ! -d ${LOCALNET} -p udp -m multiport --sports 135,137,138,139,445 -j DROP
## Discard all private packets from external interface after logging
## (*) for Ingress
iptables -N INGRESS
iptables -A INGRESS -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [INGRESS_ATTACK]: "
iptables -A INPUT -i ${EXTERNAL_IF} -s 0.0.0.0/8 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 127.0.0.0/8 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 10.0.0.0/8 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 172.16.0.0/12 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 192.168.0.0/16 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 169.254.0.0/16 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 192.0.2.0/24 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 224.0.0.0/4 -j INGRESS
iptables -A INPUT -i ${EXTERNAL_IF} -s 240.0.0.0/4 -j INGRESS
## Discard all private packets which go to outside from external interface after logging
## (*) for Egress
iptables -N EGRESS
iptables -A EGRESS -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [EGRESS_ATTACK]: "
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 0.0.0.0/8 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 127.0.0.0/8 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 10.0.0.0/8 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 172.16.0.0/12 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 192.168.0.0/16 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 169.254.0.0/16 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 192.0.2.0/24 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 224.0.0.0/4 -j EGRESS
iptables -A OUTPUT -o ${EXTERNAL_IF} -d 240.0.0.0/4 -j EGRESS
## Discard all packets which request over 4 times per second after logging
## (*) for TCP SYN Flood attack
iptables -N SYN_FLOOD
iptables -A SYN_FLOOD -m limit --limit 10/s --limit-burst 20 -j RETURN
iptables -A SYN_FLOOD -m limit --limit 1/s --limit-burst 10 -j LOG \
--log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [SYN_FLOOD]: "
iptables -A SYN_FLOOD -j DROP
iptables -A INPUT -p tcp --syn -j SYN_FLOOD
## Discard all private packets including multicast packets from external network after logging
## (*) for IP Spoofing
#iptables -N IP_SPOOFING
#iptables -A IP_SPOOFING -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [IP_SPOOFING]: "
#iptables -A IP_SPOOFING -j DROP
#iptables -A INPUT -i ${EXTERNAL_IF} -s 0.0.0.0/8 -j IP_SPOOFING
#iptables -A INPUT -i ${EXTERNAL_IF} -s 127.0.0.0/8 -j IP_SPOOFING
#iptables -A INPUT -i ${EXTERNAL_IF} -s 10.0.0.0/8 -j IP_SPOOFING
#iptables -A INPUT -i ${EXTERNAL_IF} -s 172.16.0.0/12 -j IP_SPOOFING
#iptables -A INPUT -i ${EXTERNAL_IF} -s 192.168.0.0/16 -j IP_SPOOFING
## Discard all ping packets which request over 4 times per second after logging
## (*) for Ping of Death attack
iptables -N PING_OF_DEATH
iptables -A PING_OF_DEATH -m limit --limit 1/s --limit-burst 4 -j ACCEPT
iptables -A PING_OF_DEATH -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [PING_OF_DEATH]: "
iptables -A PING_OF_DEATH -j DROP
iptables -A INPUT -p icmp --icmp-type echo-request -j PING_OF_DEATH
## Discard all packets for all host (broadcast, multicast) without logging
## (*) for not logging unnecessary packets
iptables -A INPUT -d 255.255.255.255 -j DROP
iptables -A INPUT -d 224.0.0.1 -j DROP
## Deny all pakcets to port 113 (IDENT)
## (*) for not delaying responses from mail servers
iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset
## Definition of the "ACCEPT_COUNTRY_MAKE" function
## Define user-defined chain to permit all pakcets from specified country
ACCEPT_COUNTRY_MAKE(){
for ADDR in `cat /tmp/cidr.txt | grep ^$1 | awk '{ print $2 }'`
do
iptables -A ACCEPT_COUNTRY -s ${ADDR} -j ACCEPT
done
}
## Definition of the "DROP_COUNTRY_MAKE" function
## Define user-defined chain to discard all packets from specified country
DROP_COUNTRY_MAKE(){
for ADDR in `cat /tmp/cidr.txt | grep ^$1 | awk '{ print $2 }'`
do
iptables -A DROP_COUNTRY -s ${ADDR} -m limit --limit 1/s -j LOG \
--log-tcp-options --log-ip-options \
--log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [DROPPED_COUNTRY]: "
iptables -A DROP_COUNTRY -s ${ADDR} -j DROP
done
}
## Obtain the list of IP addresses
. ${PATH_FUNCTIONS}
IPLISTGET
## Create user-defined chain ("ACCEPT_COUNTRY") to permit all packets from accepted country
iptables -N ACCEPT_COUNTRY
for COUNTRY in "${COUNTRY_ACCEPT[@]}"
do
ACCEPT_COUNTRY_MAKE ${COUNTRY}
done
## From below, If you need to permit all packets from accepted country,
## you can specify "ACCEPT_COUNTRY" instead of "ACCEPT".
## Discard all packets from aggressive coutries after logging
iptables -N DROP_COUNTRY
for COUNTRY in "${COUNTRY_DROP[@]}"
do
DROP_COUNTRY_MAKE ${COUNTRY}
done
iptables -A INPUT -j DROP_COUNTRY
#
# Configuration for public servecies [beginning]
#
## Permit all packets to TCP port 22 (SSH) only from accepted country
iptables -A INPUT -p tcp --dport 22 -j ACCEPT_COUNTRY
## Permit all packets to TCP/UDP port 53 (DNS)
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
## Permit all packets to TCP port 80 (HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
## Permit all packets to TCP port 443 (HTTPS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
## Permit all packets to TCP port 25 (SMTP)
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
## Permit all packets to TCP port 587 (SMTP Submission)
iptables -A INPUT -p tcp --dport 587 -j ACCEPT
## Permit all packets to TCP port 465 (SMTPS) only from accepted country
iptables -A INPUT -p tcp --dport 465 -j ACCEPT_COUNTRY
## Permit all packets to TCP port 110 (POP3) only from accepted country
iptables -A INPUT -p tcp --dport 110 -j ACCEPT_COUNTRY
## Permit all packets to TCP port 995 (POP3S) only from accepted country
iptables -A INPUT -p tcp --dport 995 -j ACCEPT_COUNTRY
## Permit all packets to TCP port 143 (IMAP) only from accepted country
iptables -A INPUT -p tcp --dport 143 -j ACCEPT_COUNTRY
## Permit all packets to TCP port 993 (IMAPS) only from accepted country
iptables -A INPUT -p tcp --dport 993 -j ACCEPT_COUNTRY
## Permit all packets to TCP port 1723 (PPTP) only from accepted country
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT_COUNTRY
## Permit all packets to GRE only from accepted country
iptables -A INPUT -p gre -j ACCEPT_COUNTRY
## for NAT via PPTP
iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -j MASQUERADE
## Permit all packets to TCP/UDP port 5154 - 5170 (BZFS)
iptables -A INPUT -p tcp --dport 5154:5170 -j ACCEPT
iptables -A INPUT -p udp --dport 5154:5170 -j ACCEPT
## Permit all packets to TCP port 10382 (Squid) only from allowed host or network
#if [ -s ${PATH_ALLOW_PROXY_LIST} ]; then
# iptables -N ALLOW_PROXY
# iptables -A ALLOW_PROXY -j ACCEPT
#
# for ADDR in `cat ${PATH_ALLOW_PROXY_LIST}`
# do
# iptables -A INPUT -s ${ADDR} -p tcp --dport 10382 -j ALLOW_PROXY
# done
#fi
#
# Configuration for public servecies [end]
#
## Discard all packets from aggressive IP addresses or networks after logging
if [ -s ${PATH_BLACKLIST} ]; then
iptables -N BLACKLIST
iptables -A BLACKLIST -j LOG --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [BLACKLIST]: "
iptables -A BLACKLIST -j DROP
for ADDR in `cat ${PATH_BLACKLIST}`
do
iptables -I INPUT -s ${ADDR} -j BLACKLIST
done
fi
## Permit all packets from reliable IP addresses or networks
if [ -s ${PATH_WHITELIST} ]; then
iptables -N WHITELIST
iptables -A WHITELIST -j ACCEPT
for ADDR in `cat ${PATH_WHITELIST}`
do
iptables -I INPUT -s ${ADDR} -j WHITELIST
done
fi
## Discard all packets which did not match any rules above after logging
iptables -A INPUT -m limit --limit 1/s -j LOG \
--log-tcp-options --log-ip-options \
--log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [DROPPED_INPUT]: "
iptables -A INPUT -j DROP
#iptables -A FORWARD -m limit --limit 1/s -j LOG \
# --log-tcp-options --log-ip-options \
# --log-level ${SYSLOG_PRIORITY} --log-prefix "iptables: [DROPPED_FORWARD]: "
#iptables -A FORWARD -j DROP
## Save rules
${PATH_INIT_SCRIPT} save
## Start iptables
${PATH_INIT_SCRIPT} start
# [EOF]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment