update
This commit is contained in:
230
README.md
230
README.md
@@ -1,2 +1,230 @@
|
||||
# opnsense_cert_exporter
|
||||
# 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](https://docs.astral.sh/uv/) (recommended) or pip
|
||||
- OPNsense firewall with API access enabled
|
||||
- API key and secret with access to Trust/Certificates
|
||||
|
||||
## Installation
|
||||
|
||||
### Using uv (recommended)
|
||||
|
||||
```bash
|
||||
git clone https://git.project-insanity.de/gmarth/opnsense_cert_exporter.git
|
||||
cd opnsense-cert-exporter
|
||||
uv sync
|
||||
```
|
||||
|
||||
### Using pip
|
||||
|
||||
```bash
|
||||
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):
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. Edit `.env` with your settings:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
uv run python main.py <certificate_name>
|
||||
```
|
||||
|
||||
### Using Python directly
|
||||
|
||||
```bash
|
||||
python main.py <certificate_name>
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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:**
|
||||
```cron
|
||||
0 0 * * * /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com
|
||||
```
|
||||
|
||||
**Export multiple certificates:**
|
||||
```cron
|
||||
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:**
|
||||
```cron
|
||||
0 2 * * 0 /usr/local/bin/uv run python /opt/opnsense-cert-exporter/main.py mail.example.com
|
||||
```
|
||||
|
||||
### 3. Example with service reload
|
||||
|
||||
```cron
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user