version 1.2, 1999/02/24 23:33:11 |
version 1.3, 1999/08/28 12:10:37 |
|
|
#!/bin/sh |
#!/bin/sh |
|
|
# |
# |
# rc.vpn -- configure IPSec in tunnel mode for M x N networks |
# $OpenBSD$ |
# |
# |
# Richard Reiner, Ph.D., FSC Internet Corp. |
# Richard Reiner, Ph.D., FSC Internet Corp. |
# rreiner@fscinternet.com |
# rreiner@fscinternet.com |
# v0.81 / 26Jul98 |
# v0.81 / 26Jul98 |
# |
# |
|
# Modifications and cleanup by H. Olsson <ho@openbsd.org>, 28Aug99 |
echo ' VPN' |
|
|
|
|
|
############################################################################# |
|
# |
# |
# Configurable parameters |
# rc.vpn -- configure IPSec in tunnel mode for a mesh of N local and |
|
# M remote networks. (N x M mesh) |
# |
# |
|
# For this to work, you will need to have these enabled (in /etc/sysct.conf): |
|
# 'sysctl -w net.inet.ip.forwarding=1' (IP packet routing) |
|
# 'sysctl -w net.inet.esp.enable=1' (IPsec ESP protocol) |
|
|
# Should all the commands executed be printed when the script runs? |
# XXX The configuration parameters should be moved to another file. |
# N.B. setting this to "YES" may reveal your keys to persons present |
|
# at the console when your system boots. |
|
VPN_DO_ECHO_COMMANDS="YES" |
|
|
|
# My interfaces |
# Uncomment to debug (and not execute) commands |
VPN_MY_INT_IFACE="ep0" |
#DEBUG=echo |
VPN_MY_EXT_IFACE="ep1" |
|
|
|
# External IP of my tunnel partner |
# Gateway adresses |
VPN_PEER_EXT_IP="207.253.158.194" |
GW_LOCAL=192.168.254.254 |
|
GW_PEER=192.168.1.2 |
|
|
# The internal IP(s) and mask(s) on the other end of the tunnel -- add as |
# Local and remote networks, numbered, syntax <network>:<mask> |
# many sets as necessary, numbered from 0 upwards. |
LOCAL_NET_0=192.168.254.0:0xffffff00 |
VPN_PEER_INT_IP_0="192.139.247.253" |
LOCAL_NET_1=192.168.253.0:0xffffff00 |
VPN_PEER_INT_MASK_0="255.255.255.0" |
REMOTE_NET_0=192.168.1.0:0xffffff00 |
|
REMOTE_NET_1=192.168.2.0:0xffffff00 |
|
|
# IP(s) and mask(s) for *additional* subnets on *our* end of the tunnel |
# Crypto options and keys, note that key/iv lengths need to correspond |
# (the first one is automagically determined below) -- add as many sets |
# to the selected encryption and authentication algorithms. |
# as necessary, numbered from *1* upwards, or comment out if not needed. |
ENC=des |
VPN_MY_INT_IP_1="192.139.241.1" |
AUTH=sha1 |
VPN_MY_INT_MASK_1="255.255.255.0" |
SPI_OUT=1000 |
VPN_MY_INT_IP_2="192.139.243.1" |
SPI_IN=1001 |
VPN_MY_INT_MASK_2="255.255.255.0" |
KEY=2ea140ac3911cb27 |
|
AUTHKEY=176cc284bc1631afbd1468fbe976fa729fcb4321 |
|
IV=c4b279f1a9bcd849 |
|
|
# Crypto options and keys |
|
VPN_ENC="des" |
|
VPN_AUTH="sha1" |
|
VPN_SPI_OUT="1000" |
|
VPN_SPI_IN="1001" |
|
VPN_KEY="2ea140ac3911cb27" |
|
VPN_AUTHKEY="176cc284bc1631afbd1468fbe976fa729fcb4321" |
|
VPN_IV="c4b279f1a9bcd849" |
|
|
|
|
|
|
|
############################################################################# |
############################################################################# |
############# ############# |
|
############# -- NO CHANGES SHOULD BE NEEDED BELOW THIS LINE -- ############# |
############# -- NO CHANGES SHOULD BE NEEDED BELOW THIS LINE -- ############# |
############# ############# |
|
############################################################################# |
############################################################################# |
|
|
|
ipsecadm=/sbin/ipsecadm |
|
|
|
|
############################################################################# |
|
# |
# |
# Derived (automagically found) parameters |
# Sanity, be verbose about errors. |
|
# XXX In a 1 x M mesh, ip.forwarding may not be strictly necessary. |
# |
# |
# Hostnames for ech of our interfaces |
|
VPN_MY_EXT_NAME=`cut -d" " -f2 < /etc/hostname.$VPN_MY_EXT_IFACE` |
|
VPN_MY_INT_NAME=`cut -d" " -f2 < /etc/hostname.$VPN_MY_INT_IFACE` |
|
|
|
# Our internal IP and mask (extra subnets, if any, are configured above) |
abort=0 |
VPN_MY_INT_IP_0=`grep $VPN_MY_INT_NAME < /etc/hosts | cut -d" " -f1` |
if [ `/usr/sbin/sysctl -n net.inet.esp.enable` == 0 ]; then |
VPN_MY_INT_MASK_0=`cut -d" " -f3 < /etc/hostname.$VPN_MY_INT_IFACE` |
echo " VPN: variable 'net.inet.esp.enable' (IPsec ESP protocol)" |
|
abort=1 |
|
fi |
|
if [ `/usr/sbin/sysctl -n net.inet.ip.forwarding` == 0 ]; then |
|
echo " VPN: variable 'net.inet.ip.forwarding' (IP forwarding/routing)" |
|
abort=1 |
|
fi |
|
if [ ${abort} = 1 ]; then |
|
echo " VPN: must be enabled in /etc/sysctl.conf. Aborting VPN setup." |
|
exit 0 |
|
fi |
|
|
# Our external IP and mask |
[ ! -n "${DEBUG}" ] && echo " VPN " |
VPN_MY_EXT_IP=`grep $VPN_MY_EXT_NAME < /etc/hosts | cut -d" " -f1` |
|
VPN_MY_EXT_MASK=`cut -d" " -f3 < /etc/hostname.$VPN_MY_INT_IFACE` |
|
|
|
|
|
############################################################################# |
|
# |
# |
# Pseudo-constants |
# Setup the SAs |
# |
# |
ipsecadm=/sbin/ipsecadm |
|
|
|
|
$DEBUG $ipsecadm new esp -src $GW_LOCAL -dst $GW_PEER \ |
|
-forcetunnel -spi $SPI_OUT -enc $ENC -auth $AUTH \ |
|
-key $KEY -authkey $AUTHKEY |
|
|
############################################################################# |
$DEBUG $ipsecadm new esp -src $GW_PEER -dst $GW_LOCAL \ |
# |
-forcetunnel -spi $SPI_IN -enc $ENC -auth $AUTH \ |
# Function definitions |
-key $KEY -authkey $AUTHKEY |
# |
|
eval_and_echo () { |
|
if [ "$VPN_DO_ECHO_COMMANDS" = "YES" ]; then |
|
echo "$*" |
|
fi |
|
eval "$*" |
|
} |
|
|
|
|
|
############################################################################# |
|
# |
# |
# Executable setup statements |
# Create the flows |
# |
# |
|
|
# Create the SAs |
# Gateway to gateway |
eval_and_echo "$ipsecadm new esp -src $VPN_MY_EXT_IP -dst $VPN_PEER_EXT_IP -forcetunnel -spi $VPN_SPI_OUT -enc $VPN_ENC -auth $VPN_AUTH -key $VPN_KEY -authkey $VPN_AUTHKEY" |
$DEBUG ipsecadm flow -proto esp -dst $GW_PEER -spi $SPI_OUT \ |
|
-addr 0.0.0.0 0xffffffff $GW_PEER 0xffffffff |
|
|
eval_and_echo "$ipsecadm new esp -src $VPN_PEER_EXT_IP -dst $VPN_MY_EXT_IP -forcetunnel -spi $VPN_SPI_IN -enc $VPN_ENC -auth $VPN_AUTH -key $VPN_KEY -authkey $VPN_AUTHKEY" |
# Flows from each local, to each remote, subnet |
|
|
|
|
# |
|
# Create IPSec routes |
|
# |
|
|
|
# Route between the two external IPs |
|
eval_and_echo "ipsecadm flow -proto esp -dst $VPN_PEER_EXT_IP -spi $VPN_SPI_OUT -addr $VPN_MY_EXT_IP 255.255.255.255 $VPN_PEER_EXT_IP 255.255.255.255 -local" |
|
|
|
# Routes from each internal subnet, to each internal subnet on the far side |
|
mycount=0 |
mycount=0 |
while : |
while : |
do |
do |
eval next_my_ip=\$VPN_MY_INT_IP_${mycount} |
eval network=\$LOCAL_NET_${mycount} |
eval next_my_mask=\$VPN_MY_INT_MASK_${mycount} |
set `echo $network | sed 's/:/ /g'` 0x0 0x0 |
if [ -n "${next_my_ip}" ]; then |
local_net=$1 |
|
local_mask=$2 |
|
if [ "${local_net}" != "0x0" ]; then |
peercount=0 |
peercount=0 |
while : |
while : |
do |
do |
eval next_peer_ip=\$VPN_PEER_INT_IP_${peercount} |
eval network=\$REMOTE_NET_${peercount} |
eval next_peer_mask=\$VPN_PEER_INT_MASK_${peercount} |
set `echo $network | sed 's/:/ /g'` 0x0 0x0 |
if [ -n "${next_peer_ip}" ]; then |
remote_net=$1 |
# set an IPSec route for this pair of networks |
remote_mask=$2 |
eval_and_echo "$ipsecadm flow -proto esp -dst $VPN_PEER_EXT_IP -spi $VPN_SPI_OUT -addr $next_my_ip $next_my_mask $next_peer_ip $next_peer_mask" |
if [ "${remote_net}" != "0x0" ]; then |
peercount=`expr ${peercount} + 1` |
$DEBUG $ipsecadm flow \ |
|
-proto esp -dst $GW_PEER -spi $SPI_OUT \ |
|
-addr $local_net $local_mask $remote_net $remote_mask |
|
peercount=$(($peercount + 1)) |
else |
else |
break; |
break; |
fi |
fi |
done |
done |
mycount=`expr ${mycount} + 1` |
mycount=$(($mycount + 1)) |
else |
else |
break; |
break; |
fi |
fi |
done |
done |
|
|
|
# XXX Stuff below is mainly for testing, may be removed later. |
|
|
# Routes to each remote internal subnet |
# Flows from local gw to each remote subnet |
peercount=0 |
peercount=0 |
while : |
while : |
do |
do |
eval next_peer_ip=\$VPN_PEER_INT_IP_${peercount} |
eval network=\$REMOTE_NET_${peercount} |
eval next_peer_mask=\$VPN_PEER_INT_MASK_${peercount} |
set `echo $network | sed 's/:/ /g'` 0x0 0x0 |
if [ -n "${next_peer_ip}" ]; then |
remote_net=$1 |
|
remote_mask=$2 |
# Route from my ext IP to each remote internal subnet |
if [ "${remote_net}" != "0x0" ]; then |
eval_and_echo "$ipsecadm flow -proto esp -dst $VPN_PEER_EXT_IP -spi $VPN_SPI_OUT -addr $VPN_MY_EXT_IP 255.255.255.255 $next_peer_ip $next_peer_mask -local" |
$DEBUG $ipsecadm flow \ |
peercount=`expr ${peercount} + 1` |
-proto esp -dst $GW_PEER -spi $SPI_OUT \ |
|
-addr 0.0.0.0 0xffffffff $remote_net $remote_mask |
|
peercount=$(($peercount + 1)) |
else |
else |
break; |
break; |
fi |
fi |
done |
done |
|
|
|
# Flows from local subnets to the remote gw |
# Routes from each of my internal subnets to the remote external IP |
|
mycount=0 |
mycount=0 |
while : |
while : |
do |
do |
eval next_my_ip=\$VPN_MY_INT_IP_${mycount} |
eval network=\$LOCAL_NET_${mycount} |
eval next_my_mask=\$VPN_MY_INT_MASK_${mycount} |
set `echo $network | sed 's/:/ /g'` 0x0 0x0 |
if [ -n "${next_my_ip}" ]; then |
local_net=$1 |
eval_and_echo $ipsecadm flow -proto esp -dst $VPN_PEER_EXT_IP -spi $VPN_SPI_OUT -addr $next_my_ip $next_my_mask $VPN_PEER_EXT_IP 255.255.255.255 |
local_mask=$2 |
mycount=`expr ${mycount} + 1` |
if [ "${local_net}" != "0x0" ]; then |
|
$DEBUG $ipsecadm flow \ |
|
-proto esp -dst $GW_PEER -spi $SPI_OUT \ |
|
-addr $local_net $local_mask $GW_PEER 0xffffffff |
|
mycount=$(($mycount + 1)) |
else |
else |
break; |
break; |
fi |
fi |
done |
done |
|
|
|
exit 0 |