support ipv6
[vpn-setup] / vpn-server-setup
index bbfd41b8687c9ab31f9c1176b07f32610b7823f7..a311ba8d0ae09bbc3f543921af3b06a07451fbbd 100755 (executable)
@@ -20,8 +20,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
 
 usage() {
 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
 
 usage() {
-    cat <<'EOF'
-usage: ${0##*/} [-d|-h|--help]
+  cat <<'EOF'
+usage: ${0##*/} [-d|-h|--help] [IPV6_ADDR/BITS IPV6_DEFAULT_ROUTE]
 
 -r  Do not push default route
 -d  Do not push dns
 
 -r  Do not push default route
 -d  Do not push dns
@@ -32,12 +32,18 @@ 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.
 
 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.
 
 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.
 
+For future updates to this script, this is a good place to
+take inspiration.
+https://github.com/angristan/openvpn-install/blob/master/openvpn-install.sh
+
 Note: Uses GNU getopt options parsing style
 EOF
 Note: Uses GNU getopt options parsing style
 EOF
-    exit $1
+  exit $1
 }
 
 dns=true
 }
 
 dns=true
@@ -46,47 +52,77 @@ start=true
 temp=$(getopt -l help drsh "$@") || usage 1
 eval set -- "$temp"
 while true; do
 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
+  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
 
 done
 
+read -r ip6 ip6route <<<"$@"
+
+
 apt-get update
 apt-get update
-# suggests get's us openssl
+# suggests get's us openssl. policy-rc.d is to prevent install from starting services
+f=/usr/sbin/policy-rc.d;
+dd of=$f <<EOF
+#!/bin/sh
+exit 101
+EOF
+chmod +x $f;
 apt-get install --install-suggests -y openvpn
 apt-get install --install-suggests -y openvpn
+rm $f
+
 if [[ -e /lib/systemd/system/openvpn-server@.service ]]; then
 if [[ -e /lib/systemd/system/openvpn-server@.service ]]; then
-    vpn_service=openvpn-server@server
+  vpn_service=openvpn-server@server
 else
 else
-    vpn_service=openvpn@server
+  vpn_service=openvpn@server
 fi
 apt-get install -y uuid-runtime easy-rsa
 mkdir -p /etc/openvpn/easy-rsa
 cd /etc/openvpn/easy-rsa
 cp -r /usr/share/easy-rsa/* .
 if [[ -e openssl-1.0.0.cnf && ! -e openssl.cnf ]]; then
 fi
 apt-get install -y uuid-runtime easy-rsa
 mkdir -p /etc/openvpn/easy-rsa
 cd /etc/openvpn/easy-rsa
 cp -r /usr/share/easy-rsa/* .
 if [[ -e openssl-1.0.0.cnf && ! -e openssl.cnf ]]; then
-    # there's a debian bug about this.
-    ln -s openssl-1.0.0.cnf openssl.cnf
+  # there's a debian bug about this.
+  ln -s openssl-1.0.0.cnf openssl.cnf
+fi
+
+server_dir=/etc/openvpn/server
+mkdir -p $server_dir
+chmod 700 $server_dir
+
+
+new=true
+keyfiles=(/etc/openvpn/easy-rsa/pki/{ca.crt,private/server.key,issued/server.crt})
+if [[ -e /etc/openvpn/easy-rsa/build-ca ]]; then
+  new=false
+  keyfiles=(/etc/openvpn/easy-rsa/keys/{ca.crt,server.{crt,key}})
 fi
 
 keys_exist=true
 fi
 
 keys_exist=true
-keyfiles=(/etc/openvpn/easy-rsa/keys/{ca.crt,server.{crt,key},dh2048.pem,ta.key})
 for f in ${keyfiles[@]}; do
 for f in ${keyfiles[@]}; do
-    if [[ ! -e $f ]]; then
-        keys_exist=false
-        break
-    fi
+  if [[ ! -e $f ]]; then
+    keys_exist=false
+    break
+  fi
 done
 
 if ! $keys_exist; then
 done
 
 if ! $keys_exist; then
-    source vars # dun care about setting cert cn etc from the non-example values
+  # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
+  openvpn --genkey --secret $server_dir/ta.key
+  if $new; then
+    ./easyrsa init-pki
+    ./easyrsa --batch build-ca nopass
+    ./easyrsa build-server-full server nopass
+    openssl dhparam -out $server_dir/dh2048.pem 2048
+  else
+    # dun care about settning cert cn etc from the non-example values
+    source vars
+    # doesnt exist in buster
     ./clean-all # note: removes and creates /etc/openvpn/easy-rsa/keys
     ./clean-all # note: removes and creates /etc/openvpn/easy-rsa/keys
-    # newer sample configs (post stretch) use ta.key. no harm making it for earlier oses
-    openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key
     # accept default prompts
     echo -e '\n\n\n\n\n\n\n\n' | ./build-ca
 
     # accept default prompts
     echo -e '\n\n\n\n\n\n\n\n' | ./build-ca
 
@@ -97,11 +133,9 @@ if ! $keys_exist; then
     # Note, this is not idempotent.
     { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | ./build-key-server server
     ./build-dh
     # Note, this is not idempotent.
     { echo -e '\n\n\n\n\n\n\n\n\n\n'; sleep 1; echo -e 'y\ny\n'; } | ./build-key-server server
     ./build-dh
+  fi
 fi
 
 fi
 
-server_dir=/etc/openvpn/server
-mkdir -p $server_dir
-chmod 700 $server_dir
 
 cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz $server_dir
 gzip -df $server_dir/server.conf.gz
 
 cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz $server_dir
 gzip -df $server_dir/server.conf.gz
@@ -110,7 +144,7 @@ gzip -df $server_dir/server.conf.gz
 cp ${keyfiles[@]} $server_dir
 # for legacy systems
 for f in ${keyfiles[@]}; do
 cp ${keyfiles[@]} $server_dir
 # for legacy systems
 for f in ${keyfiles[@]}; do
-    ln -sf server/${f##*/} /etc/openvpn
+  ln -sf server/${f##*/} /etc/openvpn
 done
 
 cat >>$server_dir/server.conf <<'EOF'
 done
 
 cat >>$server_dir/server.conf <<'EOF'
@@ -153,27 +187,43 @@ mkdir -p /etc/openvpn/client-config
 
 
 if $dns; then
 
 
 if $dns; then
-    # Be the dns server for clients
-    cat >>$server_dir/server.conf <<'EOF'
+  # Be the dns server for clients
+  cat >>$server_dir/server.conf <<'EOF'
 push "dhcp-option DNS 10.8.0.1"
 EOF
 fi
 
 push "dhcp-option DNS 10.8.0.1"
 EOF
 fi
 
+if $ip6; then
+  cat >>$server_dir/server.conf <<EOF
+push tun-ipv6 # legacy option that flidas needs, has no harm.
+ifconfig-ipv6 $ip6 $ip6_route
+EOF
+fi
+
+
 if $route; then
 if $route; then
-    cat >>$server_dir/server.conf <<'EOF'
+  cat >>$server_dir/server.conf <<'EOF'
 # Be the default gateway for clients.
 push "redirect-gateway def1"
 EOF
 # Be the default gateway for clients.
 push "redirect-gateway def1"
 EOF
-    echo "1" > /proc/sys/net/ipv4/ip_forward
-    sed -i --follow-symlinks '/^ *net\.ipv4\.ip_forward=.*/d' /etc/sysctl.conf
-    cat >>/etc/sysctl.conf <<'EOF'
-net.ipv4.ip_forward=1
+  if $ip6; then
+    cat >>$server_dir/server.conf <<'EOF'
+push "route-ipv6 2000::/3"
 EOF
 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')
+gw=$(ip route | sed -rn 's/^default via .* dev (\S+).*/\1/p')
 
 
-    cat >/etc/systemd/system/vpnnat.service <<EOF
+cat >/etc/systemd/system/vpnnat.service <<EOF
 [Unit]
 Description=Turns on nat iptables setting
 
 [Unit]
 Description=Turns on nat iptables setting
 
@@ -184,13 +234,13 @@ ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERA
 ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
 
 [Install]
 ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $gw -j MASQUERADE
 
 [Install]
-WantedBy=$vpn_service
+WantedBy=$vpn_service.service
 EOF
 EOF
-    systemctl daemon-reload # needed if the file was already there
-    # note, no need to start it, the vpn_service does that.
-fi
+systemctl daemon-reload # needed if the file was already there
+# note, no need to start it, the vpn_service does that.
+systemctl enable vpnnat
 
 if $start; then
 
 if $start; then
-    systemctl enable $vpn_service
-    systemctl restart $vpn_service
+  systemctl enable $vpn_service
+  systemctl restart $vpn_service
 fi
 fi