☠️ Certbot Reaper
Certbot Reaper is a Python utility that finds, revokes, and deletes unused Let's Encrypt certificates from your system – so you stay clean and secure. It compares existing certificates with active NGINX configurations and safely removes those that are no longer in use.
🧭 How it works
flowchart TD
A["certreap"] --> B["walk the nginx config tree for *.conf"]
B --> C["collect every domain-like string found"]
A --> D["list the subdirectories of the cert dir"]
D --> E["openssl x509 -text on cert.pem"]
E --> F["read the DNS: entries"]
F --> G{"any of them still referenced by nginx?"}
C --> G
G -- yes --> K["keep the certificate"]
G -- no --> H{"--force?"}
H -- no --> I{"confirm at the prompt?"}
I -- no --> K
I -- yes --> J
H -- yes --> J["certbot revoke --delete-after-revoke"]
J --> L["remove the certificate directory"]
A revoke that certbot rejects is reported, and the directory is removed anyway.
🚀 Features
- 🔍 Scans
/etc/letsencrypt/livefor all installed certificates - 🧠 Checks if domain names are referenced in NGINX configs under
/etc/nginx/ - 🗑️ Offers interactive or forced cleanup of unused certificates
- 🔁 Can be run manually or scheduled with
systemdtimers - ⚙️ Supports
--forceand--helpviaargparse
📦 Installation
pip install certreap
pip is the single supported installation path.
🔧 Requirements
- Python 3.10+ 🐍
opensslonPATH— reads the DNS names out of each certificatecertbotonPATH— performs the revocation
If either is missing, the command exits with code 127 and a one‑line error instead of a traceback. A missing openssl is never silently treated as "no certificates found".
🛠️ Usage
certreap # Interactive mode (asks before deleting)
certreap --force # Deletes unused certificates without confirmation
certreap --help # Shows help message
Both scanned locations can be pointed elsewhere, which is what the integration tests use:
certreap --cert-dir /etc/letsencrypt/live --nginx-conf-dir /etc/nginx
Exit codes
| Code | Meaning |
|---|---|
0 |
Finished. A certificate certbot failed to revoke is reported and its directory is still removed. |
2 |
Invalid command line arguments. |
127 |
A required command is not installed. |
🧪 Development
make lint # ruff check + ruff format --check
make format # apply ruff format
make test # unit + integration tests
make test-unit
make test-integration
make test-e2e # install the package in a container and exercise the CLI
Tests run against the working tree — the Makefile puts src/ on PYTHONPATH, so no install is needed. The integration tests stub openssl and certbot on PATH, so nothing real is ever revoked.
👤 Author
Developed by Kevin Veen-Birkenbach 🧠 Feedback and contributions welcome!
📄 License
This project is licensed under the MIT License. Feel free to use, modify, and share it as you wish.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file certreap-1.0.0.tar.gz.
File metadata
- Download URL: certreap-1.0.0.tar.gz
- Upload date:
- Size: 10.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d900f91328df11567160f3cd08771a5a6d4ad080ada11212cee743e471e14f43
|
|
| MD5 |
5cb2d4168808ed9d134ee6c632a5b6f3
|
|
| BLAKE2b-256 |
37f2d5a877133437acd54380ed83a54f8d1f20cf4ffdc9b81e3823771d5d6957
|
File details
Details for the file certreap-1.0.0-py3-none-any.whl.
File metadata
- Download URL: certreap-1.0.0-py3-none-any.whl
- Upload date:
- Size: 6.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
267034f3d7613b3a1d9f30cb771276c96041db7cd846e7ebf75d9ac5c82427cf
|
|
| MD5 |
d9ed1c4a2774cd34666288299b32a42b
|
|
| BLAKE2b-256 |
2a44e54cec31f062f1a9fc99c40e10aa5e97586d6e10edceca556beae4cc8117
|