mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-03-15 09:24:34 +01:00
510 lines
20 KiB
Plaintext
Executable File
510 lines
20 KiB
Plaintext
Executable File
#!/usr/bin/with-contenv bashio
|
|
# shellcheck shell=bash
|
|
|
|
# --- Common Functions ---
|
|
|
|
declare -A config
|
|
config["MySelf"]="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
|
|
|
|
declare -a dns_servers_ipv4=()
|
|
declare -a dns_servers_ipv6=()
|
|
|
|
log_level="$(bashio::config "log_level")"
|
|
[[ "$log_level" == "debug" ]] && bashio::log.warning "--- Debug mode is active ---"
|
|
[[ "$log_level" == "debug" ]] && set -x
|
|
|
|
_parse_config() {
|
|
local -n config_ref="$1"
|
|
local config_file="$2"
|
|
local line
|
|
|
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
# Skip comments and empty lines
|
|
[[ "$line" =~ ^[#!] ]] && continue
|
|
# Extract key and value using regex (trim spaces)
|
|
#if [[ "$line" =~ ^[[:space:]]*([^ =]+)[[:space:]]*=[[:space:]]*(.*)[[:space:]]* ]]; then
|
|
if [[ "$line" =~ ^[[:space:]]*([^=[:space:]]+)[=[:space:]]+(.*)[[:space:]]* ]]; then
|
|
local key="${BASH_REMATCH[1]}"
|
|
local value="${BASH_REMATCH[2]}"
|
|
if [[ "$key" == "Address" ]]; then
|
|
if [[ -n "${config_ref["Address"]:-}" ]]; then
|
|
config_ref["Address"]+=",${value}"
|
|
else
|
|
config_ref["Address"]="${value}"
|
|
fi
|
|
else
|
|
config_ref["$key"]="$value"
|
|
fi
|
|
fi
|
|
done < "$config_file"
|
|
}
|
|
|
|
_parse_dns() {
|
|
local -a dns_conf=()
|
|
local -a dns_backup_ipv4=("8.8.8.8" "1.1.1.1")
|
|
local -a dns_backup_ipv6=("2001:4860:4860::8888" "2606:4700:4700::1111")
|
|
local dns_servers=$(bashio::config 'DNS_server')
|
|
|
|
mapfile -d ',' -t dns_conf < <(echo "${dns_servers}" | tr -d ' ' | tr -d '\n')
|
|
if [ ${config["IPv4Enabled"]} = "true" ]; then
|
|
for dns_ip in "${dns_conf[@]}"; do
|
|
local result=0
|
|
_check_host "${dns_ip}" || result=$?
|
|
if [ "${result}" -eq 1 ]; then
|
|
dns_servers_ipv4+=("${dns_ip}")
|
|
fi
|
|
done
|
|
if [ ${#dns_servers_ipv4[@]} -eq 0 ]; then
|
|
bashio::log.warning "No valid IPv4 DNS servers configured. Using addon defaults ${dns_backup_ipv4[@]}"
|
|
dns_servers_ipv4=("${dns_backup_ipv4[@]}")
|
|
fi
|
|
fi
|
|
if [ ${config["IPv6Enabled"]} = "true" ]; then
|
|
for dns_ip in "${dns_conf[@]}"; do
|
|
local result=0
|
|
_check_host "${dns_ip}" || result=$?
|
|
if [ "${result}" -eq 2 ]; then
|
|
dns_servers_ipv6+=("${dns_ip}")
|
|
fi
|
|
done
|
|
if [ ${#dns_servers_ipv6[@]} -eq 0 ]; then
|
|
bashio::log.warning "No valid IPv6 DNS servers configured. Using addon defaults ${dns_backup_ipv6[@]}"
|
|
dns_servers_ipv6=("${dns_backup_ipv6[@]}")
|
|
fi
|
|
fi
|
|
}
|
|
|
|
_cmd() {
|
|
cmd="$1"
|
|
bashio::log.debug "Executing command: ${cmd}"
|
|
eval "${cmd}"
|
|
}
|
|
|
|
_check_host() {
|
|
if ipcalc -c -4 "$1" >/dev/null 2>&1; then
|
|
return 1 # IPv4
|
|
elif ipcalc -c -6 "$1" >/dev/null 2>&1; then
|
|
return 2 # IPv6
|
|
elif getent ahosts "$1" >/dev/null 2>&1; then
|
|
return 3 # resolvable hostnamee
|
|
else
|
|
return 0 # neither IP nor resolvable hostname
|
|
fi
|
|
}
|
|
|
|
_resolvconf() {
|
|
local mode=$1
|
|
local resolv_conf="/etc/resolv.conf"
|
|
local resolv_backup="/etc/resolv.conf.bak"
|
|
|
|
if [ "${mode}" = "reset" ]; then
|
|
bashio::log.info "Resetting ${resolv_conf} to default DNS servers."
|
|
if bashio::fs.file_exists "${resolv_backup}"; then
|
|
cp "${resolv_backup}" "${resolv_conf}"
|
|
else
|
|
bashio::log.warning "No original resolv.conf backup found. Leaving as is."
|
|
fi
|
|
elif [ "${mode}" = "update" ]; then
|
|
bashio::log.info "Updating ${resolv_conf} with VPN DNS servers."
|
|
if ! bashio::fs.file_exists "${resolv_backup}"; then
|
|
bashio::log.debug "Creating backup of original resolv.conf at ${resolv_backup}"
|
|
cp "${resolv_conf}" "${resolv_backup}" 2>/dev/null || true
|
|
fi
|
|
bashio::log.debug "Updating ${resolv_conf} with DNS servers: ${dns_servers_ipv4[*]} ${dns_servers_ipv6[*]}"
|
|
{
|
|
echo "# Generated by vpn script"
|
|
local dns_ip
|
|
for dns_ip in ${dns_servers_ipv4[@]} ${dns_servers_ipv6[@]}; do
|
|
echo "nameserver ${dns_ip}"
|
|
done
|
|
} > "${resolv_conf}"
|
|
else
|
|
bashio::exit.nok "Invalid resolvconf mode specified. Use 'update' or 'reset'."
|
|
fi
|
|
}
|
|
|
|
_resolve_hostname() {
|
|
local hostname=$1
|
|
local -a ips=()
|
|
local -a ipv4_candidates=()
|
|
local -a ipv6_candidates=()
|
|
|
|
# Resolve hostname to IPv4
|
|
mapfile -t ipv4_candidates < <(getent ahostsv4 "${hostname}" | awk '{print $1}' | uniq)
|
|
|
|
# Resolve hostname to IPv6
|
|
mapfile -t ipv6_candidates < <(getent ahostsv6 "${hostname}" | awk '{print $1}' | uniq)
|
|
|
|
if [ ${#ipv4_candidates[@]} -gt 0 ]; then
|
|
bashio::log.debug "Resolved ${hostname} to ${ipv4_candidates[@]}"
|
|
ips+=("${ipv4_candidates[@]}")
|
|
fi
|
|
|
|
if [ ${#ipv6_candidates[@]} -gt 0 ]; then
|
|
bashio::log.debug "Resolved ${hostname} to ${ipv6_candidates[@]}"
|
|
ips+=("${ipv6_candidates[@]}")
|
|
fi
|
|
|
|
echo "${ips[@]}"
|
|
}
|
|
|
|
_routing_add() {
|
|
bashio::log.info "Adding routing rules for VPN interface ${config["Interface"]}..."
|
|
|
|
local local_ipv4=$(ip addr show ${config["Interface"]} | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)
|
|
local local_ipv6=$(ip addr show ${config["Interface"]} | grep 'inet6 ' | awk '{print $2}' | cut -d'/' -f1)
|
|
local ipv4
|
|
local ipv6
|
|
|
|
# add routing rules for local IPs
|
|
for ipv4 in ${local_ipv4}; do
|
|
config["IPv4Enabled"]="true"
|
|
_cmd "ip -4 route add default dev ${config["Interface"]} table ${config["Table"]}" || return 1
|
|
_cmd "ip -4 rule add priority 1 from ${ipv4} table ${config["Table"]}" || return 1
|
|
done
|
|
for ipv6 in ${local_ipv6}; do
|
|
config["IPv6Enabled"]="true"
|
|
_cmd "ip -6 rule add priority 1 from ${ipv6} table ${config["Table"]}" || return 1
|
|
done
|
|
if [ "${config["IPv6Enabled"]}" = "true" ]; then
|
|
_cmd "ip -6 route add default dev ${config["Interface"]} table ${config["Table"]}" || true
|
|
fi
|
|
|
|
# get valid DNS servers
|
|
_parse_dns
|
|
|
|
# add routing rules for DNS servers
|
|
for dns_ip in "${dns_servers_ipv4[@]}"; do
|
|
#_cmd "ip -4 route add ${dns_ip} dev ${config["Interface"]}" || return 1
|
|
_cmd "ip -4 rule add priority 1 to ${dns_ip} table ${config["Table"]}" || return 1
|
|
done
|
|
for dns_ip in "${dns_servers_ipv6[@]}"; do
|
|
#_cmd "ip -6 route add ${dns_ip} dev ${config["Interface"]}" || return 1
|
|
_cmd "ip -6 rule add priority 1 to ${dns_ip} table ${config["Table"]}" || return 1
|
|
done
|
|
|
|
# Update resolv.conf with VPN DNS servers
|
|
_resolvconf "update"
|
|
}
|
|
|
|
_routing_del() {
|
|
bashio::log.info "Removing routing rules for VPN interface ${config["Interface"]}..."
|
|
|
|
_resolvconf "reset"
|
|
while _cmd "ip -4 rule del priority 1 from all table ${config["Table"]} 2>/dev/null"; do :; done
|
|
while _cmd "ip -4 rule del priority 1 to all table ${config["Table"]} 2>/dev/null"; do :; done
|
|
while _cmd "ip -4 route del default dev ${config["Interface"]} table ${config["Table"]} 2>/dev/null"; do :; done
|
|
while _cmd "ip -6 rule del priority 1 from all table ${config["Table"]} 2>/dev/null"; do :; done
|
|
while _cmd "ip -6 rule del priority 1 to all table ${config["Table"]} 2>/dev/null"; do :; done
|
|
while _cmd "ip -6 route del default dev ${config["Interface"]} table ${config["Table"]} 2>/dev/null"; do :; done
|
|
}
|
|
|
|
# --- WireGuard Specific Logic ---
|
|
|
|
_wg_wait_handshake() {
|
|
local timeout="${1:-20}"
|
|
local iface="${config["Interface"]}"
|
|
local peer_pk="${config["PublicKey"]}"
|
|
local deadline ts
|
|
|
|
deadline=$(( $(date +%s) + timeout ))
|
|
|
|
while [ "$(date +%s)" -lt "${deadline}" ]; do
|
|
ping -I "${iface}" -c1 -W1 1.1.1.1 >/dev/null 2>&1 || true
|
|
|
|
ts="$(wg show "${iface}" latest-handshakes 2>/dev/null | awk -v pk="${peer_pk}" '$1==pk{print $2; exit}')"
|
|
if [ -n "${ts}" ] && [ "${ts}" -gt 0 ] 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
bashio::log.error "WireGuard handshake not established after ${timeout}s (latest-handshake=${ts:-0})."
|
|
wg show "${iface}" 2>&1 | while IFS= read -r l; do bashio::log.error "${l}"; done
|
|
return 1
|
|
}
|
|
|
|
_wireguard_up() {
|
|
bashio::log.warning "This script force Wireguard to ignore any routes and DNS settings."
|
|
bashio::log.warning "Default route will be inserted into custom routing table: ${config["Table"]}"
|
|
bashio::log.warning "This routing table will be used for traffic from the VPN interface and to the configured DNS servers."
|
|
bashio::log.warning "Qbittorrent bittorrent client shall be set to use the VPN interface ${config["Interface"]} only."
|
|
|
|
for key in "Interface" "ListenPort" "PrivateKey" "PublicKey" "EndpointIP" "EndpointPort" ; do
|
|
if [ ! -v config[$key] ] || [ -z "${config[$key]}" ]; then
|
|
bashio::log.error "Missing required WireGuard configuration parameter: ${key}"
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
_cmd "ip link add ${config["Interface"]} type wireguard" || return 1
|
|
local allowed_ips=""
|
|
local -a local_ips=()
|
|
mapfile -d ',' -t local_ips < <(echo "${config["Address"]}" | tr -d ' ')
|
|
for local_ip in ${local_ips[@]}; do
|
|
local result=0
|
|
_check_host "${local_ip}" || result=$?
|
|
if [ "${result}" -eq 1 ]; then
|
|
allowed_ips="${allowed_ips},0.0.0.0/0"
|
|
_cmd "ip addr add ${local_ip} dev ${config["Interface"]}" || return 1
|
|
elif [ "${result}" -eq 2 ]; then
|
|
allowed_ips="${allowed_ips},::/0"
|
|
_cmd "ip addr add ${local_ip} dev ${config["Interface"]}" || return 1
|
|
else
|
|
bashio::log.warning "Ignoring invalid local IP address: ${local_ip}"
|
|
fi
|
|
done
|
|
allowed_ips="${allowed_ips#,}"
|
|
if [ -z "${allowed_ips}" ]; then
|
|
bashio::log.error "No valid local IP addresses configured."
|
|
return 1
|
|
fi
|
|
|
|
_cmd "wg set ${config["Interface"]} listen-port ${config["ListenPort"]} private-key ${config["PrivateKey"]}" || return 1
|
|
local endpoint="${config["EndpointIP"]}:${config["EndpointPort"]}"
|
|
if [[ "${config["EndpointIP"]}" == *:* ]]; then
|
|
endpoint="[${config["EndpointIP"]}]:${config["EndpointPort"]}"
|
|
fi
|
|
local peer_cmd="wg set ${config["Interface"]} peer ${config["PublicKey"]} endpoint ${endpoint} allowed-ips ${allowed_ips}"
|
|
if [ -n "${config["PresharedKey"]:-}" ]; then
|
|
peer_cmd="${peer_cmd} preshared-key ${config["PresharedKey"]}"
|
|
fi
|
|
if [ -n "${config["PersistentKeepalive"]:-}" ]; then
|
|
peer_cmd="${peer_cmd} persistent-keepalive ${config["PersistentKeepalive"]}"
|
|
fi
|
|
_cmd "${peer_cmd}" || return 1
|
|
|
|
if [ -v config["MTU"] ] && [ -n "${config["MTU"]}" ]; then
|
|
_cmd "ip link set ${config["Interface"]} mtu ${config["MTU"]}" || return 1
|
|
fi
|
|
|
|
_cmd "ip link set ${config["Interface"]} up" || return 1
|
|
_routing_add
|
|
_wg_wait_handshake 10 || return 1
|
|
}
|
|
|
|
_wireguard_down() {
|
|
_routing_del
|
|
_cmd "ip link set ${config["Interface"]} down" 2>/dev/null || true
|
|
_cmd "ip link del ${config["Interface"]}" 2>/dev/null || true
|
|
}
|
|
|
|
wireguard() {
|
|
local mode=$1
|
|
local interface
|
|
local config_file
|
|
local WIREGUARD_STATE_DIR="/var/run/wireguard"
|
|
|
|
if ! bashio::fs.file_exists "${WIREGUARD_STATE_DIR}/interface"; then
|
|
bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
interface=$(cat "${WIREGUARD_STATE_DIR}/interface")
|
|
if [ -z "${interface}" ]; then
|
|
bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
if ! bashio::fs.file_exists "${WIREGUARD_STATE_DIR}/config"; then
|
|
bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
config_file=$(cat "${WIREGUARD_STATE_DIR}/config")
|
|
if [ -z "${config_file}" ]; then
|
|
bashio::exit.nok 'WireGuard runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
|
|
bashio::log.info "Using Wireguard configuration file: ${config_file}"
|
|
|
|
_parse_config config "${config_file}"
|
|
config["Interface"]="${interface}"
|
|
config["ConfigFile"]="${config_file}"
|
|
config["Table"]="${config["Table"]:-1000}"
|
|
config["ListenPort"]="${config["ListenPort"]:-51820}"
|
|
config["EndpointHost"]="${config["Endpoint"]%:*}"
|
|
config["EndpointPort"]="${config["Endpoint"]##*:}"
|
|
config["IPv4Enabled"]="false"
|
|
config["IPv6Enabled"]="false"
|
|
for key in "${!config[@]}"; do
|
|
bashio::log.debug "${key}: ${config[$key]}"
|
|
done
|
|
|
|
printf '%s\n' "${config["PrivateKey"]}" > "${WIREGUARD_STATE_DIR}/privatekey"
|
|
chmod 600 "${WIREGUARD_STATE_DIR}/privatekey" || true
|
|
config["PrivateKey"]="${WIREGUARD_STATE_DIR}/privatekey"
|
|
|
|
if [ -n "${config["PresharedKey"]:-}" ]; then
|
|
printf '%s\n' "${config["PresharedKey"]}" > "${WIREGUARD_STATE_DIR}/presharedkey"
|
|
chmod 600 "${WIREGUARD_STATE_DIR}/presharedkey" || true
|
|
config["PresharedKey"]="${WIREGUARD_STATE_DIR}/presharedkey"
|
|
fi
|
|
|
|
if [ "${mode}" = "up" ]; then
|
|
bashio::log.info "Starting WireGuard on interface ${config["Interface"]}..."
|
|
local result=0
|
|
_check_host "${config["EndpointHost"]}" || result=$?
|
|
if [ "${result}" -eq 0 ]; then
|
|
bashio::log.error "WireGuard endpoint ${config["EndpointHost"]} is neither a valid IP address nor a resolvable hostname."
|
|
bashio::exit.nok 'WireGuard start failed.'
|
|
elif [ "${result}" -eq 3 ]; then
|
|
local -a endpoint_ips=()
|
|
mapfile -d ' ' -t endpoint_ips < <(_resolve_hostname ${config["EndpointHost"]})
|
|
if [ ${#endpoint_ips[@]} -eq 0 ]; then
|
|
bashio::log.error "Failed to resolve WireGuard endpoint hostname: ${config["EndpointHost"]}"
|
|
bashio::exit.nok 'WireGuard start failed.'
|
|
fi
|
|
for endpoint_ip in "${endpoint_ips[@]}"; do
|
|
bashio::log.info "Resolved WireGuard endpoint hostname ${config["EndpointHost"]} to IP: ${endpoint_ip}"
|
|
config["EndpointIP"]="${endpoint_ip}"
|
|
if _wireguard_up; then
|
|
bashio::log.info "WireGuard interface ${config["Interface"]} is up."
|
|
bashio::exit.ok 'WireGuard started.'
|
|
fi
|
|
bashio::log.error 'WireGuard failed to establish connection.'
|
|
_wireguard_down
|
|
done
|
|
else
|
|
bashio::log.debug "WireGuard endpoint ${config["EndpointHost"]} is a valid IP address. Using as is."
|
|
config["EndpointIP"]="${config["EndpointHost"]}"
|
|
if _wireguard_up; then
|
|
bashio::log.info "WireGuard interface ${config["Interface"]} is up."
|
|
bashio::exit.ok 'WireGuard started.'
|
|
fi
|
|
bashio::log.error 'WireGuard failed to establish connection.'
|
|
_wireguard_down
|
|
fi
|
|
elif [ "${mode}" = "down" ]; then
|
|
bashio::log.info "Stopping WireGuard on interface ${config["Interface"]}..."
|
|
_wireguard_down
|
|
bashio::log.info "WireGuard on interface ${config["Interface"]} is down."
|
|
bashio::exit.ok 'WireGuard stopped.'
|
|
else
|
|
bashio::log.error "Invalid WireGuard mode specified. Use 'up' or 'down'."
|
|
bashio::exit.nok 'WireGuard start failed.'
|
|
fi
|
|
|
|
bashio::exit.nok 'WireGuard start failed.'
|
|
}
|
|
|
|
# --- OpenVPN Specific Logic ---
|
|
|
|
_openvpn_up() {
|
|
bashio::log.warning "This script force OpenvPN to ignore any routes and DNS settings pushed by the server."
|
|
bashio::log.warning "Default route will be inserted into custom routing table: ${config["Table"]}"
|
|
bashio::log.warning "This routing table will be used for traffic from the VPN interface and to the configured DNS servers."
|
|
bashio::log.warning "Qbittorrent bittorrent client shall be set to use the VPN interface ${config["Interface"]} only."
|
|
|
|
# Register this script as OpenVPN up/down handlers to manage routing
|
|
echo '#!/bin/bash' > ${config["PostUpScript"]}
|
|
echo "${config["MySelf"]} openvpn postup" >> ${config["PostUpScript"]}
|
|
chmod 755 ${config["PostUpScript"]}
|
|
echo '#!/bin/bash' > ${config["PostDownScript"]}
|
|
echo "${config["MySelf"]} openvpn postdown" >> ${config["PostDownScript"]}
|
|
chmod 755 ${config["PostDownScript"]}
|
|
|
|
# Define logging
|
|
log_path="/dev/null"
|
|
[[ "$log_level" == "debug" ]] && log_path="/proc/1/fd/1"
|
|
|
|
# Start OpenVPN in the background
|
|
_cmd "/usr/sbin/openvpn \
|
|
--config "${config["ConfigFile"]}" \
|
|
--client \
|
|
--daemon \
|
|
--log "$log_path" \
|
|
--script-security 2 \
|
|
--auth-user-pass "${OPENVPN_STATE_DIR}/credentials.conf" \
|
|
--auth-retry none \
|
|
--up ${config["PostUpScript"]} \
|
|
--down ${config["PostDownScript"]} \
|
|
--up-delay \
|
|
--up-restart \
|
|
--route-nopull \
|
|
--route-noexec" || return 1
|
|
|
|
#wait for slow OpenVPN interface to come up
|
|
for i in {1..10}; do
|
|
if ip link show "${config["Interface"]}" > /dev/null 2>&1 ; then
|
|
return 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
bashio::log.error "OpenVPN interface ${config["Interface"]} failed to come up."
|
|
return 1
|
|
}
|
|
|
|
_openvpn_down() {
|
|
# Terminate OpenVPN process
|
|
pkill -f "openvpn --config ${config["ConfigFile"]}" || true
|
|
_routing_del
|
|
}
|
|
|
|
openvpn() {
|
|
local mode=$1
|
|
local interface
|
|
local config_file
|
|
local OPENVPN_STATE_DIR="/var/run/openvpn"
|
|
|
|
if ! bashio::fs.file_exists "${OPENVPN_STATE_DIR}/interface"; then
|
|
bashio::exit.nok 'OpenVPN runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
interface=$(cat "${OPENVPN_STATE_DIR}/interface")
|
|
if [ -z "${interface}" ]; then
|
|
bashio::exit.nok 'OpenVPN runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
if ! bashio::fs.file_exists "${OPENVPN_STATE_DIR}/config"; then
|
|
bashio::exit.nok 'OpenVPN runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
config_file=$(cat "${OPENVPN_STATE_DIR}/config")
|
|
if [ -z "${config_file}" ]; then
|
|
bashio::exit.nok 'OpenVPN runtime configuration not prepared. Please restart the add-on.'
|
|
fi
|
|
|
|
bashio::log.warning "Using OpenVPN configuration file: ${config_file}"
|
|
|
|
_parse_config config "${config_file}"
|
|
config["Interface"]="${interface}"
|
|
config["ConfigFile"]="${config_file}"
|
|
config["Table"]="${config["Table"]:-1000}"
|
|
config["PostUpScript"]="${OPENVPN_STATE_DIR}/up.sh"
|
|
config["PostDownScript"]="${OPENVPN_STATE_DIR}/down.sh"
|
|
|
|
if [ "${mode}" = "up" ]; then
|
|
# register up and down scripts
|
|
bashio::log.info "Starting OpenVPN on interface ${config["Interface"]}..."
|
|
if _openvpn_up; then
|
|
bashio::log.info "OpenVPN interface ${config["Interface"]} is up."
|
|
bashio::exit.ok 'OpenVPN started.'
|
|
fi
|
|
bashio::log.error 'OpenVPN failed to establish connection.'
|
|
_openvpn_down
|
|
elif [ "${mode}" = "down" ]; then
|
|
bashio::log.info "Stopping OpenVPN on interface ${config["Interface"]}..."
|
|
_openvpn_down
|
|
bashio::log.info "OpenVPN on interface ${config["Interface"]} is down."
|
|
bashio::exit.ok 'OpenVPN stopped.'
|
|
elif [ "${mode}" = "postup" ]; then
|
|
_routing_add
|
|
bashio::exit.ok 'OpenVPN routes added.'
|
|
elif [ "${mode}" = "postdown" ]; then
|
|
_routing_del
|
|
bashio::exit.ok 'OpenVPN routes deleted.'
|
|
else
|
|
bashio::log.error "Invalid OpenVPN mode specified. Use 'up', 'down', 'postup', or 'postdown'."
|
|
bashio::exit.nok 'OpenVPN start failed.'
|
|
fi
|
|
|
|
bashio::exit.nok 'OpenVPN start failed.'
|
|
}
|
|
|
|
# --- Entry Point ---
|
|
|
|
if [ $# -ne 2 ]; then
|
|
bashio::log.error "Invalid number of arguments. Usage: vpn.sh <wireguard|openvpn> <up|down>"
|
|
bashio::exit.nok 'VPN start failed.'
|
|
fi
|
|
if [[ "$1" == "wireguard" ]]; then
|
|
wireguard "$2"
|
|
elif [[ "$1" == "openvpn" ]]; then
|
|
openvpn "$2"
|
|
else
|
|
bashio::log.error "Invalid VPN type specified. Use 'wireguard' or 'openvpn'."
|
|
bashio::exit.nok 'VPN start failed.'
|
|
fi
|