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 -n NAME default = server. 2 servers on the same host need different names.
32 -r Do not push default route
33 -s Do not start openvpn
36 Sets up a vpn server which pushes gateway route and dns server so all
37 traffic goes through the vpn. requires systemd, and might have some
38 debian specific paths.
40 For ipv6, we assume ipv6_addr routes to the server.
42 You can save all the keys by storing /etc/openvpn/easy-rsa-NAME/keys, and
43 the script will not generate them if it sees they exist already.
45 For future updates to this script, this is a good place to
47 https://github.com/angristan/openvpn-install/blob/master/openvpn-install.sh
49 Note: Uses GNU getopt options parsing style
59 temp
=$
(getopt
-l help 4:6:dn
:p
:rsh "$@") || usage
1
63 -4) ip4
=$2; shift 2 ;;
64 -6) ip6net
=$2; shift 2 ;;
65 -d) dns
=false
; shift ;;
66 -n) name
=$2; shift 2 ;;
67 -p) port
=$2; shift 2 ;;
68 -r) route
=false
; shift ;;
69 -s) start
=false
; shift ;;
72 *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;;
76 read -r ip6 ip6route
<<<"$@"
78 source /a
/bin
/distro-functions
/src
/package-manager-abstractions
80 pi-nostart openvpn openssl easy-rsa uuid-runtime
82 if [[ -e /lib
/systemd
/system
/openvpn-server@.service
]]; then
83 vpn_service
=openvpn-server@
$name
85 vpn_service
=openvpn@
$name
87 rsadir
=/etc
/openvpn
/easy-rsa-
$name
90 cp -r /usr
/share
/easy-rsa
/* .
91 if [[ -e openssl-1.0
.0.cnf
&& ! -e openssl.cnf
]]; then
92 # there's a debian bug about this.
93 ln -s openssl-1.0
.0.cnf openssl.cnf
96 server_dir
=/etc
/openvpn
/server
99 conf
=$server_dir/$name.conf
103 ca_origin
=$rsadir/pki
/ca.crt
105 $rsadir/pki
/private
/$name.key
106 $rsadir/pki
/issued
/$name.crt
108 if [[ -e /etc
/openvpn
/easy-rsa
/build-ca
]]; then
110 ca_origin
=$rsadir/ca.crt
112 $rsadir/keys
/$name.key
113 $rsadir/keys
/$name.crt
118 for f
in ${keyfiles[@]}; do
119 if [[ ! -e $f ]]; then
125 f
=$server_dir/dh2048.pem
126 if [[ ! -e $f ]]; then
127 openssl dhparam
-out $f 2048
130 f
=$server_dir/ta-
$name.key
131 if [[ ! -e $f ]]; then
132 openvpn
--genkey --secret $server_dir/ta-
$name.key
136 if ! $keys_exist; then
137 # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
139 echo 'set_var EASYRSA_NS_SUPPORT "yes"' >vars
141 .
/easyrsa
--batch build-ca nopass
142 .
/easyrsa build-server-full
$name nopass
144 # dun care about settning cert cn etc from the non-example values
146 # doesnt exist in buster
147 .
/clean-all
# note: removes and creates /etc/openvpn/easy-rsa/keys
148 # accept default prompts
149 echo -e '\n\n\n\n\n\n\n\n' | .
/build-ca
151 # This builds the server's key/cert. argument is the name of the file,
152 # but it also is the default common name of the cert.
153 # 'server' is the default name in our conf file for the name of the file
154 # and I've seen no reason to change it.
155 # Note, this is not idempotent.
156 { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | .
/build-key-server
$name
162 gzip -dc /usr
/share
/doc
/openvpn
/examples
/sample-config-files
/server.conf.gz
>$conf
164 cafile
=$server_dir/ca-
$name.crt
165 cp $ca_origin $cafile
166 cp ${keyfiles[@]} $server_dir
168 for f
in ${keyfiles[@]} $cafile; do
169 ln -sf server
/${f##*/} /etc
/openvpn
174 # I cat an extra blank line to start because the example config does
175 # not have a final newline. ....
177 # not in example config, but openvpn outputs a warning about insecure
178 # cipher without a setting like this (the default i can understand due
179 # to compatibility issues, but not changing the example config... not
181 # requires the same setting on the client side.
183 # just sets up the ability to have client specific configs
184 client-config-dir /etc/openvpn/client-config
186 # duplicate in newer sample configs
187 tls-auth ta-$name.key 0 # This file is secret
189 # depending on sample config, this may not be there, which means i can't
190 # talk to $ip4.1, there might be some other way, but stretch's
191 # sample config says:
192 # Should be subnet (addressing via IP)
193 # unless Windows clients v2.0.9 and lower have to
194 # be supported (then net30, i.e. a /30 per client)
195 # Defaults to net30 (not recommended)
198 status /var/log/openvpn/openvpn-status-$name.log
199 ifconfig-pool-persist /var/log/openvpn/ipp-$name.txt
203 client-config-dir /etc/openvpn/client-config-$name
204 server $ip4.0 255.255.255.0
206 mkdir
-p /etc
/openvpn
/client-config-
$name
208 # dh improve security,
209 # remove comp-lzo to increase perf
210 sed -i --follow-symlinks -f - $conf <<'EOF'
211 s/^dh dh1024.pem/dh dh2048.pem/
217 # Be the dns server for clients
219 push "dhcp-option DNS $ip4.1"
225 push tun-ipv6 # legacy option that flidas needs, has no harm.
226 # the ::1 is not used, i just put a short valid address there
227 ifconfig-ipv6 $ip6 ::1
230 sed -i --follow-symlinks '/^ *net.ipv6.conf.all.forwarding=.*/d' /etc
/sysctl.conf
231 cat >>/etc
/sysctl.conf
<<'EOF'
232 net.ipv6.conf.all.forwarding=1
240 # Be the default gateway for clients.
241 push "redirect-gateway def1"
245 push "route-ipv6 2000::/3"
256 sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc
/sysctl.conf
257 cat >>/etc
/sysctl.conf
<<'EOF'
258 net.ipv4.ip_forward=1
260 sysctl
-p /etc
/sysctl.conf
262 gw
=$
(ip route |
sed -rn 's/^default via .* dev (\S+).*/\1/p' |
head -n1)
264 d
=/etc
/systemd
/system
/$vpn_service.service.d
269 ExecStartPre=/sbin/iptables -t nat -A POSTROUTING -s $ip4.0/24 -o $gw -j MASQUERADE
270 ExecStopPost=/sbin/iptables -t nat -D POSTROUTING -s $ip4.0/24 -o $gw -j MASQUERADE
272 if [[ $ip6net ]]; then
274 ExecStartPre=/sbin/ip6tables -t nat -A POSTROUTING -s $ip6net -o $gw -j MASQUERADE
275 ExecStopPost=/sbin/ip6tables -t nat -D POSTROUTING -s $ip6net -o $gw -j MASQUERADE
277 systemctl daemon-reload
# needed if the file was already there
280 systemctl
enable $vpn_service
281 systemctl restart
$vpn_service