#!/bin/bash -x # Copyright (C) 2016 Ian Kelling # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" usage() { cat <<'EOF' usage: ${0##*/} [-d|-h|--help] [IPV6_ADDR/BITS IPV6_DEFAULT_ROUTE] -r Do not push default route -d Do not push dns -s Do not start openvpn -h --help print help Sets up a vpn server which pushes gateway route and dns server so all traffic goes through the vpn. requires systemd, and might have some debian specific paths. For ipv6, we assume ipv6_addr routes to the server. You can save all the keys by storing /etc/openvpn/easy-rsa/keys, and the script will not generate them if it sees they exist already. Note: Uses GNU getopt options parsing style EOF exit $1 } dns=true route=true start=true temp=$(getopt -l help drsh "$@") || usage 1 eval set -- "$temp" while true; do case $1 in -d) dns=false; shift ;; -r) route=false; shift ;; -s) start=false; shift ;; -h|--help) usage ;; --) shift; break ;; *) echo "$0: Internal error! unexpected args: $*" ; exit 1 ;; esac done read -r ip6 ip6route <<<"$@" apt-get update # suggests get's us openssl. policy-rc.d is to prevent install from starting services f=/usr/sbin/policy-rc.d; dd of=$f <>$server_dir/server.conf <<'EOF' # I cat an extra blank line to start because the example config does # not have a final newline. .... # not in example config, but openvpn outputs a warning about insecure # cipher without a setting like this (the default i can understand due # to compatibility issues, but not changing the example config... not # cool). # requires the same setting on the client side. cipher AES-256-CBC # just sets up the ability to have client specific configs client-config-dir /etc/openvpn/client-config # duplicate in newer sample configs tls-auth ta.key 0 # This file is secret # depending on sample config, this may not be there, which means i can't # talk to 10.8.0.1, there might be some other way, but stretch's # sample config says: # Should be subnet (addressing via IP) # unless Windows clients v2.0.9 and lower have to # be supported (then net30, i.e. a /30 per client) # Defaults to net30 (not recommended) topology subnet EOF # dh improve security, # remove comp-lzo to increase perf sed -i --follow-symlinks -f - $server_dir/server.conf <<'EOF' s/^dh dh1024.pem/dh dh2048.pem/ /^comp-lzo.*/d EOF mkdir -p /etc/openvpn/client-config if $dns; then # Be the dns server for clients cat >>$server_dir/server.conf <<'EOF' push "dhcp-option DNS 10.8.0.1" EOF fi if $ip6; then cat >>$server_dir/server.conf <>$server_dir/server.conf <<'EOF' # Be the default gateway for clients. push "redirect-gateway def1" EOF if $ip6; then cat >>$server_dir/server.conf <<'EOF' push "route-ipv6 2000::/3" EOF fi fi sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc/sysctl.conf sed -i --follow-symlinks '/^ *net.ipv6.conf.all.forwarding=.*/d' /etc/sysctl.conf cat >>/etc/sysctl.conf <<'EOF' net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 EOF sysctl -p /etc/sysctl.conf gw=$(ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p') cat >/etc/systemd/system/vpnnat.service <