#!/bin/sh ################################################################################ # # ipsecvpn -- script for use on a roadwarrior to start/stop a tunnel-mode # IPSEC connection # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 2004 - Tom Eastep (teastep@shorewall.net) # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA RCDLINKS="2,S42 3,S42 6,K42" #### BEGIN INIT INFO # Provides: ipsecvpn # Required-Start: $shorewall # Required-Stop: # Default-Start: 2 3 5 # Default-Stop: 0 1 6 # Description: starts and stops a tunnel-mode VPN connection ### END INIT INFO # chkconfig: 2345 26 89 # description: IPSEC tunnel-mode connection # ################################################################################ # # External Interface # INTERFACE=eth0 # # Remote IPSEC Gateway # GATEWAY=1.2.3.4 # # Networks behind the remote gateway (space-separated list) # NETWORKS="192.168.1.0/24" # # Directory where X.509 certificates are stored. # CERTS=/etc/certs # # Certificate to be used for this connection. The cert # directory must contain: # # ${CERT}.pem - the certificate # ${CERT}_key.pem - the certificates's key # CERT=roadwarrior # # The setkey binary # SETKEY=/usr/sbin/setkey # # The racoon binary # RACOON=/usr/sbin/racoon # # Message to stderr # error_message() # $* = Error Message { echo " $@" >&2 } # # Fatal error -- stops the firewall after issuing the error message # fatal_error() # $* = Error Message { echo " Error: $@" >&2 exit 2 } # # Find interface address--returns the first IP address assigned to the passed # device # find_first_interface_address() # $1 = interface { # # get the line of output containing the first IP address # addr=$(ip -f inet addr show $1 2> /dev/null | grep inet | head -n1) # # If there wasn't one, bail out now # [ -n "$addr" ] || fatal_error "Can't determine the IP address of $1" # # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) # along with everything else on the line # echo $addr | sed 's/inet //;s/\/.*//;s/ peer.*//' } # # Create a Racoon configuration file using the variables above # make_racoon_conf() { echo "path certificate \"$CERTS\";" echo echo "listen" echo "{" echo " isakmp $IPADDR;" echo "}" echo echo "remote $GATEWAY" echo "{" echo " exchange_mode main;" echo " certificate_type x509 \"$CERT.pem\" \"${CERT}_key.pem\";" echo " verify_cert on;" echo " my_identifier asn1dn ;" echo " peers_identifier asn1dn ;" echo " verify_identifier on ;" echo " lifetime time 24 hour ;" echo " proposal {" echo " encryption_algorithm blowfish;" echo " hash_algorithm sha1;" echo " authentication_method rsasig ;" echo " dh_group 2 ;" echo " }" echo "}" echo for network in $NETWORKS; do echo "sainfo address $IPADDR/32 any address $network any" echo "{" echo " pfs_group 2;" echo " lifetime time 12 hour ;" echo " encryption_algorithm blowfish ;" echo " authentication_algorithm hmac_sha1, hmac_md5 ;" echo " compression_algorithm deflate ;" echo "}" echo echo "sainfo address $network any address $IPADDR/32 any" echo "{" echo " pfs_group 2;" echo " lifetime time 12 hour ;" echo " encryption_algorithm blowfish ;" echo " authentication_algorithm hmac_sha1, hmac_md5 ;" echo " compression_algorithm deflate ;" echo "}" done echo "sainfo address $IPADDR/32 any address $GATEWAY/32 any" echo "{" echo " pfs_group 2;" echo " lifetime time 12 hour ;" echo " encryption_algorithm blowfish ;" echo " authentication_algorithm hmac_sha1, hmac_md5 ;" echo " compression_algorithm deflate ;" echo "}" echo echo "sainfo address $GATEWAY/32 any address $IPADDR/32 any" echo "{" echo " pfs_group 2;" echo " lifetime time 12 hour ;" echo " encryption_algorithm blowfish ;" echo " authentication_algorithm hmac_sha1, hmac_md5 ;" echo " compression_algorithm deflate ;" echo "}" } # # Make a setkey configuration file using the variables above # make_setkey_conf() { echo "flush;" echo "spdflush;" echo "spdadd $IPADDR/32 $GATEWAY/32 any -P out ipsec esp/tunnel/${IPADDR}-${GATEWAY}/require;" echo "spdadd $GATEWAY/32 $IPADDR/32 any -P in ipsec esp/tunnel/${GATEWAY}-${IPADDR}/require;" for network in $NETWORKS; do echo "spdadd $IPADDR/32 $network any -P out ipsec esp/tunnel/${IPADDR}-${GATEWAY}/require;" echo "spdadd $network $IPADDR/32 any -P in ipsec esp/tunnel/${GATEWAY}-${IPADDR}/require;" done } # # Start the Tunnel # start() { # # Get the first IP address configured on the device in INTERFACE # IPADDR=$(find_first_interface_address $INTERFACE) # # Create the name of the setkey temporary file # TEMPFILE=$(mktemp /tmp/$(basename $0).XXXXXXXX) [ $? -eq 0 ] || fatal_error "Can't create temporary file name" # # Create the file # make_setkey_conf > $TEMPFILE # # Create the SPD # $SETKEY -f $TEMPFILE # # We can now remove the file # rm -f $TEMPFILE # # Create another name -- make this distict to aid debugging # (just comment out the 'rm' commands) # TEMPFILE=$(mktemp /tmp/$(basename $0).XXXXXXXX) [ $? -eq 0 ] || fatal_error "Can't create temporary file name" # # Create the file # make_racoon_conf > $TEMPFILE # # Start Racoon Daemon # $RACOON -4 -f $TEMPFILE # # Once the Daemon is running, we can remove the file # rm -f $TEMPFILE } # # Stop the Tunnel # stop() { # # Kill any racoon daemons # killall racoon # # Purge the SAD and SPD # setkey -F -FP } # # Display command syntax and abend # usage() { error_message "usage: $(basename $0) [start|stop|restart]" exit 1 } ################################################################################ # C O D E S T A R T S H E R E ################################################################################ [ $# -eq 1 ] || usage case $1 in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; *) usage ;; esac