openvpn: introduce proto handler

openvpn needs a proto handler. Here it is.

Removed all of the up/down scripts from the init handler
and made those entirely optional (with some ucode examples).

The config options have been updated to reflect v 2.6/2.7,
with a 'd' flag to denote deprecated. Deprecated flags are
gated behind an 'allow_deprecated' config flag, which must
be on to use them. Some flags will cease to work in the next
version.

Users should not be using compression. Openvpn has enough
security holes and pitfalls already without using
compression.

Updated the example configs (left in place as legacy
documentation) and removed older cryptos which do not exist
in ovpn any longer.

A migration script is included -x. /etc/config/openvpn
entries become interface entries in /etc/config/network
with proto='openvpn'. The source config is retained.

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
https://github.com/openwrt/packages/pull/28533
This commit is contained in:
Paul Donald
2026-02-16 20:01:50 +01:00
committed by Hannu Nyman
parent 0814aba3b0
commit 2607b76154
21 changed files with 706 additions and 574 deletions

View File

@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=openvpn
PKG_VERSION:=2.6.14
PKG_RELEASE:=4
PKG_RELEASE:=5
PKG_SOURCE_URL:=\
https://build.openvpn.net/downloads/releases/ \
@@ -90,11 +90,6 @@ define Build/Configure
)
endef
define Package/openvpn-$(BUILD_VARIANT)/conffiles
/etc/config/openvpn
/etc/openvpn.user
endef
define Package/openvpn-$(BUILD_VARIANT)/install
$(INSTALL_DIR) \
$(1)/usr/sbin \
@@ -102,7 +97,9 @@ define Package/openvpn-$(BUILD_VARIANT)/install
$(1)/etc/init.d \
$(1)/etc/config \
$(1)/etc/openvpn \
$(1)/etc/uci-defaults \
$(1)/lib/functions \
$(1)/lib/netifd/proto \
$(1)/lib/upgrade/keep.d \
$(1)/usr/libexec \
$(1)/etc/hotplug.d/openvpn
@@ -112,34 +109,26 @@ define Package/openvpn-$(BUILD_VARIANT)/install
$(1)/usr/sbin/
$(INSTALL_BIN) \
files/openvpn.init \
$(1)/etc/init.d/openvpn
files/lib/netifd/proto/openvpn.sh \
$(1)/lib/netifd/proto/
$(INSTALL_BIN) \
files/usr/libexec/openvpn-hotplug \
$(1)/usr/libexec/openvpn-hotplug
$(INSTALL_DATA) \
files/lib/functions/openvpn.sh \
$(1)/lib/functions/openvpn.sh
$(INSTALL_DATA) \
files/etc/hotplug.d/openvpn/01-user \
$(1)/etc/hotplug.d/openvpn/01-user
$(INSTALL_DATA) \
files/etc/openvpn.user \
$(1)/etc/openvpn.user
files/etc/uci-defaults/60_openvpn_migrate.sh \
$(1)/etc/uci-defaults/
$(INSTALL_DATA) \
files/openvpn.options \
$(1)/usr/share/openvpn/openvpn.options
$(INSTALL_CONF) files/openvpn.config \
$(1)/etc/config/openvpn
$(INSTALL_BIN) \
files/up.uc files/down.uc files/route-pre-down.uc files/route-up.uc \
files/ipchange.uc \
files/client-connect.uc files/client-disconnect.uc files/client-crresponse.uc \
files/auth-user-pass-verify.uc files/tls-verify.uc \
$(1)/usr/share/openvpn/
$(INSTALL_DATA) \
files/openvpn.upgrade \
files/openvpn.sysupgrade \
$(1)/lib/upgrade/keep.d/openvpn
endef

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env ucode
// cmd method { via-env|via-file }
print('cmd ', ARGV, '\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* do something */
/*
exit(0); // client auth request accepted
exit(1); // reject client
exit(2); // deferred auth
*/

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env ucode
// cmd [args]
print('cmd ', ARGV, '\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* do something */
// If script returns a non-zero error status, it will cause the client to be disconnected.
exit(0);

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env ucode
import { readfile } from 'fs';
// cmd client_response_temp_file
print('cmd ', ARGV, '\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
const content = trim(readfile(ARGV[0]));
const reply = b64dec(content);
/* do something */
// write result to the `auth_control_file` filename stored in the environment.

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env ucode
// cmd [args]
print('cmd ', ARGV, '\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
/* do something */

37
net/openvpn/files/down.uc Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env ucode
// 0 == link_mtu => historic
// cmd tun_dev tun_mtu 0 ifconfig_local_ip ifconfig_remote_ip [init | restart]
// cmd tap_dev tap_mtu 0 ifconfig_local_ip ifconfig_netmask [init | restart]
print('tun_dev ', ARGV[0],' tun_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_rip "', ARGV[4], '" i/r "', ARGV[5], '"\n');
print('tap_dev ', ARGV[0],' tap_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_nm "', ARGV[4], '" i/r "', ARGV[5], '"\n');
/* e.g.
tun_dev asdf0 tun_mtu 1500 0 if_lip "" if_rip "" i/r "init"
*/
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* e.g.
{
"script_type": "down",
"dev_type": "tun",
"dev": "asdf0",
"tun_mtu": "1500",
"script_context": "init",
"verb": "6",
"daemon": "0",
"daemon_log_redirect": "0",
"daemon_start_time": "1770389648",
"daemon_pid": "6116",
"proto_1": "udp",
"local_port_1": "1194",
"remote_1": "192.0.2.10",
"remote_port_1": "1194"
}
*/

View File

@@ -1,27 +0,0 @@
#!/bin/sh
[ -e "/etc/openvpn.user" ] && {
env -i ACTION="$ACTION" INSTANCE="$INSTANCE" \
/bin/sh \
/etc/openvpn.user \
$*
}
# Wrap user defined scripts on up/down/route-up/route-pre-down/ipchange events
# Scriptp set with up/down/route-up/route-pre-down/ipchange in the openvpn config are also executed with the command=user_xxxx
case "$ACTION" in
up) command=$user_up ;;
down) command=$user_down ;;
route-up) command=$user_route_up ;;
route-pre-down) command=$user_route_pre_down ;;
ipchange) command=$user_ipchange ;;
*) command= ;;
esac
if [ -n "$command" ]; then
shift
exec /bin/sh -c "$command $*"
fi
exit 0

