support buster
[vpn-setup] / vpn-server-setup
1 #!/bin/bash -x
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
17 set -eE -o pipefail
18 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
19
20 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
21
22 usage() {
23 cat <<'EOF'
24 usage: ${0##*/} [-d|-h|--help]
25
26 -r Do not push default route
27 -d Do not push dns
28 -s Do not start openvpn
29 -h --help print help
30
31 Sets up a vpn server which pushes gateway route and dns server so all
32 traffic goes through the vpn. requires systemd, and might have some
33 debian specific paths.
34
35 You can save all the keys by storing /etc/openvpn/easy-rsa/keys, and
36 the script will not generate them if it sees they exist already.
37
38 Note: Uses GNU getopt options parsing style
39 EOF
40 exit $1
41 }
42
43 dns=true
44 route=true
45 start=true
46 temp=$(getopt -l help drsh "$@") || usage 1
47 eval set -- "$temp"
48 while true; do
49 case $1 in
50 -d) dns=false; shift ;;
51 -r) route=false; shift ;;
52 -s) start=false; shift ;;
53 -h|--help) usage ;;
54 --) shift; break ;;
55 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
56 esac
57 done
58
59 apt-get update
60 # suggests get's us openssl. policy-rc.d is to prevent install from starting services
61 f=/usr/sbin/policy-rc.d;
62 dd of=$f <<EOF
63 #!/bin/sh
64 exit 101
65 EOF
66 chmod +x $f;
67 apt-get install --install-suggests -y openvpn
68 rm $f
69
70 if [[ -e /lib/systemd/system/openvpn-server@.service ]]; then
71 vpn_service=openvpn-server@server
72 else
73 vpn_service=openvpn@server
74 fi
75 apt-get install -y uuid-runtime easy-rsa
76 mkdir -p /etc/openvpn/easy-rsa
77 cd /etc/openvpn/easy-rsa
78 cp -r /usr/share/easy-rsa/* .
79 if [[ -e openssl-1.0.0.cnf && ! -e openssl.cnf ]]; then
80 # there's a debian bug about this.
81 ln -s openssl-1.0.0.cnf openssl.cnf
82 fi
83
84 server_dir=/etc/openvpn/server
85 mkdir -p $server_dir
86 chmod 700 $server_dir
87
88
89 new=true
90 keyfiles=(/etc/openvpn/easy-rsa/pki/{ca.crt,private/server.key,issued/server.crt})
91 if [[ -e /etc/openvpn/easy-rsa/build-ca ]]; then
92 new=false
93 keyfiles=(/etc/openvpn/easy-rsa/keys/{ca.crt,server.{crt,key}})
94 fi
95
96 keys_exist=true
97 for f in ${keyfiles[@]}; do
98 if [[ ! -e $f ]]; then
99 keys_exist=false
100 break
101 fi
102 done
103
104 if ! $keys_exist; then
105 # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
106 openvpn --genkey --secret $server_dir/ta.key
107 if $new; then
108 ./easyrsa init-pki
109 ./easyrsa --batch build-ca nopass
110 ./easyrsa build-server-full server nopass
111 openssl dhparam -out $server_dir/dh2048.pem 2048
112 else
113 # dun care about settning cert cn etc from the non-example values
114 source vars
115 # doesnt exist in buster
116 ./clean-all # note: removes and creates /etc/openvpn/easy-rsa/keys
117 # accept default prompts
118 echo -e '\n\n\n\n\n\n\n\n' | ./build-ca
119
120 # This builds the server's key/cert. argument is the name of the file,
121 # but it also is the default common name of the cert.
122 # 'server' is the default name in our conf file for the name of the file
123 # and I've seen no reason to change it.
124 # Note, this is not idempotent.
125 { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | ./build-key-server server
126 ./build-dh
127 fi
128 fi
129
130
131 cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz $server_dir
132 gzip -df $server_dir/server.conf.gz
133
134
135 cp ${keyfiles[@]} $server_dir
136 # for legacy systems
137 for f in ${keyfiles[@]}; do
138 ln -sf server/${f##*/} /etc/openvpn
139 done
140
141 cat >>$server_dir/server.conf <<'EOF'
142
143 # I cat an extra blank line to start because the example config does
144 # not have a final newline. ....
145
146 # not in example config, but openvpn outputs a warning about insecure
147 # cipher without a setting like this (the default i can understand due
148 # to compatibility issues, but not changing the example config... not
149 # cool).
150 # requires the same setting on the client side.
151 cipher AES-256-CBC
152 # just sets up the ability to have client specific configs
153 client-config-dir /etc/openvpn/client-config
154
155 # duplicate in newer sample configs
156 tls-auth ta.key 0 # This file is secret
157
158 # depending on sample config, this may not be there, which means i can't
159 # talk to 10.8.0.1, there might be some other way, but stretch's
160 # sample config says:
161 # Should be subnet (addressing via IP)
162 # unless Windows clients v2.0.9 and lower have to
163 # be supported (then net30, i.e. a /30 per client)
164 # Defaults to net30 (not recommended)
165 topology subnet
166 EOF
167
168
169 # dh improve security,
170 # remove comp-lzo to increase perf
171 sed -i --follow-symlinks -f - $server_dir/server.conf <<'EOF'
172 s/^dh dh1024.pem/dh dh2048.pem/
173 /^comp-lzo.*/d
174 EOF
175
176
177 mkdir -p /etc/openvpn/client-config
178
179
180 if $dns; then
181 # Be the dns server for clients
182 cat >>$server_dir/server.conf <<'EOF'
183 push "dhcp-option DNS 10.8.0.1"
184 EOF
185 fi
186
187 if $route; then
188 cat >>$server_dir/server.conf <<'EOF'
189 # Be the default gateway for clients.
190 push "redirect-gateway def1"
191 EOF
192 fi
193
194 sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc/sysctl.conf
195 sed -i --follow-symlinks '/^ *net.ipv6.conf.all.forwarding=.*/d' /etc/sysctl.conf
196 cat >>/etc/sysctl.conf <<'EOF'
197 net.ipv4.ip_forward=1
198 net.ipv6.conf.all.forwarding=1
199 EOF
200 sysctl -p /etc/sysctl.conf
201
202 gw=$(ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p')
203
204 cat >/etc/systemd/system/vpnnat.service <<EOF
205 [Unit]
206 Description=Turns on nat iptables setting
207
208 [Service]
209 Type=oneshot
210 RemainAfterExit=yes
211 ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
212 ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
213
214 [Install]
215 WantedBy=$vpn_service.service
216 EOF
217 systemctl daemon-reload # needed if the file was already there
218 # note, no need to start it, the vpn_service does that.
219 systemctl enable vpnnat
220
221 if $start; then
222 systemctl enable $vpn_service
223 systemctl restart $vpn_service
224 fi