mostly avoid momentary disconnections
[vpn-setup] / vpn-server-setup
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
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 dns=true
23 route=true
24 case $1 in
25 -r) route=false ;;
26 -d) dns=false ;;
27 -h|--help|*)
28 cat <<'EOF'
29 usage: ${0##*/} [-d|-h|--help]
30
31 -r Do not push default route
32 -d Do not push dns
33 -h --help print help
34
35 Sets up a vpn server which pushes gateway route and dns server
36 so all traffic goes through the vpn. requires systemd,
37 and might have some debian specific paths.
38 EOF
39 exit
40 ;;
41 esac
42
43 apt-get update
44 # suggests get's us openssl & easy rsa
45 apt-get install --install-suggests -y openvpn
46 apt-get install -y uuid-runtime
47 mkdir -p /etc/openvpn/easy-rsa/keys
48 cd /etc/openvpn/easy-rsa
49 cp -r /usr/share/easy-rsa/* .
50 source vars # dun care about setting cert cn etc from the non-example values
51 ./clean-all
52 # accept default prompts
53 echo -e '\n\n\n\n\n\n\n\n' | ./build-ca
54
55 # This builds the server's key/cert. argument is the name of the file,
56 # but it also is the default common name of the cert.
57 # 'server' is the default name in our conf file for the name of the file
58 # and I've seen no reason to change it.
59 # Note, this is not idempotent.
60 { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | ./build-key-server server
61 ./build-dh
62 cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
63 cp /etc/openvpn/easy-rsa/keys/{ca.crt,server.{crt,key},dh2048.pem} /etc/openvpn
64 gzip -df /etc/openvpn/server.conf.gz
65 # dh improve security,
66 # remove comp-lzo to increase perf
67 sed -i --follow-symlinks -f - /etc/openvpn/server.conf <<'EOF'
68 s/^dh dh1024.pem/dh dh2048.pem/
69 /^comp-lzo.*/d
70 EOF
71
72
73 cat >>/etc/openvpn/server.conf <<'EOF'
74 # not in example config, but openvpn outputs a warning about insecure
75 # cipher without a setting like this (the default i can understand due
76 # to compatibility issues, but not changing the example config... not
77 # cool). exact cipher taken from config of vpn provider I trust. This
78 # requires the same setting on the client side.
79 cipher aes-256-cbc
80 # just sets up the ability to have client specific configs
81 client-config-dir /etc/openvpn/client-config
82 # 30 days. default is 3600, 1 hour. we momentarily disconnect
83 # after this time, and get a new tls key. The idea is that
84 # if someone is working very hard to break our encryption,
85 # they have less time to do it, and less time in the past
86 # for it to be broken. online sources say that there is no
87 # good objective idea about what a good value is here, since
88 # we don't expect our encryption to be breakable, but 1 hour
89 # seems very conservative. Since I want to support hosting
90 # a server over the tunnel, having the server break up to once
91 # an hour is very tough. I've seen a vpn service that seems
92 # very on top of things set this to 5 days.
93 reneg-sec 2592000
94 EOF
95 mkdir -p /etc/openvpn/client-config
96
97 if $route; then
98 cat >>/etc/openvpn/server.conf <<'EOF'
99 # Be the default gateway for clients.
100 push "redirect-gateway def1"
101 EOF
102 fi
103
104 if $dns; then
105 # Be the dns server for clients
106 cat >>/etc/openvpn/server.conf <<'EOF'
107 push "dhcp-option DNS 10.8.0.1"
108 EOF
109 fi
110
111 echo "1" > /proc/sys/net/ipv4/ip_forward
112 sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc/sysctl.conf
113 cat >>/etc/sysctl.conf <<'EOF'
114 net.ipv4.ip_forward=1
115 EOF
116
117
118 gw=$(ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p')
119
120 cat >/etc/systemd/system/vpnnat.service <<EOF
121 [Unit]
122 Description=Turns on nat iptables setting
123
124 [Service]
125 Type=oneshot
126 RemainAfterExit=yes
127 ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
128 ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
129
130 [Install]
131 WantedBy=openvpn.service
132 EOF
133 systemctl daemon-reload # needed if the file was already there
134 systemctl enable vpnnat.service
135 systemctl start vpnnat.service
136
137 systemctl restart openvpn@server