Commit Graph

242 Commits

Author SHA1 Message Date
Stanislas
d8aa625639 feat: add native firewalld support (#1388)
## Summary

- Add native firewalld support for RHEL/Fedora/CentOS systems
- When firewalld is active, use `firewall-cmd --permanent` instead of
raw iptables
- Rules persist across `firewall-cmd --reload`
- Fall back to iptables when firewalld is not active
- Add `After=firewalld.service` to iptables systemd unit for safety

## Changes

**Install:** Detect firewalld, use `firewall-cmd` to add port,
masquerade, and rich rules. Fall back to iptables if inactive.

**Uninstall:** Detect which method was used and clean up accordingly.

**Tests:** Add `fedora-42-firewalld` CI test with firewalld enabled.

---

Closes https://github.com/angristan/openvpn-install/issues/356
Closes https://github.com/angristan/openvpn-install/pull/1200
2025-12-13 20:49:40 +01:00
Stanislas
9175c2c221 feat: support headless client revocation by name (#1387)
Add support for revoking clients by setting the CLIENT environment
variable directly with the client name, in addition to the existing
CLIENTNUMBER support (from
https://github.com/angristan/openvpn-install/pull/1328)

This makes headless revocation more user-friendly as users no longer
need to know the client's index number.
2025-12-13 20:18:07 +01:00
Podesta
9fd183caed feat: add flag for creation or not of new client after install (#1010)
Add a flag `NEW_CLIENT` so that the user can choose whether or not he
wishes to create a new user after installation.
It is specially useful on headless installations, when upgrading to a
different server, but keeping old credentials.
It does not change any defaults, so if no flag is passed, it still
creates the new user.

---------

Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-13 19:57:02 +01:00
Stanislas
190e49ec33 feat: add list clients menu option (#1382)
## Summary

- Add new "List existing users" option to management menu (option 2)
- Displays all client certificates with status (Valid/Revoked),
expiration date, and days remaining
- Reads expiry directly from certificate files using openssl for
accurate 4-digit year dates
- Output sorted by expiration date (oldest first)
- Updates test MENU_OPTION values to match new menu numbering

Example output:
```
=== Existing Clients ===

Found 2 certificate(s)

   Name                      Status     Expiry       Remaining
   ----                      ------     ------       ---------
   user1                     Valid      2035-12-11   3649 days
   user2                     Revoked    unknown      unknown
```

Closes #567
Closes #563
Closes #587
2025-12-13 19:17:30 +01:00
Siebren Kraak
cb2d67be74 Add PASSPHRASE support in headless mode (#1015)
Add support for a password protected user in headless mode

Fixes #389

---------

Co-authored-by: Siebren Kraak <siebren.kraak@secura.com>
Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-13 15:42:43 +01:00
Stanislas
3561d13389 feat: add tls-crypt-v2 support with per-client keys (#1377)
## Summary

- Add support for OpenVPN's `tls-crypt-v2` feature (per-client TLS keys)
- Set `tls-crypt-v2` as the new recommended default
- Add CI tests for all 3 TLS key types

Closes #983
Closes #758
Closes https://github.com/angristan/openvpn-install/pull/1257

## What is tls-crypt-v2?

Unlike `tls-crypt` (shared key), `tls-crypt-v2` generates unique keys
per client:

- **Better security**: Compromised client keys don't affect other
clients
- **Easier management**: Individual client key revocation without
regenerating server key
- **Scalability**: Better suited for large deployments

Requires OpenVPN 2.5+ (released 2020).

## Menu options

```
1) tls-crypt-v2 (recommended): Encrypts control channel, unique key per client
2) tls-crypt: Encrypts control channel, shared key for all clients
3) tls-auth: Authenticates control channel, no encryption
```
2025-12-13 14:32:38 +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 Yunhe
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
Leo Wang
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
renovate[bot]
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](2daf461143))
- customize phpstan config file name
([#&#8203;5940](https://redirect.github.com/super-linter/super-linter/issues/5940))
([20c4df5](20c4df58c0))
- enable dotenv-linter for slim images
([#&#8203;5868](https://redirect.github.com/super-linter/super-linter/issues/5868))
([c770a8d](c770a8d253))
- remove no-eslintrc and simplify eslint conf
([#&#8203;5809](https://redirect.github.com/super-linter/super-linter/issues/5809))
([5be4926](5be4926633)),
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](57c86588c3)),
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](ef57e132e1))
- store outputs in the main output directory
([#&#8203;5899](https://redirect.github.com/super-linter/super-linter/issues/5899))
([78ed3ef](78ed3ef5fc))
- update pylint to ignore import-errors
([#&#8203;5927](https://redirect.github.com/super-linter/super-linter/issues/5927))
([eec862d](eec862d0ea))
- update the list of linters to remove
([#&#8203;5870](https://redirect.github.com/super-linter/super-linter/issues/5870))
([6bd7659](6bd76596f3))

##### ⬆️ Dependency updates

- **bundler:** bump rubocop-minitest in /dependencies
([#&#8203;5875](https://redirect.github.com/super-linter/super-linter/issues/5875))
([9751e62](9751e62bee))
- **bundler:** bump rubocop-performance in /dependencies
([#&#8203;5777](https://redirect.github.com/super-linter/super-linter/issues/5777))
([763dcc4](763dcc4d45))
- **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](592d903c50))
- **dev-docker:** bump node in /dev-dependencies
([#&#8203;5872](https://redirect.github.com/super-linter/super-linter/issues/5872))
([587fe0a](587fe0a8b9))
- **dev-npm:** bump release-please in /dev-dependencies
([#&#8203;5754](https://redirect.github.com/super-linter/super-linter/issues/5754))
([6bb3f78](6bb3f789bb))
- **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](b5bf9f297d))
- **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](95feeacb0a))
- **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](b75f1cfcef))
- **docker:** bump dotnet/sdk
([#&#8203;5873](https://redirect.github.com/super-linter/super-linter/issues/5873))
([f068663](f06866359b))
- **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](81ab76d001))
- **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](d84d439393))
- **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](d384e674c7))
- **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](81196f4267))
- **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](8a044b58de))
- **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](4931da55da))
- **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](ae1dba53fd))
- **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](913bd0dd47))
- **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](33bb4b46d4))
- **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](ed72e66416))
- **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](dd4313c9b3))
- **github-actions:** bump docker/build-push-action from 5 to 6
([#&#8203;5770](https://redirect.github.com/super-linter/super-linter/issues/5770))
([27170b8](27170b8e92))
- **java:** bump com.pinterest.ktlint:ktlint-cli in /dependencies/ktlint
([#&#8203;5849](https://redirect.github.com/super-linter/super-linter/issues/5849))
([19c5fce](19c5fcea2e))
- **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](387a2b5626))
- **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](4eeb62862e))
- **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](de4b193006))
- **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](28c228dfc0))
- **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](7f5b018fb7))
- **npm:** bump eslint-plugin-jest in /dependencies
([#&#8203;5738](https://redirect.github.com/super-linter/super-linter/issues/5738))
([1312398](1312398b9c))
- **npm:** bump eslint-plugin-jsx-a11y in /dependencies
([#&#8203;5797](https://redirect.github.com/super-linter/super-linter/issues/5797))
([8972772](8972772732))
- **npm:** bump eslint-plugin-react in /dependencies
([#&#8203;5890](https://redirect.github.com/super-linter/super-linter/issues/5890))
([fe3e1f8](fe3e1f83b7))
- **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](c2e85a9f03))
- **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](042c6b1917))
- **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](22b7ba91d0))
- **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](b6012126df))
- **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](ef71e944ab))
- **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](09a01ebbe6))
- **npm:** bump textlint-rule-terminology in /dependencies
([#&#8203;5853](https://redirect.github.com/super-linter/super-linter/issues/5853))
([55b065d](55b065d3c2))
- **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](8605c2b584))
- **python:** bump ansible-lint in /dependencies/python
([#&#8203;5877](https://redirect.github.com/super-linter/super-linter/issues/5877))
([e90ee32](e90ee328a2))
- **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](ebf8cc807a))
- **python:** bump checkov in /dependencies/python
([#&#8203;5879](https://redirect.github.com/super-linter/super-linter/issues/5879))
([47392ad](47392ad663))
- **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](f019ee34d2))
- **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](3fd69a107b))
- **python:** bump snakemake in /dependencies/python
([#&#8203;5874](https://redirect.github.com/super-linter/super-linter/issues/5874))
([2b6aa12](2b6aa12906))
- **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](31da61e189))