View File

@@ -1,11 +0,0 @@
#!/bin/sh
#
# This file is interpreted as shell script.
# Put your custom openvpn action here, they will
# be executed with each opevnp event.
#
# $ACTION
# <down> down action is generated after the TUN/TAP device is closed
# <up> up action is generated after the TUN/TAP device is opened
# $INSTANCE Name of the openvpn instance which went up or down

View File

@@ -0,0 +1,48 @@
#!/bin/sh
OPENVPN_PKG="openvpn"
NETWORK_PKG="network"
# Exit if no openvpn config exists
uci -q show "$OPENVPN_PKG" >/dev/null || exit 0
uci batch <<EOF
$(
# Find named openvpn sections
uci show "$OPENVPN_PKG" | \
sed -n "s/^$OPENVPN_PKG\.\\([^=]*\\)=openvpn$/\\1/p" | \
while read -r sec; do
iface="$sec"
# Skip if interface already exists
uci -q get $NETWORK_PKG.$iface >/dev/null && continue
# Create interface in network
echo "set $NETWORK_PKG.$iface=interface"
# Set the interface protocol to 'openvpn'
echo "set $NETWORK_PKG.$iface.proto='openvpn'"
# Copy options, skipping the section header
uci show "$OPENVPN_PKG.$sec" | \
while IFS='=' read -r key val; do
case "$key" in
# section declaration: openvpn.vpn0=openvpn
"$OPENVPN_PKG.$sec") continue ;;
"$OPENVPN_PKG.$sec.proto")
echo "set $NETWORK_PKG.$iface.ovpnproto=$val"
continue
;;
esac
opt="${key##*.}"
echo "set $NETWORK_PKG.$iface.$opt=$val"
done
done
echo "commit $NETWORK_PKG"
)
EOF
exit 0

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env ucode
// cmd ip address port number
print('cmd ', ARGV[0],' ip ', ARGV[1], ' address ', ARGV[2], ' port ', ARGV[3], ' number ', ARGV[4], '"\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179

View File

@@ -1,16 +0,0 @@
#!/bin/sh
get_openvpn_option() {
local config="$1"
local variable="$2"
local option="$3"
local value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+'"'([^']+)'"'[ \t]*$/\1/p' "$config" | tail -n1)"
[ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+"(([^"\\]|\\.)+)"[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')"
[ -n "$value" ] || value="$(sed -rne 's/^[ \t]*'"$option"'[ \t]+(([^ \t\\]|\\.)+)[ \t]*$/\1/p' "$config" | tail -n1 | sed -re 's/\\(.)/\1/g')"
[ -n "$value" ] || return 1
export -n "$variable=$value"
return 0
}

View File

@@ -0,0 +1,189 @@
#!/bin/sh
# OpenVPN netifd proto handler for OpenWrt
# Copyright (C) 2026
# shellcheck disable=SC1091,2046,2091,3043,3060
[ -x /usr/sbin/openvpn ] || exit 0
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. /usr/share/openvpn/openvpn.options # OPENVPN_* options
. ../netifd-proto.sh
. /usr/share/libubox/jshn.sh
init_proto "$@"
}
# Helper to DRY up repeated option handling in init/setup
option_builder() {
# option_builder <action:add|build> <LIST_VAR_NAME> <type>
local action="$1"; shift
local list_var="$1"; shift
local opt_type="$1"; shift
local f v
for f in $(eval echo \$"$list_var")
do
f=${f%%:*}
if [ "$action" = "add" ]; then
case "$opt_type" in
bool) proto_config_add_boolean "$f:bool" ;;
protobool) proto_config_add_boolean "$f:protobool" ;;
uinteger) proto_config_add_int "$f:uinteger" ;;
integer) proto_config_add_int "$f:integer" ;;
string) proto_config_add_string "$f:string" ;;
protostring) proto_config_add_string "$f:protostring" ;;
file) proto_config_add_string "$f:file" ;;
list) proto_config_add_array "$f:list" ;;
esac
elif [ "$action" = "build" ]; then
[ "${f#*:}" = "d" ] && [ "$allow_deprecated" = 0 ] && continue
case "$opt_type" in
bool)
json_get_var v "$f"
[ "$v" = 1 ] && append exec_params " --${f//_/-}"
;;
uinteger|integer|string)
json_get_var v "$f"
[ -n "$v" ] && append exec_params " --${f//_/-} $v"
;;
file)
json_get_var v "$f"
[ -f "$v" ] || continue
[ -n "$v" ] && append exec_params " --${f//_/-} $v"
;;
list)
json_get_values v "$f"
[ -n "${v}" ] && append exec_params "$(for d in $v; do echo " --${f//_/-} $d"; done)"
;;
esac
fi
done
}
# Not real config params used by openvpn - only by our proto handler
PROTO_BOOLS='
allow_deprecated
'
PROTO_STRINGS='
username
password
cert_password
'
proto_openvpn_init_config() {
available=1
no_device=1
lasterror=1
renew_handler=1
# There may be opvnvpn options which mean that a tap L2 device exists.
# TODO: Set no_device to depend on tap device
proto_add_dynamic_defaults
# Add proto config options - netifd compares these for changes between interface events
option_builder add PROTO_BOOLS protobool
option_builder add PROTO_STRINGS string
option_builder add OPENVPN_BOOLS bool
option_builder add OPENVPN_UINTS uinteger
option_builder add OPENVPN_INTS integer
option_builder add OPENVPN_PARAMS_STRING string
option_builder add OPENVPN_PARAMS_FILE file
option_builder add OPENVPN_LIST list
}
proto_openvpn_setup() {
local config="$1"
local allow_deprecated exec_params
allow_deprecated=0
exec_params=
json_get_var allow_deprecated allow_deprecated
# Build exec params from configured options we get from ubus values stored during init_config
option_builder build OPENVPN_BOOLS bool
option_builder build OPENVPN_UINTS uinteger
option_builder build OPENVPN_INTS integer
option_builder build OPENVPN_PARAMS_STRING string
option_builder build OPENVPN_PARAMS_FILE file
option_builder build OPENVPN_LIST list
proto_add_dynamic_defaults
json_get_var username username
json_get_var password password
json_get_var cert_password cert_password
json_get_var config_file config
mkdir -p /var/run
# combine into --askpass:
if [ -n "$cert_password" ]; then
cp_file="/var/run/openvpn.$config.pass"
umask 077
printf '%s\n' "${cert_password:-}" > "$cp_file"
umask 022
append exec_params " --askpass $cp_file"
elif [ -n "$askpass" ]; then
append exec_params " --askpass $askpass"
fi
# combine into --auth-user-pass:
if [ -n "$username" ] || [ -n "$password" ]; then
auth_file="/var/run/openvpn.$config.auth"
umask 077
printf '%s\n' "${username:-}" "${password:-}" > "$auth_file"
umask 022
append exec_params " --auth-user-pass $auth_file"
elif [ -n "$auth_user_pass" ]; then
auth_file="$auth_user_pass"
fi
# shellcheck disable=SC2154
cd_dir="${config_file%/*}"
[ "$cd_dir" = "$config_file" ] && cd_dir="/"
# Testing option
# ${tls_exit:+--tls-exit} \
json_get_var dev_type dev_type
# shellcheck disable=SC2086
proto_run_command "$config" openvpn \
$([ -z "$dev_type" ] && echo " --dev-type tun") \
--cd "$cd_dir" \
--status "/var/run/openvpn.$config.status" \
--syslog "openvpn_$config" \
--tmp-dir "/var/run" \
$exec_params
# last param wins; user provided status or syslog supersedes these.
}
proto_openvpn_renew() {
config="$1"
local sigusr1
sigusr1="$(kill -l SIGUSR1)"
[ -n "$sigusr1" ] && proto_kill_command "$config" "$sigusr1"
}
proto_openvpn_teardown() {
local iface="$1"
rm -f \
"/var/run/openvpn.$iface.pass" \
"/var/run/openvpn.$iface.auth" \
"/var/run/openvpn.$iface.status"
proto_kill_command "$iface"
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol openvpn
}

