Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions lib/ansible/roles/firewall/files/init.d/iptables-persistent
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#!/bin/sh

### BEGIN INIT INFO
# Provides: iptables-persistent
# Required-Start: mountkernfs $local_fs
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Start-Before: $network
# X-Stop-After: $network
# Short-Description: Set up iptables rules
### END INIT INFO

# Based on https://github.com/zertrin/iptables-persistent

PATH="/sbin:/bin:/usr/sbin:/usr/bin"

# Include config file for iptables-persistent
. /etc/default/iptables-persistent.conf

. /lib/lsb/init-functions

rc=0

case "$1" in
start)
log_action_begin_msg "Starting iptables"

if [ -e /var/run/iptables ]; then
log_warning_msg "iptables is already started"
exit 1
else
touch /var/run/iptables
fi

# if fail2ban is already running, stop it the time needed to load the new rules
if [ -x /etc/init.d/fail2ban ]; then
/etc/init.d/fail2ban stop
fi

if [ $ENABLE_ROUTING -ne 0 ]; then
# Enable Routing
echo 1 > /proc/sys/net/ipv4/ip_forward
log_action_cont_msg "v4 Routing"
if [ $IPV6 -ne 0 ]; then
echo 1 >/proc/sys/net/ipv6/conf/all/forwarding
log_action_cont_msg "v6 Routing"
fi
fi

if [ $MODULES ]; then
# Load Modules
modprobe -a $MODULES
log_action_cont_msg "Modules $MODULES"
fi

# Load saved rules
if [ -f /etc/iptables/rules.v4 ]; then
iptables-restore </etc/iptables/rules.v4
if [ $? -ne 0 ]; then
rc=1
fi
log_action_cont_msg "IPv4"
fi
if [ $IPV6 -ne 0 -a -f /etc/iptables/rules.v6 ]; then
ip6tables-restore </etc/iptables/rules.v6
if [ $? -ne 0 ]; then
rc=1
fi
log_action_cont_msg "IPv6"
fi

# restart of fail2ban
if [ -x /etc/init.d/fail2ban ]; then
/etc/init.d/fail2ban start
fi

log_action_end_msg $rc
;;

stop|force-stop)
log_action_begin_msg "Stopping iptables"

if [ ! -e /var/run/iptables ]; then
log_warning_msg "iptables is already stopped!"
exit 1
else
rm /var/run/iptables
fi

if [ $SAVE_NEW_RULES -ne 0 ]; then
# Backup old rules
cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.bak
# Save new rules
iptables-save >/etc/iptables/rules.v4
if [ $? -ne 0 ]; then
rc=1
fi
log_action_cont_msg "IPv4"

if [ $IPV6 -ne 0 ]; then
# Backup old rules
cp /etc/iptables/rules.v6 /etc/iptables/rules.v6.bak
# Save new rules
ip6tables-save >/etc/iptables/rules.v6
if [ $? -ne 0 ]; then
rc=1
fi
log_action_cont_msg "IPv6"
fi
fi

# stop fail2ban before flushing iptables chains
if [ -x /etc/init.d/fail2ban ]; then
/etc/init.d/fail2ban stop
fi

# Restore Default Policies
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Flush rules on default tables
iptables -F
iptables -t nat -F
iptables -t mangle -F

if [ $IPV6 -ne 0 ]; then
# Restore Default Policies
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT

# Flush rules on default tables
ip6tables -F
ip6tables -t mangle -F
fi

if [ $MODULES ]; then
# Unload previously loaded modules
modprobe -r $MODULES
fi

# Disable Routing if enabled
if [ $ENABLE_ROUTING -ne 0 ]; then
# Disable Routing
echo 0 > /proc/sys/net/ipv4/ip_forward
if [ $IPV6 -ne 0 ]; then
echo 0 >/proc/sys/net/ipv6/conf/all/forwarding
fi
fi

# start of fail2ban
if [ -x /etc/init.d/fail2ban ]; then
/etc/init.d/fail2ban start
fi

log_action_end_msg $rc
;;

restart|force-reload)
$0 stop
$0 start
;;

status)
echo "Filter Rules:"
echo "--------------"
iptables -L -v
echo ""
echo "NAT Rules:"
echo "-------------"
iptables -t nat -L -v
echo ""
echo "Mangle Rules:"
echo "----------------"
iptables -t mangle -L -v

if [ $IPV6 -ne 0 ]; then
echo "**********"
echo "** IPV6 **"
echo "**********"
echo "Filter Rules:"
echo "--------------"
ip6tables -L -v
echo ""
echo "Mangle Rules:"
echo "----------------"
ip6tables -t mangle -L -v
fi
;;

*)
echo "Usage: $0 {start|stop|force-stop|restart|force-reload|status}" >&2
exit 1
;;
esac

exit 0
70 changes: 70 additions & 0 deletions lib/ansible/roles/firewall/files/iptables/rules.v4
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
*filter
# Set default chain policies
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Drop any tcp packet that does not start a connection with a syn flag.
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Drop any invalid packet that could not be identified.
-A INPUT -m state --state INVALID -j DROP

# Blacklist (examples)
#-A INPUT -i eth+ -s 198.51.100.1 -p tcp --dport 22 -j DROP # Example IP from RFC 5737
#-A INPUT -i eth+ -s 203.0.113.34 -j DROP # Example IP from RFC 5737

# Allow incoming FTP
#-A INPUT -i eth+ -p tcp --dport 21 -j ACCEPT

# Allow incoming SSH
-A INPUT -i eth+ -p tcp --dport 22 -j ACCEPT