##### 🧰 Maintenance

- add super-linter configuration in the bug template
([#&#8203;5910](https://redirect.github.com/super-linter/super-linter/issues/5910))
([26ddd8b](26ddd8b084))
- authenticate tflint init
([#&#8203;5894](https://redirect.github.com/super-linter/super-linter/issues/5894))
([cc20e45](cc20e4561e))
- 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](d9d19095ec))
- enable dev-dependencies docker build checks
([#&#8203;5871](https://redirect.github.com/super-linter/super-linter/issues/5871))
([12da497](12da4973c6))
- fix docker build warnings
([#&#8203;5862](https://redirect.github.com/super-linter/super-linter/issues/5862))
([fc094cc](fc094cc1a4))
- print info about the environment, image size
([#&#8203;5869](https://redirect.github.com/super-linter/super-linter/issues/5869))
([bcf8ca8](bcf8ca82ad))
- remove duplicated configuration files
([#&#8203;5928](https://redirect.github.com/super-linter/super-linter/issues/5928))
([70e0239](70e0239117))
- run docker build checks
([#&#8203;5864](https://redirect.github.com/super-linter/super-linter/issues/5864))
([ce59f5c](ce59f5c323))
- split validation logic in smaller functions
([#&#8203;5892](https://redirect.github.com/super-linter/super-linter/issues/5892))
([d2d7334](d2d73347d3))
- update dependabot config for ci/dev updates
([#&#8203;5898](https://redirect.github.com/super-linter/super-linter/issues/5898))
([e374e48](e374e48933))
- update release-please to the new workspace
([#&#8203;5901](https://redirect.github.com/super-linter/super-linter/issues/5901))
([2ecf945](2ecf945339))

</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
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
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:
bda450948a

## 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
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
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
cd0fc55bf7 docs: add duplicate-cn feature to README 2025-12-09 18:15:54 +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
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
46a295b538 docs: update security section note for OpenVPN 2.5+
Replace the warning about outdated documentation with a note
clarifying that TLS 1.2 is kept as minimum for client compatibility
while acknowledging OpenVPN 2.5+ features.
2025-12-04 23:04:11 +01:00
Stanislas Lange
bf31e0ca64 docs: fix broken workflow link (push.yml -> lint.yml)
The workflow file was renamed but the README link was not updated.
2025-12-04 23:04:11 +01:00
Stanislas Lange
7e32f6ae83 Fix mermaid diagram in README 2025-03-15 22:52:11 +01:00
Blake Fleischer
399c3c87b9 Add support for Amazon Linux 2023 out of the box (#1259)
Co-authored-by: Stanislas Lange <git@slange.me>
2025-03-10 10:24:45 +01:00
Stanislas Lange
e2d4990ae1 Improve README 2025-01-06 17:25:26 +01:00
Stanislas Lange
dc114f3243 Update distribution matrix for end-to-end tests 2024-11-07 20:49:42 +01:00
Stanislas Lange
5a4b31bd0d Fix typo in README 2023-11-20 21:21:56 +01:00
Stanislas Lange
80feebed16 Remove visitors badge 2023-01-22 16:43:13 +01:00
Stanislas Lange
d096f7a3a2 Add star history 2023-01-22 16:42:48 +01:00
Stanislas Lange
33fe6af131 Update cloud providers 2023-01-22 01:55:06 +01:00
Stanislas Lange
d2556ff235 Add support for CentOS 9 + update supported distributions 2023-01-22 00:57:40 +01:00
Stanislas Lange
0ac1bf4f51 Format markdown table in readme 2023-01-21 23:41:03 +01:00
Stanislas Lange
64cbbce0b7 Add OpenVPN 2.5 notice to README 2023-01-21 23:40:01 +01:00
Stanislas Lange
2d0eca1a1d Update issue/PR template + contributing guidelines 2023-01-21 23:06:44 +01:00
Adiyat Mubarak
deb5867979 Update README.md OpenVPN client for macOS 2022-08-02 10:16:42 +02:00
Stanislas
c2059d684d Add SayThanks badge 2022-01-31 01:40:10 +01:00
Stanislas
fdc3f25987 Fix saythanks URL in README 2022-01-31 01:36:59 +01:00
Paul Marsicovetere
fa123bede7 Add openvpn-ephemeral Terraform module to README (#881) 2021-10-18 10:44:45 +02:00
James Lee
8783719459 Add support for AlmaLinux 8 (#891) 2021-08-27 15:24:53 +02:00
Stanislas
bcd1d8a53e Document Rocky Linux support 2021-07-06 10:56:15 +02:00
Stanislas
b9deadef61 readme: remove broken hall of fame 2021-05-31 02:00:33 +02:00
rvva
bfdf48c392 Add support for Oracle Linux 8 (#810)
Co-authored-by: Stanislas <stanislas.lange@pm.me>
2021-03-22 10:48:15 +01:00
Stanislas Lange
e16d93f314 readme: update provider link 2020-10-28 18:58:51 +01:00
Stanislas
bd047c08d7 ci: use super-linter (#683) 2020-10-21 13:59:49 +02:00
Stanislas
4eb349bf10 readme: update badge 2020-10-19 12:05:08 +02:00