Task Write a iptables script that blocks everything except ping (icmp) and ssh (port 22), http (80) and https (443). Solution
#!/bin/bash
export ipt=/sbin/iptables
$ipt -F #Flush all the rules one by one
#Allow SSH
$ipt -A INPUT -p tcp --dport 22 -j ACCEPT
#Allow HTTP
$ipt -A INPUT -p tcp --dport 80 -j ACCEPT
#Allow HTTPS
$ipt -A INPUT -p tcp --dport 443 -j ACCEPT
# Set default policies for INPUT, FORWARD and OUTPUT chains
$ipt -P INPUT DROP
$ipt -P FORWARD DROP
$ipt -P OUTPUT ACCEPT
# Set access for localhost
$ipt -A INPUT -i lo -j ACCEPT
# Accept packets belonging to established and related connections
$ipt -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Allow pings
#Ping requires the ability to accept packets and send packet back out.
#Ping is a layer 3,ICMP operation.
#In order to allow it our protocol now becomes icmp instead of tcp.
#Ping packets are able to be received.
$ipt -I INPUT -p icmp -j ACCEPT
#Ping packets are able to be sent
$ipt -I OUTPUT -p icmp -j ACCEPT
#Drop everything else incoming
$ipt -A INPUT -j DROP
# List rules
$ipt -L -v
-m
says load a module state which allows access to the connection tracking state of the packets
--state
precedes a comma separated list of the connection states to match. In this case it’s NEW.
NEW
the packet has started a new connection or a connection that has not seen packets going in both directions
-m tcp
load the tcp module (just like we loaded the state module) this module allows us extra functionality with tcp
-p tcp
specifies protocol, in my case TCP
--dport 22
feature provided by the -m tcp module, in this case I want the rule to be applicable to port 22 (ssh).
-j ACCEPT
means the results of this chain is to accept the packets. (-j
specifies the target of the rule if the
packet matches the rule. If I said -j DROP
we would block all traffic to port 22).