Skip to main content

Simple Firewall, Port Knocking and DDoS Testing

Take care

Please do not run this if you don't understand it. I don't take any responsibility for losing access to your servers because of a too tight firewall rules.

iptables with bash

#!/bin/bash
### BEGIN INIT INFO
# Provides: Simple Firewall for iptables
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start/stop/restart/status iptables-firewall
### END INIT INFO

# Modified by Teo
# Initial Author: Marian Amza.
# $ sudo nano /etc/init.d/fw
# $ sudo chmod +x /etc/init.d/fw
# $ sudo update-rc.d fw defaults
# $ sudo /etc/init.d/fw start
#####

# Custom Variables
IPT="iptables"
PORT_SSH="4422"

# Class for MASQUERADE
MASQ="10.10.10.0/24"

# User have the sudo rights?
fw_check() {
if [ "$(id -u)" != "0" ]; then
echo "You need to be root for using this script."
exit 1
fi
return 0
}

# Remove all rules from iptables
fw_clear() {
echo "Removing rules from iptables..."
tables="filter nat mangle"
for tables in ${table}
do
${IPT} -F -t ${table}
${IPT} -X -t ${table}
# Reset iptables counters
${IPT} -Z -t ${table}
done

# Policy ACCEPT to all packets
echo "All packets have policy ACCEPT..."
${IPT} --policy INPUT ACCEPT
${IPT} --policy OUTPUT ACCEPT
${IPT} --policy FORWARD ACCEPT

return 0
}

# Start Firewall
fw_start() {
fw_clear

# Policy default DROP all packets. Paranoid Mode - Whitelist.
${IPT} --policy INPUT DROP
${IPT} --policy OUTPUT DROP
${IPT} --policy FORWARD DROP

# Kernel
# Drop ICMP echo-request messages sent to broadcast or multicast addresses
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Don't accept ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
# Don't send ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
# Drop source routed packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
# Enable TCP SYN cookie protection from SYN floods
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Enable source address spoofing protection
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
# Log packets with impossible source addresses (spoofing)
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
# Enable IP Forward
echo 1 > /proc/sys/net/ipv4/ip_forward

# General permissions
# Allow traffic to 127.0.0.1 (localhost)
${IPT} -I INPUT -d 127.0.0.0/8 -j ACCEPT
${IPT} -I OUTPUT -s 127.0.0.0/8 -j ACCEPT
# Allow established traffic
${IPT} -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT} -I OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT} -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Services
# Accept all OUTPUT (reverse shell?)
${IPT} -I OUTPUT -p all -j ACCEPT
# SSH
${IPT} -I INPUT -p tcp --dport ${PORT_SSH} -j ACCEPT

# OpenVZ
# Masquerade
for NET in ${MASQ}
do
${IPT} -t nat -A POSTROUTING -s ${NET} -o vmbr0 -j MASQUERADE
done
${IPT} -A FORWARD -i vmbr0 -o vmbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT
${IPT} -A FORWARD -i vmbr1 -o vmbr0 -j ACCEPT

# DROP invalid or malformation packets
# Check TCP Flags
# Flags are: SYN ACK FIN RST URG PSH : ALL NONE
# NULL Packets || No TCP Flags
${IPT} -I INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Stop Xmas Tree type scanning
${IPT} -I INPUT -p tcp --tcp-flags ALL ALL -j DROP
${IPT} -I INPUT -p tcp --tcp-flags ALL URG,ACK,PSH,RST,SYN,FIN -j DROP
# NMAP Xmas Scan
${IPT} -I INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP
# NMAP ID
${IPT} -I INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP
# NMAP FIN/URG/PSH
${IPT} -I INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
# SYN-FIN Scan
${IPT} -I INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP
# FIN Scan
${IPT} -I INPUT -p tcp --tcp-flags ALL FIN -j DROP
# pscan
${IPT} -I INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# SYN/RST
${IPT} -I INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# SYN/FIN || pscan 2
${IPT} -I INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# FIN/RST || pscan 2
${IPT} -I INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
# FIN without ACK
${IPT} -I INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
# PSH without ACK
${IPT} -I INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
# URG without ACK
${IPT} -I INPUT -p tcp --tcp-flags ACK,URG URG -j DROP

# Fragments Packets
${IPT} -I INPUT -p tcp -f -j DROP
# Bad Packets
${IPT} -I INPUT -p tcp -m state --state INVALID -j DROP
${IPT} -I FORWARD -p tcp -m state --state INVALID -j DROP
${IPT} -I OUTPUT -p tcp -m state --state INVALID -j DROP
# Check SYN Packets
${IPT} -I INPUT -p tcp ! --syn -m state --state NEW -j DROP

echo "Firewall Started!"
return 0
}

# Stop Firewall
fw_stop() {
fw_clear
echo "Firewall Stopped!"
return 0
}

# Status Firewall
fw_status() {
tables="filter nat mangle"
for tables in ${table}
do
echo "$table table: "
${IPT} -t $table -L -v
done
return 0
}

# MAIN
case "${1}" in
start)
fw_check
fw_start
;;
stop)
fw_check
fw_stop
;;
restart)
fw_check
fw_stop
fw_start
;;
status)
fw_check
fw_status
;;
version)
echo "Version: 1.0"
;;
*)
echo "Use: ${0} {start|stop|restart|status}"
exit 1
;;
esac

exit 0

Port Knocking

This is useful if you don't want to have any ports open on your servers.

# Add new chain for KNOCKING
iptables -N KNOCKING
iptables -N GATE1
iptables -N GATE2
iptables -N GATE3
iptables -N PASSED

# Remaining traffic will go to KNOCKING
iptables -A INPUT -j KNOCKING

# Gate 1
iptables -A GATE1 -p tcp --dport 1111 -m recent --name AUTH1 --set -j DROP
iptables -A GATE1 -j DROP
iptables -A GATE2 -m recent --name AUTH1 --remove
iptables -A GATE2 -p tcp --dport 2222 -m recent --name AUTH2 --set -j DROP
iptables -A GATE2 -j GATE1
iptables -A GATE2 -j GATE1
iptables -A GATE3 -m recent --name AUTH2 --remove
iptables -A GATE3 -p tcp --dport 3333 -m recent --name AUTH3 --set -j DROP
iptables -A GATE3 -j GATE1
iptables -A PASSED -m recent --name AUTH3 --remove
iptables -A PASSED -p tcp --dport 22 -j ACCEPT
iptables -A PASSED -j GATE1

# Only 30 seconds to connect to SSH
iptables -A KNOCKING -m recent --rcheck --seconds 30 --name AUTH3 -j PASSED

# 10 seconds to hit all gates
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH2 -j GATE3
sudo iptables -A KNOCKING -m recent --rcheck --seconds 10 --name AUTH1 -j GATE2
sudo iptables -A KNOCKING -j GATE1
# https://www.digitalocean.com/community/tutorials/how-to-configure-port-knocking-using-only-iptables-on-an-ubuntu-vps

DDoS Testing

You can do this with BoNeSi.