| #!/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 |