From 5c3c4c911b061f4d2ded8c25e530754b60bb23c0 Mon Sep 17 00:00:00 2001 From: Fabian van Koppen Date: Sun, 12 Oct 2025 12:46:00 +0200 Subject: [PATCH] Convert to Python package with setuptools --- README.md | 91 +++++++++++++++++++++++++ prolo-tlsa.py => prolo_tlsa/__init__.py | 12 ++-- prolo_tlsa/__main__.py | 4 ++ pyproject.toml | 29 ++++++++ 4 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 README.md rename prolo-tlsa.py => prolo_tlsa/__init__.py (96%) mode change 100755 => 100644 create mode 100644 prolo_tlsa/__main__.py create mode 100644 pyproject.toml diff --git a/README.md b/README.md new file mode 100644 index 0000000..9846196 --- /dev/null +++ b/README.md @@ -0,0 +1,91 @@ +# prolo-tlsa + +Generate TLSA records from Let's Encrypt certificates and optionally publish to DNS via Prolocation API. + +## Description + +This Python package generates TLSA records for DNS-based Authentication of Named Entities (DANE) using X.509 certificates from Let's Encrypt. It employs OpenSSL to compute the SHA-256 hash of the Subject Public Key Info (SPKI) in DER format. + +Optionally, it can publish the generated TLSA records directly to the Prolocation DNS API. + +The package is designed for sysadmins and developers managing secure TLS connections with DANE. + +## Features + +- Generate TLSA records for end-entity (usage 3) and issuer (usage 2) certificates. +- Support for custom port and protocol (default: 25/tcp for SMTP). +- Automatic DNS zone detection, preferring the deepest sub-zone. +- Safe publishing: removes existing TLSA records before adding new ones. +- CLI interface with logging. + +## Installation + +### From Source + +Clone the repository and install: + +```bash +git clone https://git.fabianvk.nl/faab/prolo-tlsa.git +cd prolo-tlsa +pip install . +``` + +### Dependencies + +- Python >= 3.8 +- `requests` (automatically installed) +- OpenSSL (for certificate processing) + +## Usage + +### Command Line + +Generate TLSA records for a hostname: + +```bash +prolo-tlsa example.com +``` + +Output will be the TLSA record values (e.g., `3 1 1 abc123...`). + +To publish to DNS (requires API key): + +```bash +export PROLOCATION_API_KEY="your-api-key" +prolo-tlsa example.com --publish --port 443 --protocol tcp +``` + +### Options + +- `hostname`: The hostname to generate records for. +- `--publish`: Publish records to Prolocation DNS API. +- `--port`: Port number for TLSA record (default: 25). +- `--protocol`: Protocol for TLSA record (default: tcp). + +### Python Module + +Import and use programmatically: + +```python +from prolo_tlsa import generate_tlsa_for_cert, get_api_key, publish_tlsa_records + +# Example: generate for a cert file +tlsa = generate_tlsa_for_cert(Path("/path/to/cert.pem"), usage=3) +``` + +## Assumptions + +- Certificates located at `/etc/letsencrypt/live//cert.pem` and `/etc/letsencrypt/live//chain.pem`. +- For publishing: Set `PROLOCATION_API_KEY` environment variable. + +## License + +MIT License + +## Contributing + +Issues and pull requests welcome at: https://git.fabianvk.nl/faab/prolo-tlsa + +## Author + +Fabian van Keulen \ No newline at end of file diff --git a/prolo-tlsa.py b/prolo_tlsa/__init__.py old mode 100755 new mode 100644 similarity index 96% rename from prolo-tlsa.py rename to prolo_tlsa/__init__.py index 3ed2cdb..99a27f4 --- a/prolo-tlsa.py +++ b/prolo_tlsa/__init__.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python3 - """ -prolo-tlsa.py +prolo_tlsa -This script generates TLSA records for DANE (DNS-based Authentication of Named Entities) +This package generates TLSA records for DANE (DNS-based Authentication of Named Entities) from X.509 certificates obtained via Let's Encrypt. It uses OpenSSL to compute the SHA-256 hash of the Subject Public Key Info (SPKI) in DER format. @@ -13,9 +11,9 @@ additional security for TLS connections. Optionally, it can publish the generated TLSA records to the Prolocation DNS API. Usage: - python prolo-tlsa.py [--publish] + python -m prolo_tlsa [--publish] -The script assumes certificates are located in /etc/letsencrypt/live//cert.pem +The package assumes certificates are located in /etc/letsencrypt/live//cert.pem and /etc/letsencrypt/live//chain.pem. It generates TLSA records with usage values: @@ -23,7 +21,7 @@ It generates TLSA records with usage values: - 2: For the issuer certificate (chain.pem) To publish, set the PROLOCATION_API_KEY environment variable and use --publish. -The script will detect the appropriate DNS zone, including sub-zones. +The package will detect the appropriate DNS zone, including sub-zones. """ import argparse diff --git a/prolo_tlsa/__main__.py b/prolo_tlsa/__main__.py new file mode 100644 index 0000000..868d99e --- /dev/null +++ b/prolo_tlsa/__main__.py @@ -0,0 +1,4 @@ +from . import main + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..6def8cb --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "prolo-tlsa" +version = "0.1.0" +description = "Generate TLSA records from Let's Encrypt certificates and optionally publish to DNS" +readme = "README.md" +license = {text = "MIT"} +requires-python = ">=3.8" +authors = [ + {name = "Fabian van Keulen", email = "f@bianvk.nl"}, +] +maintainers = [ + {name = "Fabian van Keulen", email = "f@bianvk.nl"}, +] +dependencies = [ + "requests>=2.28.0", +] +keywords = ["dns", "tlsa", "dane", "letsencrypt", "prolocation"] + +[project.scripts] +prolo-tlsa = "prolo_tlsa:main" + +[project.urls] +Homepage = "https://git.fabianvk.nl/faab/prolo-tlsa" +Repository = "https://git.fabianvk.nl/faab/prolo-tlsa" +Issues = "https://git.fabianvk.nl/faab/prolo-tlsa/issues"