View File

@@ -1,20 +1,22 @@
package openvpn
package network
#################################################
# Sample to include a custom config file. #
#################################################
config openvpn custom_config
config interface custom_config
# Set to 1 to enable this instance:
option enabled 0
option proto 'openvpn'
# Set to 1 to disable this interface:
option disabled 0
# Credentials to login
#option username 'login'
#option password 'password'
# option username 'login'
# option password 'password'
# Password for client certificate
#option cert_password 'cert_password'
# option cert_password 'cert_password'
# Include OpenVPN configuration
option config /etc/openvpn/my-vpn.conf
@@ -25,13 +27,16 @@ config openvpn custom_config
# multi-client server. #
#################################################
config openvpn sample_server
config interface sample_server
# Set to 1 to enable this instance:
option enabled 0
option proto 'openvpn'
# Set to 1 to disable this interface:
option disabled 0
# Which local IP address should OpenVPN
# listen on? (optional)
# option local 0.0.0.0
# Which TCP/UDP port should OpenVPN listen on?
@@ -39,17 +44,19 @@ config openvpn sample_server
# on the same machine, use a different port
# number for each one. You will need to
# open up this port on your firewall.
option port 1194
# TCP or UDP server?
# option proto tcp
option proto udp
# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
# Use "dev tap0" if you are ethernet bridging
# and have precreated a tap0 virtual interface
# and bridged it with your ethernet interface.
# "dev_type tun" will create a routed IP tunnel,
# "dev_type tap" will create an Ethernet tunnel.
# Use "dev tap0" if you are Ethernet bridging
# and have created a tap0 virtual interface
# and bridged it with your Ethernet interface.
# If you want to control access policies
# over the VPN, you must create firewall
# rules for the the TUN/TAP interface.
@@ -59,8 +66,9 @@ config openvpn sample_server
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
# option dev tap
option dev tun
# option dev_type tap
option dev_type tun
# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key). Each client
@@ -77,16 +85,20 @@ config openvpn sample_server
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
option ca /etc/openvpn/ca.crt
option cert /etc/openvpn/server.crt
# This file should be kept secret:
option key /etc/openvpn/server.key
# Diffie hellman parameters.
# Diffie-Hellman parameters.
# Generate your own with:
# openssl dhparam -out dh2048.pem 2048
# Substitute 2048 for 1024 if you are using
# 1024 bit keys.
option dh /etc/openvpn/dh2048.pem
# Configure server mode and supply a VPN subnet
@@ -95,7 +107,8 @@ config openvpn sample_server
# the rest will be made available to clients.
# Each client will be able to reach the server
# on 10.8.0.1. Comment this line out if you are
# ethernet bridging. See the man page for more info.
# Ethernet bridging. See the man page for more info.
option server "10.8.0.0 255.255.255.0"
# Maintain a record of client <-> virtual IP address
@@ -103,18 +116,20 @@ config openvpn sample_server
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
option ifconfig_pool_persist /tmp/ipp.txt
# Configure server mode for ethernet bridging.
# Configure server mode for Ethernet bridging.
# You must first use your OS's bridging capability
# to bridge the TAP interface with the ethernet
# to bridge the TAP interface with the Ethernet
# NIC interface. Then you must manually set the
# IP/netmask on the bridge interface, here we
# IP/net-mask on the bridge interface, here we
# assume 10.8.0.4/255.255.255.0. Finally we
# must set aside an IP range in this subnet
# (start=10.8.0.50 end=10.8.0.100) to allocate
# to connecting clients. Leave this line commented
# out unless you are ethernet bridging.
# out unless you are Ethernet bridging.
# option server_bridge "10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100"
# Push routes to the client to allow it
@@ -123,7 +138,8 @@ config openvpn sample_server
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
# back to the OpenVPN server:
# list push "route 192.168.10.0 255.255.255.0"
# list push "route 192.168.20.0 255.255.255.0"
@@ -138,10 +154,14 @@ config openvpn sample_server
# also has a small subnet behind his connecting
# machine, such as 192.168.40.128/255.255.255.248.
# First, uncomment out these lines:
# option client_config_dir /etc/openvpn/ccd
# list route "192.168.40.128 255.255.255.248"
# Then create a file ccd/Thelonious with this line:
# iroute 192.168.40.128 255.255.255.248
# iroute 192.168.40.128 255.255.255.248
# This will allow Thelonious' private subnet to
# access the VPN. This example will only work
# if you are routing, not bridging, i.e. you are
@@ -149,12 +169,16 @@ config openvpn sample_server
# EXAMPLE: Suppose you want to give
# Thelonious a fixed VPN IP address of 10.9.0.1.
# First uncomment out these lines:
# First uncomment these lines:
# option client_config_dir /etc/openvpn/ccd
# list route "10.9.0.0 255.255.255.252"
# list route "192.168.100.0 255.255.255.0"
# Then add this line to ccd/Thelonious:
# ifconfig-push "10.9.0.1 10.9.0.2"
#ifconfig-push "10.9.0.1 10.9.0.2"
# Suppose that you want to enable different
# firewall access policies for different groups
@@ -166,6 +190,7 @@ config openvpn sample_server
# modify the firewall in response to access
# from different clients. See man
# page for more info on learn-address script.
# option learn_address /etc/openvpn/script
# If enabled, this directive will configure
@@ -182,12 +207,14 @@ config openvpn sample_server
# client's local DHCP server is reachable via
# a more specific route than the default route
# of 0.0.0.0/0.0.0.0.
# list push "redirect-gateway"
# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses. CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
# list push "dhcp-option DNS 10.8.0.1"
# list push "dhcp-option WINS 10.8.0.1"
@@ -197,6 +224,7 @@ config openvpn sample_server
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
# option client_to_client 1
# Uncomment this directive if multiple clients
@@ -209,7 +237,8 @@ config openvpn sample_server
# IF YOU HAVE NOT GENERATED INDIVIDUAL
# CERTIFICATE/KEY PAIRS FOR EACH CLIENT,
# EACH HAVING ITS OWN UNIQUE "COMMON NAME",
# UNCOMMENT THIS LINE OUT.
# UNCOMMENT THIS LINE.
# option duplicate_cn 1
# The keepalive directive causes ping-like
@@ -219,6 +248,7 @@ config openvpn sample_server
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
option keepalive "10 120"
# For extra security beyond that provided
@@ -233,6 +263,7 @@ config openvpn sample_server
# The second parameter should be '0'
# on the server and '1' on the clients.
# This file is secret:
# option tls_auth "/etc/openvpn/ta.key 0"
# For additional privacy, a shared secret key
@@ -248,21 +279,24 @@ config openvpn sample_server
# tls_auth and tls_crypt should NOT
# be combined, as tls_crypt implies tls_auth.
# Use EITHER tls_crypt, tls_auth, or neither option.
# option tls_crypt "/etc/openvpn/ta.key"
# Set the minimum required TLS protocol version
# for all connections.
#
# Require at least TLS 1.1
# option tls_version_min "1.1"
# Require at least TLS 1.2
# Require at least TLS 1.2:
# option tls_version_min "1.2"
# Require TLS 1.2, or the highest version supported
# on the system
# on the system:
# option tls_version_min "1.2 'or-highest'"
# List the preferred ciphers to use for the data channel.
# Run openvpn --show-ciphers to see all supported ciphers.
# list data_ciphers 'AES-256-GCM'
# list data_ciphers 'AES-128-GCM'
# list data_ciphers 'CHACHA20-POLY1305'
@@ -271,51 +305,16 @@ config openvpn sample_server
# peers that do not support cipher negotiation.
#
# Use AES-256-CBC as fallback
# option data_ciphers_fallback 'AES-128-CBC'
# Use AES-128-CBC as fallback
# Use AES-128-CBC as fallback:
# option data_ciphers_fallback 'AES-256-CBC'
# Use Triple-DES as fallback
# option data_ciphers_fallback 'DES-EDE3-CBC'
# Use BF-CBC as fallback
# option data_ciphers_fallback 'BF-CBC'
# OpenVPN versions 2.4 and later will attempt to
# automatically negotiate the most secure cipher
# between the client and server, regardless of a
# configured "option cipher" (see below).
# Automatic negotiation is recommended.
#
# Uncomment this option to disable this behavior,
# and force all OpenVPN peers to use the configured
# cipher option instead (not recommended).
# option ncp_disable
# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
#
# Compression is not recommended, as compression and
# encryption in combination can weaken the security
# of the connection.
#
# LZ4 requires OpenVPN 2.4+ client and server
# option compress lz4
# LZO is available by default only in openvpn-openssl variant
# LZO is compatible with most OpenVPN versions
# option compress lzo
# Control how OpenVPN handles peers using compression
#
# Do not allow any connections using compression
# option allow_compression 'no'
# Allow incoming compressed packets, but do not send compressed packets to other peers
# This can be useful when migrating old configurations with compression activated
# option allow_compression 'asym'
# Both incoming and outgoing packets may be compressed
# option allow_compression 'yes'
# The maximum number of concurrently connected
# clients we want to allow.
# option max_clients 100
# The persist options will try to avoid
@@ -338,8 +337,9 @@ config openvpn sample_server
# "log" will truncate the log file on OpenVPN startup,
# while "log-append" will append to it. Use one
# or the other (but not both).
# option log /tmp/openvpn.log
# option log_append /tmp/openvpn.log
# option log /tmp/openvpn.log
# option log_append /tmp/openvpn.log
# Set the appropriate level of log
# file verbosity.
@@ -352,7 +352,8 @@ config openvpn sample_server
# Silence repeating messages. At most 20
# sequential messages of the same message
# category will be output to the log.
# category will be output to the log:
# option mute 20
@@ -361,10 +362,12 @@ config openvpn sample_server
# for connecting to multi-client server. #
##############################################
config openvpn sample_client
config interface sample_client
# Set to 1 to enable this instance:
option enabled 0
option proto 'openvpn'
# Set to 1 to disable this interface:
option disabled 0
# Specify that we are a client and that we
# will be pulling certain config file directives
@@ -376,24 +379,28 @@ config openvpn sample_client
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
# option dev tap
option dev tun
# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
# option proto tcp
option proto udp
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
list remote "my_server_1 1194"
# list remote "my_server_2 1194"
# Choose a random host from the remote
# list for load_balancing. Otherwise
# try hosts in the order specified.
# option remote_random 1
# Keep trying indefinitely to resolve the
@@ -418,8 +425,11 @@ config openvpn sample_client
# if your proxy server requires
# authentication.
# retry on connection failures:
# option http_proxy_retry 1
# specify http proxy address and port:
# option http_proxy "192.168.1.100 8080"
# Wireless networks often produce a lot
@@ -433,6 +443,7 @@ config openvpn sample_client
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
option ca /etc/openvpn/ca.crt
option cert /etc/openvpn/client.crt
option key /etc/openvpn/client.key
@@ -448,28 +459,32 @@ config openvpn sample_client
# your server certificates with the nsCertType
# field set to "server". The build_key_server
# script in the easy_rsa folder will do this.
# option remote_cert_tls server
# If a tls_auth key is used on the server
# then every client must also have the key.
# option tls_auth "/etc/openvpn/ta.key 1"
# If a tls_crypt key is used on the server
# every client must also have the key.
# option tls_crypt "/etc/openvpn/ta.key"
# Set the minimum required TLS protocol version
# for all connections.
#
# Require at least TLS 1.1
# option tls_version_min "1.1"
# Require at least TLS 1.2
# option tls_version_min "1.2"
# Require TLS 1.2, or the highest version supported
# on the system
# option tls_version_min "1.2 'or-highest'"
# List the preferred ciphers for the data channel.
# List the preferred ciphers for the data channel":
# list data_ciphers 'AES-256-GCM'
# list data_ciphers 'AES-128-GCM'
# list data_ciphers 'CHACHA20-POLY1305'
@@ -480,24 +495,6 @@ config openvpn sample_client
# option data_ciphers_fallback 'AES-128-CBC'
# Use AES-128-CBC as fallback
# option data_ciphers_fallback 'AES-256-CBC'
# Use Triple-DES as fallback
# option data_ciphers_fallback 'DES-EDE3-CBC'
# Use BF-CBC as fallback
# option data_ciphers_fallback 'BF-CBC'
# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
#
# Compression is not recommended, as compression and
# encryption in combination can weaken the security
# of the connection.
#
# LZ4 requires OpenVPN 2.4+ on server and client
# option compress lz4
# LZO is available by default only in openvpn-openssl variant
# LZO is compatible with most OpenVPN versions
# option compress lzo
# Set log file verbosity.
option verb 3

