Difference between revisions of "Firewall VPN"

 
(2 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`
  
INT_ETH=eth0
+
# usage:  vpn <vpn interface> <vpn port> <vpn protocol> <local interface> <remote LAN IPv4 [optional]> <remote LAN IPv6 [optional]>
IP_LAN_ETH=`/sbin/ifconfig $INT_ETH | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
+
#    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
  
INT_VPN=tun0
+
    echo "Setting up VPN rules"  
VPN_PORT="8080"
 
VPN_PROTOCOL="udp"
 
IP_LAN_VPN="172.16.60.0/24"
 
  
echo " "
+
    #####
echo "------------------------"
+
    # Allow VPN connections through $INT_VPN
echo " VPN configuration"
+
    # Hint: if you do not accept all RELATED,ESTABLISHED connections then you must allow the source port
echo "------------------------"
+
    #####
echo "    # VPN interface  : $INT_VPN"
+
    echo "Init VPN"
echo "    # VPN port       : $VPN_PORT"
+
    $IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT
echo "   # VPN protocol  : $VPN_PROTOCOL"
+
    $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
echo "    -------------------------------------- "
+
    $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
  
echo "      ... Allow VPN connections through $INT_VPN"
+
    $IP6TABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN incoming" -j ACCEPT
$IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -j ACCEPT
+
    $IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
$IPTABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -j ACCEPT
+
    $IP6TABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -m comment --comment "VPN outgoing" -j ACCEPT
# Hint: if you do not accept all RELATED,ESTABLISHED connections then you must allow the source port
 
$IPTABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -j ACCEPT
 
 
echo "     ... Allow VPN packets type INPUT,OUTPUT,FORWARD"
 
$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
 
  
# Allow forwarding
+
    # Allow VPN packets type INPUT,OUTPUT,FORWARD
echo "     ... Allow packets to by forward from|to the VPN"
+
    $IPTABLES -A INPUT -i $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IPTABLES -A FORWARD -i $INT_VPN -o $INT_ETH -j ACCEPT
+
    $IPTABLES -A OUTPUT -o $INT_VPN -m state ! --state INVALID -m comment --comment "Invalid VPN packet" -j ACCEPT
$IPTABLES -A FORWARD -i $INT_ETH -o $INT_VPN -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
  
echo "    -------------------------------------- "
 
echo "      Open VPN LAN(s)"
 
echo "    -------------------------------------- "
 
echo "      # VPN network IP @  : $IP_LAN_VPN"
 
  
# Allow packets to be send from|to the VPN network
+
    ######
$IPTABLES -A FORWARD -s $IP_LAN_VPN -j ACCEPT
+
    # Allow forwarding
$IPTABLES -t nat -A POSTROUTING -s $IP_LAN_VPN -o $INT_ETH -j MASQUERADE
+
    ######
 +
    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
  
# Allow VPN client <-> client communication
+
    $IP6TABLES -A FORWARD -i $INT_VPN -o $INT_LOCAL -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
$IPTABLES -A INPUT -s $IP_LAN_VPN -d $IP_LAN_VPN -m state ! --state INVALID -j ACCEPT
+
    $IP6TABLES -A FORWARD -i $INT_LOCAL -o $INT_VPN -m comment --comment "Forwarding $INT_LOCAL <> VPN" -j ACCEPT
$IPTABLES -A OUTPUT -s $IP_LAN_VPN -d $IP_LAN_VPN -m state ! --state INVALID -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
  
####### 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!
+
    # Allow local LAN / remote LAN communication through VPN
# 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>
+
    if [[ ! -z "$VPN_LAN_IPv4" ]]
#
+
    then
# !! This information should be pushed by the server !!  
+
    echo "VPN LAN IPv4: $VPN_LAN_IPv4"
# If not you can either add it manually over here (= in Iptables) or in the OpenVPN client conf.
+
        # Allow packets to be send to VPN
#######
+
        $IPTABLES -A OUTPUT -d $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT
#echo "     ... add VPN route between VPN LAN and current location"
+
        $IPTABLES -A FORWARD -s $VPN_LAN_IPv4 -m comment --comment "VPN LAN: $VPN_LAN_IPv4" -j ACCEPT
#route add -net 192.168.12.0/24 gw 192.168.1.45
 
  
</syntaxhighlight>
+
        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
  
  
=Many VPN networks=
+
    ####### 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
  
If you plan to use many VPN networks then you can use something like that:
+
}
 +
</syntaxhighlight>
  
  
<syntaxhighlight lang="bash">
 
