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.
18 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
20 [[ $EUID == 0 ]] ||
exec sudo
-E "$BASH_SOURCE" "$@"
24 usage: ${0##*/} [OPTIONS] [IPV6_ADDR/BITS]
26 -4 Prefix of range for ipv4, default 10.8.0
27 -6 IP6_NETWORK Do ip6 nat for this network. ipv6 will work without nat,
28 but you may want it in certain circumstances.
30 -i INTERFACE_NAME name of tun interface
31 -n NAME default = server. 2 servers on the same host need different names.
33 -r Do not push default route
34 -s Do not start openvpn
37 IPV6_ADDR/BITS Ipv6 address of the vpn interface.
39 Sets up a vpn server which pushes gateway route and dns server so all
40 traffic goes through the vpn. requires systemd, and might have some
41 debian specific paths.
43 For ipv6, we assume ipv6_addr routes to the server.
45 You can save all the keys by storing /etc/openvpn/easy-rsa-NAME/keys, and
46 the script will not generate them if it sees they exist already.
48 For future updates to this script, this is a good place to
50 https://github.com/angristan/openvpn-install/blob/master/openvpn-install.sh
52 Note: Uses GNU getopt options parsing style
62 temp
=$
(getopt
-l help 4:6:di
:n
:p
:rsh "$@") || usage
1
66 -4) ip4
=$2; shift 2 ;;
67 -6) ip6net
=$2; shift 2 ;;
68 -d) dns
=false
; shift ;;
69 -i) ifname
=$2; shift 2 ;;
70 -n) name
=$2; shift 2 ;;
71 -p) port
=$2; shift 2 ;;
72 -r) route
=false
; shift ;;
73 -s) start
=false
; shift ;;
76 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
80 read -r ip6 ip6route
<<<"$@"
82 source /a
/bin
/distro-functions
/src
/package-manager-abstractions
84 pi-nostart openvpn openssl easy-rsa uuid-runtime
86 if [[ -e /lib
/systemd
/system
/openvpn-server@.service
]]; then
87 vpn_service
=openvpn-server@
$name
89 vpn_service
=openvpn@
$name
91 rsadir
=/etc
/openvpn
/easy-rsa-
$name
94 cp -r /usr
/share
/easy-rsa
/* .
95 if [[ -e openssl-1.0
.0.cnf
&& ! -e openssl.cnf
]]; then
96 # there's a debian bug about this.
97 ln -s openssl-1.0
.0.cnf openssl.cnf
100 server_dir
=/etc
/openvpn
/server
102 chmod 700 $server_dir
103 conf
=$server_dir/$name.conf
107 ca_origin
=$rsadir/pki
/ca.crt
109 $rsadir/pki
/private
/$name.key
110 $rsadir/pki
/issued
/$name.crt
112 if [[ -e /etc
/openvpn
/easy-rsa
/build-ca
]]; then
114 ca_origin
=$rsadir/ca.crt
116 $rsadir/keys
/$name.key
117 $rsadir/keys
/$name.crt
122 for f
in ${keyfiles[@]}; do
123 if [[ ! -e $f ]]; then
129 f
=$server_dir/dh2048.pem
130 if [[ ! -e $f ]]; then
131 openssl dhparam
-out $f 2048
134 f
=$server_dir/ta-
$name.key
135 if [[ ! -e $f ]]; then
136 openvpn
--genkey --secret $server_dir/ta-
$name.key
140 if ! $keys_exist; then
141 # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
143 echo 'set_var EASYRSA_NS_SUPPORT "yes"' >vars
145 .
/easyrsa
--batch build-ca nopass
146 .
/easyrsa
--days=3650 build-server-full
$name nopass
148 # dun care about settning cert cn etc from the non-example values
150 # doesnt exist in buster
151 .
/clean-all
# note: removes and creates /etc/openvpn/easy-rsa/keys
152 # accept default prompts
153 echo -e '\n\n\n\n\n\n\n\n' | .
/build-ca
155 # This builds the server's key/cert. argument is the name of the file,
156 # but it also is the default common name of the cert.
157 # 'server' is the default name in our conf file for the name of the file
158 # and I've seen no reason to change it.
159 # Note, this is not idempotent.
160 { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | .
/build-key-server
$name
165 if [[ -e /usr
/share
/doc
/openvpn
/examples
/sample-config-files
/server.conf
]]; then
166 cat /usr
/share
/doc
/openvpn
/examples
/sample-config-files
/server.conf
>$conf
169 gzip -dc /usr
/share
/doc
/openvpn
/examples
/sample-config-files
/server.conf.gz
>$conf
172 cafile
=$server_dir/ca-
$name.crt
173 cp $ca_origin $cafile
174 cp ${keyfiles[@]} $server_dir
176 for f
in ${keyfiles[@]} $cafile; do
177 ln -sf server
/${f##*/} /etc
/openvpn
182 # I cat an extra blank line to start because the example config does
183 # not have a final newline. ....
185 # not in example config, but openvpn outputs a warning about insecure
186 # cipher without a setting like this (the default i can understand due
187 # to compatibility issues, but not changing the example config... not
189 # requires the same setting on the client side.
191 # just sets up the ability to have client specific configs
192 client-config-dir /etc/openvpn/client-config
194 # duplicate in newer sample configs
195 tls-auth ta-$name.key 0 # This file is secret
197 # depending on sample config, this may not be there, which means i can't
198 # talk to $ip4.1, there might be some other way, but stretch's
199 # sample config says:
200 # Should be subnet (addressing via IP)
201 # unless Windows clients v2.0.9 and lower have to
202 # be supported (then net30, i.e. a /30 per client)
203 # Defaults to net30 (not recommended)
206 status /var/log/openvpn/openvpn-status-$name.log
207 ifconfig-pool-persist /var/log/openvpn/ipp-$name.txt
211 client-config-dir /etc/openvpn/client-config-$name
212 server $ip4.0 255.255.255.0
214 mkdir
-p /etc
/openvpn
/client-config-
$name
216 # dh improve security,
217 # remove comp-lzo to increase perf
218 sed -i --follow-symlinks -f - $conf <<'EOF'
219 s/^dh dh1024.pem/dh dh2048.pem/
225 # Be the dns server for clients
227 push "dhcp-option DNS $ip4.1"
231 if [[ $ifname ]]; then
239 push tun-ipv6 # legacy option that flidas needs, has no harm.
240 # the ::1 is not used, i just put a short valid address there
241 ifconfig-ipv6 $ip6 ::1
244 sed -i --follow-symlinks '/^ *net.ipv6.conf.all.forwarding=.*/d' /etc
/sysctl.conf
245 cat >>/etc
/sysctl.conf
<<'EOF'
246 net.ipv6.conf.all.forwarding=1
254 # Be the default gateway for clients.
255 push "redirect-gateway def1"
259 push "route-ipv6 2000::/3"
270 sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc
/sysctl.conf
271 cat >>/etc
/sysctl.conf
<<'EOF'
272 net.ipv4.ip_forward=1
274 sysctl
-p /etc
/sysctl.conf
276 gw
=$
(ip route |
sed -rn 's/^default via .* dev (\S+).*/\1/p' |
head -n1)
278 d
=/etc
/systemd
/system
/$vpn_service.service.d
283 ExecStartPre=/sbin/iptables -t nat -A POSTROUTING -s $ip4.0/24 -o $gw -j MASQUERADE
284 ExecStopPost=/sbin/iptables -t nat -D POSTROUTING -s $ip4.0/24 -o $gw -j MASQUERADE
286 if [[ $ip6net ]]; then
288 ExecStartPre=/sbin/ip6tables -t nat -A POSTROUTING -s $ip6net -o $gw -j MASQUERADE
289 ExecStopPost=/sbin/ip6tables -t nat -D POSTROUTING -s $ip6net -o $gw -j MASQUERADE
291 systemctl daemon-reload
# needed if the file was already there
294 systemctl
enable $vpn_service
295 systemctl restart
$vpn_service