#!/bin/bash ########################### ## debugging ########################### #set -x ########################### ## error_handler ########################### error_handler() { echo "##################################################" echo "VPN firewall script failed!" echo "##################################################" exit 1 } trap "error_handler" ERR INT TERM ########################### ## configuration ########################### ## IP address of the VPN server. ## Get the IP using: nslookup vpn-example-server.org ## Example: seattle.vpn.riseup.net ## Some providers provide multiple VPN servers. ## You can enter multiple IP addresses, separated by spaces VPN_SERVERS="198.252.153.26" ## For OpenVPN. VPN_INTERFACE=tun0 ## Destinations you don not want routed through the VPN. LOCAL_NET="192.168.1.0/24 192.168.0.0/24 127.0.0.0/8" ###################################################################### ## DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! # ## DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! # ## DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! # ## DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! # ## DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING! # ###################################################################### ########################### ## root check ########################### if [ "$(id -u)" != "0" ]; then echo "FATAL ERROR: This script must be run as root (sudo)!" exit 1 fi ########################### ## comments ########################### ## --reject-with ## http://ubuntuforums.org/showthread.php?p=12011099 ## Set to icmp-admin-prohibited because icmp-port-unreachable caused ## confusion. icmp-port-unreachable looks like a bug while ## icmp-admin-prohibited hopefully makes clear it is by design. ########################### ## /usr/local/bin/vpnfirewall ########################### echo "OK: Loading VPN firewall..." ########################### ## IPv4 DEFAULTS ########################### ## Set secure defaults. iptables -P INPUT DROP ## FORWARD rules does not actually do anything if forwarding is disabled. Better be safe just in case. iptables -P FORWARD DROP ## Only the VPN process is allowed to establish outgoing connections. iptables -P OUTPUT DROP ########################### ## IPv4 PREPARATIONS ########################### ## Flush old rules. iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X ############################ ## IPv4 DROP INVALID PACKAGES ############################ ## DROP INVALID iptables -A INPUT -m state --state INVALID -j DROP ## DROP INVALID SYN PACKETS iptables -A INPUT -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP ## DROP PACKETS WITH INCOMING FRAGMENTS. THIS ATTACK ONCE RESULTED IN KERNEL PANICS iptables -A INPUT -f -j DROP ## DROP INCOMING MALFORMED XMAS PACKETS iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP ## DROP INCOMING MALFORMED NULL PACKETS iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP ########################### ## IPv4 INPUT ########################### ## Traffic on the loopback interface is accepted. iptables -A INPUT -i lo -j ACCEPT ## Established incoming connections are accepted. iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ## Allow all incoming connections on the virtual VPN network interface. iptables -A INPUT -i "$VPN_INTERFACE" -j ACCEPT ## Log. iptables -A INPUT -j LOG --log-prefix "VPN firewall blocked input4: " ## Reject anything not explicitly allowed above. ## Drop is better than reject here, because ... iptables -A INPUT -j DROP ########################### ## IPv4 FORWARD ########################### ## Log. iptables -A FORWARD -j LOG --log-prefix "VPN firewall blocked forward4: " ## Reject everything. iptables -A FORWARD -j REJECT --reject-with icmp-admin-prohibited ########################### ## IPv4 OUTPUT ########################### ## XXX iptables -A OUTPUT -o "$VPN_INTERFACE" -j ACCEPT ## XXX for SERVER in $VPN_SERVERS; do iptables -A OUTPUT -d "$SERVER" -j ACCEPT done ## Existing connections are accepted. iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ## Accept outgoing connections to local network. for NET in $LOCAL_NET; do iptables -A OUTPUT -d "$NET" -j ACCEPT done ## Log. iptables -A OUTPUT -j LOG --log-prefix "VPN firewall blocked output4: " ## Reject all other outgoing traffic. iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited ########################### ## IPv6 ########################### ## Policy DROP for all traffic as fallback. ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP ## Flush old rules. ip6tables -F ip6tables -X ip6tables -t mangle -F ip6tables -t mangle -X ## Allow unlimited access on loopback. ## Not activated, since we do not need it. #ip6tables -A INPUT -i lo -j ACCEPT #ip6tables -A OUTPUT -o lo -j ACCEPT ## Log. #ip6tables -A INPUT -j LOG --log-prefix "VPN firewall blocked input6: " #ip6tables -A OUTPUT -j LOG --log-prefix "VPN firewall blocked output6: " #ip6tables -A FORWARD -j LOG --log-prefix "VPN firewall blocked forward6: " ## Drop/reject all other traffic. ip6tables -A INPUT -j DROP ## --reject-with icmp-admin-prohibited not supported by ip6tables ip6tables -A OUTPUT -j REJECT ## --reject-with icmp-admin-prohibited not supported by ip6tables ip6tables -A FORWARD -j REJECT ########################### ## End ########################### echo "OK: The firewall should not show any messages," echo "OK: besides output beginning with prefix OK:..." echo "OK: VPN firewall loaded." exit 0