Difference between revisions of "Firewall VPN"
(6 intermediate revisions by the same user not shown) | |||
Line 14: | Line 14: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
IPTABLES=`which iptables` | IPTABLES=`which iptables` | ||
+ | IP6TABLES=`which ip6tables` | ||
− | + | # usage: vpn <vpn interface> <vpn port> <vpn protocol> <local interface> <remote LAN IPv4 [optional]> <remote LAN IPv6 [optional]> | |
− | + | # ex vpn tun0 8080 udp eth0 | |
+ | # ex vpn tun0 8080 udp eth0 "192.168.15.0/24" | ||
+ | # ex vpn tun0 8080 udp eth0 "192.168.15.0/24" "2001:41d0:8:9318::/64" | ||
+ | function vpn { | ||
+ | INT_VPN=$1 | ||
+ | VPN_PORT=$2 | ||
+ | VPN_PROTOCOL=$3 | ||
+ | INT_LOCAL=$4 | ||
+ | VPN_LAN_IPv4=$5 | ||
+ | VPN_LAN_IPv6=$6 | ||
− | + | echo "Setting up VPN rules" | |
− | |||
− | |||
− | |||
− | echo | + | ##### |
− | + | # Allow VPN connections through $INT_VPN | |
− | + | # Hint: if you do not accept all RELATED,ESTABLISHED connections then you must allow the source port | |
− | + | ##### | |
+ | echo "Init VPN" | ||
+ | $IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT | ||
+ | $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT | ||
+ | $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT | ||
− | + | $IP6TABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT | |
− | + | $IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT | |
− | + | $IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT | |
− | |||
− | |||
− | |||
− | # | + | # Allow VPN packets type INPUT,OUTPUT,FORWARD |
− | + | $IPTABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT | |
− | + | $IPTABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT | |
− | + | $IPTABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT | |
− | |||
− | |||
− | $IPTABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -j ACCEPT | ||
− | $IPTABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -j ACCEPT | ||
− | $IPTABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -j ACCEPT | ||
− | + | $IP6TABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT | |
− | + | $IP6TABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT | |
− | $ | + | $IP6TABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT |
− | $ | ||
− | $ | ||
− | |||
− | |||
− | # Allow | + | ###### |
− | echo | + | # Allow forwarding |
− | $IPTABLES -A | + | ###### |
− | $IPTABLES -A | + | echo "Enable forwarding form $INT_VPN /to/ $INT_LOCAL" |
+ | $IPTABLES -A FORWARD -i $INT_VPN -o $INT_LOCAL -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT | ||
+ | $IPTABLES -A FORWARD -i $INT_LOCAL -o $INT_VPN -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT | ||
− | + | $IP6TABLES -A FORWARD -i $INT_VPN -o $INT_LOCAL -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT | |
− | + | $IP6TABLES -A FORWARD -i $INT_LOCAL -o $INT_VPN -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | # Allow packet to go/from the VPN network to the LAN | ||
+ | $IPTABLES -t nat -A POSTROUTING -o $INT_LOCAL -m comment --comment "Forward between interfaces" -j MASQUERADE | ||
+ | $IP6TABLES -t nat -A POSTROUTING -o $INT_LOCAL -m comment --comment "Forward between interfaces" -j MASQUERADE | ||
+ | |||
+ | ###### | ||
+ | # Allow local LAN / remote LAN communication through VPN | ||
+ | ###### | ||
+ | if [[ ! -z "$VPN_LAN_IPv4" ]] | ||
+ | then | ||
+ | echo "VPN LAN IPv4: $VPN_LAN_IPv4" | ||
+ | # Allow packets to be send to VPN | ||
+ | $IPTABLES -A OUTPUT -d $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT | ||
+ | $IPTABLES -A FORWARD -s $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT | ||
+ | |||
+ | log_progress_msg "Allow VPN client to client communication" | ||
+ | # Allow VPN client <-> client communication | ||
+ | $IPTABLES -A INPUT -s $VPN_LAN_IPv4 -d $VPN_LAN_IPv4 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT | ||
+ | $IPTABLES -A OUTPUT -s $VPN_LAN_IPv4 -d $VPN_LAN_IPv4 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT | ||
+ | fi | ||
+ | if [[ ! -z "$VPN_LAN_IPv6" ]] | ||
+ | then | ||
+ | echo "VPN LAN IPv6: $VPN_LAN_IPv6" | ||
+ | # Allow packets to be send to VPN | ||
+ | $IP6TABLES -A OUTPUT -d $VPN_LAN_IPv6 -m comment --comment "VPN LAN: $VPN_LAN_IPv6" -j ACCEPT | ||
+ | $IP6TABLES -A FORWARD -s $VPN_LAN_IPv6 -m comment --comment "VPN LAN: $VPN_LAN_IPv6" -j ACCEPT | ||
+ | |||
+ | log_progress_msg "Allow VPN client to client communication" | ||
+ | # Allow VPN client <-> client communication | ||
+ | $IP6TABLES -A INPUT -s $VPN_LAN_IPv6 -d $VPN_LAN_IPv6 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT | ||
+ | $IP6TABLES -A OUTPUT -s $VPN_LAN_IPv6 -d $VPN_LAN_IPv6 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT | ||
+ | fi | ||
+ | |||
+ | |||
+ | ####### Add route(s) to remote network(s) | ||
+ | # You must add a new route for each network you'd like to access through the VPN server! | ||
+ | # The VPN server must be able to reach the remote network! (otherwise it cannot acts as a GW !) | ||
+ | # route add -net <network>/<mask> gw <VPN_SERVER_ETH_IP> | ||
+ | # | ||
+ | # !! This information should be pushed by the server !! | ||
+ | # If not you can either add it manually over here (= in Iptables) or in the OpenVPN client conf. | ||
+ | ####### | ||
+ | #echo " ... add VPN route between VPN LAN and current location" | ||
+ | #route add -net 192.168.12.0/24 gw 192.168.1.45 | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | ==Sysctl== | ||
+ | |||
+ | You must enable FORWARDING somewhere else: | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | vim /etc/sysctl.conf | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | |||
+ | <syntaxhighlight lang="apache"> | ||
+ | # Uncomment the next line to enable packet forwarding for IPv4 | ||
+ | net.ipv4.ip_forward=1 | ||
+ | |||
+ | |||
+ | # Uncomment the next line to enable packet forwarding for IPv6 | ||
+ | # Enabling this option disables Stateless Address Autoconfiguration | ||
+ | # based on Router Advertisements for this host | ||
+ | net.ipv6.conf.all.forwarding=1 | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 21:36, 10 September 2015
What is a VPN?
See What is a VPN?
VPN firewall
Adjust the following to your own port, network ID and protocol:
IPTABLES=`which iptables`
IP6TABLES=`which ip6tables`
# usage: vpn <vpn interface> <vpn port> <vpn protocol> <local interface> <remote LAN IPv4 [optional]> <remote LAN IPv6 [optional]>
# ex vpn tun0 8080 udp eth0
# ex vpn tun0 8080 udp eth0 "192.168.15.0/24"
# ex vpn tun0 8080 udp eth0 "192.168.15.0/24" "2001:41d0:8:9318::/64"
function vpn {
INT_VPN=$1
VPN_PORT=$2
VPN_PROTOCOL=$3
INT_LOCAL=$4
VPN_LAN_IPv4=$5
VPN_LAN_IPv6=$6
echo "Setting up VPN rules"
#####
# Allow VPN connections through $INT_VPN
# Hint: if you do not accept all RELATED,ESTABLISHED connections then you must allow the source port
#####
echo "Init VPN"
$IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT
$IPTABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
$IPTABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
$IP6TABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT
$IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
$IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
# Allow VPN packets type INPUT,OUTPUT,FORWARD
$IPTABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IPTABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IPTABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IP6TABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IP6TABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IP6TABLES -A FORWARD -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
######
# Allow forwarding
######
echo "Enable forwarding form $INT_VPN /to/ $INT_LOCAL"
$IPTABLES -A FORWARD -i $INT_VPN -o $INT_LOCAL -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
$IPTABLES -A FORWARD -i $INT_LOCAL -o $INT_VPN -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
$IP6TABLES -A FORWARD -i $INT_VPN -o $INT_LOCAL -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
$IP6TABLES -A FORWARD -i $INT_LOCAL -o $INT_VPN -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
# Allow packet to go/from the VPN network to the LAN
$IPTABLES -t nat -A POSTROUTING -o $INT_LOCAL -m comment --comment "Forward between interfaces" -j MASQUERADE
$IP6TABLES -t nat -A POSTROUTING -o $INT_LOCAL -m comment --comment "Forward between interfaces" -j MASQUERADE
######
# Allow local LAN / remote LAN communication through VPN
######
if [[ ! -z "$VPN_LAN_IPv4" ]]
then
echo "VPN LAN IPv4: $VPN_LAN_IPv4"
# Allow packets to be send to VPN
$IPTABLES -A OUTPUT -d $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT
$IPTABLES -A FORWARD -s $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT
log_progress_msg "Allow VPN client to client communication"
# Allow VPN client <-> client communication
$IPTABLES -A INPUT -s $VPN_LAN_IPv4 -d $VPN_LAN_IPv4 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT
$IPTABLES -A OUTPUT -s $VPN_LAN_IPv4 -d $VPN_LAN_IPv4 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT
fi
if [[ ! -z "$VPN_LAN_IPv6" ]]
then
echo "VPN LAN IPv6: $VPN_LAN_IPv6"
# Allow packets to be send to VPN
$IP6TABLES -A OUTPUT -d $VPN_LAN_IPv6 -m comment --comment "VPN LAN: $VPN_LAN_IPv6" -j ACCEPT
$IP6TABLES -A FORWARD -s $VPN_LAN_IPv6 -m comment --comment "VPN LAN: $VPN_LAN_IPv6" -j ACCEPT
log_progress_msg "Allow VPN client to client communication"
# Allow VPN client <-> client communication
$IP6TABLES -A INPUT -s $VPN_LAN_IPv6 -d $VPN_LAN_IPv6 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT
$IP6TABLES -A OUTPUT -s $VPN_LAN_IPv6 -d $VPN_LAN_IPv6 -m state ! --state INVALID -m comment --comment "VPN client-to-client" -j ACCEPT
fi
####### Add route(s) to remote network(s)
# You must add a new route for each network you'd like to access through the VPN server!
# The VPN server must be able to reach the remote network! (otherwise it cannot acts as a GW !)
# route add -net <network>/<mask> gw <VPN_SERVER_ETH_IP>
#
# !! This information should be pushed by the server !!
# If not you can either add it manually over here (= in Iptables) or in the OpenVPN client conf.
#######
#echo " ... add VPN route between VPN LAN and current location"
#route add -net 192.168.12.0/24 gw 192.168.1.45
}
Sysctl
You must enable FORWARDING somewhere else:
vim /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
net.ipv6.conf.all.forwarding=1