| #!/bin/bash | 
 |  | 
 | # **install_openvpn.sh** | 
 |  | 
 | # Install OpenVPN and generate required certificates | 
 | # | 
 | # install_openvpn.sh --client name | 
 | # install_openvpn.sh --server [name] | 
 | # | 
 | # name is used on the CN of the generated cert, and the filename of | 
 | # the configuration, certificate and key files. | 
 | # | 
 | # --server mode configures the host with a running OpenVPN server instance | 
 | # --client mode creates a tarball of a client configuration for this server | 
 |  | 
 | # Get config file | 
 | if [ -e localrc ]; then | 
 |     . localrc | 
 | fi | 
 | if [ -e vpnrc ]; then | 
 |     . vpnrc | 
 | fi | 
 |  | 
 | # Do some IP manipulation | 
 | function cidr2netmask { | 
 |     set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 | 
 |     if [[ $1 -gt 1 ]]; then | 
 |         shift $1 | 
 |     else | 
 |         shift | 
 |     fi | 
 |     echo ${1-0}.${2-0}.${3-0}.${4-0} | 
 | } | 
 |  | 
 | FIXED_NET=`echo $FIXED_RANGE | cut -d'/' -f1` | 
 | FIXED_CIDR=`echo $FIXED_RANGE | cut -d'/' -f2` | 
 | FIXED_MASK=`cidr2netmask $FIXED_CIDR` | 
 |  | 
 | # VPN Config | 
 | VPN_SERVER=${VPN_SERVER:-`ifconfig eth0 | awk "/inet addr:/ { print \$2 }" | cut -d: -f2`}  # 50.56.12.212 | 
 | VPN_PROTO=${VPN_PROTO:-tcp} | 
 | VPN_PORT=${VPN_PORT:-6081} | 
 | VPN_DEV=${VPN_DEV:-tap0} | 
 | VPN_BRIDGE=${VPN_BRIDGE:-br100} | 
 | VPN_BRIDGE_IF=${VPN_BRIDGE_IF:-$FLAT_INTERFACE} | 
 | VPN_CLIENT_NET=${VPN_CLIENT_NET:-$FIXED_NET} | 
 | VPN_CLIENT_MASK=${VPN_CLIENT_MASK:-$FIXED_MASK} | 
 | VPN_CLIENT_DHCP="${VPN_CLIENT_DHCP:-net.1 net.254}" | 
 |  | 
 | VPN_DIR=/etc/openvpn | 
 | CA_DIR=$VPN_DIR/easy-rsa | 
 |  | 
 | function usage { | 
 |     echo "$0 - OpenVPN install and certificate generation" | 
 |     echo "" | 
 |     echo "$0 --client name" | 
 |     echo "$0 --server [name]" | 
 |     echo "" | 
 |     echo " --server mode configures the host with a running OpenVPN server instance" | 
 |     echo " --client mode creates a tarball of a client configuration for this server" | 
 |     exit 1 | 
 | } | 
 |  | 
 | if [ -z $1 ]; then | 
 |     usage | 
 | fi | 
 |  | 
 | # Install OpenVPN | 
 | VPN_EXEC=`which openvpn` | 
 | if [ -z "$VPN_EXEC" -o ! -x "$VPN_EXEC" ]; then | 
 |     apt-get install -y openvpn bridge-utils | 
 | fi | 
 | if [ ! -d $CA_DIR ]; then | 
 |     cp -pR /usr/share/doc/openvpn/examples/easy-rsa/2.0/ $CA_DIR | 
 | fi | 
 |  | 
 | # Keep track of the current directory | 
 | TOOLS_DIR=$(cd $(dirname "$0") && pwd) | 
 | TOP_DIR=$(cd $TOOLS_DIR/.. && pwd) | 
 |  | 
 | WEB_DIR=$TOP_DIR/../vpn | 
 | if [[ ! -d $WEB_DIR ]]; then | 
 |     mkdir -p $WEB_DIR | 
 | fi | 
 | WEB_DIR=$(cd $TOP_DIR/../vpn && pwd) | 
 |  | 
 | cd $CA_DIR | 
 | source ./vars | 
 |  | 
 | # Override the defaults | 
 | export KEY_COUNTRY="US" | 
 | export KEY_PROVINCE="TX" | 
 | export KEY_CITY="SanAntonio" | 
 | export KEY_ORG="Cloudbuilders" | 
 | export KEY_EMAIL="rcb@lists.rackspace.com" | 
 |  | 
 | if [ ! -r $CA_DIR/keys/dh1024.pem ]; then | 
 |     # Initialize a new CA | 
 |     $CA_DIR/clean-all | 
 |     $CA_DIR/build-dh | 
 |     $CA_DIR/pkitool --initca | 
 |     openvpn --genkey --secret $CA_DIR/keys/ta.key  ## Build a TLS key | 
 | fi | 
 |  | 
 | function do_server { | 
 |     NAME=$1 | 
 |     # Generate server certificate | 
 |     $CA_DIR/pkitool --server $NAME | 
 |  | 
 |     (cd $CA_DIR/keys; | 
 |         cp $NAME.crt $NAME.key ca.crt dh1024.pem ta.key $VPN_DIR | 
 |     ) | 
 |     cat >$VPN_DIR/br-up <<EOF | 
 | #!/bin/bash | 
 |  | 
 | BR="$VPN_BRIDGE" | 
 | TAP="\$1" | 
 |  | 
 | if [[ ! -d /sys/class/net/\$BR ]]; then | 
 |     brctl addbr \$BR | 
 | fi | 
 |  | 
 | for t in \$TAP; do | 
 |     openvpn --mktun --dev \$t | 
 |     brctl addif \$BR \$t | 
 |     ifconfig \$t 0.0.0.0 promisc up | 
 | done | 
 | EOF | 
 |     chmod +x $VPN_DIR/br-up | 
 |     cat >$VPN_DIR/br-down <<EOF | 
 | #!/bin/bash | 
 |  | 
 | BR="$VPN_BRIDGE" | 
 | TAP="\$1" | 
 |  | 
 | for i in \$TAP; do | 
 |     brctl delif \$BR $t | 
 |     openvpn --rmtun --dev \$i | 
 | done | 
 | EOF | 
 |     chmod +x $VPN_DIR/br-down | 
 |     cat >$VPN_DIR/$NAME.conf <<EOF | 
 | proto $VPN_PROTO | 
 | port $VPN_PORT | 
 | dev $VPN_DEV | 
 | up $VPN_DIR/br-up | 
 | down $VPN_DIR/br-down | 
 | cert $NAME.crt | 
 | key $NAME.key  # This file should be kept secret | 
 | ca ca.crt | 
 | dh dh1024.pem | 
 | duplicate-cn | 
 | server-bridge $VPN_CLIENT_NET $VPN_CLIENT_MASK $VPN_CLIENT_DHCP | 
 | ifconfig-pool-persist ipp.txt | 
 | comp-lzo | 
 | user nobody | 
 | group nogroup | 
 | persist-key | 
 | persist-tun | 
 | status openvpn-status.log | 
 | EOF | 
 |     /etc/init.d/openvpn restart | 
 | } | 
 |  | 
 | function do_client { | 
 |     NAME=$1 | 
 |     # Generate a client certificate | 
 |     $CA_DIR/pkitool $NAME | 
 |  | 
 |     TMP_DIR=`mktemp -d` | 
 |     (cd $CA_DIR/keys; | 
 |         cp -p ca.crt ta.key $NAME.key $NAME.crt $TMP_DIR | 
 |     ) | 
 |     if [ -r $VPN_DIR/hostname ]; then | 
 |         HOST=`cat $VPN_DIR/hostname` | 
 |     else | 
 |         HOST=`hostname` | 
 |     fi | 
 |     cat >$TMP_DIR/$HOST.conf <<EOF | 
 | proto $VPN_PROTO | 
 | port $VPN_PORT | 
 | dev $VPN_DEV | 
 | cert $NAME.crt | 
 | key $NAME.key  # This file should be kept secret | 
 | ca ca.crt | 
 | client | 
 | remote $VPN_SERVER $VPN_PORT | 
 | resolv-retry infinite | 
 | nobind | 
 | user nobody | 
 | group nogroup | 
 | persist-key | 
 | persist-tun | 
 | comp-lzo | 
 | verb 3 | 
 | EOF | 
 |     (cd $TMP_DIR; tar cf $WEB_DIR/$NAME.tar *) | 
 |     rm -rf $TMP_DIR | 
 |     echo "Client certificate and configuration is in $WEB_DIR/$NAME.tar" | 
 | } | 
 |  | 
 | # Process command line args | 
 | case $1 in | 
 |     --client)   if [ -z $2 ]; then | 
 |                     usage | 
 |                 fi | 
 |                 do_client $2 | 
 |                 ;; | 
 |     --server)   if [ -z $2 ]; then | 
 |                     NAME=`hostname` | 
 |                 else | 
 |                     NAME=$2 | 
 |                     # Save for --client use | 
 |                     echo $NAME >$VPN_DIR/hostname | 
 |                 fi | 
 |                 do_server $NAME | 
 |                 ;; | 
 |     --clean)    $CA_DIR/clean-all | 
 |                 ;; | 
 |     *)          usage | 
 | esac |