1ffcbf09dcac5d52adb57e1ed151bde7fecdc6a4
OPNsense Certificate Exporter
A Python tool to export SSL/TLS certificates and private keys from OPNsense firewalls via the API.
Features
- Search and export certificates from OPNsense Trust store
- Exports both certificate (
cert.pem) and private key (privkey.pem) - Change detection: only writes files if content has changed
- Environment-based configuration (supports
.envfiles) - Optional systemd journal logging
- Optional file permission settings (Linux only)
Prerequisites
- Python 3.13+
- uv (recommended) or pip
- OPNsense firewall with API access enabled
- API key and secret with access to Trust/Certificates
Installation
Using uv (recommended)
git clone https://git.project-insanity.de/gmarth/opnsense_cert_exporter.git
cd opnsense-cert-exporter
uv sync
Using pip
git clone https://git.project-insanity.de/gmarth/opnsense_cert_exporter.git
cd opnsense-cert-exporter
pip install -r requirements.txt
Optional: systemd journal logging
To enable native systemd journal logging (Linux only):
# Install system dependency first
sudo apt install libsystemd-dev pkg-config # Debian/Ubuntu
sudo dnf install systemd-devel pkg-config # Fedora/RHEL
# Then install the optional Python dependency
uv sync --extra systemd
Configuration
- Copy the example environment file:
cp .env.example .env
- Edit
.envwith your settings:
# Required
OPNSENSE_API_KEY=your_api_key_here
OPNSENSE_API_SECRET=your_api_secret_here
OPNSENSE_HOST=https://your-opnsense.local
# Optional
OUTPUT_DIRECTORY=./certs
# Optional: disable SSL verification for self-signed certificates
# VERIFY_SSL=false
# Optional: file permissions (Linux only)
# FILE_OWNER=root
# FILE_GROUP=root
# FILE_MODE=0600
Configuration Options
| Environment Variable | Required | Description |
|---|---|---|
OPNSENSE_API_KEY |
Yes | OPNsense API key |
OPNSENSE_API_SECRET |
Yes | OPNsense API secret |
OPNSENSE_HOST |
Yes | OPNsense URL (e.g., https://192.168.1.1) |
OUTPUT_DIRECTORY |
No | Directory to save exported certificates (default: ./certs) |
VERIFY_SSL |
No | Set to false to disable SSL verification for self-signed certs (default: true) |
FILE_OWNER |
No | Set file owner (Linux only) |
FILE_GROUP |
No | Set file group (Linux only) |
FILE_MODE |
No | Set file permissions in octal (e.g., 0600) |
Setting up OPNsense API Access
For security, create a dedicated user with minimal privileges for certificate export.
1. Create a Group with Certificate Manager Access
- Log in to your OPNsense web interface
- Go to System > Access > Groups
- Click + to add a new group
- Configure the group:
- Group name:
cert-exporter - Description:
Certificate export API access - Restrict access to networks (optional): Limit API access to specific networks (e.g.,
192.168.1.0/24or a single host192.168.1.100/32)
- Group name:
- Click Save
- Click the Edit (pencil icon) on the newly created group
- Under Assigned Privileges, click Edit
- Select only System: Certificate Manager from the list
- Click Save
Security tip: Restricting access to the network where your export script runs adds an extra layer of security. Even if the API credentials are compromised, they cannot be used from unauthorized networks.
2. Create a Dedicated API User
- Go to System > Access > Users
- Click + to add a new user
- Configure the user:
- Username:
cert-exporter - Password: Set a strong password (not used for API access, but required)
- Group Memberships: Select
cert-exporter
- Username:
- Click Save
3. Generate an API Key
- Edit the
cert-exporteruser - Scroll down to API keys and click the + button
- Download the generated key file containing the key and secret
- Store the credentials securely - they cannot be retrieved later
Usage
Using uv
uv run python main.py <certificate_name>
Using Python directly
python main.py <certificate_name>
Examples
# Export a single certificate
uv run python main.py mail.example.com
# Export multiple certificates
uv run python main.py mail.example.com
uv run python main.py vpn.example.com
uv run python main.py wildcard.example.com
The tool will:
- Search for the certificate matching the provided name
- Check if the certificate has changed since last export
- Export the certificate to
<output_directory>/<certificate_name>/cert.pem - Export the private key to
<output_directory>/<certificate_name>/privkey.pem - Log whether the certificate was updated or unchanged
Viewing logs
With systemd journal logging enabled:
journalctl -t opnsense-cert-exporter
journalctl -t opnsense-cert-exporter --since "1 hour ago"
journalctl -t opnsense-cert-exporter -f # follow
Setting up a Cronjob for Periodic Exports
To automatically export certificates on a schedule, set up a cron job:
1. Open the crontab editor
crontab -e
2. Add a cron entry
The .env file is automatically loaded from the script directory, so no need to cd first.
Daily at midnight:
0 0 * * * /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com
Export multiple certificates:
0 0 * * * /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com
0 0 * * * /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py vpn.example.com
Weekly on Sunday at 2 AM:
0 2 * * 0 /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com
3. Example with service reload
# Export certificate daily at midnight and reload nginx if changed
0 0 * * * /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com && systemctl reload nginx
Cron Format Reference
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * * command
Tips
- Use absolute paths for the
uvbinary andmain.pyscript - The
.envfile is loaded from the script directory automatically - With systemd journal logging, output automatically goes to the journal
- Test the command manually before adding to cron
- Consider adding a service reload command (e.g.,
systemctl reload nginx) after export - Ensure the cron user has appropriate permissions to write to the output directory
License
MIT
Languages
Python
100%