Certs4MikroTik
Automated SSL/TLS certificate management and deployment for MikroTik routers using Kubernetes, cert-manager, and external-dns.
Overview
This project automates the process of:
- Creating DNS records for your MikroTik routers via external-dns
- Requesting and managing SSL/TLS certificates via cert-manager and Let's Encrypt
- Uploading certificates to MikroTik routers via their API (SSL or plain)
Features
- ✅ Automatic certificate management - Uses cert-manager to automatically request and renew certificates
- ✅ DNS automation - Creates DNS records automatically via external-dns
- ✅ SSL/TLS API support - Connects via SSL (port 8729) with certificate verification disabled
- ✅ Fallback to plain - Falls back to plain API (port 8728) if SSL is unavailable
- ✅ Kubernetes native - Runs as a CronJob in your Kubernetes cluster
- ✅ Multiple routers - Manages certificates for multiple routers from a single configuration
Prerequisites
- Kubernetes cluster
- cert-manager installed
- external-dns configured for your DNS provider
- Let's Encrypt Issuer or ClusterIssuer configured
- MikroTik routers with API access enabled (SSL recommended)
Installation
1. Install from PyPI
pip install certs4mikrotik
2. Configure your routers
Edit k8s/routers-config.yaml to include your routers:
apiVersion: v1
kind: ConfigMap
metadata:
name: mikrotik-routers-config
namespace: default
data:
routers.json: |
{
routers: [
{
name: router1,
host: 192.168.1.1,
port: 8728,
username: admin,
cert_secret: router1-tls,
password_secret: router1-credentials,
cert_name: router1-cert
}
]
}
3. Create router credentials
For each router, create a Kubernetes secret with the admin password:
kubectl create secret generic router1-credentials \
--from-literal=password='your-router-password'
4. Configure the Let's Encrypt Issuer or ClusterIssuer
Option A: Namespace-scoped Issuer (default):
kubectl apply -f k8s/issuer-example.yaml
Option B: Cluster-wide ClusterIssuer:
kubectl apply -f k8s/clusterissuer-example.yaml
kubectl apply -f k8s/cluster-role-issuers.yaml
kubectl apply -f k8s/clusterrolebinding-issuers.yaml
Update the YAML file with your email address and DNS provider credentials before applying.
5. Deploy the application
kubectl apply -f k8s/service-account.yaml
kubectl apply -f k8s/routers-config.yaml
kubectl apply -f k8s/cronjob.yaml
Configuration
Router Configuration
Each router entry in the configuration requires:
| Field | Description | Example |
|---|---|---|
name |
Router identifier (used for DNS) | router1 |
host |
Router IP address | 192.168.1.1 |
port |
Plain API port | 8728 |
ssl_port |
SSL API port (optional, default: 8729) | 8729 |
username |
API username | admin |
cert_secret |
Kubernetes secret name for TLS cert | router1-tls |
password_secret |
Kubernetes secret name for password | router1-credentials |
cert_name |
Certificate name on the router | router1-cert |
CronJob Schedule
The default schedule runs at 2 AM on Sundays and Wednesdays:
schedule: 0 2 * * 0,3
Modify this in k8s/cronjob.yaml to fit your needs.
How It Works
- CronJob triggers on the scheduled time
- DNS records created/updated via DNSEndpoint resources
- Certificates requested via cert-manager Certificate resources
- Script connects to each router:
- First tries SSL connection (port 8729) with cert verification disabled
- Falls back to plain connection (port 8728) if SSL fails
- Certificates uploaded to the router via API
- Certificates imported and marked as trusted on the router
MikroTik Router Setup
Enable API Access
For SSL API (recommended):
/ip service
set api-ssl disabled=no
For plain API (less secure):
/ip service
set api disabled=no
Create API User (Optional)
For better security, create a dedicated API user:
/user group add name=api-users policy=api,read,write,test
/user add name=certbot group=api-users password=strong-password
Usage
Using Issuer vs ClusterIssuer
By default, the script uses namespace-scoped Issuers. To use a ClusterIssuer, pass the --issuer-kind flag:
# Using default Issuer
cert2mikrotik --config routers.json --issuer letsencrypt-prod
# Using ClusterIssuer
cert2mikrotik --config routers.json --issuer letsencrypt-prod --issuer-kind ClusterIssuer
Command-line Options
--config Path to routers config JSON file (required)
--namespace Kubernetes namespace (default: default)
--issuer cert-manager Issuer name (default: letsencrypt-prod)
--issuer-kind Issuer kind: Issuer or ClusterIssuer (default: Issuer)
--domain-suffix Domain suffix for DNS names (default: .adviser.com)
--ensure-resources Create/update Certificate and DNSEndpoint resources (default: true)
--skip-resources Skip creating/updating Certificate and DNSEndpoint resources
--verbose, -v Enable verbose logging
Manual Testing
You can manually trigger a job run:
kubectl create job --from=cronjob/mikrotik-cert-upload manual-test
kubectl logs -f job/manual-test
Troubleshooting
Connection Issues
Check if the API port is accessible:
# Test SSL API
openssl s_client -connect <router-ip>:8729
# Test plain API
telnet <router-ip> 8728
View Job Logs
# List recent jobs
kubectl get jobs
# View logs
kubectl logs job/<job-name>
Certificate Issues
Check cert-manager certificate status:
kubectl get certificates
kubectl describe certificate <cert-name>
Security Considerations
- Use SSL API - Always prefer SSL API (port 8729) over plain API (port 8728)
- Restrict API access - Use firewall rules to limit API access to the Kubernetes cluster
- Use strong passwords - Store router passwords securely in Kubernetes secrets
- Certificate verification - The script disables cert verification for compatibility; consider using proper CA-signed certificates for production
- RBAC - The service account has minimal permissions required for operation
License
Apache License 2.0 - See LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Acknowledgments
This project was developed with the assistance of Claude Code, an AI-powered coding assistant by Anthropic.
Author
Created for automated MikroTik certificate management in Kubernetes environments.
Author: Meno Abels
Metadata
Release files for certs4mikrotik 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| certs4mikrotik-0.0.2.tar.gz | 14.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| certs4mikrotik-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.9 kB
Release files / certs4mikrotik-0.0.2.tar.gz
| Download URL | certs4mikrotik-0.0.2.tar.gz |
|---|---|
| Size | 14.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
33f07c9c66df816a3354a198414ef7a15f5278970bba89225d5725bef567f809
|
|
BLAKE2b-256 checksum How to use checksums |
4be48642324d76255f08b99e4d4970826358ed098ac2932793c64cacaa33a551
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2025.
Transparency logRelease files / certs4mikrotik-0.0.2-py3-none-any.whl
| Download URL | certs4mikrotik-0.0.2-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0170d9a2ac8c1bc61a152ae7775e3746f19819d114c26ee771fdf9a619d1bac1
|
|
BLAKE2b-256 checksum How to use checksums |
591b4c9660d5973c18c27c2a497868ac092eed845f28d22dad1417e86a17598e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2025.
Transparency logSecurity for certs4mikrotik 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for certs4mikrotik-0.0.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.