View File

@@ -1,308 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2008-2013 OpenWrt.org
# Copyright (C) 2008 Jo-Philipp Wich
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
START=90
STOP=10
USE_PROCD=1
PROG=/usr/sbin/openvpn
PATH_INSTANCE_DIR="/etc/openvpn"
LIST_SEP="
"
UCI_STARTED=
UCI_DISABLED=
append_param() {
local s="$1"
local v="$2"
case "$v" in
*_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
*_*) v=${v%%_*}-${v#*_} ;;
esac
echo -n "$v" >> "/var/etc/openvpn-$s.conf"
return 0
}
append_bools() {
local p; local v; local s="$1"; shift
for p in $*; do
config_get_bool v "$s" "$p"
[ "$v" = 1 ] && append_param "$s" "$p" && echo >> "/var/etc/openvpn-$s.conf"
done
}
append_params() {
local p; local v; local s="$1"; shift
for p in $*; do
config_get v "$s" "$p"
IFS="$LIST_SEP"
for v in $v; do
[ "$v" = "frames_only" ] && [ "$p" = "compress" ] && unset v && append_param "$s" "$p" && echo >> "/var/etc/openvpn-$s.conf"
[ -n "$v" ] && [ "$p" != "push" ] && append_param "$s" "$p" && echo " $v" >> "/var/etc/openvpn-$s.conf"
[ -n "$v" ] && [ "$p" = "push" ] && append_param "$s" "$p" && echo " \"$v\"" >> "/var/etc/openvpn-$s.conf"
done
unset IFS
done
}
append_list() {
local p; local v; local s="$1"; shift
list_cb_append() {
v="${v}:$1"
}
for p in $*; do
unset v
config_list_foreach "$s" "$p" list_cb_append
[ -n "$v" ] && append_param "$s" "$p" && echo " ${v:1}" >> "/var/etc/openvpn-$s.conf"
done
}
section_enabled() {
config_get_bool enable "$1" 'enable' 0
config_get_bool enabled "$1" 'enabled' 0
[ $enable -gt 0 ] || [ $enabled -gt 0 ]
}
create_temp_file() {
mkdir -p "$(dirname "$1")"
rm -f "$1"
touch "$1"
chown root "$1"
chmod 0600 "$1"
}
openvpn_get_dev() {
local dev dev_type
local name="$1"
local conf="$2"
# Do override only for configurations with config_file
config_get config_file "$name" config
[ -n "$config_file" ] || return
# Check there is someething to override
config_get dev "$name" dev
config_get dev_type "$name" dev_type
[ -n "$dev" ] || return
# If there is a no dev_type, try to guess it
if [ -z "$dev_type" ]; then
. /lib/functions/openvpn.sh
local odev odev_type
get_openvpn_option "$conf" odev dev
get_openvpn_option "$conf" odev_type dev-type
[ -n "$odev_type" ] || odev_type="$odev"
case "$odev_type" in
tun*) dev_type="tun" ;;
tap*) dev_type="tap" ;;
*) return;;
esac
fi
# Return overrides
echo "--dev-type $dev_type --dev $dev"
}
openvpn_get_credentials() {
local name="$1"
local ret=""
config_get cert_password "$name" cert_password
config_get password "$name" password
config_get username "$name" username
if [ -n "$cert_password" ]; then
create_temp_file /var/run/openvpn.$name.pass
echo "$cert_password" > /var/run/openvpn.$name.pass
ret=" --askpass /var/run/openvpn.$name.pass "
fi
if [ -n "$username" ]; then
create_temp_file /var/run/openvpn.$name.userpass
echo "$username" > /var/run/openvpn.$name.userpass
echo "$password" >> /var/run/openvpn.$name.userpass
ret=" --auth-user-pass /var/run/openvpn.$name.userpass "
fi
# Return overrides
echo "$ret"
}
openvpn_add_instance() {
local name="$1"
local dir="$2"
local conf=$(basename "$3")
local security="$4"
local up="$5"
local down="$6"
local route_up="$7"
local route_pre_down="$8"
local ipchange="$9"
local client=$(grep -qEx "client|tls-client" "$dir/$conf" && echo 1)
procd_open_instance "$name"
procd_set_param command "$PROG" \
--syslog "openvpn($name)" \
--status "/var/run/openvpn.$name.status" \
--cd "$dir" \
--config "$conf"
# external scripts can only be called on script-security 2 or higher
if [ "${security:-2}" -lt 2 ]; then
logger -t "openvpn(${name})" "not adding hotplug scripts due to script-security ${security:-2}"
else
procd_append_param command \
--up "/usr/libexec/openvpn-hotplug up $name" \
--down "/usr/libexec/openvpn-hotplug down $name" \
--route-up "/usr/libexec/openvpn-hotplug route-up $name" \
--route-pre-down "/usr/libexec/openvpn-hotplug route-pre-down $name" \
${client:+--ipchange "/usr/libexec/openvpn-hotplug ipchange $name"} \
${up:+--setenv user_up "$up"} \
${down:+--setenv user_down "$down"} \
${route_up:+--setenv user_route_up "$route_up"} \
${route_pre_down:+--setenv user_route_pre_down "$route_pre_down"} \
${client:+${ipchange:+--setenv user_ipchange "$ipchange"}}
fi
procd_append_param command \
--script-security "${security:-2}" \
$(openvpn_get_dev "$name" "$conf") \
$(openvpn_get_credentials "$name" "$conf")
procd_set_param file "$dir/$conf"
procd_set_param term_timeout 15
procd_set_param respawn
procd_append_param respawn 3600
procd_append_param respawn 5
procd_append_param respawn -1
procd_close_instance
}
start_uci_instance() {
local s="$1"
config_get config "$s" config
config="${config:+$(readlink -f "$config")}"
section_enabled "$s" || {
append UCI_DISABLED "$config" "$LIST_SEP"
return 1
}
local up down route_up route_pre_down ipchange script_security
config_get up "$s" up
config_get down "$s" down
config_get route_up "$s" route_up
config_get route_pre_down "$s" route_pre_down
config_get ipchange "$s" ipchange
config_get script_security "$s" script_security
[ ! -d "/var/run" ] && mkdir -p "/var/run"
if [ ! -z "$config" ]; then
append UCI_STARTED "$config" "$LIST_SEP"
[ -n "$script_security" ] || get_openvpn_option "$config" script_security script-security
[ -n "$up" ] || get_openvpn_option "$config" up up
[ -n "$down" ] || get_openvpn_option "$config" down down
[ -n "$route_up" ] || get_openvpn_option "$config" route_up route-up
[ -n "$route_pre_down" ] || get_openvpn_option "$config" route_pre_down route-pre-down
[ -n "$ipchange" ] || get_openvpn_option "$config" ipchange ipchange
openvpn_add_instance "$s" "${config%/*}" "$config" "$script_security" "$up" "$down" "$route_up" "$route_pre_down" "$ipchange"
return
fi
create_temp_file "/var/etc/openvpn-$s.conf"
append_bools "$s" $OPENVPN_BOOLS
append_params "$s" $OPENVPN_PARAMS
append_list "$s" $OPENVPN_LIST
openvpn_add_instance "$s" "/var/etc" "openvpn-$s.conf" "$script_security" "$up" "$down" "$route_up" "$route_pre_down" "$ipchange"
}
start_path_instances() {
local path name
for path in ${PATH_INSTANCE_DIR}/*.conf; do
[ -f "$path" ] && {
name="${path##*/}"
name="${name%.conf}"
start_path_instance "$name"
}
done
}
start_path_instance() {
local name="$1"
local path name up down route_up route_pre_down ipchange
path="${PATH_INSTANCE_DIR}/${name}.conf"
# don't start configs again that are already started by uci
if echo "$UCI_STARTED" | grep -qxF "$path"; then
logger -t openvpn "$name.conf already started"
return
fi
# don't start configs which are set to disabled in uci
if echo "$UCI_DISABLED" | grep -qxF "$path"; then
logger -t openvpn "$name.conf is disabled in /etc/config/openvpn"
return
fi
get_openvpn_option "$path" up up || up=""
get_openvpn_option "$path" down down || down=""
get_openvpn_option "$path" route_up route-up || route_up=""
get_openvpn_option "$path" route_pre_down route-pre-down || route_pre_down=""
get_openvpn_option "$path" ipchange ipchange || ipchange=""
openvpn_add_instance "$name" "${path%/*}" "$path" "" "$up" "$down" "$route_up" "$route_pre_down" "$ipchange"
}
start_service() {
local instance="$1"
local instance_found=0
config_cb() {
local type="$1"
local name="$2"
if [ "$type" = "openvpn" ]; then
if [ -n "$instance" -a "$instance" = "$name" ]; then
instance_found=1
fi
fi
}
. /lib/functions/openvpn.sh
. /usr/share/openvpn/openvpn.options
config_load 'openvpn'
if [ -n "$instance" ]; then
if [ "$instance_found" -gt 0 ]; then
start_uci_instance "$instance"
elif [ -f "${PATH_INSTANCE_DIR}/${instance}.conf" ]; then
start_path_instance "$instance"
fi
else
config_foreach start_uci_instance 'openvpn'
auto="$(uci_get openvpn globals autostart 1)"
if [ "$auto" = "1" ]; then
start_path_instances
else
logger -t openvpn "Autostart for configs in '$PATH_INSTANCE_DIR/*.conf' disabled"
fi
fi
}
service_triggers() {
procd_add_reload_trigger openvpn
}

