Skip to content

[fix] Decouple OpenVPN config filename from VPN name #572#609

Open
nemesifier wants to merge 1 commit into
masterfrom
issues/572-vpn-name-supervisord
Open

[fix] Decouple OpenVPN config filename from VPN name #572#609
nemesifier wants to merge 1 commit into
masterfrom
issues/572-vpn-name-supervisord

Conversation

@nemesifier
Copy link
Copy Markdown
Member

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #572.

Description of Changes

This fixes the OpenVPN startup failure that happens when VPN_NAME contains whitespace.

The OpenVPN process managed by supervisord now always starts from a fixed openvpn.conf filename instead of deriving the config path from VPN_NAME. The downloaded VPN archive is extracted in an isolated temporary directory, then its .conf file is normalized to openvpn.conf so stale files in / cannot be reused accidentally.

The cron update script now restarts OpenVPN only after a successful config download. A container-backed regression test was added for a downloaded config named my vpn.conf.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR fixes a bug where OpenVPN configurations with whitespace in the VPN_NAME environment variable cannot be used due to supervisord's command-line parsing limitations. The solution isolates config downloads into a temporary directory, normalizes any extracted configuration file to a fixed openvpn.conf filename, updates supervisord to reference the fixed filename instead of a VPN_NAME template, and makes service restart conditional on successful download. An integration test validates the behavior with whitespace-containing config filenames.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bug


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Bug Fixes ❌ Error PR fixes root cause and includes regression test that reproduces the whitespace bug. However, review comment identifies unaddressed issue: non-deterministic behavior when multiple .conf files exist. Per review comment, code should error if not exactly one .conf file found. Test only covers single file case. Multiple .conf files could cause non-deterministic selection in production.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly follows the required format with [fix] prefix and directly addresses the core change (decoupling OpenVPN config filename from VPN name) while referencing the linked issue #572.
Description check ✅ Passed The description addresses all critical sections: completed checklist items, issue reference, and detailed description of changes. Only documentation update was not completed, which is acceptable as a non-critical item.
Linked Issues check ✅ Passed The code changes fully address issue #572 by decoupling config filename from VPN_NAME, extracting to temp directory, normalizing to openvpn.conf, and adding regression tests for whitespace handling.
Out of Scope Changes check ✅ Passed All code changes are directly related to fixing the VPN_NAME whitespace issue: utils.sh improves config download isolation, openvpn.sh adds conditional restart, supervisord.conf uses fixed filename, and tests add regression coverage.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/572-vpn-name-supervisord

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented May 19, 2026

Code Review Summary

Status: No Critical Issues Found | Recommendation: LGTM, ready to merge

Security Improvements Observed

Aspect Assessment
Command Injection Fixed - variables are now properly quoted in curl commands
Path Traversal Protected - uses -- to prevent option injection via filenames
Resource Leaks Prevented - TMPDIR cleaned up on all error paths
Race Conditions Mitigated - extracts to temp directory before moving files
Error Handling Robust - proper error handling throughout

Files Reviewed

  • images/common/utils.sh: Excellent security improvements with proper quoting and cleanup
  • images/openwisp_openvpn/openvpn.sh: Good use of conditional restart
  • images/openwisp_openvpn/supervisord.conf: Simplified to fixed filename
  • tests/runtests.py: Comprehensive regression test added

Summary

The changes are minimal, focused, and security-conscious. The refactor from unquoted variables to properly quoted ones eliminates potential command injection. The cleanup-on-error pattern is consistent throughout.

Action: Approved for merge.


