Files
opnsense_cert_exporter/README.md
2025-12-20 06:12:03 +01:00

6.5 KiB

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 .env files)
  • 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

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

  1. Copy the example environment file:
cp .env.example .env
  1. Edit .env with 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: 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)
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

  1. Log in to your OPNsense web interface
  2. Go to System > Access > Groups
  3. Click + to add a new group
  4. 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/24 or a single host 192.168.1.100/32)
  5. Click Save
  6. Click the Edit (pencil icon) on the newly created group
  7. Under Assigned Privileges, click Edit
  8. Select only System: Certificate Manager from the list
  9. 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

  1. Go to System > Access > Users
  2. Click + to add a new user
  3. Configure the user:
    • Username: cert-exporter
    • Password: Set a strong password (not used for API access, but required)
    • Group Memberships: Select cert-exporter
  4. Click Save

3. Generate an API Key

  1. Edit the cert-exporter user
  2. Scroll down to API keys and click the + button
  3. Download the generated key file containing the key and secret
  4. 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:

  1. Search for the certificate matching the provided name
  2. Check if the certificate has changed since last export
  3. Export the certificate to <output_directory>/<certificate_name>/cert.pem
  4. Export the private key to <output_directory>/<certificate_name>/privkey.pem
  5. 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 uv binary and main.py script
  • The .env file 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