Netfilter old school with IPTABLES

Preliminaries

Ubuntu

systemctl stop ufw
systemctl disable ufw

ls -lF /etc/iptables.rules
ls -lF /etc/iptables.rules6

RHEL/CentOS

systemctl stop firewalld
systemctl disable firewalld
yum install iptables-services iptables-utils

ls -lF  /etc/sysconfig/iptables
ls -lF /etc/sysconfig/ip6tables

Check what chains you got and if DOCKER is there already

iptables -L | grep ^Chain
ps auxww | grep dockerd
iptables -L -t filter
iptables -L -t nat
iptables -L -t mangle

==> in case you have Docker, see the dedicated guide

Quick & dirty NAT

With two one-liners

Enable forwarding

#sysctl -w net.ipv4.ip_forward=1
echo 1 > /proc/sys/net/ipv4/ip_forward

#echo net.ipv4.ip_forward=1 > /etc/sysctl.d/ip_forward.conf
#echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
#sysctl -p

SNAT a static IP

iptables -t nat -A POSTROUTING -o INTERNAL-DEVICE -s INTERNAL/CIDR -j SNAT --to-source FACING-IP

SNAT a changing IP

iptables -t nat -A POSTROUTING -o INTERNAL-DEVICE -s INTERNAL/CIDR -j MASQUERADE

Eventually force it through the system firewall

#iptables -P FORWARD ACCEPT
#iptables -A INPUT -i ens2 -s 10.8.8.0/24 -j ACCEPT
#iptables -A OUTPUT -o ens2 -d 10.8.8.0/24 -j ACCEPT

NAT + firewalling (on a single NIC)

Assuming you got the DROP policy in place, you can even do NAT on a single NIC using an IP alias

iptables -t nat -A POSTROUTING -o xenbr0 -s INTERNAL-CIDR -j MASQUERADE
iptables -A FORWARD -i xenbr0 -o xenbr0:0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i xenbr0:0 -o xenbr0 -j ACCEPT

and in case you want port forwarding (draft)

iptables -t nat -A PREROUTING -i xenbr0:0 -p tcp --dport PORT -j DNAT --to-destination INTERNAL-IP:PORT

Rules template

Dealing with all network interfaces at once here, otherwise add -i netif to the rules

mkdir -p ~/bin/
vi ~/bin/iptables.bash

https://pub.nethence.com/bin/network/iptables.sample.txt

chmod +x ~/bin/iptables.bash

Define policy

Flush all the chains on three tables

iptables -F
iptables -F -t nat
iptables -F -t mangle

to flush a specific chain e.g.

iptables -F INPUT

Delete any custom chain on three tables

iptables -X
iptables -X -t nat
iptables -X -t mangle

The equivalent for block in all

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

and happy troubleshooting

iptables -A INPUT -p icmp -j ACCEPT

Permanent rule set

Save thes rule set

iptables-save
#> /etc/iptables.rules

and check that it re-applies fine

iptables-restore < /etc/iptables.rules
iptables -nvL

also

service iptables restore

Ready to go

RHEL/CentOS7+

systemctl start iptables
systemctl start ip6tables
systemctl enable iptables
systemctl enable ip6tables

RHEL/CentOS6-

cd /etc/sysconfig/
cp -pi iptables-config iptables-config.`date +%s`
cp -pi system-config-securitylevel system-config-securitylevel.`date +%s`
#system-config-securitylevel-tui
chkconfig iptables on
chkconfig ip6tables on

Debian

vi /etc/network/if-pre-up.d/iptables

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.rules

chmod +x /etc/network/if-pre-up.d/iptables

DIY

vi /etc/rc.local

echo -n loading /etc/iptables.rules...
iptables-restore < /etc/iptables.rules && echo done

chmod +x /etc/rc.local

Acceptance

Reboot and check that you can ping and reach your services from a remote host and that the rest is truly filtered accordingly (return, not drop) using ping, nmap, nc, telnet, …

