Home
Softono
mikrotik-proxy-manager

mikrotik-proxy-manager

Open source MIT Python
39
Stars
5
Forks
1
Issues
2
Watchers
2 months
Last Commit

About mikrotik-proxy-manager

RouterOS container for managing reverse proxy through Winbox, CLI, or REST API

Platforms

Web Self-hosted Docker

Languages

Python

Links

MikroTik Proxy Manager

Automated reverse proxy management through MikroTik interface

[!IMPORTANT]

Choose the right tool for the job

If you need… Use
A simple built-in reverse proxy MikroTik Reverse Proxy (no extra software required)
Traefik as a reverse proxy Run it on a separate host (VM or bare-metal) β€” much simpler
A management UI for proxying Nginx Proxy Manager
You love Linux, containers, network, debugging, and suffering Welcome to MikroTik Proxy Manager πŸ”₯

Docker License

πŸ“‹ Table of Contents

πŸ“– Description

MikroTik Proxy Manager is an automated solution for managing reverse proxy servers through the MikroTik RouterOS interface. Adding hosts via Winbox automatically creates dynamic Traefik configuration with Let's Encrypt SSL certificate support.

πŸ—οΈ Architecture

Architecture Diagram

The system consists of two containers running in RouterOS Container:

  • Traefik - Reverse proxy with automatic SSL management
  • MikroTik Proxy Manager - Python application for configuration synchronization

✨ Features

  • πŸ”„ Automatic creation of Traefik configuration
  • 🌐 DNS management for proxy hosts
  • πŸ”’ SSL certificates via Let's Encrypt or custom certificates (including Cloudflare configuration example)
  • πŸ–₯️ Simple management through Winbox, CLI, or REST API
  • πŸ“Š Monitoring and logging

