Commit Graph

8 Commits

Author SHA1 Message Date
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
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
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]
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
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
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