Fail-safe

To be safe while accessing a remote server and testing new rules, flush those every 5 minutes,

crontab -e

*/5 * * * * /usr/sbin/iptables -F

Trash

# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

If you really want to restrict ICMP to ping (bad idea),

#-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT

you can also add other restrictions to ICMP e.g.,

-A INPUT -p icmp -m state --state NEW,ESTABLISHED -m limit --limit 10/s -j ACCEPT

If you’re experiencing some issues accessing some services, maybe -m state --state NEW is in cause and try without it.

You can define some restrictions for tcp ports e.g.,

#-A INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -m limit --limit 1/s -j ACCEPT
#-A INPUT -p tcp -m tcp --dport 80 --tcp-flags SYN,RST,ACK SYN -m state --state NEW -j ACCEPT

Note. the short and simplest form would be,

#iptables -A INPUT -m state --state NEW -j ACCEPT
#iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Note. also worth interesting,

#... -j REJECT --reject-with tcp-reset

Additional restrictions

Allow your NIC to talk to a precise subnet only

iptables -A INPUT -i eth0 -s 10.1.1.0/24 -d 10.1.1.0/24 -j ACCEPT
iptables -A OUTPUT -o eth0 -s 10.1.1.0/24 -d 10.1.1.0/24 -j ACCEPT

Or allow the whole computer to talk to a precise subnet only

iptables -A INPUT -s 10.1.1.0/24 -d 10.1.1.0/24 -j ACCEPT
iptables -A OUTPUT -s 10.1.1.0/24 -d 10.1.1.0/24 -j ACCEPT

The VirtualBox situation

leftovers

iptables -t nat -A POSTROUTING -o xenbr0 -s 192.168.56.0/24 -j MASQUERADE
iptables -A FORWARD -i xenbr0 -o vboxnet0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i vboxnet0 -o xenbr0 -j ACCEPT

#iptables -A FORWARD -s 192.168.56.0/24 -j ACCEPT
#iptables -A FORWARD -s 192.168.56.0/24 -d 192.168.56.0/24 -j ACCEPT
iptables -A FORWARD -j LOG

#iptables -A INPUT -i vboxnet0 -s 192.168.56.0/24 -d 192.168.56.0/24 -j ACCEPT
#iptables -A OUTPUT -o vboxnet0 -s 192.168.56.0/24 -d 192.168.56.0/24 -j ACCEPT
iptables -A INPUT -i vboxnet0 -j ACCEPT
iptables -A OUTPUT -o vboxnet0 -j ACCEPT

Resources

Chapter 11. iptables firewall http://linux-training.be/security/ch11.html

Laptop Iptables configuration http://www.pantz.org/software/iptables/laptopiptables.html

DMZ IP Firewall script for Linux 2.4.x and iptables - http://iptables-tutorial.frozentux.net/scripts/rc.DMZ.firewall.txt

Chapter 1: Care and Feeding of iptables http://www.cipherdyne.org/LinuxFirewalls/ch01/

iptables & netfilter - How to get started http://security.maruhn.com/

Netfilter et IP Tables… http://christian.caleca.free.fr/netfilter.html

reject vs drop

REJECT https://unix.stackexchange.com/questions/191607/iptables-and-return-target

DROP http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject

port ranges

What is the correct way to open a range of ports in iptables https://serverfault.com/questions/594835/what-is-the-correct-way-to-open-a-range-of-ports-in-iptables

Linux: Iptables Forward Multiple Ports https://www.cyberciti.biz/faq/linux-iptables-multiport-range/

debian

https://wiki.debian.org/iptables

https://wiki.debian.org/DebianFirewall

nat

New iptables Gotchas - SNAT VS MASQUERADE https://terrywang.net/2016/02/02/new-iptables-gotchas.html

Difference between SNAT and Masquerade https://unix.stackexchange.com/questions/21967/difference-between-snat-and-masquerade


HOME | GUIDES | BENCHMARKS | html