Code:
#!/bin/bash
### BEGIN INIT INFO
# Provides: Firewall
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop Firewall
### END INIT INFO
. /lib/lsb/init-functions
#---------------------------------------------------------------------
# /etc/init.d/firewall
#
# IPTables (netfilter) firewall manager script
#
# Server: backup
#
# History of modifications
# When Who What
# ---- --- ----------
# 2011-06-01 Mark Original version
# 2011-07-13 Mark Moved OUTPUT rules above INPUT rules
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global variables
#
IPT=`which iptables`
MODPROBE=`which modprobe`
DEPMOD=`which depmod`
FLAGS='URG,ACK,PSH,RST,SYN,FIN'
LOG_LEVEL="debug"
CONFIG_FILE="/usr/local/etc/firewall.conf"
#---------------------------------------------------------------------
# Config file
#
if [ ! -f $CONFIG_FILE ];
then
echo "Error: $CONFIG_FILE not found!";
exit 1;
else
source $CONFIG_FILE
fi
#---------------------------------------------------------------------
# Function: Usage
# Shows a reminder
#---------------------------------------------------------------------
Usage() {
echo "Usage: $0: start|stop|restart"
exit 1
}
#---------------------------------------------------------------------
# Function: StartFirewall
# Loads the rules in memory
#---------------------------------------------------------------------
StartFirewall() {
#---------------------------------------------------------------------
# Load kernel modules
#
$DEPMOD -a
$MODPROBE ip_tables
$MODPROBE ip_conntrack
$MODPROBE ip_conntrack_ftp
$MODPROBE iptable_filter
$MODPROBE ipt_LOG
$MODPROBE ipt_limit
$MODPROBE ipt_state
#---------------------------------------------------------------------
# Empty the "filter" table
#
$IPT -t filter -F
$IPT -t filter -X
#---------------------------------------------------------------------
# Default policy for all tables: drop everything
#
$IPT -t filter -P INPUT DROP
$IPT -t filter -P OUTPUT DROP
$IPT -t filter -P FORWARD DROP
#---------------------------------------------------------------------
# Log entries definitions
#
# Every log "line" will be prefixed with "[FW:" (for firewall), to
# make log filtering easier down the road.
# Log DROPs
$IPT -N LOG_DROP
if [ `echo "x$LOG_DROPPED_PACKETS" | tr [:upper:] [:lower:]` = "xyes" ];
then
$IPT -A LOG_DROP -j LOG --log-prefix '[FW:DROP] ' --log-level $LOG_LEVEL
fi
$IPT -A LOG_DROP -j DROP
# Log ACCEPTs
$IPT -N LOG_ACCEPT
if [ `echo "x$LOG_ACCEPTED_PACKETS" | tr [:upper:] [:lower:]` = "xyes" ];
then
$IPT -A LOG_ACCEPT -j LOG --log-prefix '[FW:ACCEPT] ' --log-level $LOG_LEVEL
fi
$IPT -A LOG_ACCEPT -j ACCEPT
# Log REJECTs
$IPT -N LOG_REJECT
if [ `echo "x$LOG_REJECTED_PACKETS" | tr [:upper:] [:lower:]` = "xyes" ];
then
$IPT -A LOG_REJECT -j LOG --log-prefix '[FW: REJECT] ' --log-level $LOG_LEVEL
fi
$IPT -A LOG_REJECT -j REJECT
#---------------------------------------------------------------------
# Drop weird packets
#
# A packet can't have SYN+ACK and also be new! (state NEW)
$IPT -A INPUT -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j LOG_REJECT
# No legal packet can have all flags on or off: doesn't make sense
$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j LOG_DROP
$IPT -A INPUT -p tcp --tcp-flags ALL ALL -j LOG_DROP
#---------------------------------------------------------------------
#Loopback interface (lo: 127.0.0.1) must be open to itself
#
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Anti spoofing: traffic from 127.0.0.0/8 must originate from the loopback interface
$IPT -A INPUT -s 127.0.0.0/8 ! -i lo -j LOG_DROP
#---------------------------------------------------------------------
# Logging of start and end of connections (but not the "middle" packets)
#
$IPT -t filter -A OUTPUT -p tcp --tcp-flags $FLAGS SYN,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A OUTPUT -p tcp --tcp-flags $FLAGS FIN,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A OUTPUT -p tcp --tcp-flags $FLAGS RST,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A INPUT -p tcp --tcp-flags $FLAGS SYN,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A INPUT -p tcp --tcp-flags $FLAGS FIN,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A INPUT -p tcp --tcp-flags $FLAGS RST,ACK -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT
$IPT -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#---------------------------------------------------------------------
# OUTBOUND traffic (OUTPUT table)
# Traffic that this server sends (not forwarded traffic)
# Allow all outbound traffic
$IPT -t filter -A OUTPUT -j ACCEPT
#---------------------------------------------------------------------
# INBOUND traffic (INPUT table)
# Traffic addressed explicitly for this server (ie: not forwarded traffic,
# if the server is used as router/firewall).
for SERVICE in $SERVICES_ALLOWED_TCP;
do
IPS_LIST=`echo IP_ALLOWED_$SERVICE | tr '[:lower:]' '[:upper:]'`
if [ "x${!IPS_LIST}" = "x" ];
then
# No IP limitations for this service
$IPT -t filter -A INPUT -p tcp --dport $SERVICE --tcp-flags $FLAGS SYN -m state --state NEW -j LOG_ACCEPT
else
for IP in ${!IPS_LIST};
do
$IPT -t filter -A INPUT -p tcp --dport $SERVICE -s "$IP" --tcp-flags $FLAGS SYN -m state --state NEW -j LOG_ACCEPT
done
fi
done
for SERVICE in $SERVICES_ALLOWED_UDP;
do
IPS_LIST=`echo IP_ALLOWED_$SERVICE | tr '[:lower:]' '[:upper:]'`
if [ "x${!IPS_LIST}" = "x" ];
then
# No IP limitations for this service
$IPT -t filter -A INPUT -p udp --dport $SERVICE -j LOG_ACCEPT
else
for IP in ${!IPS_LIST};
do
$IPT -t filter -A INPUT -p udp --dport $SERVICE -s "$IP" -j LOG_ACCEPT
done
fi
done
# PING
$IPT -t filter -A INPUT -p icmp --icmp-type echo-request -j LOG_ACCEPT
#---------------------------------------------------------------------
# Log all packets before they are dropped
# (default policy)
$IPT -t filter -A INPUT -j LOG_DROP
$IPT -t filter -A OUTPUT -j LOG_DROP
$IPT -t filter -A FORWARD -j LOG_DROP
}
#---------------------------------------------------------------------
# Function: StopFirewall
# Stop the firewall and ACCEPT ALL TRAFFIC
#---------------------------------------------------------------------
StopFirewall() {
#---------------------------------------------------------------------
# Empty all filter tables
#
$IPT -t filter -F
$IPT -t filter -X
#---------------------------------------------------------------------
# Default policy: Accept everything
#
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
}
#---------------------------------------------------------------------
# Function: RestartFirewall
# Empty and reload firewall rules
#---------------------------------------------------------------------
RestartFirewall() {
StartFirewall
}
#---------------------------------------------------------------------
# Main program [ main() ]
# Check first argument and launch appropriate function
#---------------------------------------------------------------------
case "$1" in
start)
echo -n "Starting firewall: "
StartFirewall
echo `basename $0`;
;;
stop)
echo -n "Stopping firewall: "
StopFirewall
echo `basename $0`;
;;
restart)
echo -n "Restarting firewall: "
RestartFirewall
echo `basename $0`;
;;
*)
Usage
;;
esac
exit 0
Code:
# Configuration file for firewall
# ===============================
# SERVICES_ALLOWED: defines the services that are allowed to be accessed
# IP_ALLOWED_<SERVICE>: Default all have access to the open services defined in SERVICES_ALLOWED
# But if you define an "IP_ALLOWED_<SERVICE>" variable,
# only those ip's are allowed to the service.
# (this counts for internal AND external traffic!!)
# Checkout /etc/services for service names, else use port number
SERVICES_ALLOWED_TCP="ssh http https nrpe"
SERVICES_ALLOWED_UDP="snmp"
IP_ALLOWED_SSH="192.168.4.0/22 host1.domain.tld host2.domain.tld"
IP_ALLOWED_NRPE="noc.domain.tld"
IP_ALLOWED_SNMP="noc.domain.tld"
LOG_DROPPED_PACKETS=no
LOG_ACCEPTED_PACKETS=no
LOG_REJECTED_PACKETS=yes
basic example of the setup.
I'm no bash guru, but I think it's a nice base to start working with.
Recent comments
21 hours 15 min ago
1 day 2 hours ago
1 day 3 hours ago
1 day 4 hours ago
1 day 6 hours ago
1 day 10 hours ago
1 day 11 hours ago
1 day 13 hours ago
2 days 2 hours ago
2 days 4 hours ago