stop using uuid always
[vpn-setup] / vpn-mk-client-cert
1 #!/bin/bash
2 # Copyright (C) 2016 Ian Kelling
3
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
7
8 # http://www.apache.org/licenses/LICENSE-2.0
9
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.
15
16 set -eE -o pipefail
17 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
18
19 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
20
21 usage() {
22 cat <<EOF
23 usage: ${0##*/} VPN_SERVER_HOST
24
25 -b COMMON_NAME By default, use CONFIG_NAME. If the cert already exists
26 on the server, with the CLIENT_NAME name, we use the
27 existing one. See comment below if we ever want to
28 check existing common names. They must be unique per
29 server, so you can use $(uuidgen) if needed. You used
30 to be able to create multiple with the same name, but
31 not connect at the same time, but now, the generator
32 keeps track, so you can't generate.
33 -c CLIENT_HOST default is localhost. Else we ssh to root@CLIENT_HOST
34 -n CONFIG_NAME default is client
35
36 Generate a client cert and config and install it on locally or on
37 CLIENT_HOST if given. Uses default config options, and expects be able
38 to ssh to VPN_SERVER_HOST and CLIENT_HOST as root, or if CLIENT_HOST is
39 localhost, just to sudo this script as root.
40
41
42
43
44 Note: Uses GNU getopt options parsing style
45 EOF
46 exit ${1:-0}
47 }
48
49 # to get the common name
50 # cn=$(s openssl x509 -noout -nameopt multiline -subject \
51 # -in /etc/openvpn/client/mail.crt | \
52 # sed -rn 's/^\s*commonName\s*=\s*(.*)/\1/p')
53
54
55 shell="bash -c"
56 name=client
57
58 temp=$(getopt -l help hb:c:n: "$@") || usage 1
59 eval set -- "$temp"
60 while true; do
61 case $1 in
62 -b) common_name="$2"; shift 2 ;;
63 -c) shell="ssh root@$2"; shift 2 ;;
64 -n) name="$2"; shift 2 ;;
65 -h|--help) usage ;;
66 --) shift; break ;;
67 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
68 esac
69 done
70
71 if [[ ! $common_name ]]; then common_name=$name; fi
72
73 host=$1
74 [[ $host ]] || usage 1
75
76 # bash or else we get motd spam. note sleep 2, sleep 1 failed.
77 ssh root@$host bash <<EOF | $shell 'id -u | grep -xF 0 || s=sudo; $s tar xzv -C /etc/openvpn/client'
78 set -eE -o pipefail
79
80 exists=true
81 for x in /etc/openvpn/easy-rsa/keys/{$name.{crt,key},ca.crt}; do
82 if [[ ! -e \$x ]]; then
83 exists=false
84 break
85 fi
86 done
87
88 if ! \$exists; then
89 cd /etc/openvpn/easy-rsa
90 source vars >/dev/null
91
92 { 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
93 fi
94
95 d=\$(mktemp -d)
96 cp /etc/openvpn/easy-rsa/keys/ca.crt \$d/$name-ca.crt
97 cp /etc/openvpn/easy-rsa/keys/$name.{crt,key} \$d
98
99 tar cz -C \$d .
100 rm -rf \$d
101 EOF
102
103 f=/etc/openvpn/client/$name.crt
104 if [[ ! -s $f ]]; then
105 echo "$0: error: $f is empty or otherwise bad. is this common name unique?"
106 exit 1
107 fi
108
109 $shell "dd of=/etc/openvpn/client/$name.conf" <<EOF
110 # From example config, from debian stretch as of 1-2017
111 client
112 dev tun
113 proto udp
114 remote $host 1194
115 resolv-retry infinite
116 nobind
117 persist-key
118 persist-tun
119 ca $name-ca.crt
120 cert $name.crt
121 key $name.key
122 # disabled for better performance
123 #comp-lzo
124 verb 3
125
126 # This script will update local dns
127 # to what the server sends, if it sends dns.
128 script-security 2
129 up /etc/openvpn/update-resolv-conf
130 down /etc/openvpn/update-resolv-conf
131
132 # matching server config
133 cipher aes-256-cbc
134
135
136 # example config has the commented line, but this other thing looks stronger,
137 # and I've seen it in a vpn provider I trust
138 # ns-cert-type server
139 remote-cert-tls server
140
141 # more resilient when running as nonroot
142 persist-key
143
144 # see comments in server side configuration.
145 # the minimum of the 2 is used.
146 reneg-sec 2592000
147 EOF