2 # Copyright (C) 2016 Ian Kelling
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
19 [[ $EUID == 0 ]] ||
exec sudo
-E "$BASH_SOURCE" "$@"
24 usage: ${0##*/} VPN_SERVER_HOST
26 -b COMMON_NAME By default, use $HOSTNAME or $CLIENT_HOST. If the cert
27 already exists on the server, with the CLIENT_NAME
28 name, we use the existing one. See comment below if we
29 ever want to check existing common names. They must be
30 unique per server, so you can use $(uuidgen) if
31 needed. You used to be able to create multiple with the
32 same name, but not connect at the same time, but now,
33 the generator keeps track, so you can't generate.
34 -c CLIENT_HOST default is localhost. Else we ssh to root@CLIENT_HOST
35 -n CONFIG_NAME default is client
36 -s SCRIPT_PATH Use custom up/down script at PATH, copied to same path
39 Generate a client cert and config and install it on locally or on
40 CLIENT_HOST if given. Uses default config options, and expects be able
41 to ssh to VPN_SERVER_HOST and CLIENT_HOST as root, or if CLIENT_HOST is
42 localhost, just to sudo this script as root.
47 Note: Uses GNU getopt options parsing style
52 # to get the common name
53 # cn=$(s openssl x509 -noout -nameopt multiline -subject \
54 # -in /etc/openvpn/client/mail.crt | \
55 # sed -rn 's/^\s*commonName\s*=\s*(.*)/\1/p')
58 ####### begin command line parsing and checking ##############
63 script=/etc
/openvpn
/update-resolv-conf
65 temp
=$
(getopt
-l help hb
:c
:n
:s
: "$@") || usage
1
69 -b) common_name
="$2"; shift 2 ;;
70 -c) client_host
=$2; shell
="ssh root@$client_host"; shift 2 ;;
71 -n) name
="$2"; shift 2 ;;
72 -s) custom_script
=true
; script="$2"; shift 2 ;;
75 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
79 if [[ ! $common_name ]]; then
80 if [[ $client_host ]]; then
81 common_name
=$client_host
88 [[ $host ]] || usage
1
90 ####### end command line parsing and checking ##############
93 # bash or else we get motd spam. note sleep 2, sleep 1 failed.
94 ssh root@
$host bash
<<EOF | $shell 'id -u | grep -xF 0 || s=sudo; $s tar xzv -C /etc/openvpn/client'
97 server_dir=/etc/openvpn
98 if [[ -e /etc/openvpn/server ]]; then
99 server_dir=/etc/openvpn/server
103 for x in /etc/openvpn/easy-rsa/keys/{$name.{crt,key},ca.crt}; do
104 if [[ ! -e \$x ]]; then
111 cd /etc/openvpn/easy-rsa
112 source vars >/dev/null
114 { echo -e '\n\n\n\n\n'$common_name'\n\n\n\n\n'; sleep 2; echo -e 'y\ny\n'; } | ./build-key $name &>/dev/null
118 cp /etc/openvpn/easy-rsa/keys/ca.crt \$d/$name-ca.crt
119 cp /etc/openvpn/easy-rsa/keys/$name.{crt,key} \$d
121 cp \$server_dir/ta.key \$d/$name-ta.key
127 f
=/etc
/openvpn
/client
/$name.crt
128 if ! $shell "test -s $f"; then
129 # if common name is not unique, you get empty file. and if we didn't silence
130 # build-key, you'd see an error "TXT_DB error number 2"
131 echo "$0: error: $f is empty or otherwise bad. is this common name unique?"
135 $shell "dd of=/etc/openvpn/client/$name.conf" <<EOF
136 # From example config, from debian stretch as of 1-2017
141 resolv-retry infinite
148 # disabled for better performance
152 # This script will update local dns
153 # to what the server sends, if it sends dns.
158 # matching server config
162 # example config has the commented line, but this other thing looks stronger,
163 # and I've seen it in a vpn provider I trust
164 # ns-cert-type server
165 remote-cert-tls server
167 # more resilient when running as nonroot
170 # See comments in server side configuration.
171 # The minimum of the client & server config is what is used by openvpn.
174 tls-auth $name-ta.key 1
177 if [[ $client_host ]] && $custom_script; then
178 $shell "dd of=$script" <$script
179 $shell "chmod +x $script"
182 $shell 'cd /etc/openvpn; for f in client/*; do ln -sf $f .; done'