To avoid vendor lock ins I prefer to use iptables to manage my firewalls in the cloud, but as most of you know iptables isn't exactly user friendly, it's easy to fail and lock yourself out. So here's a script I throw together to make things a bit easier:
#!/bin/bash
if [ -z "$1" ]; then
echo "use syntax: ./firewall.bash (up|down)"
exit 1
fi
case $1 in
"up")
# Allow incoming EXTERNAL connections on these ports
input_tcp="80,443"
input_udp=""
# Allow outgoing EXTERNAL connections on these ports
output_tcp="0:65535"
output_udp="0:65535"
# Allow incoming LAN connections on these ports
input_lan_tcp="0:65535"
input_lan_udp="0:65535"
# Allow outgoing LAN connections on these ports
output_lan_tcp=""
output_lan_udp=""
# List of IP addresses considered to be LAN servers
lan_ips=""
# Flush old rules
sudo iptables -F
# Respond to ICMP ping
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
# Allow external TCP
sudo iptables -A INPUT -p tcp --match multiport --dport $input_tcp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --match multiport --sport $output_tcp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
# Allow external UDP
if [ ! -z "$input_udp" ]; then
sudo iptables -A INPUT -p udp --match multiport --dport $input_udp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
fi
sudo iptables -A OUTPUT -p udp --match multiport --sport $output_udp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
# Allow lan TCP
if [ ! -z "$input_lan_tcp" ]; then
sudo iptables -A INPUT -p tcp --match multiport --src $lan_ips --dport $input_lan_tcp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
fi
if [ ! -z "$output_lan_tcp" ]; then
sudo iptables -A OUTPUT -p tcp --match multiport --dst $lan_ips --sport $output_lan_tcp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
fi
# Allow lan UDP
if [ ! -z "$input_lan_udp" ]; then
sudo iptables -A INPUT -p udp --match multiport --src $lan_ips --dport $input_lan_udp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
fi
if [ ! -z "$output_lan_udp" ]; then
sudo iptables -A OUTPUT -p udp --match multiport --dst $lan_ips --sport $output_lan_udp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
fi
# Set default policy to drop for incoming only
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
# Always allow localhost connections
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow any established or related connection
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
;;
"down")
# Set default policy to accept
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
# Flush all the rules
sudo iptables -F
;;
esac
Now, all you gotta do is to add your own ip to lan_ips
as well as any other server ip from which you want to allow connectivity on all ports, like a LAN but with public ips so more of a WAN (Wide Area Network) that isn't the internet.
Additionally you can specify ports in and out using variables like input_*
and output_*
, basic definitions for a web server is already setup.
Then save your script to a file, i.e firewall.bash
and call ./firewall.bash up/down
to enable/disable it. Optionally you can add it to crontab too, but I wouldn't recomend that as reboting your server might be your only way back in, in case you lock yourself out from SSH.