basic security

by woomoo
16 deployments · 4 still active · last rev. 4 years ago

Compatible with: Ubuntu 14.04 LTS
						#!/bin/bash
#
# Basic Security StackScript
# By Jed Smith <jed@linode.com>
#
# <UDF name="allow" label="Allowed services" example="Punch holes in the firewall for these services. SSH is already open (see Restrict SSH)." default="" manyOf="FTP Server: TCP 21,Telnet: TCP 23,SMTP: TCP 25,DNS Server: TCP/UDP 53,Web Server: TCP 80,POP3 Mail Service: TCP 110,NTP Service: UDP 123,IMAP Mail Service: TCP 143,SSL Web Server: TCP 443,Mail Submission: TCP 587,SSL IMAP Server: TCP 993,OpenVPN Server: UDP 1194,IRC Server: TCP 6667" />
# <UDF name="extraT" label="Extra TCP holes" example="Extra holes in the firewall for TCP. Understands service names ('kerberos') and port numbers ('31337'), separate by spaces." default="" />
# <UDF name="extraU" label="Extra UDP holes" example="Extra holes in the firewall for UDP. Understands service names ('daytime') and port numbers ('1094'), separate by spaces." default="" />
# <UDF name="sshrange" label="Restrict SSH" example="Will restrict SSH access to the given CIDR range. Leave empty for no restrictions." default="0/0" />
# <UDF name="icmplevel" label="ICMP paranoia level" example="Rules for ICMP. You should leave this at the default to be a good net citizen." oneOf="Well-behaved,Only allow pings,Ignore all ICMP" default="None" />
# <UDF name="loglevel" label="Logging level" example="How much to log. This can generate a lot of output." oneOf="Nothing,Some stuff,Everything" default="Nothing" />
#

IFUP=/etc/network/if-up.d/iptables.sh
IFDOWN=/etc/network/if-down.d/iptables.sh
IPTABLES() {
  echo iptables $@ >&1 2>&1
  iptables $@
}

# Make sure we have iptables, and do this business while we're at it
echo Updating system and installing iptables.
aptitude -y update
aptitude -y safe-upgrade
aptitude -y install iptables

echo
echo ===========================================================================
echo Configuring iptables firewall.

# Set up scripts to load/unload the rules at ifup/ifdown
echo Generating store/restore scripts.
for i in $IFUP $IFDOWN; do
  echo $i
  touch $i && chmod 744 $i
  echo >$i "#!/bin/bash"
  echo >>$i "# Generated by iptables StackScript"
  echo >>$i
done
echo >>$IFUP "iptables-restore < /etc/firewall.conf"
echo >>$IFDOWN "iptables-save > /etc/firewall.conf"

# Fix sysctl so this will not log to console
# The distro-default kernel printk is commented out, so we cheat and add
echo Changing kernel.printk in the kernel.
echo "3 1 1 1" > /proc/sys/kernel/printk
echo Modifying /etc/sysctl.conf.
echo >>/etc/sysctl.conf
echo "# Added by iptables StackScript, to not log iptables information to console" >>/etc/sysctl.conf
echo 'kernel.printk = "3 1 1 1"' >>/etc/sysctl.conf

# Build iptables
echo Building iptables rules.
for i in INPUT OUTPUT; do IPTABLES -P $i ACCEPT && IPTABLES -F $i; done
IPTABLES -P FORWARD DROP && IPTABLES -F FORWARD
for i in DROP1 DROP2 TCP UDP; do
  IPTABLES -F $i >/dev/null 2>/dev/null
  IPTABLES -X $i >/dev/null 2>/dev/null
  IPTABLES -N $i
done

# Dropper rules based on selected loglevel
# Drop1 is logged if loglevel >= Some Stuff, Drop2 if loglevel = Everything
test "${LOGLEVEL}" == "Everything" && (for i in DROP1 DROP2; do IPTABLES -A $i -j LOG --log-level notice --log-prefix "iptables: "; done)
test "${LOGLEVEL}" == "Some stuff" && (IPTABLES -A DROP1 -j LOG --log-level notice --log-prefix "iptables: ")
for i in DROP1 DROP2; do IPTABLES -A $i -j DROP; done

# Preamble
IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
IPTABLES -A INPUT -m state --state INVALID -j DROP1
IPTABLES -A INPUT -i lo -j ACCEPT
IPTABLES -A INPUT -p tcp -j TCP
IPTABLES -A INPUT -p udp -j UDP

# ICMP
echo Configuring ICMP behavior.
test "${ICMPLEVEL}" == "Well-behaved" && (IPTABLES -A INPUT -p icmp -j ACCEPT)
test "${ICMPLEVEL}" == "Only allow pings" && (IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT)

# Bottom of the input chain -- log?
test "${LOGLEVEL}" == "Everything" && (IPTABLES -A INPUT -j LOG --log-level notice --log-prefix "iptables: ")

# SSH is open by default
if [ -z "$SSHRANGE" ]; then SSHRANGE="0/0"; fi
echo Allowing: SSH from $SSHRANGE
IPTABLES -A TCP -p tcp --dport ssh -s $SSHRANGE -j ACCEPT

# Allowed services
IFS=$','
for service in $ALLOW; do
  echo Allowing: $service
  interested=${service#*: }
  IFS=$' '
  set -- $interested
  for i in TCP UDP; do
    if [[ "$1" == *$i* ]]; then IPTABLES -A $i -p $i --dport $2 -j ACCEPT; fi
  done
done
unset IFS

# Extras
for i in $EXTRAU; do
  echo Allowing: UDP $i
  IPTABLES -A UDP -p UDP --dport $i -j ACCEPT
done
for i in $EXTRAT; do
  echo Allowing: TCP $i
  IPTABLES -A TCP -p TCP --dport $i -j ACCEPT
done

# Lock 'n save
echo Completing.
IPTABLES -P INPUT DROP
iptables-save > /etc/firewall.conf

echo Done.