├── Dockerfile ├── README.md ├── bin ├── entrypoint.sh ├── generate-dhcpd-conf.py ├── qemu-ifdown └── qemu-ifup ├── docker-compose.yml └── media ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png └── Readme.md /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM alpine AS build 2 | 3 | LABEL maintainer="Federico Pereira " 4 | 5 | # Configuración de variables de entorno 6 | ENV ROUTEROS_URL=https://download.mikrotik.com/routeros/7.9/chr-7.9.vdi.zip 7 | ENV ROUTEROS_IMAGE=chr-7.9.vdi 8 | ENV ROUTEROS_VERSION=7.9 9 | ENV VNCPASSWORD=false 10 | ENV KEYBOARD=en-us 11 | 12 | # Instalación de dependencias 13 | RUN set -xe \ 14 | && apk add --no-cache --update \ 15 | wget \ 16 | netcat-openbsd \ 17 | qemu-x86_64 \ 18 | qemu-system-x86_64 \ 19 | busybox-extras \ 20 | iproute2 \ 21 | iputils \ 22 | bridge-utils \ 23 | iptables \ 24 | jq \ 25 | bash \ 26 | python3 \ 27 | curl 28 | 29 | # Descarga y descompresión del archivo de imagen de RouterOS 30 | RUN mkdir /routeros && wget ${ROUTEROS_URL} -O /routeros/${ROUTEROS_IMAGE}.zip \ 31 | && unzip /routeros/${ROUTEROS_IMAGE}.zip -d /routeros \ 32 | && rm -fr /routeros/${ROUTEROS_IMAGE}.zip 33 | 34 | # Configuración de directorio de trabajo 35 | WORKDIR /routeros 36 | 37 | # Copia de archivos y directorios 38 | COPY bin /routeros/bin 39 | 40 | # Exposición de puertos 41 | # EXPOSE 1723 42 | # EXPOSE 1701 43 | # EXPOSE 1194 44 | # EXPOSE 21 45 | # EXPOSE 22 46 | # EXPOSE 23 47 | # EXPOSE 443 48 | # EXPOSE 80 49 | # EXPOSE 8291 50 | # EXPOSE 8728 51 | # EXPOSE 8729 52 | 53 | # Dar permisos de ejecución a los archivos necesarios 54 | RUN chmod +x /routeros/bin/entrypoint.sh 55 | RUN chmod +x /routeros/bin/generate-dhcpd-conf.py 56 | RUN chmod +x /routeros/bin/qemu-ifup 57 | RUN chmod +x /routeros/bin/qemu-ifdown 58 | 59 | # Punto de entrada 60 | ENTRYPOINT ["/routeros/bin/entrypoint.sh"] 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mikrotik-routeros 2 | **Install and run mikrotik routeros using docker** 3 | 4 | If you want to install a Mikrotik on the server, but also use the rest of the server, you should use Docker. 5 | 6 | ## Pull the image 7 | ```sh 8 | docker pull ghcr.io/im-ecorp/mikrotik-routeros:latest 9 | ``` 10 | or 11 | ```sh 12 | docker pull hossein3piol/mikrotik-routeros:latest 13 | ``` 14 | You can use version tag instead of `latest` 15 | 16 | for example `hossein3piol/mikrotik-routeros:7.9` 17 | 18 | ## Run container using command 19 | 20 | * command line 21 | 22 | ```sh 23 | docker run -itd \ 24 | --name mikrotik \ 25 | -p 80:80 -p 443:443 -p 1194:1194 -p 8291:8291 -p 8729:8729 \ 26 | --cap-add=NET_ADMIN \ 27 | --device=/dev/net/tun \ 28 | ghcr.io/im-ecorp/mikrotik-routeros:latest 29 | ``` 30 | 31 | to stop the container 32 | 33 | ```sh 34 | docker stop mikrotik 35 | docker rm mikrotik 36 | ``` 37 | 38 | ## Run container using compose 39 | 40 | * compose file 41 | 42 | ``` 43 | version: '3.9' 44 | 45 | services: 46 | routers: 47 | container_name: "mikrotik" 48 | image: ghcr.io/im-ecorp/mikrotik-routeros:latest 49 | privileged: true 50 | ports: 51 | - "21:21" #ftp 52 | - "22:22" #ssh 53 | - "23:23" #telnet 54 | - "80:80" #http 55 | - "443:443" #https 56 | - "1194:1194" #OVPN 57 | - "1450:1450" #L2TP 58 | - "8291:8291" #winbox 59 | - "8728:8728" #api 60 | - "8729:8729" #api-ssl 61 | - "13231:13231" #WireGuard 62 | cap_add: 63 | - NET_ADMIN 64 | devices: 65 | - /dev/net/tun 66 | ``` 67 | If you want to give your container static IP, its example is included in the project 68 | 69 | ## Configure Openvpn 70 | 71 | 72 |
73 | Click for Openvpn configuration details 74 | 75 | ### Openvpn 76 | 77 | - first of all we need add private range IP address for each client to have an IP address 78 | 79 | I use 172.24.0.0/16 rage. you can use other range like 192.168.0.0/16 80 | ![ip_pool](./media/1.png) 81 | 82 | - after setting IP pool, must get certificate for Openvpn 83 | ![certificate](./media/2.png) 84 | 85 | - crete profile for Openvpn 86 | ![profile](./media/3.png) 87 | 88 | - add new client in secret tab 89 | ![clinet](./media/4.png) 90 | 91 | - create Openvpn profile on interface tab 92 | ![interface](./media/5.png) 93 | I use `4646` port for Openvpn. You can use other ports 94 | 95 | 96 | - Finally, in order for each configuration to connect to the Internet, the firewall rule must be set 97 | ![firewall_nat](./media/6.png) 98 | 99 |
100 | 101 | 102 | ## A Special Thanks to 103 | - [lordbasex](https://github.com/lordbasex) 104 | 105 | ## If this project is helpful to you, you may wish to give it a🌟 106 | - USDT (TRC20): `TH1iDsFr2wjgpptghFBn6h7DVt88pp5WoH` 107 | 108 | ## Stargazers over time 109 | [![Stargazers over time](https://starchart.cc/im-ecorp/mikrotik-routeros.svg?variant=light)](https://starchart.cc/im-ecorp/mikrotik-routeros) 110 | -------------------------------------------------------------------------------- /bin/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # A bridge of this name will be created to host the TAP interface created for 4 | # the VM 5 | QEMU_BRIDGE='qemubr0' 6 | 7 | # DHCPD must have an IP address to run, but that address doesn't have to 8 | # be valid. This is the dummy address dhcpd is configured to use. 9 | DUMMY_DHCPD_IP='10.0.0.254' 10 | 11 | # These scripts configure/deconfigure the VM interface on the bridge. 12 | QEMU_IFUP='/routeros/bin/qemu-ifup' 13 | QEMU_IFDOWN='/routeros/bin/qemu-ifdown' 14 | 15 | # The name of the dhcpd config file we make 16 | DHCPD_CONF_FILE='/routeros/dhcpd.conf' 17 | 18 | function default_intf() { 19 | ip -json route show | jq -r '.[] | select(.dst == "default") | .dev' 20 | } 21 | 22 | # First step, we run the things that need to happen before we start mucking 23 | # with the interfaces. We start by generating the DHCPD config file based 24 | # on our current address/routes. We "steal" the container's IP, and lease 25 | # it to the VM once it starts up. 26 | /routeros/bin/generate-dhcpd-conf.py $QEMU_BRIDGE > $DHCPD_CONF_FILE 27 | default_dev=`default_intf` 28 | 29 | # Now we start modifying the networking configuration. First we clear out 30 | # the IP address of the default device (will also have the side-effect of 31 | # removing the default route) 32 | ip addr flush dev $default_dev 33 | 34 | # Next, we create our bridge, and add our container interface to it. 35 | ip link add $QEMU_BRIDGE type bridge 36 | ip link set dev $default_dev master $QEMU_BRIDGE 37 | 38 | # Then, we toggle the interface and the bridge to make sure everything is up 39 | # and running. 40 | ip link set dev $default_dev up 41 | ip link set dev $QEMU_BRIDGE up 42 | 43 | touch /var/lib/udhcpd/udhcpd.leases 44 | # Finally, start our DHCPD server 45 | udhcpd -I $DUMMY_DHCPD_IP -f $DHCPD_CONF_FILE & 46 | 47 | # And run the VM! A brief explanation of the options here: 48 | # -enable-kvm: Use KVM for this VM (much faster for our case). 49 | # -nographic: disable SDL graphics. 50 | # -serial mon:stdio: use "monitored stdio" as our serial output. 51 | # -nic: Use a TAP interface with our custom up/down scripts. 52 | # -drive: The VM image we're booting. 53 | exec qemu-system-x86_64 \ 54 | -nographic -serial mon:stdio \ 55 | -m 256 \ 56 | "$@" \ 57 | -hda $ROUTEROS_IMAGE \ 58 | -device e1000,netdev=net0 \ 59 | -netdev user,id=net0 \ 60 | -device e1000,netdev=net1 \ 61 | -netdev user,id=net1 \ 62 | -device e1000,netdev=net2 \ 63 | -netdev user,id=net2 \ 64 | -device e1000,netdev=net3 \ 65 | -netdev user,id=net3 \ 66 | -device e1000,netdev=net4 \ 67 | -netdev user,id=net4 \ 68 | -device e1000,netdev=net5 \ 69 | -netdev user,id=net5 \ 70 | -device e1000,netdev=net6 \ 71 | -netdev user,id=net6 \ 72 | -device e1000,netdev=net7 \ 73 | -netdev user,id=net7 \ 74 | -device e1000,netdev=net8 \ 75 | -netdev user,id=net8 \ 76 | -device e1000,netdev=net9 \ 77 | -netdev user,id=net9 \ 78 | -device e1000,netdev=net10 \ 79 | -netdev user,id=net10,hostfwd=tcp::21-:21,hostfwd=tcp::22-:22,hostfwd=tcp::23-:23,hostfwd=tcp::80-:80,hostfwd=tcp::443-:443,hostfwd=tcp::8291-:8291,hostfwd=tcp::8728-:8728,hostfwd=tcp::8729-:8729,hostfwd=tcp::1194-:1194,hostfwd=tcp::1701-:1701,hostfwd=tcp::1723-:1723 \ 80 | -nic tap,id=qemu0,script=$QEMU_IFUP,downscript=$QEMU_IFDOWN 81 | 82 | -------------------------------------------------------------------------------- /bin/generate-dhcpd-conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import ipaddress 5 | import json 6 | import re 7 | import socket 8 | import subprocess 9 | 10 | from typing import List, Iterable 11 | 12 | DEFAULT_ROUTE = 'default' 13 | DEFAULT_DNS_IPS = ('8.8.8.8', '8.8.4.4') 14 | 15 | DHCP_CONF_TEMPLATE = """ 16 | start {host_addr} 17 | end {host_addr} 18 | # avoid dhcpd complaining that we have 19 | # too many addresses 20 | maxleases 1 21 | interface {dhcp_intf} 22 | option dns {dns} 23 | option router {gateway} 24 | option subnet {subnet} 25 | option hostname {hostname} 26 | """ 27 | 28 | def default_route(routes): 29 | """Returns the host's default route""" 30 | for route in routes: 31 | if route['dst'] == DEFAULT_ROUTE: 32 | return route 33 | raise ValueError('no default route') 34 | 35 | def addr_of(addrs, dev : str) -> ipaddress.IPv4Interface: 36 | """Finds and returns the IP address of `dev`""" 37 | for addr in addrs: 38 | if addr['ifname'] != dev: 39 | continue 40 | info = addr['addr_info'][0] 41 | return ipaddress.IPv4Interface((info['local'], info['prefixlen'])) 42 | raise ValueError('dev {0} not found'.format(dev)) 43 | 44 | def generate_conf(intf_name : str, dns : Iterable[str]) -> str: 45 | """Generates a dhcpd config. `intf_name` is the interface to listen on.""" 46 | with subprocess.Popen(['ip', '-json', 'route'], stdout=subprocess.PIPE) as proc: 47 | routes = json.load(proc.stdout) 48 | with subprocess.Popen(['ip', '-json', 'addr'], stdout=subprocess.PIPE) as proc: 49 | addrs = json.load(proc.stdout) 50 | 51 | droute = default_route(routes) 52 | host_addr = addr_of(addrs, droute['dev']) 53 | 54 | return DHCP_CONF_TEMPLATE.format( 55 | dhcp_intf = intf_name, 56 | dns = ' '.join(dns), 57 | gateway = droute['gateway'], 58 | host_addr = host_addr.ip, 59 | hostname = socket.gethostname(), 60 | subnet = host_addr.network.netmask, 61 | ) 62 | 63 | if __name__ == '__main__': 64 | parser = argparse.ArgumentParser() 65 | parser.add_argument('intf_name') 66 | parser.add_argument('dns_ips', nargs='*') 67 | args = parser.parse_args() 68 | 69 | dns_ips = args.dns_ips 70 | if not dns_ips: 71 | dns_ips = DEFAULT_DNS_IPS 72 | 73 | print(generate_conf(args.intf_name, dns_ips)) 74 | 75 | 76 | -------------------------------------------------------------------------------- /bin/qemu-ifdown: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | QEMU_BRIDGE='qemubr0' 4 | 5 | ip link set dev $1 nomaster 6 | ip link set dev $1 down 7 | -------------------------------------------------------------------------------- /bin/qemu-ifup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | QEMU_BRIDGE='qemubr0' 4 | 5 | ip link set dev $1 up 6 | ip link set dev $1 master $QEMU_BRIDGE 7 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | routers: 5 | container_name: "mikrotik" 6 | image: hossein3piol/mikrotik-routeros:latest 7 | privileged: true 8 | ports: 9 | - "21:21" #ftp 10 | - "22:22" #ssh 11 | - "23:23" #telnet 12 | - "80:80" #http 13 | - "443:443" #https 14 | - "1194:1194" #OVPN 15 | - "1450:1450" #L2TP 16 | - "8291:8291" #winbox 17 | - "8728:8728" #api 18 | - "8729:8729" #api-ssl 19 | - "13231:13231" #WireGuard 20 | cap_add: 21 | - NET_ADMIN 22 | devices: 23 | - /dev/net/tun 24 | networks: 25 | - mikro_network 26 | 27 | networks: 28 | mikro_network: 29 | driver: bridge 30 | ipam: 31 | config: 32 | - subnet: 172.24.0.0/16 33 | gateway: 172.24.0.1 34 | -------------------------------------------------------------------------------- /media/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/1.png -------------------------------------------------------------------------------- /media/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/2.png -------------------------------------------------------------------------------- /media/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/3.png -------------------------------------------------------------------------------- /media/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/4.png -------------------------------------------------------------------------------- /media/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/5.png -------------------------------------------------------------------------------- /media/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/6.png -------------------------------------------------------------------------------- /media/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/im-ecorp/mikrotik-routeros/40b58bdeafd24f543f79d3f1ace9fe29ca6e7c4f/media/Readme.md --------------------------------------------------------------------------------