View File

@@ -1,18 +1,15 @@
OPENVPN_PARAMS='
allow_compression
askpass
# proto ==> ovpnproto
# options suffixed with :d are deprecated
OPENVPN_PARAMS_STRING='
allow_compression:d
auth
auth_gen_token
auth_gen_token_secret
auth_retry
auth_user_pass
auth_user_pass_verify
bcast_buffers
bind_dev
ca
capath
cd
cert
chroot
cipher
client_config_dir
@@ -20,31 +17,23 @@ client_connect
client_crresponse
client_disconnect
client_nat
comp_lzo
compat_mode
compress
comp_lzo:d
compress:d
connect_freq
connect_freq_initial
connect_retry
connect_retry_max
connect_timeout
crl_verify
data_ciphers_fallback
dev
dev_node
dev_type
dh
dhcp_option
dns
down
ecdh_curve
echo
engine
explicit_exit_notify
extra_certs
fragment
group
hand_window
hash_size
http_proxy
http_proxy_option
@@ -56,69 +45,43 @@ ifconfig_ipv6_push
ifconfig_pool
ifconfig_pool_persist
ifconfig_push
ignore_unknown_option
inactive
ipchange
iproute
iroute
iroute_ipv6
keepalive
key
key_direction
keying_material_exporter
learn_address
link_mtu
lladdr
local
log
log_append
lport
management
management_client_group
management_client_user
management_external_cert
management_external_key
management_log_cache
mark
max_clients
max_packet_size
max_routes_per_client
mode
mssfix
mtu_disc
mute
nice
ovpnproto
peer_fingerprint
ping
ping_exit
ping_restart
pkcs11_cert_private
pkcs11_id
pkcs11_pin_cache
pkcs11_private_mode
pkcs11_protected_authentication
pkcs11_providers
pkcs12
plugin
port
port_share
proto
proto_force
providers
pull_filter
push
push_remove
rcvbuf
redirect_gateway
redirect_private
remap_usr1
remote
remote_cert_eku
remote_cert_ku
remote_cert_tls
reneg_bytes
reneg_pkts
reneg_sec
replay_persist
replay_window
resolv_retry
@@ -127,58 +90,121 @@ route_delay
route_gateway
route_ipv6
route_ipv6_gateway
route_metric
route_pre_down
route_up
rport
script_security
secret
server
server_bridge
server_ipv6
server_poll_timeout
session_timeout
setcon
setenv
setenv_safe
shaper
sndbuf
socket_flags
socks_proxy
stale_routes_check
static_challenge
status
status_version
syslog
tcp_queue_limit
tls_auth
tls_cert_profile
tls_crypt
tls_crypt_v2
tls_crypt_v2_verify
tls_export_cert
tls_timeout
tls_verify
tls_version_min
tls_version_max
tls_version_min
tmp_dir
topology
up
user
verify_client_cert
verify_hash:d
verify_x509_name
vlan_accept
x509_track
x509_username_field
'
OPENVPN_PARAMS_DEPRECATED='
allow_compression
comp_lzo
comp_noadapt
compress
link_mtu
opt_verify
secret
verify_hash
'
OPENVPN_PARAMS_REMOVED='
ncp_disable
ncp_ciphers
'
# peer_fingerprint and verify_hash can be either file or string
OPENVPN_PARAMS_FILE='
askpass
auth_user_pass
ca
cert
config
dh
extra_certs
extra_certs
http_proxy_user_pass
key
pkcs12
secret:d
tls_crypt
tls_crypt_v2
'
OPENVPN_INTS='
nice
'
OPENVPN_UINTS='
auth_gen_token_lifetime
bcast_buffers
connect_retry
connect_retry_max
connect_timeout
explicit_exit_notify
hand_window
key_direction
link_mtu:d
lport
management_log_cache
max_clients
max_packet_size
max_routes_per_client
mssfix
mute
ping
ping_exit
ping_restart
pkcs11_cert_private
pkcs11_pin_cache
pkcs11_private_mode
pkcs11_protected_authentication
port
rcvbuf
reneg_bytes
reneg_pkts
reneg_sec
route_metric
rport
script_security
server_poll_timeout
session_timeout
shaper
sndbuf
socks_proxy_retry
status_version
tcp_queue_limit
tls_timeout
tran_window
tun_max_mtu
tun_mtu
tun_mtu_extra
txqueuelen
up
user
up_delay
verb
verify_client_cert
verify_hash
verify_x509_name
vlan_accept
vlan_pvid
writepid
x509_track
x509_username_field
'
OPENVPN_BOOLS='
@@ -191,8 +217,7 @@ block_ipv6
ccd_exclusive
client
client_to_client
comp_noadapt
disable
comp_noadapt:d
disable_dco
disable_occ
down_pre
@@ -219,7 +244,7 @@ mtu_test
multihome
mute_replay_warnings
nobind
opt_verify
opt_verify:d
passtos
persist_key
persist_local_ip
@@ -242,7 +267,6 @@ test_crypto
tls_client
tls_exit
tls_server
up_delay
up_restart
use_prediction_resistance
username_as_common_name
@@ -251,7 +275,13 @@ vlan_tagging
OPENVPN_LIST='
data_ciphers
ncp_ciphers
disable
ignore_unknown_option
push
remote
route
setenv
setenv_safe
tls_cipher
tls_ciphersuites
tls_groups

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env ucode
// 0 == link_mtu => historic
// cmd tun_dev tun_mtu 0 ifconfig_local_ip ifconfig_remote_ip [init | restart]
// cmd tap_dev tap_mtu 0 ifconfig_local_ip ifconfig_netmask [init | restart]
print('tun_dev ', ARGV[0],' tun_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_rip "', ARGV[4], '" i/r "', ARGV[5], '"\n');
print('tap_dev ', ARGV[0],' tap_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_nm "', ARGV[4], '" i/r "', ARGV[5], '"\n');
/* e.g.
tun_dev asdf0 tun_mtu 1500 0 if_lip "" if_rip "" i/r "init"
*/
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* e.g.
{
"script_type": "route-pre-down",
"dev": "asdf0",
"tun_mtu": "1500",
"script_context": "init",
"signal": "sigint",
"redirect_gateway": "0",
"dev_type": "tun",
"verb": "6",
"daemon": "0",
"daemon_log_redirect": "0",
"daemon_start_time": "1770390291",
"daemon_pid": "7435",
"proto_1": "udp",
"local_port_1": "1194",
"remote_1": "192.0.2.10",
"remote_port_1": "1194"
}
*/

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env ucode
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* e.g.
{
"script_type": "route-up",
"dev": "asdf0",
"tun_mtu": "1500",
"script_context": "init",
"signal": "sigint",
"redirect_gateway": "0",
"dev_type": "tun",
"verb": "6",
"daemon": "0",
"daemon_log_redirect": "0",
"daemon_start_time": "1770390291",
"daemon_pid": "7435",
"proto_1": "udp",
"local_port_1": "1194",
"remote_1": "192.0.2.10",
"remote_port_1": "1194"
}
*/

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env ucode
// cmd certificate_depth subject
print('cmd ', ARGV, '\n');
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
/* do something */
/*
exit(0); // allow the TLS handshake to proceed
exit(1); // fail
*/

