| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 1 | #!/bin/bash | 
| Dean Troyer | e62ba4d | 2012-06-27 22:07:34 -0500 | [diff] [blame] | 2 |  | 
|  | 3 | # **install_openvpn.sh** | 
|  | 4 |  | 
|  | 5 | # Install OpenVPN and generate required certificates | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 6 | # | 
|  | 7 | # install_openvpn.sh --client name | 
|  | 8 | # install_openvpn.sh --server [name] | 
|  | 9 | # | 
|  | 10 | # name is used on the CN of the generated cert, and the filename of | 
|  | 11 | # the configuration, certificate and key files. | 
|  | 12 | # | 
|  | 13 | # --server mode configures the host with a running OpenVPN server instance | 
|  | 14 | # --client mode creates a tarball of a client configuration for this server | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 15 |  | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 16 | # Get config file | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 17 | if [ -e localrc ]; then | 
|  | 18 | . localrc | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 19 | fi | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 20 | if [ -e vpnrc ]; then | 
|  | 21 | . vpnrc | 
|  | 22 | fi | 
|  | 23 |  | 
|  | 24 | # Do some IP manipulation | 
|  | 25 | function cidr2netmask() { | 
|  | 26 | set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0 | 
|  | 27 | if [[ $1 -gt 1 ]]; then | 
|  | 28 | shift $1 | 
|  | 29 | else | 
|  | 30 | shift | 
|  | 31 | fi | 
|  | 32 | echo ${1-0}.${2-0}.${3-0}.${4-0} | 
|  | 33 | } | 
|  | 34 |  | 
|  | 35 | FIXED_NET=`echo $FIXED_RANGE | cut -d'/' -f1` | 
|  | 36 | FIXED_CIDR=`echo $FIXED_RANGE | cut -d'/' -f2` | 
|  | 37 | FIXED_MASK=`cidr2netmask $FIXED_CIDR` | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 38 |  | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 39 | # VPN Config | 
|  | 40 | VPN_SERVER=${VPN_SERVER:-`ifconfig eth0 | awk "/inet addr:/ { print \$2 }" | cut -d: -f2`}  # 50.56.12.212 | 
|  | 41 | VPN_PROTO=${VPN_PROTO:-tcp} | 
|  | 42 | VPN_PORT=${VPN_PORT:-6081} | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 43 | VPN_DEV=${VPN_DEV:-tap0} | 
|  | 44 | VPN_BRIDGE=${VPN_BRIDGE:-br100} | 
|  | 45 | VPN_BRIDGE_IF=${VPN_BRIDGE_IF:-$FLAT_INTERFACE} | 
|  | 46 | VPN_CLIENT_NET=${VPN_CLIENT_NET:-$FIXED_NET} | 
|  | 47 | VPN_CLIENT_MASK=${VPN_CLIENT_MASK:-$FIXED_MASK} | 
|  | 48 | VPN_CLIENT_DHCP="${VPN_CLIENT_DHCP:-net.1 net.254}" | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 49 |  | 
|  | 50 | VPN_DIR=/etc/openvpn | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 51 | CA_DIR=$VPN_DIR/easy-rsa | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 52 |  | 
|  | 53 | usage() { | 
|  | 54 | echo "$0 - OpenVPN install and certificate generation" | 
|  | 55 | echo "" | 
|  | 56 | echo "$0 --client name" | 
|  | 57 | echo "$0 --server [name]" | 
|  | 58 | echo "" | 
|  | 59 | echo " --server mode configures the host with a running OpenVPN server instance" | 
|  | 60 | echo " --client mode creates a tarball of a client configuration for this server" | 
|  | 61 | exit 1 | 
|  | 62 | } | 
|  | 63 |  | 
|  | 64 | if [ -z $1 ]; then | 
|  | 65 | usage | 
|  | 66 | fi | 
|  | 67 |  | 
|  | 68 | # Install OpenVPN | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 69 | VPN_EXEC=`which openvpn` | 
|  | 70 | if [ -z "$VPN_EXEC" -o ! -x "$VPN_EXEC" ]; then | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 71 | apt-get install -y openvpn bridge-utils | 
|  | 72 | fi | 
|  | 73 | if [ ! -d $CA_DIR ]; then | 
|  | 74 | cp -pR /usr/share/doc/openvpn/examples/easy-rsa/2.0/ $CA_DIR | 
|  | 75 | fi | 
|  | 76 |  | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 77 | # Keep track of the current directory | 
|  | 78 | TOOLS_DIR=$(cd $(dirname "$0") && pwd) | 
|  | 79 | TOP_DIR=$(cd $TOOLS_DIR/.. && pwd) | 
|  | 80 |  | 
|  | 81 | WEB_DIR=$TOP_DIR/../vpn | 
|  | 82 | if [[ ! -d $WEB_DIR ]]; then | 
|  | 83 | mkdir -p $WEB_DIR | 
|  | 84 | fi | 
|  | 85 | WEB_DIR=$(cd $TOP_DIR/../vpn && pwd) | 
|  | 86 |  | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 87 | cd $CA_DIR | 
|  | 88 | source ./vars | 
|  | 89 |  | 
|  | 90 | # Override the defaults | 
|  | 91 | export KEY_COUNTRY="US" | 
|  | 92 | export KEY_PROVINCE="TX" | 
|  | 93 | export KEY_CITY="SanAntonio" | 
|  | 94 | export KEY_ORG="Cloudbuilders" | 
|  | 95 | export KEY_EMAIL="rcb@lists.rackspace.com" | 
|  | 96 |  | 
|  | 97 | if [ ! -r $CA_DIR/keys/dh1024.pem ]; then | 
|  | 98 | # Initialize a new CA | 
|  | 99 | $CA_DIR/clean-all | 
|  | 100 | $CA_DIR/build-dh | 
|  | 101 | $CA_DIR/pkitool --initca | 
|  | 102 | openvpn --genkey --secret $CA_DIR/keys/ta.key  ## Build a TLS key | 
|  | 103 | fi | 
|  | 104 |  | 
|  | 105 | do_server() { | 
|  | 106 | NAME=$1 | 
|  | 107 | # Generate server certificate | 
|  | 108 | $CA_DIR/pkitool --server $NAME | 
|  | 109 |  | 
|  | 110 | (cd $CA_DIR/keys; | 
|  | 111 | cp $NAME.crt $NAME.key ca.crt dh1024.pem ta.key $VPN_DIR | 
|  | 112 | ) | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 113 | cat >$VPN_DIR/br-up <<EOF | 
|  | 114 | #!/bin/bash | 
|  | 115 |  | 
|  | 116 | BR="$VPN_BRIDGE" | 
|  | 117 | TAP="\$1" | 
|  | 118 |  | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 119 | if [[ ! -d /sys/class/net/\$BR ]]; then | 
|  | 120 | brctl addbr \$BR | 
|  | 121 | fi | 
|  | 122 |  | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 123 | for t in \$TAP; do | 
|  | 124 | openvpn --mktun --dev \$t | 
|  | 125 | brctl addif \$BR \$t | 
|  | 126 | ifconfig \$t 0.0.0.0 promisc up | 
|  | 127 | done | 
|  | 128 | EOF | 
|  | 129 | chmod +x $VPN_DIR/br-up | 
|  | 130 | cat >$VPN_DIR/br-down <<EOF | 
|  | 131 | #!/bin/bash | 
|  | 132 |  | 
|  | 133 | BR="$VPN_BRIDGE" | 
|  | 134 | TAP="\$1" | 
|  | 135 |  | 
|  | 136 | for i in \$TAP; do | 
|  | 137 | brctl delif \$BR $t | 
|  | 138 | openvpn --rmtun --dev \$i | 
|  | 139 | done | 
|  | 140 | EOF | 
|  | 141 | chmod +x $VPN_DIR/br-down | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 142 | cat >$VPN_DIR/$NAME.conf <<EOF | 
|  | 143 | proto $VPN_PROTO | 
|  | 144 | port $VPN_PORT | 
|  | 145 | dev $VPN_DEV | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 146 | up $VPN_DIR/br-up | 
|  | 147 | down $VPN_DIR/br-down | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 148 | cert $NAME.crt | 
|  | 149 | key $NAME.key  # This file should be kept secret | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 150 | ca ca.crt | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 151 | dh dh1024.pem | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 152 | duplicate-cn | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 153 | server-bridge $VPN_CLIENT_NET $VPN_CLIENT_MASK $VPN_CLIENT_DHCP | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 154 | ifconfig-pool-persist ipp.txt | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 155 | comp-lzo | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 156 | user nobody | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 157 | group nogroup | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 158 | persist-key | 
|  | 159 | persist-tun | 
|  | 160 | status openvpn-status.log | 
|  | 161 | EOF | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 162 | /etc/init.d/openvpn restart | 
|  | 163 | } | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 164 |  | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 165 | do_client() { | 
|  | 166 | NAME=$1 | 
|  | 167 | # Generate a client certificate | 
|  | 168 | $CA_DIR/pkitool $NAME | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 169 |  | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 170 | TMP_DIR=`mktemp -d` | 
|  | 171 | (cd $CA_DIR/keys; | 
|  | 172 | cp -p ca.crt ta.key $NAME.key $NAME.crt $TMP_DIR | 
|  | 173 | ) | 
|  | 174 | if [ -r $VPN_DIR/hostname ]; then | 
|  | 175 | HOST=`cat $VPN_DIR/hostname` | 
|  | 176 | else | 
|  | 177 | HOST=`hostname` | 
|  | 178 | fi | 
|  | 179 | cat >$TMP_DIR/$HOST.conf <<EOF | 
|  | 180 | proto $VPN_PROTO | 
|  | 181 | port $VPN_PORT | 
|  | 182 | dev $VPN_DEV | 
|  | 183 | cert $NAME.crt | 
|  | 184 | key $NAME.key  # This file should be kept secret | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 185 | ca ca.crt | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 186 | client | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 187 | remote $VPN_SERVER $VPN_PORT | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 188 | resolv-retry infinite | 
|  | 189 | nobind | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 190 | user nobody | 
| Dean Troyer | 78f2140 | 2011-11-14 17:45:37 -0600 | [diff] [blame] | 191 | group nogroup | 
| Jesse Andrews | 2969c70 | 2011-09-24 12:31:57 -0700 | [diff] [blame] | 192 | persist-key | 
|  | 193 | persist-tun | 
|  | 194 | comp-lzo | 
|  | 195 | verb 3 | 
|  | 196 | EOF | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 197 | (cd $TMP_DIR; tar cf $WEB_DIR/$NAME.tar *) | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 198 | rm -rf $TMP_DIR | 
| Dean Troyer | f44e98d | 2011-11-29 17:39:51 -0600 | [diff] [blame] | 199 | echo "Client certificate and configuration is in $WEB_DIR/$NAME.tar" | 
| Dean Troyer | 135fb64 | 2011-09-27 12:57:53 -0500 | [diff] [blame] | 200 | } | 
|  | 201 |  | 
|  | 202 | # Process command line args | 
|  | 203 | case $1 in | 
|  | 204 | --client)   if [ -z $2 ]; then | 
|  | 205 | usage | 
|  | 206 | fi | 
|  | 207 | do_client $2 | 
|  | 208 | ;; | 
|  | 209 | --server)   if [ -z $2 ]; then | 
|  | 210 | NAME=`hostname` | 
|  | 211 | else | 
|  | 212 | NAME=$2 | 
|  | 213 | # Save for --client use | 
|  | 214 | echo $NAME >$VPN_DIR/hostname | 
|  | 215 | fi | 
|  | 216 | do_server $NAME | 
|  | 217 | ;; | 
|  | 218 | --clean)    $CA_DIR/clean-all | 
|  | 219 | ;; | 
|  | 220 | *)          usage | 
|  | 221 | esac |