# Allow incoming HTTP
-A INPUT -i eth+ -p tcp --dport 80 -j ACCEPT

# Allow incoming HTTPS
-A INPUT -i eth+ -p tcp --dport 443 -j ACCEPT

# Allow ping from inside to outside
-A OUTPUT -o eth+ -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -i eth+ -p icmp --icmp-type echo-reply -m limit --limit 2/s -j ACCEPT

# Allow ping from outside to inside
-A INPUT -i eth+ -p icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT
-A OUTPUT -o eth+ -p icmp --icmp-type echo-reply -j ACCEPT

# Allow NTP
#-A INPUT -i eth+ -p udp --dport 123 -j ACCEPT
#-A OUTPUT -o eth+ -p udp --sport 123 -j ACCEPT

# Allow DNS
#-A OUTPUT -o eth+ -p tcp --dport 53 -j ACCEPT
#-A OUTPUT -o eth+ -p udp --dport 53 -j ACCEPT
#-A INPUT -i eth+ -p tcp --sport 53 -j ACCEPT
#-A INPUT -i eth+ -p udp --sport 53 -j ACCEPT

# Log dropped packets
-N LOGGING
-A INPUT -j LOGGING
-A LOGGING -p tcp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [denied TCP] " --log-level 7
-A LOGGING -p udp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [denied UDP] " --log-level 7
-A LOGGING -p icmp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [denied ICMP] " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT

# Allow all other outbound traffic
-A OUTPUT -j ACCEPT

# Reject forwarded traffic, explicitely (despite chain policy)
-A FORWARD -j REJECT

COMMIT
51 changes: 51 additions & 0 deletions lib/ansible/roles/firewall/files/iptables/rules.v6
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# allow all loopback traffic
-A INPUT -i lo -j ACCEPT

# allow all ICMP traffic
-A INPUT -p icmpv6 -j ACCEPT

# Drop any tcp packet that does not start a connection with a syn flag.
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# packets belonging to an established connection or related to one can pass
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP

# Allow incoming FTP
#-A INPUT -i eth+ -p tcp --dport 21 -j ACCEPT

# Allow incoming SSH
-A INPUT -i eth+ -p tcp -m tcp --dport 22 -j ACCEPT

# Allow incoming HTTP
-A INPUT -i eth+ -p tcp -m tcp --dport 80 -j ACCEPT

# Allow incoming HTTPS
-A INPUT -i eth+ -p tcp -m tcp --dport 443 -j ACCEPT

# Allow DNS
#-A OUTPUT -o eth+ -p tcp --dport 53 -j ACCEPT
#-A OUTPUT -o eth+ -p udp --dport 53 -j ACCEPT
#-A INPUT -i eth+ -p tcp --sport 53 -j ACCEPT
#-A INPUT -i eth+ -p udp --sport 53 -j ACCEPT

# Log dropped packets
-N LOGGING
-A INPUT -j LOGGING
-A LOGGING -p tcp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [INPUT6 ][denied TCP] " --log-level 7
-A LOGGING -p udp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [INPUT6 ][denied UDP] " --log-level 7
-A LOGGING -p icmp -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "iptables: [INPUT6 ][denied ICMP] " --log-level 7
-A INPUT -j REJECT

# allow outgoing traffic, explicitly (despite chain policy)
-A OUTPUT -j ACCEPT

# disallow forwarded traffic, explicitly (despite chain policy)
-A FORWARD -j REJECT

COMMIT
4 changes: 4 additions & 0 deletions lib/ansible/roles/firewall/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
- name: restart firewall
command: /etc/init.d/iptables-persistent restart
sudo: yes
37 changes: 37 additions & 0 deletions lib/ansible/roles/firewall/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
- name: Attempt to install vanilla iptables-persistent
apt: pkg=iptables-persistent state=latest update_cache=yes
register: iptables_attempted
ignore_errors: yes
sudo: yes

# See https://forum.linode.com/viewtopic.php?t=9070&p=58732
- name: Postinst workaround for iptables-persistent
replace: dest=/var/lib/dpkg/info/iptables-persistent.postinst regexp='^(\s*?modprobe -q ip6?table_filter\s*?)$' replace='\1 || true'
when: iptables_attempted | failed
sudo: yes

- name: Install firewall packages
apt: pkg={{ item }} state=present
with_items: firewall_packages
sudo: yes

- name: Install iptables init script + rulesets
copy: src={{ item }} dest=/etc/{{ item }} mode=0644 backup=yes
sudo: yes
with_items:
- init.d/iptables-persistent
- iptables/rules.v4
- iptables/rules.v6

- name: Create iptables + fail2ban configs
template: src={{ item }} dest=/etc/{{ item }} mode=0644
sudo: yes
with_items:
- default/iptables-persistent.conf
- fail2ban/jail.local

- name: Ensure iptables init script is executable
file: path=/etc/init.d/iptables-persistent mode=0755
notify: restart firewall
sudo: yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# A basic config file for the /etc/init.d/iptable-persistent script
#

# Should new manually added rules from command line be saved on reboot? Assign to a value different that 0 if you want this enabled.
SAVE_NEW_RULES=0

# Modules to load:
#modules="ip_conntrack_ftp" #example for ftp conntracking
modules=""

# Enable Routing? Assign to a value different that 0 if you want this enabled.
ENABLE_ROUTING=0

# Enable IPv6? Assign to a value different that 0 if you want this enabled.
IPV6={% if iptables.ipv6 is defined and iptables.ipv6 %}1{% else %}0{% endif %}
Loading