Browse Source

add optional script to route local ipv6 over tun interface

HgO 5 months ago
parent
commit
eb0d438718

+ 4 - 0
conf/optional-scripts/route-down.d/50-vpnclient-unset-ipv6-send-over-tun

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+ip -6 route flush table send_over_tun
+rm -f /etc/iproute2/rt_tables.d/vpnclient_ynh.conf

+ 31 - 0
conf/optional-scripts/route-up.d/50-vpnclient-set-ipv6-send-over-tun

@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# cf https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/#environmental-variables
+# to have a list of variables provided by OpenVPN, i.e:
+# - dev
+# - net_gateway_ipv6
+# - ifconfig_ipv6_local
+gateway_interface=${dev}
+ip6_gw=${net_gateway_ipv6}
+
+if [[ -n "${net_gateway_ipv6}" ]]; then
+  echo "[INFO] Native IPv6 detected"
+  echo "[INFO] Autodetected native IPv6 gateway: ${ip6_gw}"
+
+  ip6_addr=$(yunohost app setting "vpnclient" "ip6_addr")
+  if [[ -z "${ip6_addr}" ]] || [[ "${ip6_addr}" == none ]]; then
+    if [[ -z ${ifconfig_ipv6_local} ]]; then
+      echo "[FAIL] Cannot find IPv6 address"
+      exit 1
+    fi
+    ip6_addr="${ifconfig_ipv6_local}"
+  fi
+
+  echo "[INFO] Found IPv6 address: ${ip6_addr}"
+
+  echo "1 send_over_tun" > /etc/iproute2/rt_tables.d/vpnclient_ynh.conf
+  ip -6 route flush table send_over_tun || true
+  ip -6 route add default via "${ip6_gw}" dev "${gateway_interface}" table send_over_tun proto static
+  ip -6 rule flush lookup send_over_tun
+  ip -6 rule add from "${ip6_addr}/64" pref 1 table send_over_tun
+fi

+ 9 - 7
conf/scripts/route-up.d/30-vpnclient-set-server-ipv6-route

@@ -26,10 +26,12 @@ wired_device=$(ip route | awk '/default via/ { print $5; }')
 # to have a list of variables provided by OpenVPN, i.e:
 # - ifconfig_ipv6_remote
 # - net_gateway_ipv6
+server_ip6=${ifconfig_ipv6_remote}
+ip6_gw=${net_gateway_ipv6}
 
 echo "[INFO] Autodetected internet interface: ${wired_device}"
-if [[ -n "${ifconfig_ipv6_remote}" ]]; then
-  echo "[INFO] Autodetected IPv6 address for the VPN server: ${ifconfig_ipv6_remote}"
+if [[ -n "${server_ip6}" ]]; then
+  echo "[INFO] Autodetected IPv6 address for the VPN server: ${server_ip6}"
 else
   echo "[INFO] No IPv6 address for the VPN server detected"
   echo "[INFO] No IPv6 route set"
@@ -37,15 +39,15 @@ else
 fi
 
 # Set the new server ipv6 route
-if [[ -n "${net_gateway_ipv6}" ]]; then
-  if ! is_serverip6route_set "${ifconfig_ipv6_remote}"; then
-    set_serverip6route "${ifconfig_ipv6_remote}" "${net_gateway_ipv6}" "${wired_device}"
+if [[ -n "${ip6_gw}" ]]; then
+  if ! is_serverip6route_set "${server_ip6}"; then
+    set_serverip6route "${server_ip6}" "${ip6_gw}" "${wired_device}"
   fi
 
   echo "[INFO] Native IPv6 detected"
-  echo "[INFO] Autodetected native IPv6 gateway: ${net_gateway_ipv6}"
+  echo "[INFO] Autodetected native IPv6 gateway: ${ip6_gw}"
 
-  if is_serverip6route_set "${ifconfig_ipv6_remote}"; then
+  if is_serverip6route_set "${server_ip6}"; then
     echo "[ OK ] IPv6 server route correctly set"
   else
     echo "[FAIL] No IPv6 server route set" >&2

+ 6 - 0
config_panel.toml

