Commit Graph

431 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
renovate[bot]
be2a195bb5 chore(deps): update dependency openvpn/easy-rsa to v3.2.5 (#1381)
This PR contains the following updates:

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

---

### Release Notes

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

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

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

#### What's Changed

- Replace `local` / `global` `openssl-easyrsa.cnf` by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1394](https://redirect.github.com/OpenVPN/easy-rsa/pull/1394)
- init-pki: Introduce configurable cryptography by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1397](https://redirect.github.com/OpenVPN/easy-rsa/pull/1397)
- Drop x509 type kdc built-in by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1399](https://redirect.github.com/OpenVPN/easy-rsa/pull/1399)
- Always generate an `openssl-easyrsa.cnf` or `x509-types` tmp-file by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1401](https://redirect.github.com/OpenVPN/easy-rsa/pull/1401)
- Libressl use `$EASYRSA_FORCE_SAFE_SSL` by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1402](https://redirect.github.com/OpenVPN/easy-rsa/pull/1402)
- Update EasyRSA-Advanced.md by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1403](https://redirect.github.com/OpenVPN/easy-rsa/pull/1403)
- `source_vars()`: Add `grep` regex for assign by equal `=` by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1405](https://redirect.github.com/OpenVPN/easy-rsa/pull/1405)
- export\_pkcs(), PKCS12 inline: Respect $EASYRSA\_NO\_INLINE by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1407](https://redirect.github.com/OpenVPN/easy-rsa/pull/1407)
- Introduce peer-fingerprint inline lists by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1410](https://redirect.github.com/OpenVPN/easy-rsa/pull/1410)
- help: Add '-b' alias for --batch and correct default 'vars' file by
[@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1411](https://redirect.github.com/OpenVPN/easy-rsa/pull/1411)
- New function ssl\_cert\_sig\_digest(); Extract certificae digest name
by [@&#8203;TinCanTech](https://redirect.github.com/TinCanTech) in
[#&#8203;1414](https://redirect.github.com/OpenVPN/easy-rsa/pull/1414)
- Upgrading OpenSSL for Windows to 3.6.0 by
[@&#8203;ecrist](https://redirect.github.com/ecrist) in
[#&#8203;1416](https://redirect.github.com/OpenVPN/easy-rsa/pull/1416)

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

</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>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-13 19:48:07 +01:00
Stanislas
0f2bd04447 feat: change default DNS resolver to Cloudflare (#1385)
- Change default DNS resolver from AdGuard DNS to Cloudflare (1.1.1.1)
- Applies to both interactive mode and AUTO_INSTALL mode
2025-12-13 19:32:07 +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
Stanislas
90f2313ff3 fix: use non-deprecated --genkey syntax for tls-crypt and tls-auth (#1383)
## Summary

- Replace deprecated `--genkey --secret` syntax with `--genkey secret`
for tls-crypt and tls-auth key generation

The OpenVPN source explicitly warns about this:
```
WARNING: Using --genkey --secret filename is DEPRECATED. Use --genkey secret filename instead.
```

Closes #1256
Close https://github.com/angristan/openvpn-install/issues/1280
2025-12-13 18:59:40 +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
Cezar Lungu
99c74e5af4 Delete old easy-rsa remove (#655)
It isn't packaged anymore with openvpn in the supported distros

Co-authored-by: Stanislas Lange <git@slange.me>
2025-12-13 15:11:17 +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
2c53bc0f83 feat: add run_cmd_fatal, fix Fedora, improve CI (#1369)
## Summary

This PR contains three related improvements:

### 1. Add `run_cmd_fatal` for critical operations
- New helper function that wraps `run_cmd` and exits on failure
- Converts critical operations (package installs, PKI setup, certificate
generation) to fail fast
- Non-critical operations (systemctl, cleanup) still use `run_cmd`
- Password-protected client certs run directly to preserve interactive
prompt

### 2. Fix Fedora installation
- Skip Copr repository setup since Fedora already ships OpenVPN 2.6.x
- Simplifies installation and removes external repository dependency

### 3. Improve CI test reliability
- Fail fast when `openvpn-test.service` fails during startup
- Add `journalctl` output to error diagnostics
- Display service status in wait loop
- Increase VPN gateway ping count from 3 to 10 for stability
2025-12-13 13:31:54 +01:00
wid-get
a6c88ddfda fix: use After=network-online.target for iptables service (#1140)
fixes not executing add-openvpn-rules.sh after OS reboot.
systemctl shows service as _running_ but no iptables rules added to
list.
Also this fixes issue
https://github.com/angristan/openvpn-install/issues/1127
2025-12-13 11:17:51 +01:00
Stanislas
e7aa52b51f fix(arch): detect pending kernel upgrades before installation (#1372)
On Arch Linux, the script uses `pacman -Syu` which performs a full
system upgrade. If a user's system is out of date and has pending kernel
updates:

1. Script runs `pacman -Syu` to install OpenVPN
2. Kernel gets upgraded along with other packages
3. The TUN module for the **new** kernel isn't loaded (old kernel still
running)
4. OpenVPN fails to start because TUN is unavailable
5. User has to reboot anyway, but now they're confused about why it
broke

So we check preventively now, and ask them to upgrade & reboot before
running the script

<img width="1342" height="488" alt="image"
src="https://github.com/user-attachments/assets/e9646737-eaf4-4035-b247-20e8f2daea60"
/>
2025-12-13 10:55:36 +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
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
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
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
Joel Ramos
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
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
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]
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
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 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
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 Shojaee
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
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
Shahzain Ali
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
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
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
cc834519ff Fix path to easy-rsa tarball in checksum verification 2025-12-04 23:04:11 +01:00
Stanislas Lange
7e9a713657 Fix shfmt formatting for constant comments 2025-12-04 23:04:11 +01:00
Stanislas Lange
3a0260e9b8 Make openvpn-install.sh executable 2025-12-04 23:04:11 +01:00
Stanislas Lange
b7557dd77f refactor: extract magic numbers to named constants
Move hardcoded values to readonly constants at the top of the script:
- CERT_VALIDITY_DAYS: certificate expiry (10 years)
- CRL_VALIDITY_DAYS: CRL expiry (10 years)
- EASYRSA_VERSION: easy-rsa version
- EASYRSA_SHA256: easy-rsa checksum

This improves maintainability and makes it easier to update these
values in the future.
2025-12-04 23:04:11 +01:00
Stanislas Lange
7304dbaac8 style: reduce shellcheck disables and fix warnings
- Remove unnecessary shellcheck disables (SC2164, SC1072, SC1073, SC1009)
- Add explanatory comments for remaining disables
- Fix SC2181: use direct exit code check instead of $?
- Fix SC2086: quote DH_KEY_SIZE variable
2025-12-04 23:04:11 +01:00
Stanislas Lange
960be1a658 security: add validation for root.hints download
Verify that the downloaded root.hints file is not empty and contains
expected DNS root server content before using it.
2025-12-04 23:04:11 +01:00
Stanislas Lange
94f0967878 security: add SHA256 checksum verification for easy-rsa download
Adds integrity verification to prevent supply chain attacks when
downloading easy-rsa from GitHub releases.
2025-12-04 23:04:11 +01:00
Stanislas Lange
1c5381cc03 fix: correct DNS prompt range from [1-12] to [1-13]
The prompt incorrectly showed [1-12] when option 13 (Custom DNS) is valid.
2025-12-04 23:04:11 +01:00
Stanislas Lange
74dcf67844 fix: remove duplicate echo in resolvePublicIP error message 2025-12-04 23:04:11 +01:00
mags0ft
a680d1f7e3 Correct numerous smaller spelling mistakes 2025-05-01 18:13:27 +02: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
Raphael Pinto
e1f19e0f24 Fix Public IP detection - Fix issue when seeip.org is unreachable #1241 (#1243)
The script does work when seeip.org is unreachable, so I changed the policy to define the public IP.

It solves the issue #1241

* Timeout limit on each try to solve the IP to avoid long waits;
* Extra public IP providers as failovers;
* the script only will try to solve an IP if the ENDPOINT is empty;

Co-authored-by: Stanislas <github@slange.me>
2024-11-07 20:55:14 +01:00