Reviewed by kimi-k2.5-0127 · 170,054 tokens

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@images/common/utils.sh`:
- Around line 261-263: The current logic in images/common/utils.sh that sets
CONF_FILE by using find ... -print -quit (when CONF_FILE doesn't exist) can pick
an arbitrary .conf when multiple are present; change it to explicitly collect
all matches from TMPDIR (e.g., into an array or list), then: if exactly one
match set CONF_FILE to that path, if zero leave CONF_FILE unset, and if more
than one log an error and exit (fail fast). Apply the same change to the other
similar block referenced (lines 264-268) so both places check the number of
.conf files and error out deterministically instead of using find -print -quit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c9def431-699b-4f71-8350-5d24fdc1a223

📥 Commits

Reviewing files that changed from the base of the PR and between ce822f6 and 44667d5.

📒 Files selected for processing (4)
  • images/common/utils.sh
  • images/openwisp_openvpn/openvpn.sh
  • images/openwisp_openvpn/supervisord.conf
  • tests/runtests.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: auto-assign-issue / run-bot
  • GitHub Check: CI Build
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{py,html}

📄 CodeRabbit inference engine (Custom checks)

For Django pull requests, ensure all user-facing strings are marked as translatable using the Django i18n framework

Files:

  • tests/runtests.py
🧠 Learnings (1)
📚 Learning: 2026-02-17T12:50:25.569Z
Learnt from: pandafy
Repo: openwisp/docker-openwisp PR: 564
File: images/common/utils.sh:33-40
Timestamp: 2026-02-17T12:50:25.569Z
Learning: For shell scripts under images/common that invoke certbot, in certbot >= 3.3.0 (Mar 2025), you no longer need --register-unsafely-without-email when using --noninteractive --agree-tos without providing an email. If your scripts previously passed this flag, remove it to rely on default account registration without an email. This applies when no email is supplied; if an email is provided, behavior is unchanged. Update tests to reflect that certbot will proceed without prompting for an email in non-interactive mode.

Applied to files:

  • images/common/utils.sh
🔇 Additional comments (3)
images/openwisp_openvpn/supervisord.conf (1)

21-21: LGTM!

images/openwisp_openvpn/openvpn.sh (1)

12-12: LGTM!

tests/runtests.py (1)

13-13: LGTM!

Also applies to: 61-113

Comment thread images/common/utils.sh
Comment on lines +261 to +263
if [ ! -f "$CONF_FILE" ]; then
CONF_FILE=$(find "$TMPDIR" -maxdepth 1 -type f -name '*.conf' -print -quit)
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when multiple extracted .conf files are present.

find ... -print -quit picks an arbitrary first match when there are multiple .conf files (and no pre-existing openvpn.conf), which can select the wrong profile non-deterministically.

Suggested fix
  CONF_FILE="$TMPDIR/openvpn.conf"
  if [ ! -f "$CONF_FILE" ]; then
-    CONF_FILE=$(find "$TMPDIR" -maxdepth 1 -type f -name '*.conf' -print -quit)
+    CONF_COUNT=$(find "$TMPDIR" -maxdepth 1 -type f -name '*.conf' | wc -l)
+    if [ "$CONF_COUNT" -ne 1 ]; then
+      echo "ERROR: expected exactly one OpenVPN config file, found $CONF_COUNT" >&2
+      rm -rf -- "$TMPDIR"
+      return 1
+    fi
+    CONF_FILE=$(find "$TMPDIR" -maxdepth 1 -type f -name '*.conf' -print -quit)
  fi
  if [ -z "$CONF_FILE" ]; then

Also applies to: 264-268

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@images/common/utils.sh` around lines 261 - 263, The current logic in
images/common/utils.sh that sets CONF_FILE by using find ... -print -quit (when
CONF_FILE doesn't exist) can pick an arbitrary .conf when multiple are present;
change it to explicitly collect all matches from TMPDIR (e.g., into an array or
list), then: if exactly one match set CONF_FILE to that path, if zero leave
CONF_FILE unset, and if more than one log an error and exit (fail fast). Apply
the same change to the other similar block referenced (lines 264-268) so both
places check the number of .conf files and error out deterministically instead
of using find -print -quit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] VPN_NAME cannot contain whitespace due to supervisord limitations

1 participant