@@ -130,3 +130,9 @@ name = "DNS & IPv6"
         help = "If no IPv6 address is pushed directly by your VPN provider, you can indicate a specific IP to use here."
         pattern.regexp = "^[0-9a-fA-F:]+$"
         pattern.error = "Please provide a valid IPv6"
+
+        [advanced.ipv6.ip6_send_over_tun_enabled]
+        ask = "IPv6 local routing over tun"
+        type = "boolean"
+        help = "If enabled, local IPv6 traffic will be routed through internet. You should enable this if you can't reach your server in IPv6 from your local network."
+

+ 10 - 7
scripts/_common.sh

@@ -56,16 +56,18 @@ function read_cube() {
   local config_file="$1"
   local key="$2"
   local tmp_dir=$(dirname "$config_file")
+  local default_value="$3"
 
   setting_value="$(jq --raw-output ".$key" "$config_file")"
-  if [[ "$setting_value" == "null" ]]
-  then
-    setting_value=''
+  if [[ "$setting_value" == "null" ]]; then
+    setting_value="$default_value"
+  elif [[ "$setting_value" == "true" ]]; then
+    setting_value=1
+  elif [[ "$setting_value" == "false" ]]; then
+    setting_value=0
   # Save file in tmp dir
-  elif [[ "$key" == "crt_"* ]]
-  then
-    if [ -n "${setting_value}" ]
-    then
+  elif [[ "$key" == "crt_"* ]]; then
+    if [ -n "${setting_value}" ]; then
       echo "${setting_value}" | sed 's/|/\n/g' > "$tmp_dir/$key"
       setting_value="$tmp_dir/$key"
     fi
@@ -84,6 +86,7 @@ function convert_cube_file()
   server_proto="$(read_cube $config_file server_proto)"
   ip6_net="$(read_cube $config_file ip6_net)"
   ip6_addr="$(read_cube $config_file ip6_addr)"
+  ip6_send_over_tun_enabled="$(read_cube $config_file ip6_send_over_tun 0)"
   login_user="$(read_cube $config_file login_user)"
   login_passphrase="$(read_cube $config_file login_passphrase)"
   dns0="$(read_cube $config_file dns0)"

+ 10 - 1
scripts/config

@@ -103,7 +103,6 @@ get__login_passphrase() {
     fi
 }
 
-
 #=================================================
 # SPECIFIC VALIDATORS FOR TOML SHORT KEYS
 #=================================================
@@ -192,6 +191,16 @@ set__login_passphrase() {
     :
 }
 
+set__ip6_send_over_tun() {
+  if [[ ${ip6_send_over_tun_enabled} -eq 1 ]]; then
+    install -b -o root -g root -m 0755 ../conf/optional-scripts/route-up.d/50-vpnclient-set-ipv6-send-over-tun /etc/openvpn/scripts/route-up.d/
+    install -b -o root -g root -m 0755 ../conf/optional-scripts/route-down.d/50-vpnclient-unset-ipv6-send-over-tun /etc/openvpn/scripts/route-down.d/
+  else
+    ynh_secure_remove /etc/openvpn/scripts/route-up.d/50-vpnclient-set-ipv6-send-over-tun
+    ynh_secure_remove /etc/openvpn/scripts/route-down.d/50-vpnclient-unset-ipv6-send-over-tun
+  fi
+}
+
 #=================================================
 # OVERWRITING VALIDATE STEP
 #=================================================

+ 1 - 0
scripts/install

@@ -9,6 +9,7 @@ ynh_app_setting_set "$app" dns_method "yunohost"
 ynh_app_setting_set "$app" nameservers ""
 ynh_app_setting_set "$app" ip6_addr ""
 ynh_app_setting_set "$app" ip6_net ""
+ynh_app_setting_set "$app" ip6_send_over_tun_enabled 0
 
 #=================================================
 # DEPLOY FILES FROM PACKAGE

+ 3 - 0
scripts/upgrade

@@ -62,6 +62,9 @@ fi
 if [ -z "${ip6_net:-}" ]; then
     ynh_app_setting_set --app=$app --key=ip6_net --value=""
 fi
+if [ -z "${ip6_send_over_tun_enabled:-}" ]; then
+    ynh_app_setting_set --app=$app --key=ip6_send_over_tun_enabled --value=0
+fi
 
 #=================================================
 # UPGRADE FROM BUSTER TO BULLSEYE