Raja's Exocortex

IPTables Firewall On Script

Pre-requisites

apt install iptables-persistent netfilter-persistent iptables

Usage

  1. Run fw-on.sh to create iptables ruleset.
  2. To auto load on boot, save the ruleset using netfilter-persistent save.
  3. When the docker service starts, it automatically inserts iptables rules for isolating and managing container traffic. The fw-on.sh script will delete the docker iptables rules and disrupt docker traffic. After running fw-on.sh restart the docker service by running systemctl restart docker to recreate the docker iptables rules.
  4. Ensure the docker rules are not saved using netfilter-persistent save.

Workflow

# Apply the new iptables rules, this will delete all docker iptables rules
fw-on.sh

# Save the iptables rules (without docker rules)
netfilter-persistent save

# Restart docker to recreate iptables rules
systemctl restart docker

fw-on.sh

#!/bin/bash
#
# iptables firewall script
# Filename: /usr/local/sbin/fw-on.sh
#
# Permits public services http, https from any
# Drops all other public traffic
# Internal services ssh, mysql permitted from specific IPs only
# All other incoming traffic is logged and dropped

IPTABLES=/usr/sbin/iptables

set -x

####################
## Reset iptables ##
####################
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -F
$IPTABLES -X


#####################
## PUBLIC SERVICES ##
#####################

# Public services which are permitted from anywhere
$IPTABLES -N PUBLIC-SERVICES
$IPTABLES -A PUBLIC-SERVICES -p tcp -m tcp --dport 443 -j ACCEPT
$IPTABLES -A PUBLIC-SERVICES -p tcp -m tcp --dport 80  -j ACCEPT

#######################
## INTERNAL SERVICES ##
#######################

# Internal service ssh, permit from nms1 only
$IPTABLES -N INTERNAL-SSH
$IPTABLES -A INTERNAL-SSH -s 172.16.0.211 -j ACCEPT
$IPTABLES -A INTERNAL-SSH -s 172.16.0.212 -j ACCEPT
$IPTABLES -A INTERNAL-SSH -m limit --limit 10/min -j LOG --log-prefix "iptables-ssh-drop:"
$IPTABLES -A INTERNAL-SSH -j DROP

# Internal service dns is permitted form all hosts
$IPTABLES -N INTERNAL-DNS
$IPTABLES -A INTERNAL-DNS -j ACCEPT

# Internal service ntp is permitted form all hosts
$IPTABLES -N INTERNAL-NTP
$IPTABLES -A INTERNAL-NTP -j ACCEPT

# Internal service apt-cache is permitted form all hosts
$IPTABLES -N INTERNAL-APT
$IPTABLES -A INTERNAL-APT -j ACCEPT


# Internal service any is permitted from specific IPs
$IPTABLES -N INTERNAL-ALL
$IPTABLES -A INTERNAL-ALL -s 172.16.16.16 -j ACCEPT
$IPTABLES -A INTERNAL-ALL -s 172.16.16.17 -j ACCEPT


##################
## HOUSEKEEPING ##
##################

# Drop connections from public networks
$IPTABLES -N PUBLIC-DROP
$IPTABLES -A PUBLIC-DROP -s 127.0.0.0/8     -j RETURN
$IPTABLES -A PUBLIC-DROP -s 10.0.0.0/8      -j RETURN
$IPTABLES -A PUBLIC-DROP -s 100.64.0.0/10   -j RETURN # CGNAT/tailscale network
$IPTABLES -A PUBLIC-DROP -s 172.16.0.0/12   -j RETURN
$IPTABLES -A PUBLIC-DROP -s 192.168.0.0/16  -j RETURN
$IPTABLES -A PUBLIC-DROP -s 0.0.0.0         -j DROP # silently ignore brodacsts
$IPTABLES -A PUBLIC-DROP -d 255.255.255.255 -j DROP # silently ignore brodacsts
$IPTABLES -A PUBLIC-DROP -m limit --limit 10/min -j LOG --log-prefix "iptables-drop-public:"
$IPTABLES -A PUBLIC-DROP -j DROP

###########################
## IPTABLES POLICY START ##
###########################

# Permit established traffic
$IPTABLES -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A INPUT -m conntrack --ctstate INVALID -j DROP

# Permit all ICMP traffic
$IPTABLES -A INPUT -p icmp -j ACCEPT

# Drop traffic on special loopback interface IP to system services (ssh, smtp, etc)
# This interface is for docker containers to reach host services like mysql, postgres, etc
$IPTABLES -A INPUT -d 10.255.255.10 -p tcp --dport 1:1024 -j DROP

# Permit all traffic to the loopback interface
$IPTABLES -A INPUT -i lo -j ACCEPT

# Permit public services
$IPTABLES -A INPUT -j PUBLIC-SERVICES

# Drop other traffic from public IPs
$IPTABLES -A INPUT -j PUBLIC-DROP

# Permit internal services dns and ssh
$IPTABLES -A INPUT -j INTERNAL-ALL
$IPTABLES -A INPUT -p udp -m udp --dport 53   -j INTERNAL-DNS
$IPTABLES -A INPUT -p tcp -m tcp --dport 53   -j INTERNAL-DNS
$IPTABLES -A INPUT -p udp -m udp --dport 123  -j INTERNAL-NTP
$IPTABLES -A INPUT -p tcp -m tcp --dport 3142 -j INTERNAL-APT
$IPTABLES -A INPUT -p tcp -m tcp --dport 22   -j INTERNAL-SSH

# Drop all other traffic
#$IPTABLES -A INPUT -m limit --limit 10/min -j LOG --log-prefix "iptables-drop-INPUT:"
$IPTABLES -P INPUT DROP

References

fw-off.sh