Skip to main content

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:

  1. Creating DNS records for your MikroTik routers via external-dns
  2. Requesting and managing SSL/TLS certificates via cert-manager and Let's Encrypt
  3. 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

  1. CronJob triggers on the scheduled time
  2. DNS records created/updated via DNSEndpoint resources
  3. Certificates requested via cert-manager Certificate resources
  4. 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
  5. Certificates uploaded to the router via API
  6. 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

  1. Use SSL API - Always prefer SSL API (port 8729) over plain API (port 8728)
  2. Restrict API access - Use firewall rules to limit API access to the Kubernetes cluster
  3. Use strong passwords - Store router passwords securely in Kubernetes secrets
  4. Certificate verification - The script disables cert verification for compatibility; consider using proper CA-signed certificates for production
  5. 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)

Source distribution for certs4mikrotik 0.0.2
File Size Uploaded Provenance
certs4mikrotik-0.0.2.tar.gz 14.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for certs4mikrotik 0.0.2
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page