Commit Graph
843 Commits
Author SHA1 Message Date
Stanislas 9e1bb4b175 feat: enable proper systemd support in Docker tests (#1373)
- Replace the `sed` hack that disabled `systemctl` commands with proper
systemd support in Docker containers
- This allows testing the actual `systemctl` commands used by the
install script
- No more manual workarounds for starting OpenVPN/Unbound services
2025-12-13 01:14:54 +01:00
Stanislas 236e77af68 feat: add logging for system checks in initialCheck (#1371)
Add debug and info logging to initialCheck for better troubleshooting
visibility.
2025-12-12 23:47:09 +01:00
Stanislas 179cbc0c25 fix: increase DNS test retries and use seq for loop (#1370)
- Increase DNS retry count from 5 to 10 for improved test reliability
when Unbound needs more time to initialize
- Refactor retry loop to use `seq` with a `DNS_MAX_RETRIES` to be
cleaner
2025-12-12 23:38:12 +01:00
Stanislas 408d577461 feat: add missing dependencies for all supported distros (#1368)
## Summary
- Add `tar` and DNS utilities (`dnsutils`/`bind-utils`/`bind`) to all
supported distros
- Ensures the script works reliably on minimal system images where these
tools may not be pre-installed

## Changes by distro

| Distro | Packages added |
|--------|----------------|
| debian/ubuntu | `tar`, `dnsutils` |
| centos | `bind-utils` |
| oracle | `bind-utils` |
| amzn2023 | `tar`, `bind-utils` |
| fedora | `tar`, `bind-utils` |
| opensuse | `tar`, `bind-utils` |
| arch | `tar`, `bind` |

## Why these packages?
- **tar**: Required for extracting Easy-RSA `.tgz` archive
- **dnsutils/bind-utils/bind**: Provides `dig` command used as fallback
for public IP detection
2025-12-12 23:17:12 +01:00
Stanislas 44c995df8e feat: migrate to OpenVPN 2.4+ directory structure and improve distro compatibility (#1364)
## Summary

Migrates OpenVPN configuration to use the modern OpenVPN 2.4+ directory
structure and improves compatibility across different Linux
distributions.

Close https://github.com/angristan/openvpn-install/issues/1307, close
https://github.com/angristan/openvpn-install/issues/788, close
https://github.com/angristan/openvpn-install/issues/605, close
https://github.com/angristan/openvpn-install/pull/653, close
https://github.com/angristan/openvpn-install/issues/1214

### Directory Structure Changes
- All server files now in `/etc/openvpn/server/` instead of
`/etc/openvpn/`
- Uses `openvpn-server@server.service` consistently across all distros
- `server.conf` uses relative paths for portability

### Distro-Specific User/Group Handling
Different distros configure OpenVPN differently:
| Distro | User | Group | systemd handles user? |
|--------|------|-------|----------------------|
| Debian/Ubuntu | nobody | nogroup | No |
| Fedora/RHEL/Amazon | openvpn | openvpn | No |
| Arch | openvpn | network | **Yes** (via `User=` in service) |

The script now:
1. Detects if an `openvpn` user exists and uses appropriate group
2. Checks if systemd service already has `User=` directive
3. Skips `user`/`group` in config when systemd handles it (avoids
"double privilege drop" error on Arch)
4. Sets file ownership with `chown -R` for non-root OpenVPN users

### Other Changes
- Updated FAQ.md with new paths
- Added systemd service file validation in tests
- Added CRL reload verification in tests
2025-12-12 22:09:18 +01:00
Stanislas 3bc52d245b feat: use modern data-ciphers naming while maintaining 2.4 compatibility (#1363)
## Summary

- Add `data-ciphers` directive alongside `ncp-ciphers` for
future-proofing
- Server config now emits both `data-ciphers` and `ncp-ciphers`
- Client config adds `ignore-unknown-option data-ciphers`,
`data-ciphers`, and `ncp-ciphers` for full backward compatibility with
OpenVPN 2.4 clients

## Context

The `ncp-ciphers` option is a legacy alias of `data-ciphers` that is
still accepted but deprecated in OpenVPN 2.5+. This change aligns with
modern naming conventions while maintaining compatibility with older 2.4
clients.
2025-12-12 10:23:36 +01:00
Stanislas 693b4c31fc docs: update Security and Encryption section for modern OpenVPN (#1360)
Modernise the Security and Encryption section to reflect OpenVPN's
improved defaults over the years.

- Add version-by-version changelog of security improvements (2.4, 2.5,
2.6)
- Add `[!NOTE]` callouts for default changes in subsections
- Update Easy-RSA link (v3.0.7 → v3.2.2)
2025-12-12 01:12:30 +01:00
Stanislas 79b2763514 feat: add remote-cert-tls client to server configuration (#1359)
## Summary
- Add `remote-cert-tls client` directive to server config to ensure only
certificates with "TLS Web Client Authentication" EKU can connect
- Document the feature in the Security and Encryption section of
README.md
2025-12-12 00:47:10 +01:00
Stanislas 04f2996c79 fix: disable ifconfig-pool-persist when duplicate-cn is enabled (#1354)
## Summary
- Only add `ifconfig-pool-persist` to server.conf when `MULTI_CLIENT !=
y`
- Add note in the installation prompt about this limitation
- Update README to mention the trade-off

First reported in
https://github.com/angristan/openvpn-install/issues/440#issuecomment-2987417197

## Background

`ifconfig-pool-persist` is incompatible with `duplicate-cn`. When
`duplicate-cn` is enabled, OpenVPN bypasses common name matching in the
IP pool allocation, making the persistence file ineffective.

From [OpenVPN
source](https://github.com/OpenVPN/openvpn/blob/e5ff8247/src/openvpn/init.c#L3608-L3610):
```c
if (o->duplicate_cn && o->ifconfig_pool_persist_filename)
{
    msg(M_WARN, "WARNING: --ifconfig-pool-persist will not work with --duplicate-cn");
}
```

Previously, the script always added `ifconfig-pool-persist ipp.txt`
regardless of whether `duplicate-cn` was enabled via `MULTI_CLIENT=y`.
2025-12-12 00:04:51 +01:00
Guo YunheandStanislas Lange bbf93a19d5 Add openSUSE Tumbleweed/Leap support (#1166)
<!---
❗️ Please read ❗️
➡️ Please make sure you've followed the guidelines:
https://github.com/angristan/openvpn-install#contributing
✅ Please make sure your changes are tested and working
🗣️ Please avoid large PRs, and discuss changes in a GitHub issue first
✋ If the changes are too big and not in line with the project, they will
probably be rejected. Remember that this script is meant to be simple
and easy to use.
--->

---------

Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-11 21:22:12 +01:00
Stanislas 4b00f44e8e feat: add version 10 support for RHEL-based distributions (#1346)
## Summary

- Add version 10 support for CentOS Stream, Rocky Linux, AlmaLinux, and
Oracle Linux
- Consolidate version check logic into a single check for all RHEL-based
distributions
- Fix Rocky Linux Docker image names to `rockylinux/rockylinux:tag`
- Increase Easy-RSA download curl retry from 3 to 5
- Fail early if EPEL/Copr repository setup fails
- Fix Oracle Linux EPEL package name (`oracle-epel-release-el*` instead
of `epel-release`)

## Changes

### `openvpn-install.sh`
- Combine version checks for CentOS/Rocky/AlmaLinux and Oracle Linux
into one
- Update error message to list supported distributions
- Change Easy-RSA download `--retry 3` to `--retry 5`
- Add `|| log_fatal` to EPEL and Copr setup commands to fail early on
errors
- Use `oracle-epel-release-el{8,9,10}` for Oracle Linux instead of
`epel-release`

### `.github/workflows/docker-test.yml`
- Add CentOS Stream 10 (`quay.io/centos/centos:stream10`)
- Add Rocky Linux 10 (`rockylinux/rockylinux:10`)
- Add AlmaLinux 10 (`almalinux:10`)
- Add Oracle Linux 10 (`oraclelinux:10`)
- Fix Rocky Linux image names from `rockylinux:X` to
`rockylinux/rockylinux:X`

## Test plan

- [ ] CI passes for existing distributions
- [ ] CI passes for new version 10 distributions (where images are
available)
2025-12-11 20:22:00 +01:00
Stanislas 0d4d2229f4 test: add e2e tests for certificate revocation (#1345)
## Summary

- Add end-to-end tests for certificate revocation functionality
- Test that a revoked client certificate cannot connect to the VPN
- Test that a new certificate can be created with the same name as a
revoked one (validating the fix from #1185)
- Test that the new certificate can successfully connect

## Test Flow

1. **Initial connectivity tests** - existing tests pass
2. **Certificate revocation test**:
   - Create a new client `revoketest`
   - Connect with the certificate (verifies it works)
   - Disconnect the client
   - Revoke the certificate via the install script
- Try to reconnect with revoked cert (verifies connection is rejected)
3. **Reuse revoked name test**:
   - Create a new certificate with the same name `revoketest`
   - Verify both revoked and valid entries exist in `index.txt`
   - Connect with the new certificate (verifies it works)

## Changes

| File | Changes |
|------|---------|
| `test/server-entrypoint.sh` | Start OpenVPN in background, add
revocation test orchestration |
| `test/client-entrypoint.sh` | Add revocation test phases with signal
file coordination |
| `docker-compose.yml` | Remove read-only restriction on shared volume
for client |
| `Makefile` | Increase timeout from 60 to 180 iterations |
| `.github/workflows/docker-test.yml` | Increase timeouts, fix shared
volume |
2025-12-11 18:22:16 +01:00
Stanislas Lange 690414a56e ci: update Fedora versions to 42 and 43 2025-12-11 17:21:48 +01:00
Stanislas Lange d9e11822db fix: use pgrep -f to detect OpenVPN server, not transient processes
The previous check using `pgrep -x openvpn` was matching transient
openvpn processes like `openvpn --genkey` that run during installation,
causing false positives. This led to race conditions where the CI
thought the server was running when it was actually still installing.

Use `pgrep -f "openvpn.*server.conf"` to specifically match the actual
OpenVPN server process running with the server configuration.
2025-12-11 17:21:48 +01:00
Stanislas Lange 6cca56f5b5 ci: add install script log output in docker-test workflow
Add step to display the install script log file (openvpn-install.log)
which includes timestamps and all installation activity.

This makes debugging CI failures easier by providing detailed logs
directly in the workflow output.
2025-12-11 17:21:48 +01:00
Joel RamosandStanislas 3c9580b5b4 fix: allow reusing revoked client names (#1185)
Close https://github.com/angristan/openvpn-install/pull/680, close
https://github.com/angristan/openvpn-install/issues/652, close
https://github.com/angristan/openvpn-install/issues/1024, close
https://github.com/angristan/openvpn-install/issues/746

Co-authored-by: Stanislas <git@slange.me>
2025-12-11 17:15:34 +01:00
Stanislas 65f4885c36 refactor: replace wget with curl (#1343)
- Replace `wget` with `curl` for downloading Easy-RSA
- Remove `wget` from package dependencies across all distributions
- Ensure `curl` and `ca-certificates` are installed on all distributions
- Add `--retry 3` for automatic retries on transient network failures
2025-12-11 17:04:44 +01:00
Stanislas Lange 599d122113 fix: use pgrep -x to accurately check for OpenVPN process in docker-test workflow 2025-12-11 16:26:45 +01:00
Leo WangandStanislas 77a025d042 Improve wording of README (#1134)
I know I’m setting up open VPN because google gave me this page, but I
wasn’t sure if I should run this script on my Amazon Linux 2 server or
my MacBook Pro client for a hot minute.

<!---
❗️ Please read ❗️
➡️ Please make sure you've followed the guidelines:
https://github.com/angristan/openvpn-install#contributing
✅ Please make sure your changes are tested and working
🗣️ Please avoid large PRs, and discuss changes in a GitHub issue first
✋ If the changes are too big and not in line with the project, they will
probably be rejected. Remember that this script is meant to be simple
and easy to use.
--->

---------

Co-authored-by: Stanislas <github@slange.me>
2025-12-11 13:58:40 +01:00
Stanislas Lange e06329c770 docs: update README to include Amazon Linux in supported distributions 2025-12-11 13:49:05 +01:00
Stanislas 0f324ef3b9 docs: add "Why OpenVPN?" section to README (#1341)
- Add a new "Why OpenVPN?" section explaining when OpenVPN is preferable
over WireGuard
- Move the wireguard-install link from the intro to this new section
2025-12-11 13:45:53 +01:00
StanislasandHenry N 2374e4e81c Refactor Unbound setup and add E2E tests (#1340)
Refactor Unbound DNS installation to use modern `conf.d` pattern and add
E2E testing.

**Changes:**
- Unified Unbound config across all distros using
`/etc/unbound/unbound.conf.d/openvpn.conf`
- Added startup validation with retry logic
- Added `ip-freebind` to allow binding before tun interface exists
- E2E tests now verify Unbound DNS resolution from VPN clients

**Testing:**
- Server: verifies config creation, interface binding, security options
- Client: verifies DNS resolution through Unbound (10.8.0.1)

---

Closes https://github.com/angristan/openvpn-install/issues/602 Closes
https://github.com/angristan/openvpn-install/pull/604 Closes
https://github.com/angristan/openvpn-install/issues/1189

Co-authored-by: Henry N <henrynmail-github@yahoo.de>
2025-12-11 13:14:56 +01:00
renovate[bot]andStanislas Lange 1aae852c60 chore(deps): update super-linter/super-linter action to v8 (#1339)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[super-linter/super-linter](https://redirect.github.com/super-linter/super-linter)
| action | major | `v7` -> `v8` |

---

### Release Notes

<details>
<summary>super-linter/super-linter (super-linter/super-linter)</summary>

###
[`v8`](https://redirect.github.com/super-linter/super-linter/blob/HEAD/CHANGELOG.md#680-2024-07-31)

[Compare
Source](https://redirect.github.com/super-linter/super-linter/compare/v7...v8)

##### 🚀 Features

- allow using both prettier and standardjs
([#&#8203;5679](https://redirect.github.com/super-linter/super-linter/issues/5679))
([2daf461](https://redirect.github.com/super-linter/super-linter/commit/2daf461143778318ccc60ba59f175d385f222e4d))
- customize phpstan config file name
([#&#8203;5940](https://redirect.github.com/super-linter/super-linter/issues/5940))
([20c4df5](https://redirect.github.com/super-linter/super-linter/commit/20c4df58c060cf122dce53b14ec578d48d921fb0))
- enable dotenv-linter for slim images
([#&#8203;5868](https://redirect.github.com/super-linter/super-linter/issues/5868))
([c770a8d](https://redirect.github.com/super-linter/super-linter/commit/c770a8d253f8b8852fd3404b63b807d93cc3691a))
- remove no-eslintrc and simplify eslint conf
([#&#8203;5809](https://redirect.github.com/super-linter/super-linter/issues/5809))
([5be4926](https://redirect.github.com/super-linter/super-linter/commit/5be49266330f237f4a8ab2acccffe93b69cf4b04)),
closes
[#&#8203;5688](https://redirect.github.com/super-linter/super-linter/issues/5688)
- write github actions step summary
([#&#8203;5867](https://redirect.github.com/super-linter/super-linter/issues/5867))
([57c8658](https://redirect.github.com/super-linter/super-linter/commit/57c86588c388a515ae31f498b4cc4a6337169c11)),
closes
[#&#8203;5650](https://redirect.github.com/super-linter/super-linter/issues/5650)

##### 🐛 Bugfixes

- avoid duplicated content in summary
([#&#8203;5939](https://redirect.github.com/super-linter/super-linter/issues/5939))
([ef57e13](https://redirect.github.com/super-linter/super-linter/commit/ef57e132e136ab9991a0cc1517236e827d27baf9))
- store outputs in the main output directory
([#&#8203;5899](https://redirect.github.com/super-linter/super-linter/issues/5899))
([78ed3ef](https://redirect.github.com/super-linter/super-linter/commit/78ed3ef5fc8fe45290b530f94077281d2ac8e634))
- update pylint to ignore import-errors
([#&#8203;5927](https://redirect.github.com/super-linter/super-linter/issues/5927))
([eec862d](https://redirect.github.com/super-linter/super-linter/commit/eec862d0ea33fe6a836dfd545eef1125e530c794))
- update the list of linters to remove
([#&#8203;5870](https://redirect.github.com/super-linter/super-linter/issues/5870))
([6bd7659](https://redirect.github.com/super-linter/super-linter/commit/6bd76596f3f7df70a323eabb797f028293873424))

##### ⬆️ Dependency updates

- **bundler:** bump rubocop-minitest in /dependencies
([#&#8203;5875](https://redirect.github.com/super-linter/super-linter/issues/5875))
([9751e62](https://redirect.github.com/super-linter/super-linter/commit/9751e62beed14780ff12fc073c7aa9eafbd449f7))
- **bundler:** bump rubocop-performance in /dependencies
([#&#8203;5777](https://redirect.github.com/super-linter/super-linter/issues/5777))
([763dcc4](https://redirect.github.com/super-linter/super-linter/commit/763dcc4d456ae0c347801d30b5ec00dbfaa60ef2))
- **bundler:** bump rubocop-rspec from 2.30.0 to 3.0.3 in /dependencies
([#&#8203;5878](https://redirect.github.com/super-linter/super-linter/issues/5878))
([592d903](https://redirect.github.com/super-linter/super-linter/commit/592d903c509a4c70c89cc009e74b63c3273c5e7b))
- **dev-docker:** bump node in /dev-dependencies
([#&#8203;5872](https://redirect.github.com/super-linter/super-linter/issues/5872))
([587fe0a](https://redirect.github.com/super-linter/super-linter/commit/587fe0a8b9318324fbfd86b9cd87b0ac6b24ba42))
- **dev-npm:** bump release-please in /dev-dependencies
([#&#8203;5754](https://redirect.github.com/super-linter/super-linter/issues/5754))
([6bb3f78](https://redirect.github.com/super-linter/super-linter/commit/6bb3f789bb5cacff35492a1245befb2fd13b97f5))
- **docker:** bump alpine/helm from 3.14.4 to 3.15.3
([#&#8203;5882](https://redirect.github.com/super-linter/super-linter/issues/5882))
([b5bf9f2](https://redirect.github.com/super-linter/super-linter/commit/b5bf9f297d13e9563bd708ae98e2e05b9b44698c))
- **docker:** bump alpine/terragrunt from 1.9.0 to 1.9.2
([#&#8203;5883](https://redirect.github.com/super-linter/super-linter/issues/5883))
([95feeac](https://redirect.github.com/super-linter/super-linter/commit/95feeacb0ab075e7e183c5f8ea1c515992f66bbf))
- **docker:** bump dart from 3.4.2-sdk to 3.4.4-sdk
([#&#8203;5764](https://redirect.github.com/super-linter/super-linter/issues/5764))
([b75f1cf](https://redirect.github.com/super-linter/super-linter/commit/b75f1cfcefc1b62a81b916bd00d0b8dfa7ad69aa))
- **docker:** bump dotnet/sdk
([#&#8203;5873](https://redirect.github.com/super-linter/super-linter/issues/5873))
([f068663](https://redirect.github.com/super-linter/super-linter/commit/f06866359b4158e04825a03d5852823d47d78b05))
- **docker:** bump golangci/golangci-lint from v1.59.0 to v1.59.1
([#&#8203;5748](https://redirect.github.com/super-linter/super-linter/issues/5748))
([81ab76d](https://redirect.github.com/super-linter/super-linter/commit/81ab76d00179b8d66e7f909c546cb7bfbde8ae9f))
- **docker:** bump goreleaser/goreleaser from v1.26.2 to v2.1.0
([#&#8203;5881](https://redirect.github.com/super-linter/super-linter/issues/5881))
([d84d439](https://redirect.github.com/super-linter/super-linter/commit/d84d4393933047f08abf0871aacefa04c63b5f32))
- **docker:** bump hashicorp/terraform from 1.8.4 to 1.9.2
([#&#8203;5885](https://redirect.github.com/super-linter/super-linter/issues/5885))
([d384e67](https://redirect.github.com/super-linter/super-linter/commit/d384e674c729dfd236ce888d04e4bdd24a85b630))
- **docker:** bump mstruebing/editorconfig-checker from v3.0.1 to v3.0.3
([#&#8203;5856](https://redirect.github.com/super-linter/super-linter/issues/5856))
([81196f4](https://redirect.github.com/super-linter/super-linter/commit/81196f4267199e63ec82dd0aaff9d1f400b38cac))
- **docker:** bump python from 3.12.3-alpine3.20 to 3.12.4-alpine3.20
([#&#8203;5884](https://redirect.github.com/super-linter/super-linter/issues/5884))
([8a044b5](https://redirect.github.com/super-linter/super-linter/commit/8a044b58dee1dd7a03fcaf2d7d6b58754f156be2))
- **docker:** bump scalameta/scalafmt from v3.8.1 to v3.8.2
([#&#8203;5765](https://redirect.github.com/super-linter/super-linter/issues/5765))
([4931da5](https://redirect.github.com/super-linter/super-linter/commit/4931da55da35a8b438354adc03d220f693458f75))
- **docker:** bump terraform-linters/tflint from v0.51.2 to v0.52.0
([#&#8203;5858](https://redirect.github.com/super-linter/super-linter/issues/5858))
([ae1dba5](https://redirect.github.com/super-linter/super-linter/commit/ae1dba53fdc862da0064f56382dd86cd273862f6))
- **docker:** bump yoheimuta/protolint from 0.50.2 to 0.50.3
([#&#8203;5857](https://redirect.github.com/super-linter/super-linter/issues/5857))
([913bd0d](https://redirect.github.com/super-linter/super-linter/commit/913bd0dd47d3a42d6f2d3acad8fb59c2f185337b))
- **docker:** bump zricethezav/gitleaks from v8.18.3 to v8.18.4
([#&#8203;5768](https://redirect.github.com/super-linter/super-linter/issues/5768))
([33bb4b4](https://redirect.github.com/super-linter/super-linter/commit/33bb4b46d473c80a82364c50746ed20d19231f90))
- **github-actions:** bump actions/download-artifact from 4.1.7 to 4.1.8
([#&#8203;5861](https://redirect.github.com/super-linter/super-linter/issues/5861))
([ed72e66](https://redirect.github.com/super-linter/super-linter/commit/ed72e66416df8df15b492f7df00b8621b556893f))
- **github-actions:** bump actions/upload-artifact from 4.3.3 to 4.3.4
([#&#8203;5860](https://redirect.github.com/super-linter/super-linter/issues/5860))
([dd4313c](https://redirect.github.com/super-linter/super-linter/commit/dd4313c9b3bee70bfd968923e77430f3f19785aa))
- **github-actions:** bump docker/build-push-action from 5 to 6
([#&#8203;5770](https://redirect.github.com/super-linter/super-linter/issues/5770))
([27170b8](https://redirect.github.com/super-linter/super-linter/commit/27170b8e9243df7e18e59e7c43163b142568ee22))
- **java:** bump com.pinterest.ktlint:ktlint-cli in /dependencies/ktlint
([#&#8203;5849](https://redirect.github.com/super-linter/super-linter/issues/5849))
([19c5fce](https://redirect.github.com/super-linter/super-linter/commit/19c5fcea2ea6a72741e59a30cb815c5faac524be))
- **npm:** bump
[@&#8203;babel/eslint-parser](https://redirect.github.com/babel/eslint-parser)
in /dependencies
([#&#8203;5886](https://redirect.github.com/super-linter/super-linter/issues/5886))
([387a2b5](https://redirect.github.com/super-linter/super-linter/commit/387a2b56261451b12b00fc37d2fb79766564044d))
- **npm:** bump
[@&#8203;babel/preset-react](https://redirect.github.com/babel/preset-react)
in /dependencies
([#&#8203;5740](https://redirect.github.com/super-linter/super-linter/issues/5740))
([4eeb628](https://redirect.github.com/super-linter/super-linter/commit/4eeb62862e823fd431fefb0078e5605484934254))
- **npm:** bump
[@&#8203;babel/preset-typescript](https://redirect.github.com/babel/preset-typescript)
in /dependencies
([#&#8203;5734](https://redirect.github.com/super-linter/super-linter/issues/5734))
([de4b193](https://redirect.github.com/super-linter/super-linter/commit/de4b1930064cb6b5f65625101be33892c50d400f))
- **npm:** bump
[@&#8203;react-native/eslint-config](https://redirect.github.com/react-native/eslint-config)
in /dependencies
([#&#8203;5835](https://redirect.github.com/super-linter/super-linter/issues/5835))
([28c228d](https://redirect.github.com/super-linter/super-linter/commit/28c228dfc0b8279e28ca5bb72a34e9390eca81b9))
- **npm:** bump
[@&#8203;typescript-eslint/eslint-plugin](https://redirect.github.com/typescript-eslint/eslint-plugin)
in /dependencies
([#&#8203;5895](https://redirect.github.com/super-linter/super-linter/issues/5895))
([7f5b018](https://redirect.github.com/super-linter/super-linter/commit/7f5b018fb7237ef0d6d1cb1578729065bacb4310))
- **npm:** bump eslint-plugin-jest in /dependencies
([#&#8203;5738](https://redirect.github.com/super-linter/super-linter/issues/5738))
([1312398](https://redirect.github.com/super-linter/super-linter/commit/1312398b9c72138ce76f443dd933a8ff82f75fae))
- **npm:** bump eslint-plugin-jsx-a11y in /dependencies
([#&#8203;5797](https://redirect.github.com/super-linter/super-linter/issues/5797))
([8972772](https://redirect.github.com/super-linter/super-linter/commit/89727727323246be93c3ed88c0b0fe1f07e25468))
- **npm:** bump eslint-plugin-react in /dependencies
([#&#8203;5890](https://redirect.github.com/super-linter/super-linter/issues/5890))
([fe3e1f8](https://redirect.github.com/super-linter/super-linter/commit/fe3e1f83b7c7645640af9202bb7f4d8993f088fc))
- **npm:** bump eslint-plugin-vue from 9.26.0 to 9.27.0 in /dependencies
([#&#8203;5851](https://redirect.github.com/super-linter/super-linter/issues/5851))
([c2e85a9](https://redirect.github.com/super-linter/super-linter/commit/c2e85a9f03ceccfe41107ea1e627c8c222b2154a))
- **npm:** bump jscpd from 4.0.4 to 4.0.5 in /dependencies
([#&#8203;5852](https://redirect.github.com/super-linter/super-linter/issues/5852))
([042c6b1](https://redirect.github.com/super-linter/super-linter/commit/042c6b191708878b5db2b5096eadb1b4a6f4f27d))
- **npm:** bump next from 14.2.3 to 14.2.5 in /dependencies
([#&#8203;5887](https://redirect.github.com/super-linter/super-linter/issues/5887))
([22b7ba9](https://redirect.github.com/super-linter/super-linter/commit/22b7ba91d0d273fdc5369d1ead66ae2cee451df0))
- **npm:** bump prettier from 3.3.2 to 3.3.3 in /dependencies
([#&#8203;5891](https://redirect.github.com/super-linter/super-linter/issues/5891))
([b601212](https://redirect.github.com/super-linter/super-linter/commit/b6012126df99c9a8cdc5878bb9417ca7afee6809))
- **npm:** bump react-router-dom from 6.23.1 to 6.25.0 in /dependencies
([#&#8203;5897](https://redirect.github.com/super-linter/super-linter/issues/5897))
([ef71e94](https://redirect.github.com/super-linter/super-linter/commit/ef71e944ab41a8f04ba143f44d4b8443d2d982b5))
- **npm:** bump renovate from 37.421.5 to 37.432.0 in /dependencies
([#&#8203;5896](https://redirect.github.com/super-linter/super-linter/issues/5896))
([09a01eb](https://redirect.github.com/super-linter/super-linter/commit/09a01ebbe6dbb5e502817bb927191b8986c7c912))
- **npm:** bump textlint-rule-terminology in /dependencies
([#&#8203;5853](https://redirect.github.com/super-linter/super-linter/issues/5853))
([55b065d](https://redirect.github.com/super-linter/super-linter/commit/55b065d3c2d512648c52d4d695761a7d274ae769))
- **npm:** bump typescript from 5.4.5 to 5.5.3 in /dependencies
([#&#8203;5832](https://redirect.github.com/super-linter/super-linter/issues/5832))
([8605c2b](https://redirect.github.com/super-linter/super-linter/commit/8605c2b584b36201ac8d1acf98254c2d70776c75))
- **python:** bump ansible-lint in /dependencies/python
([#&#8203;5877](https://redirect.github.com/super-linter/super-linter/issues/5877))
([e90ee32](https://redirect.github.com/super-linter/super-linter/commit/e90ee328a2f6eb42952eeda45929271fddaf0c77))
- **python:** bump cfn-lint from 1.4.2 to 1.6.1 in /dependencies/python
([#&#8203;5876](https://redirect.github.com/super-linter/super-linter/issues/5876))
([ebf8cc8](https://redirect.github.com/super-linter/super-linter/commit/ebf8cc807a6c756755e790419fefcf9e5353b911))
- **python:** bump checkov in /dependencies/python
([#&#8203;5879](https://redirect.github.com/super-linter/super-linter/issues/5879))
([47392ad](https://redirect.github.com/super-linter/super-linter/commit/47392ad6636919b4b21e6ef2c3e1418cb1e931f3))
- **python:** bump flake8 from 7.0.0 to 7.1.0 in /dependencies/python
([#&#8203;5780](https://redirect.github.com/super-linter/super-linter/issues/5780))
([f019ee3](https://redirect.github.com/super-linter/super-linter/commit/f019ee34d21aa778d4b04217e7f717779ddfa767))
- **python:** bump ruff from 0.5.0 to 0.5.2 in /dependencies/python
([#&#8203;5880](https://redirect.github.com/super-linter/super-linter/issues/5880))
([3fd69a1](https://redirect.github.com/super-linter/super-linter/commit/3fd69a107b05f04135f1c01544c50b940a3b1e99))
- **python:** bump snakemake in /dependencies/python
([#&#8203;5874](https://redirect.github.com/super-linter/super-linter/issues/5874))
([2b6aa12](https://redirect.github.com/super-linter/super-linter/commit/2b6aa1290608468ee3828efdeabbeb467be43b80))
- **python:** bump sqlfluff from 3.0.7 to 3.1.0 in /dependencies/python
([#&#8203;5847](https://redirect.github.com/super-linter/super-linter/issues/5847))
([31da61e](https://redirect.github.com/super-linter/super-linter/commit/31da61e1899ca3c9d26681c265b0928b559f1274))

##### 🧰 Maintenance

- add super-linter configuration in the bug template
([#&#8203;5910](https://redirect.github.com/super-linter/super-linter/issues/5910))
([26ddd8b](https://redirect.github.com/super-linter/super-linter/commit/26ddd8b084201554e0351abf421d184864076a56))
- authenticate tflint init
([#&#8203;5894](https://redirect.github.com/super-linter/super-linter/issues/5894))
([cc20e45](https://redirect.github.com/super-linter/super-linter/commit/cc20e4561e549c6f6609900ba68602930c01fb7d))
- bump alpine image to 3.20 and php to 8.3.x
([#&#8203;5863](https://redirect.github.com/super-linter/super-linter/issues/5863))
([d9d1909](https://redirect.github.com/super-linter/super-linter/commit/d9d19095ecf48511e4c21a2e23f0def36187d141))
- enable dev-dependencies docker build checks
([#&#8203;5871](https://redirect.github.com/super-linter/super-linter/issues/5871))
([12da497](https://redirect.github.com/super-linter/super-linter/commit/12da4973c69e6987217089a418199a8227f658d7))
- fix docker build warnings
([#&#8203;5862](https://redirect.github.com/super-linter/super-linter/issues/5862))
([fc094cc](https://redirect.github.com/super-linter/super-linter/commit/fc094cc1a4be6a290c49c633fb857c454a98da47))
- print info about the environment, image size
([#&#8203;5869](https://redirect.github.com/super-linter/super-linter/issues/5869))
([bcf8ca8](https://redirect.github.com/super-linter/super-linter/commit/bcf8ca82ad571bb0a04f028193b3f56486cfbeb4))
- remove duplicated configuration files
([#&#8203;5928](https://redirect.github.com/super-linter/super-linter/issues/5928))
([70e0239](https://redirect.github.com/super-linter/super-linter/commit/70e02391170f6aaff4f0b4e80bf9bc8300940171))
- run docker build checks
([#&#8203;5864](https://redirect.github.com/super-linter/super-linter/issues/5864))
([ce59f5c](https://redirect.github.com/super-linter/super-linter/commit/ce59f5c323a8e5038753582dc265ab172b654834))
- split validation logic in smaller functions
([#&#8203;5892](https://redirect.github.com/super-linter/super-linter/issues/5892))
([d2d7334](https://redirect.github.com/super-linter/super-linter/commit/d2d73347d3e49fb28061a41df471afdcf0a579ba))
- update dependabot config for ci/dev updates
([#&#8203;5898](https://redirect.github.com/super-linter/super-linter/issues/5898))
([e374e48](https://redirect.github.com/super-linter/super-linter/commit/e374e489339410662293e39f4147dc69d098077f))
- update release-please to the new workspace
([#&#8203;5901](https://redirect.github.com/super-linter/super-linter/issues/5901))
([2ecf945](https://redirect.github.com/super-linter/super-linter/commit/2ecf94533920fb6a90ba5f029230cd4cdc69f855))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/angristan/openvpn-install).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Mi4yIiwidXBkYXRlZEluVmVyIjoiNDIuNDIuMiIsInRhcmdldEJyYW5jaCI6Im1hc3RlciIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-11 11:12:00 +01:00
renovate[bot] 9162924468 chore(deps): update actions/checkout action to v6 (#1338)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://redirect.github.com/actions/checkout) |
action | major | `v4` -> `v6` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

### [`v6`](https://redirect.github.com/actions/checkout/compare/v5...v6)

[Compare
Source](https://redirect.github.com/actions/checkout/compare/v5...v6)

### [`v5`](https://redirect.github.com/actions/checkout/compare/v4...v5)

[Compare
Source](https://redirect.github.com/actions/checkout/compare/v4...v5)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/angristan/openvpn-install).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Mi4yIiwidXBkYXRlZEluVmVyIjoiNDIuNDIuMiIsInRhcmdldEJyYW5jaCI6Im1hc3RlciIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 10:29:01 +01:00
Stanislas 2ecd4bd6e4 feat: add Data Channel Offload (DCO) availability check (#1331)
- Add detection and logging for OpenVPN Data Channel Offload (DCO)
support during installation
- DCO is a kernel acceleration feature (merged into Linux 6.16) that
improves VPN performance
- Add DCO documentation to README
2025-12-10 18:53:45 +01:00
renovate[bot]andgithub-actions[bot] 3e46cfb3bd chore(deps): update dependency openvpn/easy-rsa to v3.2.4 (#1335)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [OpenVPN/easy-rsa](https://redirect.github.com/OpenVPN/easy-rsa) |
patch | `3.2.3` -> `3.2.4` |

---

### Release Notes

<details>
<summary>OpenVPN/easy-rsa (OpenVPN/easy-rsa)</summary>

###
[`v3.2.4`](https://redirect.github.com/OpenVPN/easy-rsa/releases/tag/v3.2.4):
3.2.4

[Compare
Source](https://redirect.github.com/OpenVPN/easy-rsa/compare/v3.2.3...v3.2.4)

#### What's Changed

- export-p12: Move inline file to 'inline/private' folder by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1356](https://redirect.github.com/OpenVPN/easy-rsa/pull/1356)
- Restructure help by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1363](https://redirect.github.com/OpenVPN/easy-rsa/pull/1363)
- New global option: `--no-lockfile` = env-var: `$EASYRSA_NO_LOCKFILE`
by [@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1364](https://redirect.github.com/OpenVPN/easy-rsa/pull/1364)
- Restructure `verify_working_env()` by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1367](https://redirect.github.com/OpenVPN/easy-rsa/pull/1367)
- Improve verbose by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1368](https://redirect.github.com/OpenVPN/easy-rsa/pull/1368)
- Windows easyrsa-shell-init.sh: Replace 'read -p' by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1371](https://redirect.github.com/OpenVPN/easy-rsa/pull/1371)
- mutual\_exclusions(): Include basic checks for --startdate/--enddate
by [@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1372](https://redirect.github.com/OpenVPN/easy-rsa/pull/1372)
- easyrsa-shell-init.sh: Allow Easy-RSA to use '\User$HOME' directory by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1374](https://redirect.github.com/OpenVPN/easy-rsa/pull/1374)
- Remove 'easyrsa\_mkdir()', use only 'mkdir' by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1376](https://redirect.github.com/OpenVPN/easy-rsa/pull/1376)
- revoke: Archive request and private key files and expand help by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1378](https://redirect.github.com/OpenVPN/easy-rsa/pull/1378)
- set\_no\_clobber(): Add simple error detection by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1379](https://redirect.github.com/OpenVPN/easy-rsa/pull/1379)
- random: Use verify\_working\_env() to configure EASYRSA\_OPENSSL by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1381](https://redirect.github.com/OpenVPN/easy-rsa/pull/1381)
- self\_sign(): Force use of Easy-RSA X509-type file 'selfsign' by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1383](https://redirect.github.com/OpenVPN/easy-rsa/pull/1383)

**Full Changelog**:
<https://github.com/OpenVPN/easy-rsa/compare/v3.2.3...v3.2.4>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/angristan/openvpn-install).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi40Mi4yIiwidXBkYXRlZEluVmVyIjoiNDIuNDIuMiIsInRhcmdldEJyYW5jaCI6Im1hc3RlciIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-10 18:39:39 +01:00
Stanislas Lange 5d9687f8b0 style: format renovate.json with prettier 2025-12-10 18:32:03 +01:00
Stanislas ba1d0419a8 fix: use PAT to trigger CI after hash update (#1337)
- Commits made with `GITHUB_TOKEN` don't trigger workflows
- Using a PAT allows the hash update commit to trigger CI checks
- Fixes the issue where PR #1335 didn't have CI triggered after the hash
update
2025-12-10 18:23:58 +01:00
Stanislas Lange a6154c2653 Disable renovate check for disabled workflow 2025-12-10 18:14:57 +01:00
Stanislas Lange 2f24d2aec7 Remove Dependabot configuration 2025-12-10 18:14:01 +01:00
Stanislas a4c51f9bf9 ci: add Renovate for Easy-RSA version updates (#1333)
## Summary

- Add Renovate configuration to automatically track Easy-RSA releases
- Add GitHub Action to auto-update SHA256 hash on Renovate PRs

## How it works

1. **Renovate** detects a new Easy-RSA release → creates PR updating
`EASYRSA_VERSION`
2. **GitHub Action** triggers on the PR → downloads tarball → computes
SHA256 → commits fix
3. PR is ready to merge with both version and hash updated

---

I intentionally updated to the second-to-last version in
https://github.com/angristan/openvpn-install/commit/bda450948a933224f4f779a24a44c6279e1574a1
to test if this works.
2025-12-10 18:08:54 +01:00
Stanislas b9a1650027 feat: drop Amazon Linux 2 support (#1332)
## Summary

- Remove Amazon Linux 2 support from the installer
- Amazon Linux 2023 remains fully supported

## Motivation

Amazon Linux 2 is reaching EOL.

Additionally, Amazon Linux 2 ships with **OpenSSL 1.0.2k** (from 2017)
which is incompatible with Easy-RSA 3.2.x. The newer Easy-RSA versions
use `openssl x509 -ext` which doesn't exist in OpenSSL 1.0.x, causing
certificate generation to fail.

This blocks our ability to upgrade Easy-RSA:
https://github.com/angristan/openvpn-install/commit/bda450948a933224f4f779a24a44c6279e1574a1

## Changes

- Updated OS detection to reject Amazon Linux 2 with a clear message
- Removed Amazon Linux 2 specific code paths (EPEL installation, yum
commands)
- Removed from CI test matrix
- Updated README supported distributions table
- Updated Makefile test targets
- Also, add Amazon Linux 2023 Unbound handling
2025-12-10 17:54:00 +01:00
Stanislas Lange bda450948a feat: update EasyRSA version and revoke command 2025-12-10 16:58:35 +01:00
Stanislas c0fcf91972 feat: add ChaCha20-Poly1305 cipher support (#1330)
## Summary

- Add `CHACHA20-POLY1305` as a data channel cipher option
- Add `ECDHE-*-CHACHA20-POLY1305` control channel cipher options  
- Add version check (requires OpenVPN 2.5+)
- Update README documentation

ChaCha20-Poly1305 is particularly useful on devices without hardware AES
acceleration (AES-NI), such as ARM-based devices (Raspberry Pi, etc.)
and older CPUs, where it can provide better performance than AES.

Closes #1244 Closes #190
2025-12-10 00:11:25 +01:00
Stanislas ffcffac061 refactor: improve certificate duration variable naming (#1329)
## Summary

- Rename constants to `DEFAULT_CERT_VALIDITY_DURATION_DAYS` and
`DEFAULT_CRL_VALIDITY_DURATION_DAYS` for clarity
- Replace all hardcoded `3650` values with the constants
- Split `DAYS_VALID` into `CLIENT_CERT_DURATION_DAYS` and
`SERVER_CERT_DURATION_DAYS` for more granular control over client vs
server certificate validity
- Increase CRL validity to 15 years (5475 days) to provide a 5-year
safety buffer over the default 10-year certificate validity
- Update README with new headless install variables

## Breaking changes

- `DAYS_VALID` environment variable is replaced by
`CLIENT_CERT_DURATION_DAYS` and `SERVER_CERT_DURATION_DAYS`
2025-12-09 23:33:57 +01:00
Stanislas Lange f9a544104e docs: add missing headless variables to README
Add MULTI_CLIENT and DAYS_VALID to the documented headless install
variables, matching what the script actually supports.
2025-12-09 21:55:36 +01:00
Stanislas 6b09270347 feat: add certificate renewal functionality (#1328)
## Summary

- Add certificate renewal for both client and server certificates
- Allow custom validity period during renewal (prompts user, defaults to
3650 days)
- Show expiry info inline in menus (e.g., "Renew the server certificate
(expires in 3542 days)")
- Regenerate `.ovpn` files after client renewal
- Restart OpenVPN service after server renewal
- Extract reusable helper functions to reduce code duplication
- Add robust input validation and error handling

## New menu option

```
What do you want to do?
   1) Add a new user
   2) Revoke existing user
   3) Renew certificate        ← NEW
   4) Remove OpenVPN
   5) Exit
```

## Renewal submenu

```
What do you want to renew?
   1) Renew a client certificate
   2) Renew the server certificate (expires in 3542 days)
   3) Back to main menu
```

Client list shows expiry for each:
```
Select the existing client certificate you want to renew
     1) alice (expires in 3542 days)
     2) bob (expires in 30 days)
     3) charlie (EXPIRED 5 days ago)
```

## Helper functions added

Extracted common code into reusable functions:
- `getHomeDir()` - home directory detection
- `regenerateCRL()` - CRL regeneration after cert changes
- `generateClientConfig()` - .ovpn file generation  
- `selectClient()` - client listing with optional expiry display
- `getDaysUntilExpiry()` - certificate expiry calculation
- `formatExpiry()` - human-readable expiry formatting

## Test plan

- [x] Client certificate renewal tested in Docker CI
- [x] Server certificate renewal tested in Docker CI
- [x] Certificate validity verified after renewal (~3650 days)
- [x] VPN connectivity tested with renewed certificate

Closes #974 #1002 #1228 #1060
2025-12-09 21:49:19 +01:00
Stanislas Lange fb2041d9bb Improve command logging in run_cmd function 2025-12-09 21:41:08 +01:00
Omid ShojaeeandStanislas Lange 625821dfd0 Allow custom certificate duration when creating clients (#1250)
For those who need it, the script asks for how many days the new client
should be valid. This defaults to 3650 days. Then it sets the
```EASYRSA_CERT_EXPIRE``` variable accordingly.

This script is meant to be simple which means it is for those who are
not tech-savvy to handle the complex task of installing and configuring
OpenVPN.

However if the user has a large number of clients and all of them are
valid for 10 years, it is very hard to keep track of them. This PR helps
them to set a reasonable validity period, while the default is the same.

---------

Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-09 20:04:29 +01:00
Stanislas 66890fb5d3 ci: prevent duplicate workflow runs (#1324)
## Summary
- Restrict `push` trigger to `master` branch only (feature branch pushes
won't trigger CI)
- Add concurrency groups to cancel redundant runs when new commits are
pushed
- Works correctly with fork PRs using standard `pull_request` event
2025-12-09 19:47:02 +01:00
Stanislas 8bd0c73f8f Use official OpenVPN repositories for latest stable versions (#1323)
## Summary

- Install OpenVPN from official upstream repositories instead of
distribution packages
- Gets the latest stable releases with security fixes and new features
- Properly cleans up repos and GPG keys on uninstall

## Repository sources

| OS | Repository |
|---|---|
| Debian/Ubuntu | `build.openvpn.net/debian/openvpn/stable` |
| CentOS/Oracle/Fedora | Fedora Copr `@OpenVPN/openvpn-release-2.6` |
| Amazon Linux/Arch | Distribution packages (no official repo available)
|

## Changes

- Add `installOpenVPNRepo()` function to configure official repos before
package installation
- Remove duplicate package installations between repo setup and install
functions
- Clean up repos and GPG keys during uninstall
- Standardize `log_success` (`[OK]`) for major milestones only


---

Close https://github.com/angristan/openvpn-install/pull/1294
2025-12-09 19:45:56 +01:00
Stanislas Lange b23517dbb0 Fix MULTI_CLIENT prompt blocking auto-install mode
The duplicate-cn feature added an interactive prompt that wasn't
following the auto-install pattern, causing the script to hang
when running with AUTO_INSTALL=y.
2025-12-09 18:30:57 +01:00
Stanislas Lange cd0fc55bf7 docs: add duplicate-cn feature to README 2025-12-09 18:15:54 +01:00
Shahzain AliandStanislas Lange 9e439b60ad Add option to allow multiple devices per client profile (duplicate-cn) (#1278)
Added duplicate-cn for connecting multiple clients using same .ovpn

---------

Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-09 18:12:23 +01:00
Stanislas Lange 8a133b7bed ci: run Docker e2e tests on pull requests 2025-12-09 18:06:53 +01:00
Stanislas 004fbb477a Add structured logging system with color-coded output and file logging (#1321)
## Summary
- Add comprehensive logging system with color-coded log levels ([INFO],
[WARN], [ERROR], [OK])
- Wrap all command executions with `run_cmd()` to capture output and
prevent leaks to stdout
- Add file logging with timestamps (default: `openvpn-install.log`)
- Suppress interactive prompts in auto-install mode for cleaner
CI/scripted usage
- Show log file location hint on errors for easier debugging

## Changes
- **openvpn-install.sh**: New logging functions (`log_info`, `log_warn`,
`log_error`, `log_fatal`, `log_success`, `log_prompt`, `log_header`,
`log_menu`, `run_cmd`), all `echo` statements converted to use logging
functions
- **test/validate-output.sh**: New E2E validator that ensures all script
output uses proper log formatting (catches raw echo leaks)
- **test/server-entrypoint.sh**: Integrates output validation into
Docker tests
- **test/Dockerfile.server**: Copies validation script into container

## Configuration
- `VERBOSE=1` - Show command output in terminal
- `LOG_FILE=path` - Customize log location (default:
`openvpn-install.log`)
- `LOG_FILE=""` - Disable file logging
- `FORCE_COLOR=1` - Force colored output in non-TTY environments
2025-12-09 15:52:37 +01:00
Stanislas Lange adc4c6d220 Remove cloud provisioning solutions section from README
I don't maintain them, so I can't vouch that they work.

Close https://github.com/angristan/openvpn-install/pull/934 as well
2025-12-09 15:02:49 +01:00
Stanislas Lange 0ed153b8ec Update pull request template to clarify maintenance burden of added features 2025-12-09 14:17:19 +01:00
Stanislas a3389c126c Add Docker-based E2E testing (#1320)
### Summary
- Add automated end-to-end testing using Docker to verify the installation script works across 18 Linux distributions
- Add Oracle Linux 9 support to the installation script
- Drop support for EOL distributions (Debian 8/9/10, CentOS 7, Ubuntu 16.04) 
- Disable Digital Ocean droplets based end-to-end tests, let's use docker from now on

### Changes
**New test infrastructure:**
- `test/Dockerfile.server` - Multi-OS server image with `BASE_IMAGE` build arg
- `test/Dockerfile.client` - Ubuntu 24.04 client for connectivity testing
- `test/server-entrypoint.sh` - Runs install script, verifies files exist, asserts iptables NAT rules, starts OpenVPN
- `test/client-entrypoint.sh` - Connects to VPN, verifies tun0 interface, pings gateway
- `docker-compose.yml` - Orchestrates server + client with shared volume
- `.github/workflows/docker-test.yml` - CI matrix testing 18 OS variants
- `.github/workflows/test.yml` - Removed push/PR triggers, now manual only for DO tests
- `Makefile` - Local testing commands (`make test`, `make test-ubuntu-24.04`, etc.)

**Distributions tested (18 total):**
| Family | Versions |
|--------|----------|
| Ubuntu | 18.04, 20.04, 22.04, 24.04 |
| Debian | 11, 12 |
| Fedora | 40, 41 |
| Rocky Linux | 8, 9 |
| AlmaLinux | 8, 9 |
| Oracle Linux | 8, 9 |
| Amazon Linux | 2, 2023 |
| CentOS Stream | 9 |
| Arch Linux | latest |
2025-12-07 12:27:41 +01:00
Stanislas Lange 94c1af2b5d Remove Fedora 43 OS image from CI workflow 2025-12-04 23:18:15 +01:00