add trisquel flidas support, small fixes and additions
[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
61 apt-get install --install-suggests -y openvpn
62 if [[ -e /lib/systemd/system/openvpn-server@.service ]]; then
63 vpn_service=openvpn-server@server
64 else
65 vpn_service=openvpn@server
66 fi
67 apt-get install -y uuid-runtime easy-rsa
68 mkdir -p /etc/openvpn/easy-rsa
69 cd /etc/openvpn/easy-rsa
70 cp -r /usr/share/easy-rsa/* .
71 if [[ -e openssl-1.0.0.cnf && ! -e openssl.cnf ]]; then
72 # there's a debian bug about this.
73 ln -s openssl-1.0.0.cnf openssl.cnf
74 fi
75
76 keys_exist=true
77 keyfiles=(/etc/openvpn/easy-rsa/keys/{ca.crt,server.{crt,key},dh2048.pem,ta.key})
78 for f in ${keyfiles[@]}; do
79 if [[ ! -e $f ]]; then
80 keys_exist=false
81 break
82 fi
83 done
84
85 if ! $keys_exist; then
86 source vars # dun care about setting cert cn etc from the non-example values
87 ./clean-all # note: removes and creates /etc/openvpn/easy-rsa/keys
88 # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
89 openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key
90 # accept default prompts
91 echo -e '\n\n\n\n\n\n\n\n' | ./build-ca
92
93 # This builds the server's key/cert. argument is the name of the file,
94 # but it also is the default common name of the cert.
95 # 'server' is the default name in our conf file for the name of the file
96 # and I've seen no reason to change it.
97 # Note, this is not idempotent.
98 { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | ./build-key-server server
99 ./build-dh
100 fi
101
102 server_dir=/etc/openvpn/server
103 mkdir -p $server_dir
104 chmod 700 $server_dir
105
106 cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz $server_dir
107 gzip -df $server_dir/server.conf.gz
108
109
110 cp ${keyfiles[@]} $server_dir
111 # for legacy systems
112 for f in ${keyfiles[@]}; do
113 ln -sf server/${f##*/} /etc/openvpn
114 done
115
116 cat >>$server_dir/server.conf <<'EOF'
117
118 # I cat an extra blank line to start because the example config does
119 # not have a final newline. ....
120
121 # not in example config, but openvpn outputs a warning about insecure
122 # cipher without a setting like this (the default i can understand due
123 # to compatibility issues, but not changing the example config... not
124 # cool).
125 # requires the same setting on the client side.
126 cipher AES-256-CBC
127 # just sets up the ability to have client specific configs
128 client-config-dir /etc/openvpn/client-config
129
130 # duplicate in newer sample configs
131 tls-auth ta.key 0 # This file is secret
132
133 # depending on sample config, this may not be there, which means i can't
134 # talk to 10.8.0.1, there might be some other way, but stretch's
135 # sample config says:
136 # Should be subnet (addressing via IP)
137 # unless Windows clients v2.0.9 and lower have to
138 # be supported (then net30, i.e. a /30 per client)
139 # Defaults to net30 (not recommended)
140 topology subnet
141 EOF
142
143
144 # dh improve security,
145 # remove comp-lzo to increase perf
146 sed -i --follow-symlinks -f - $server_dir/server.conf <<'EOF'
147 s/^dh dh1024.pem/dh dh2048.pem/
148 /^comp-lzo.*/d
149 EOF
150
151
152 mkdir -p /etc/openvpn/client-config
153
154
155 if $dns; then
156 # Be the dns server for clients
157 cat >>$server_dir/server.conf <<'EOF'
158 push "dhcp-option DNS 10.8.0.1"
159 EOF
160 fi
161
162 if $route; then
163 cat >>$server_dir/server.conf <<'EOF'
164 # Be the default gateway for clients.
165 push "redirect-gateway def1"
166 EOF
167 echo "1" > /proc/sys/net/ipv4/ip_forward
168 sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc/sysctl.conf
169 cat >>/etc/sysctl.conf <<'EOF'
170 net.ipv4.ip_forward=1
171 EOF
172
173
174 gw=$(ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p')
175
176 cat >/etc/systemd/system/vpnnat.service <<EOF
177 [Unit]
178 Description=Turns on nat iptables setting
179
180 [Service]
181 Type=oneshot
182 RemainAfterExit=yes
183 ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
184 ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
185
186 [Install]
187 WantedBy=$vpn_service
188 EOF
189 systemctl daemon-reload # needed if the file was already there
190 # note, no need to start it, the vpn_service does that.
191 fi
192
193 if $start; then
194 systemctl enable $vpn_service
195 systemctl restart $vpn_service
196 fi