πŸ“‹ Requirements

  • RouterOS with container support (arm64, x86)
  • Domain name
  • Public IP address (optional, required for Let's Encrypt)
  • USB storage or internal memory for configuration storage (Recommended for real mikrotik devices)
  • Skills: Linux, Networking, MikroTik RouterOS, Debugging (If you've set it up and launched, congratulations, you're great. It's much easier to do this on Linux than on RouterOS)

⚑ Quick Start (local)

Want to try it without touching your router? Run the whole stack locally with Docker Compose against an existing MikroTik:

cp .env.example .env
# edit .env: MIKROTIK_HOST, MIKROTIK_USER, MIKROTIK_PASSWORD, REVERSE_PROXY_IP
docker compose up --build

This launches Traefik + mikrotik-proxy-manager side by side. MPM will poll /ip/proxy/access and write Traefik dynamic configs into ./configs, which Traefik watches live.

βš™οΈ Configuration

All settings are environment variables (loaded via pydantic-settings, see .env.example).

Variable Default Description
MIKROTIK_HOST β€” RouterOS IP / hostname
MIKROTIK_USER β€” API user
MIKROTIK_PASSWORD β€” API password
MIKROTIK_PORT 8728 RouterOS API port (8729 for TLS)
MIKROTIK_USE_SSL false Use API-SSL
MIKROTIK_DNS_MANAGER true Manage /ip/dns/static entries for proxy hosts
REVERSE_PROXY_IP β€” Traefik container IP β€” used as DNS A target; falls back to MIKROTIK_HOST
TRAEFIK_CONFIGS_PATH ./configs Where MPM writes dynamic YAML files (mounted to /srv/configs in the container)
TLS_CERT_RESOLVER (empty) Per-router cert resolver. Leave empty to inherit from the entryPoint-level http.tls (recommended for wildcard setups). If set, must match a resolver defined in traefik/traefik*.yml.
SYNC_INTERVAL_SECONDS 10 Poll interval
LOG_LEVEL INFO Log level
LOG_JSON true Emit structured JSON logs

Important: If TLS_CERT_RESOLVER is set, it must match a resolver actually defined in the Traefik static config. The bundled traefik/traefik.yml defines letsEncrypt; traefik/traefik_cloudflare.yml defines cloudflare. Mismatches surface as Router uses a nonexistent certificate resolver in Traefik logs.

Wildcard tip: for a single *.example.com cert covering every generated subdomain, leave TLS_CERT_RESOLVER empty and declare the resolver + wildcard on the entryPoint in your static traefik.yml:

entryPoints:
  websecure:
    address: :443
    http:
      tls:
        certResolver: cloudflare
        domains:
          - main: example.com
            sans:
              - "*.example.com"

Generated routers will emit tls: {} and inherit this wildcard automatically β€” no per-host ACME requests.

πŸš€ Installation & Setup

Prerequisites

Before starting, prepare your MikroTik router with container support and API SSL settings. Follow the RouterOS Container Guide for detailed instructions.

Simple guide

Note: This setup uses Let's Encrypt HTTP Challenge (port 80) by default

Step 1: Prepare Directory Structure

Create necessary directories on your RouterOS device:

If you user USB storage, check format must be EXT4

# Prepare config dir
/file/add type=directory name=usb1/configs
/file/add type=directory name=usb1/traefik
# Prepare container dir
/file/add type=directory name=usb1/docker/traefik
/file/add type=directory name=usb1/docker/mpm

Step 2: Download Traefik Configuration

Fetch the static Traefik default configuration:

or the Cloudflare DNS-challenge example:

Edit the settings (set a real ACME email β€” Let's Encrypt rejects example.com addresses) and upload it to MikroTik Files as usb1/traefik/traefik.yml.

Create the ACME storage file at usb1/traefik/acme.json (must be chmod 600 β€” see Known Issues).

Step 3: Configure Container Mounts

Set up mount points for containers:

/container mounts
add dst=/srv/configs list=mpm_config src=/usb1/configs
add dst=/configs list=traefik_dynamic src=/usb1/configs
add dst=/etc/traefik list=traefik_static src=/usb1/traefik

Step 4: Configure Environment Variables

Set up API credentials for MikroTik connection:

/container envs
add key=MIKROTIK_HOST list=mpm value=192.168.88.1
add key=MIKROTIK_USER list=mpm value=user-api
add key=MIKROTIK_PASSWORD list=mpm value=password
# add key=REVERSE_PROXY_IP list=mpm value=10.0.0.1 # change Traefik container IP - defalut use MIKROTIK_HOST ip
# add key=TLS_CERT_RESOLVER list=mpm value=cloudflare # If you want to use Cloudflare DNS challenge - defalut empty
# add key=CF_DNS_API_TOKEN list=traefik value=YOUR_TOKEN

Step 5: Deploy Containers

Cloudflare DNS Challenge (Optional)

If you want to use Cloudflare DNS challenge instead of HTTP challenge:

Click to expand Cloudflare configuration
  1. Use the configuration from traefik/traefik_cloudflare.yml
  2. Add your Cloudflare API token:
/container envs
add key=CF_DNS_API_TOKEN name=traefik value=your-cloudflare-api-token
add key=TLS_CERT_RESOLVER name=mpm value=cloudflare

Deploy Traefik with environment variables

/container add envlists=traefik interface=veth1 layer-dir="" logging=yes mountlists=traefik_static,traefik_dynamic name=traefik remote-image=mirror.gcr.io/traefik:v3.6.12 root-dir=/usb1/docker/traefik start-on-boot=yes workdir=/

Deploy MikroTik Proxy Manager

/container add envlists=mpm interface=veth1 layer-dir="" logging=yes mountlists=mpm_config name=mpm remote-image=ghcr.io/akmalovaa/mikrotik-proxy-manager:latest root-dir=usb1/docker/mpm start-on-boot=yes workdir=/

Pin to a specific tag (e.g. :2.1.0) for reproducible deploys instead of :latest.

Step 6: Start Containers

Start your containers and verify they're running:

/container start [find name~"traefik"]
/container start [find name~"mpm"]

🎯 Usage

Once the containers are running, you can manage proxy configurations through multiple methods. The system monitors /ip/proxy/access entries and automatically generates Traefik configurations.

Supported Parameters

The system currently parses these proxy access parameters:

  • DST-HOST - Target hostname/domain
  • DST-ADDRESS - Destination IP address
  • DST-PORT - Destination port

Method 1: Winbox Interface

  1. Open Winbox and navigate to IP β†’ Proxy β†’ Access
  2. Add a new proxy access rule with your desired configuration

Winbox Proxy Configuration

Method 2: RouterOS Console

Add proxy configuration via CLI:

/ip proxy access
add dst-host=test.example.com dst-address=192.168.88.10 dst-port=80

Method 3: REST API

Add proxy configuration via RouterOS REST API:

curl -k -X PUT "https://192.168.88.1/rest/ip/proxy/access" \
    -u 'username:password' \
    -H "Content-Type: application/json" \
    -d '{"dst-address": "192.168.88.10", "dst-host": "test.example.com", "dst-port": "80"}'

Verify Configuration

After adding proxy entries, you can verify the generated configurations:

  1. Check generated config files: Config Files

  2. Verify SSL certificates: SSL Certificate

  3. Monitor container logs:

    /container log print

πŸ› οΈ Development

This project uses uv for dependency management (Python β‰₯ 3.13). pyproject.toml + uv.lock are the source of truth β€” don't use pip / venv directly.

Local Python Development

# Install dependencies
uv sync

# Run the application locally (reads .env)
uv run python -m mikrotik_proxy_manager

# Lint + format
uv run ruff check
uv run ruff format

# Tests
uv run pytest
uv run pytest tests/test_sync.py::test_dst_host_change_removes_old_dns

Docker Development

# Full local stack (mpm + traefik)
docker compose up --build

# Dev compose variant
docker compose -f dev_compose.yaml up --build

Testing with RouterOS Containers

Example commands for testing containers in RouterOS:

# Deploy whoami test service
/container add remote-image=ghcr.io/traefik/whoami:latest interface=veth2 root-dir=/docker/whoami logging=yes

# Deploy NGINX for testing
/container add remote-image=mirror.gcr.io/nginx:latest interface=veth1 root-dir=usb1/docker/nginx logging=yes

# Python container for debugging
/container add remote-image=mirror.gcr.io/python:3.13.7-slim interface=veth1 root-dir=usb1/docker/python logging=yes cmd="tail -f /dev/null"

πŸ”’ Security

⚠️ SECURITY WARNING

Running third-party container images on your router can pose security risks.

  • Ensure you trust the container images you deploy
  • Regularly update containers to patch security vulnerabilities
  • Monitor container activity and network traffic
  • Use strong passwords for API access
  • Consider network segmentation for container traffic

If your router is compromised, malicious containers could be used to install harmful software on your router and spread across your network.

Security Best Practices

  1. Use strong API credentials for MikroTik access
  2. Regularly update container images
  3. Monitor logs for suspicious activity
  4. Limit container network access where possible
  5. Use firewall rules to restrict container communication

πŸ“ TODO

  • [ ] Add Crowdsec application security features
  • [ ] Implement configuration validation
  • [ ] Add monitoring dashboard
  • [ ] Support for custom SSL certificates
  • [ ] Enhanced logging and alerting

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“ž Support

If you encounter any issues or have questions, please open an issue on GitHub.

Known Issues

ACME permissions- Traefik logs

traefik:: {"level":"error","error":"unable to get ACME account: permissions 644 for acme.json are too open, please use 600","resolver":"cloudflare","time":"2025-09-08T20:02:11Z","message":"The ACME resolve is skipped from the resolvers list"}
container/print
container/shell number=X
chmod 600 acme.json

restart container

Container network problems

Run container with cmd="tail -f /dev/null" and check network inside container

container/print
container/shell number=X
ip addr show or cat /proc/net/route

Check work network and change your RouterOS settings bridge or veth or ip address

An example from the official documentation:

Create a new veth interface and assign an IP address in a range that is unique in your network:

/interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1