Keep technical content intact while simplifying and clarifying descriptions
This commit is contained in:
@@ -1,211 +1,156 @@
|
|||||||
# 🔐 dynTLS
|
# dynTLS
|
||||||
|
|
||||||
**Granular Let's Encrypt certificate management for multi-service environments**
|
Granular Let's Encrypt certificate management for multi-service environments.
|
||||||
Provides flexible ACME backend integration, DNS/http challenges and per-service certificate deployment.
|
|
||||||
|
|
||||||
This utility simplifies issuing and managing TLS certificates via Let’s Encrypt for multiple services and hosts (e.g. Postfix, Dovecot, web servers and others). It separates ACME handling from deployment logic, supports HTTP-01 and DNS-01 challenges and maps issued certificates cleanly to individual services.
|
This repository provides the backend components for issuing, renewing and deploying TLS certificates in self-hosted, multi-service environments. It separates ACME handling from deployment logic, supports HTTP-01 and DNS-01 challenge workflows and maps issued certificates cleanly to individual services and hosts.
|
||||||
|
|
||||||
Key features:
|
|
||||||
|
|
||||||
- 🔁 Automated issuance and renewal of Let’s Encrypt certificates
|
|
||||||
- 🌐 Support for HTTP-01 and DNS-01 challenges via external ACME client
|
|
||||||
- 🧩 Flexible ACME backend selection (e.g. customized `letsencrypt_master_local.sh`)
|
|
||||||
- 🎯 Per-host and per-service certificate mapping with backup handling
|
|
||||||
- 📜 Central configuration via `vars` file
|
|
||||||
- 📂 Plain repository layout with optional contrib scripts under `./contrib/acme`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Outline
|
## Outline
|
||||||
|
|
||||||
1. [Features](#features)
|
- [Features](#features)
|
||||||
2. [Installation](#installation)
|
- [Installation](#installation)
|
||||||
3. [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
4. [Directory Layout](#directory-layout)
|
- [Directory Layout](#directory-layout)
|
||||||
5. [CRON Job Example](#cron-job-example)
|
- [CRON Job Example](#cron-job-example)
|
||||||
6. [ACME Backend](#acme-backend)
|
- [ACME Backend](#acme-backend)
|
||||||
7. [License](#license)
|
- [License](#license)
|
||||||
8. [Authors](#authors)
|
- [Authors](#authors)
|
||||||
9. [Project Home](#project-home)
|
- [Project Home](#project-home)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Manages Let’s Encrypt certificates for multiple domains and services
|
- Certificate management for multiple domains and services
|
||||||
- Uses a configurable ACME backend script (e.g. `letsencrypt_master_local.sh`)
|
- Configurable external ACME backend integration
|
||||||
- Supports HTTP-01 and DNS-01 challenges (e.g. via Bind/nsupdate, TSIG, `rndc`)
|
- HTTP-01 and DNS-01 challenge support
|
||||||
- Validates hostnames, SAN lists and certificate expiration before deployment
|
- Per-host and per-service certificate mapping
|
||||||
- Creates backups of replaced certificates and can prune old backups
|
- Backup creation and optional backup pruning
|
||||||
- Logs operations with log levels and domain-set IDs for better traceability
|
- Central configuration through a separate `vars` file
|
||||||
|
- Log output with domain-set context for traceability
|
||||||
|
- Designed for self-hosted Linux environments
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The following steps describe a simple, source-based installation.
|
1. Clone the repository.
|
||||||
|
2. Install the required packages for your platform.
|
||||||
|
3. Copy `vars.example` to a local `vars` file.
|
||||||
|
4. Adjust paths, ACME backend settings and domain/service mappings.
|
||||||
|
5. Run the script manually once before enabling automation.
|
||||||
|
|
||||||
1. Clone the repository
|
Example:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
git clone https://dev.town-square.de/cb601/dyntls.git /opt/dyntls
|
sudo groupadd --system dyntls
|
||||||
|
sudo install -d -m 0750 -o root -g dyntls /opt/dyntls
|
||||||
cd /opt/dyntls
|
git clone https://dev.town-square.de/cb601/dyntls.git /opt/dyntls
|
||||||
```
|
|
||||||
2. Install required packages
|
|
||||||
|
|
||||||
Make sure you have at least:
|
cd /opt/dyntls
|
||||||
- openssl
|
|
||||||
- nsupdate / bind-utils (for DNS-01 with Bind, if used)
|
|
||||||
- curl or wget (depending on your ACME script)
|
|
||||||
|
|
||||||
On RPM-based systems, for example:
|
sudo cp vars.example vars
|
||||||
|
sudo chown root:dyntls /opt/dyntls/dyntls.sh /opt/dyntls/vars
|
||||||
|
sudo chmod 0750 /opt/dyntls/dyntls.sh
|
||||||
|
sudo chmod 0640 /opt/dyntls/vars
|
||||||
|
|
||||||
```bash
|
sudo /opt/dyntls/dyntls.sh help
|
||||||
sudo dnf install openssl bind-utils curl -y
|
```
|
||||||
```
|
|
||||||
3. Prepare configuration
|
|
||||||
|
|
||||||
Copy the example vars file and adapt it to your environment:
|
For DNS-01 workflows with BIND, ensure the required tools such as `nsupdate` and `rndc` are available and that the configured TSIG key and zone permissions are valid.
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo cp vars.example vars
|
|
||||||
sudo chmod 640 vars
|
|
||||||
```
|
|
||||||
4. Test a dry run
|
|
||||||
|
|
||||||
Before using dynTLS in production, run a dry or staging-mode test (example):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./dyntls.sh help
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
dynTLS is configured via a `vars` file (e.g. `vars` or `vars.example`) which defines:
|
The backend is configured through a separate configuration file derived from `vars.example`.
|
||||||
|
|
||||||
- Base directories for PKI and HTTP token storage
|
Typical settings include:
|
||||||
- ACME backend script path (`DYNTLS_LE_PROGRAM`)
|
|
||||||
- Certificate renewal thresholds and backup behavior
|
|
||||||
- Domain lists and service mappings
|
|
||||||
|
|
||||||
Key options include, for example:
|
- Base directories for PKI data and HTTP token storage
|
||||||
|
- Path to the external ACME backend script via `DYNTLS_LE_PROGRAM`
|
||||||
|
- Renewal thresholds and backup retention settings
|
||||||
|
- Domain definitions, including CN and SAN sets
|
||||||
|
- Service mapping definitions for certificate deployment targets
|
||||||
|
- Optional DNS parameters for DNS-01 automation
|
||||||
|
|
||||||
- `DYNTLS_LE_PROGRAM` – path to the external ACME client script
|
Recommended workflow:
|
||||||
- `DYNTLS_PKI` – root PKI directory (certificates, keys, backups)
|
|
||||||
- `DYNTLS_PKI_CERT_EXPIRE` – minimum remaining validity (days) before renewal
|
|
||||||
- `DYNTLS_DOMAIN_LIST` – list of domains (CN + SANs) for a certificate
|
|
||||||
- `DYNTLS_DOMAINSERVICE_LIST` – mapping from certificate CN to service target(s)
|
|
||||||
|
|
||||||
You can keep `vars.example` under version control and use a separate, local `vars` file (ignored by Git) for host-specific secrets and paths.
|
1. Start from `vars.example`.
|
||||||
|
2. Create an environment-specific copy, for example `vars`.
|
||||||
|
3. Keep secrets and local overrides out of version control.
|
||||||
|
4. Validate ACME execution, challenge handling and deployment paths before enabling cron-based automation.
|
||||||
|
|
||||||
## Directory Layout
|
## Directory Layout
|
||||||
|
|
||||||
Minimal plain layout in the repository:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
./
|
.
|
||||||
├── dyntls # main dynTLS script
|
├── dyntls.sh
|
||||||
├── vars.example # example configuration
|
├── vars.example
|
||||||
├── LICENSE.md # project license
|
├── README.md
|
||||||
├── README.md # this file
|
├── LICENSE
|
||||||
└── contrib/
|
└── contrib/
|
||||||
└── acme/
|
└── acme/
|
||||||
├── letsencrypt_master.sh
|
├── letsencrypt_master.sh
|
||||||
└── letsencrypt_master_local.sh
|
└── letsencrypt_master_local.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Suggested runtime layout on a host (example):
|
Suggested runtime layout on a host:
|
||||||
|
|
||||||
| Path | Purpose |
|
| Path | Purpose |
|
||||||
|-----------------------------|---------------------------------|
|
|------------------------------|-------------------------------------------------|
|
||||||
| /opt/dyntls/dyntls.sh | Main script |
|
| `/opt/dyntls/dyntls.sh` | Main script |
|
||||||
| /opt/dyntls/vars.example | Example config (reference) |
|
| `/opt/dyntls/vars.example` | Reference configuration |
|
||||||
| /opt/dyntls/vars | User config (never overwritten) |
|
| `/opt/dyntls/vars` | Local configuration with host-specific settings |
|
||||||
| /etc/pki/httpd/certs | Issued certificates |
|
| `/etc/pki/...` | Certificate and key deployment targets |
|
||||||
| /etc/pki/httpd/private | Private keys |
|
| `/var/log/dyntls/dyntls.log` | dynTLS log file |
|
||||||
| /etc/pki/httpd/certs/backup | Certificate backups |
|
| `/etc/cron.daily/dyntls` | Optional cron wrapper |
|
||||||
| /var/log/dyntls/dyntls.log | dynTLS log file |
|
|
||||||
| /etc/cron.daily/dyntls | Cron job script (optional) |
|
|
||||||
|
|
||||||
Adjust these paths in your `vars` file according to your distribution and service layout.
|
Adjust all runtime paths in the `vars` file to match your distribution, PKI layout and service-specific deployment targets.
|
||||||
|
|
||||||
## CRON Job Example
|
## CRON Job Example
|
||||||
|
|
||||||
To run the key generator daily, you have two options:
|
The following examples show two common ways to automate certificate checks and renewals.
|
||||||
|
|
||||||
1. Crontab
|
Crontab example:
|
||||||
|
|
||||||
You can add a daily cron job directly to the root user's crontab:
|
```sh
|
||||||
|
30 3 * * * /opt/dyntls/dyntls.sh update-cert
|
||||||
|
#30 3 * * * /opt/dyntls/dyntls.sh -P update-cert
|
||||||
|
```
|
||||||
|
|
||||||
Open the root crontab for editing:
|
Running the job once per night at 03:30 is a reasonable default for typical `dynTLS` use cases.
|
||||||
|
|
||||||
```bash
|
System cron directory example:
|
||||||
sudo crontab -e
|
|
||||||
```
|
|
||||||
|
|
||||||
Add the following line to run the script daily at 3:30 AM:
|
```sh
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
```bash
|
/opt/dyntls/dyntls.sh update-cert
|
||||||
# Staging mode
|
#/opt/dyntls/dyntls.sh -P update-cert
|
||||||
30 3 * * * /opt/dyntls/dyntls.sh update-cert
|
|
||||||
|
|
||||||
# Productive mode
|
|
||||||
#30 3 * * * /opt/dyntls/dyntls.sh -P update-cert
|
|
||||||
```
|
|
||||||
|
|
||||||
*(Adjust the schedule as needed. This example runs the script daily.)*
|
exit 0
|
||||||
2. System Cron Daily Directory
|
```
|
||||||
|
|
||||||
Create a script as `/etc/cron.daily/dyntls`:
|
The commented lines illustrate a productive mode variant. Use a staging or non-productive mode first until ACME validation, deployment hooks and rollback behavior are verified.
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Staging mode
|
|
||||||
/opt/dyntls/dyntls.sh update-cert
|
|
||||||
|
|
||||||
# Productive mode
|
|
||||||
#/opt/dyntls/dyntls.sh -P update-cert
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
```
|
|
||||||
|
|
||||||
Ensure the script is executable:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo chmod 750 /etc/cron.daily/dyntls
|
|
||||||
```
|
|
||||||
|
|
||||||
## ACME Backend
|
## ACME Backend
|
||||||
|
|
||||||
dynTLS does not implement the ACME protocol itself. Instead, it delegates all ACME communication to an external client script configured via `DYNTLS_LE_PROGRAM`.
|
dynTLS does not implement the ACME protocol itself. Instead, it delegates ACME communication to an external client script configured through `DYNTLS_LE_PROGRAM`.
|
||||||
|
|
||||||
In this repository, ACME-related scripts are placed under:
|
In this repository, ACME-related helper scripts are located under `contrib/acme`:
|
||||||
|
|
||||||
- `contrib/acme/letsencrypt_master.sh`
|
- `letsencrypt_master.sh` for the upstream-oriented ACME helper
|
||||||
Upstream ACME client script, unchanged.
|
- `letsencrypt_master_local.sh` for a locally adapted variant, for example with customized DNS-01 handling via BIND, `nsupdate`, TSIG and `rndc`
|
||||||
- `contrib/acme/letsencrypt_master_local.sh`
|
|
||||||
Local variant with customized `dns-01` challenge handling, for example using Bind/nsupdate, TSIG and `rndc` to manage internal DNS zones.
|
|
||||||
|
|
||||||
Both scripts are based on the upstream `ght-acme.sh` client (<https://github.com/bruncsak/ght-acme.sh>) and are licensed under the GNU GPLv2-or-later; see `LICENSE.md` and the script headers for details.
|
Example configuration:
|
||||||
|
|
||||||
Example configuration in `vars`:
|
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
# Use local ACME backend
|
set_var DYNTLS_LE_PROGRAM "contrib/acme/letsencrypt_master_local.sh"
|
||||||
setvar DYNTLS_LE_PROGRAM "contrib/acme/letsencrypt_master_local.sh"
|
set_var DYNTLS_DNS_SERVER "root-dns.example365.tld"
|
||||||
|
set_var DYNTLS_DNS_TSIG "/opt/dyntls/private/tsig.key"
|
||||||
# Pass DNS parameters to the ACME script (exported to its environment)
|
|
||||||
set_var DYNTLS_DNS_SERVER "root-dns.example365.tld"
|
|
||||||
set_var DYNTLS_DNS_TSIG "/opt/dyntls/private/tsig.key"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can replace this with other ACME clients (e.g. acme.sh, lego) by pointing `DYNTLS_LE_PROGRAM` to your preferred script and ensuring its CLI options match your setup.
|
You can replace the bundled backend helper with another ACME client integration if its invocation and parameter handling match your deployment workflow.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](https://dev.town-square.de/cb601/dyntls/src/branch/main/LICENSE)
|
[MIT](https://dev.town-square.de/cb601/dyntls/src/branch/main/LICENSE)
|
||||||
|
|
||||||
See `LICENSE.md` for details and third-party license information.
|
See `LICENSE` for details and third-party licensing notes.
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
@@ -216,4 +161,4 @@ CB-601 - the open tec Elevator
|
|||||||
|
|
||||||
## Project Home
|
## Project Home
|
||||||
|
|
||||||
Project Home: <https://dev.town-square.de/cb601/dyntls>
|
Project Home: [https://dev.town-square.de/cb601/dyntls](https://dev.town-square.de/cb601/dyntls)
|
||||||
|
|||||||
Reference in New Issue
Block a user