37
net/openvpn/files/up.uc Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env ucode
// 0 == link_mtu => historic
// cmd tun_dev tun_mtu 0 ifconfig_local_ip ifconfig_remote_ip [init | restart]
// cmd tap_dev tap_mtu 0 ifconfig_local_ip ifconfig_netmask [init | restart]
print('tun_dev ', ARGV[0],' tun_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_rip "', ARGV[4], '" i/r "', ARGV[5], '"\n');
print('tap_dev ', ARGV[0],' tap_mtu ', ARGV[1], ' ', ARGV[2], ' if_lip "', ARGV[3], '" if_nm "', ARGV[4], '" i/r "', ARGV[5], '"\n');
/* e.g.
tun_dev asdf0 tun_mtu 1500 0 if_lip "" if_rip "" i/r "init"
*/
// See the environment variables passed to this script: https://ucode.mein.io/module-core.html#getenv
print(getenv(), '\n');
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#environmental-variables-177179
// https://openvpn.net/community-docs/community-articles/openvpn-2-6-manual.html#script-hooks-177179
/* e.g.
{
"script_type": "up",
"dev_type": "tun",
"dev": "asdf0",
"tun_mtu": "1500",
"script_context": "init",
"verb": "6",
"daemon": "0",
"daemon_log_redirect": "0",
"daemon_start_time": "1770389649",
"daemon_pid": "6116",
"proto_1": "udp",
"local_port_1": "1194",
"remote_1": "192.0.2.10",
"remote_port_1": "1194"
}
*/

View File

@@ -1,10 +0,0 @@
#!/bin/sh
ACTION=$1
shift
INSTANCE=$1
shift
export ACTION=$ACTION
export INSTANCE=$INSTANCE
exec /sbin/hotplug-call openvpn "$@"