IPTABLES=`which iptables`
 
  
INT_ETH=eth0
+
==Sysctl==
IP_LAN_ETH=`/sbin/ifconfig $INT_ETH | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
 
  
INT_VPN=tun0
+
You must enable FORWARDING somewhere else:
VPN_PORT="8080"
 
VPN_PROTOCOL="udp"
 
IP_LAN_VPN_PRV="172.16.60.0/24"
 
IP_LAN_VPN_PRO="192.168.12.0/24"
 
  
if [[ ! -z "$IP_LAN_VPN_PRV" || ! -z "$IP_LAN_VPN_PRO" ]]
+
<syntaxhighlight lang="bash">
then
+
vim /etc/sysctl.conf
 
+
</syntaxhighlight>
  echo " "
 
  echo "------------------------"
 
  echo " VPN configuration"
 
  echo "------------------------"
 
  echo "    # VPN interface  : $INT_VPN"
 
  echo "    # VPN port      : $VPN_PORT"
 
  echo "    # VPN protocol  : $VPN_PROTOCOL"
 
  echo "    -------------------------------------- "
 
 
 
  echo "      ... Allow VPN connections through $INT_VPN"
 
  $IPTABLES -A INPUT -p $VPN_PROTOCOL --dport $VPN_PORT -j ACCEPT
 
  $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --dport $VPN_PORT -j ACCEPT
 
  # Hint: if you do not accept all RELATED,ESTABLISHED connections then you must allow the source port
 
  $IPTABLES -A OUTPUT -p $VPN_PROTOCOL --sport $VPN_PORT -j ACCEPT
 
 
  echo "    ... Allow VPN packets type INPUT,OUTPUT,FORWARD"
 
  $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
 
 
 
  # Allow forwarding
 
  echo "      ... Allow packets to by forward from|to the VPN"
 
  $IPTABLES -A FORWARD -i $INT_VPN -o $INT_ETH -j ACCEPT
 
  $IPTABLES -A FORWARD -i $INT_ETH -o $INT_VPN -j ACCEPT
 
 
 
 
 
  echo "    -------------------------------------- "
 
  echo "      Open VPN LAN(s)"
 
  echo "    -------------------------------------- "
 
 
 
  if [ ! -z "$IP_LAN_VPN_PRV" ]
 
  then
 
      echo "      # VPN network IP @  : $IP_LAN_VPN_PRV"
 
 
 
      # Allow packets to be send from|to the VPN network
 
      $IPTABLES -A FORWARD -s $IP_LAN_VPN_PRV -j ACCEPT
 
      $IPTABLES -t nat -A POSTROUTING -s $IP_LAN_VPN_PRV -o $INT_ETH -j MASQUERADE
 
 
 
      # Allow VPN client <-> client communication
 
      $IPTABLES -A INPUT -s $IP_LAN_VPN_PRV -d $IP_LAN_VPN_PRV -m state ! --state INVALID -j ACCEPT
 
      $IPTABLES -A OUTPUT -s $IP_LAN_VPN_PRV -d $IP_LAN_VPN_PRV -m state ! --state INVALID -j ACCEPT
 
  fi
 
  
  if [ ! -z "$IP_LAN_VPN_PRO" ]
 
  then
 
      echo "      # VPN network IP @  : $IP_LAN_VPN_PRO"
 
      # Allow packets to be send from|to the VPN network
 
      $IPTABLES -A FORWARD -s $IP_LAN_VPN_PRO -j ACCEPT
 
      $IPTABLES -t nat -A POSTROUTING -s $IP_LAN_VPN_PRO -o $INT_ETH -j MASQUERADE
 
  
      # Allow VPN client <-> client communication
 
      $IPTABLES -A INPUT -s $IP_LAN_VPN_PRO -d $IP_LAN_VPN_PRO -m state ! --state INVALID -j ACCEPT
 
      $IPTABLES -A OUTPUT -s $IP_LAN_VPN_PRO -d $IP_LAN_VPN_PRO -m state ! --state INVALID -j ACCEPT
 
  fi
 
  
  ####### Add route(s) to remote network(s)
+
<syntaxhighlight lang="apache">
  # You must add a new route for each network you'd like to access through the VPN server!
+
# Uncomment the next line to enable packet forwarding for IPv4
  # The VPN server must be able to reach the remote network! (otherwise it cannot acts as a GW !)
+
net.ipv4.ip_forward=1
  # 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
 
  
fi
 
  
 +
# 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