-
Notifications
You must be signed in to change notification settings - Fork 3.9k
OpenVPN netifd Deep Integration & Configuration Refactoring #29220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,9 @@ | |||||||||||||||||
| init_proto "$@" | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| CONF_DIR="/var/run" | ||||||||||||||||||
| CONF_PREFIX="${CONF_DIR}/openvpn." | ||||||||||||||||||
|
|
||||||||||||||||||
| # Helper to DRY up repeated option handling in init/setup | ||||||||||||||||||
| option_builder() { | ||||||||||||||||||
| # option_builder <action:add|build> <LIST_VAR_NAME> <type> | ||||||||||||||||||
|
|
@@ -92,6 +95,7 @@ option_builder() { | |||||||||||||||||
| # Not real config params used by openvpn - only by our proto handler | ||||||||||||||||||
| PROTO_BOOLS=' | ||||||||||||||||||
| allow_deprecated | ||||||||||||||||||
| defaultroute | ||||||||||||||||||
| ipv6 | ||||||||||||||||||
| ' | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -124,11 +128,86 @@ proto_openvpn_init_config() { | |||||||||||||||||
| option_builder add OPENVPN_LIST list | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| # rewrite_config_line <dst> <old_path> <new_path> | ||||||||||||||||||
| # Replace a `config <old_path>` line in <dst> with `config <new_path>`. | ||||||||||||||||||
| # Handles absolute path, relative filename, no quotes / single quotes / double quotes, | ||||||||||||||||||
| # and optional trailing whitespace. | ||||||||||||||||||
| rewrite_config_line() { | ||||||||||||||||||
| local dst="$1" | ||||||||||||||||||
| local old="$2" | ||||||||||||||||||
| local new="$3" | ||||||||||||||||||
| local fname="${old##*/}" | ||||||||||||||||||
|
|
||||||||||||||||||
| # absolute path, three quote styles | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)${old}[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)'${old}'[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)\"${old}\"[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| # relative filename, three quote styles | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)${fname}[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)'${fname}'[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| sed -i "s|^\([[:space:]]*config[[:space:]]\+\)\"${fname}\"[[:space:]]*$|\1${new}|" "$dst" | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| # Recursively copy config files referenced by `config` directives. | ||||||||||||||||||
| # Updates the `config` paths in the destination file to point to the copies. | ||||||||||||||||||
| # Appends all copied files to the global CONFIG_FILES variable. | ||||||||||||||||||
| # | ||||||||||||||||||
| # Usage: copy_config_recursive <dst_file> <visited> | ||||||||||||||||||
| # dst_file: the already-copied config file to scan for `config` lines | ||||||||||||||||||
| # visited: pipe-delimited list of source paths already processed (cycle guard) | ||||||||||||||||||
| copy_config_recursive() { | ||||||||||||||||||
| local dst="$1" | ||||||||||||||||||
| local visited="$2" | ||||||||||||||||||
| local ref dst_ref fname | ||||||||||||||||||
|
|
||||||||||||||||||
| while IFS= read -r ref; do | ||||||||||||||||||
| # skip empty lines | ||||||||||||||||||
| [ -n "$ref" ] || continue | ||||||||||||||||||
|
|
||||||||||||||||||
| # expand relative path to absolute using cd_dir | ||||||||||||||||||
| case "$ref" in | ||||||||||||||||||
| /*) ;; | ||||||||||||||||||
| *) ref="$cd_dir/$ref" ;; | ||||||||||||||||||
| esac | ||||||||||||||||||
|
|
||||||||||||||||||
| # cycle guard | ||||||||||||||||||
| case "$visited" in | ||||||||||||||||||
| *"|$ref|"*) continue ;; | ||||||||||||||||||
| esac | ||||||||||||||||||
|
|
||||||||||||||||||
| [ -f "$ref" ] || continue | ||||||||||||||||||
|
|
||||||||||||||||||
| fname="${ref##*/}" | ||||||||||||||||||
| dst_ref="${CONF_PREFIX}${config}.user_${fname}" | ||||||||||||||||||
|
||||||||||||||||||
| dst_ref="${CONF_PREFIX}${config}.user_${fname}" | |
| ref_hash="$(printf '%s' "$ref" | md5sum | cut -d' ' -f1)" | |
| dst_ref="${CONF_PREFIX}${config}.user_${ref_hash}_${fname}" |
Copilot
AI
Apr 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy_config_recursive converts relative config references to absolute paths (ref="$cd_dir/$ref") and then calls rewrite_config_line using that absolute path. If the original config line was a relative path with directories (e.g., config subdir/extra.conf), rewrite_config_line won't match (it only handles absolute paths or a bare filename), so the parent file may continue referencing the original user file instead of the sandbox copy. Preserve the original token (as written) and rewrite using that, or enhance rewrite_config_line to handle relative paths containing / components.
Copilot
AI
Apr 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new defaultroute proto option is not currently respected: when is_openvpn_client is true, the code always appends --redirect-gateway def1 ipv6 and comments out any existing redirect-gateway lines, even if defaultroute=0 was configured. Gate the redirect-gateway injection (and the sed filtering) on defaultroute being enabled, and only default it to 1 when unset.
| append exec_params "--redirect-gateway def1 ipv6" | |
| [ -n "$defaultroute" ] || defaultroute=1 | |
| sed -i '/^[[:space:]]*redirect-gateway[[:space:]]*/s/^/# /' $CONFIG_FILES | |
| [ -n "$defaultroute" ] || defaultroute=1 | |
| if [ "$defaultroute" != "0" ]; then | |
| append exec_params "--redirect-gateway def1 ipv6" | |
| sed -i '/^[[:space:]]*redirect-gateway[[:space:]]*/s/^/# /' $CONFIG_FILES | |
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rewrite_config_lineinterpolates$olddirectly into a sed regex. If the source path contains regex metacharacters (e.g.,.,[,],*,\,|,&), the substitution can match incorrectly or fail. Escape the path for use in sed (both the match and replacement side) before running the replacements.