带有Qemu的Docker中的Mikrotik RouterOS

祝大家有美好的一天!在本文中,我想谈谈一个名为Docker RouterOS的开源项目,该项目最初是作为集成测试的测试平台而创建的,仅此而已,但是随着时间的推移,应用户的要求,添加了许多改进以扩展功能范围。


我将讨论项目外观的原因,项目的初始迭代以及我必须面对的问题。


继续下切。


做什么的?


这是一个正确的问题,也许值得一开始,一般来说,几年前,我启动了一个PHP库的项目,用于通过API与RouterOS一起工作(如果公众喜欢这篇文章,有关PHP库的文章将不会花费很长时间),如图所示实际上,为了使库在不同版本的RouterOS上稳定运行,进行测试非常有用。


由于检查正确的操作(例如登录或数据数组的正确解析)是正确的,因此在客户端API的当前实现中,做出决定而不是编写各种决定来拦截请求并替换答案以在实时硬件上运行测试是一项艰巨的任务。


测试的初始版本是在我的家用路由器上进行的,一切都很好,但是一些测试更改了路由器的一些重要设置,这常常导致无法正常工作的Internet和家庭不满,而其他测试则需要较旧版本的RouterOS,而不是由于以下原因而回退OS这个的。


有一天,我对此感到厌倦,然后我开始寻找解决问题的方法。


我们可以说这是可以在VirtualBox中启动某个虚拟环境的想法的那一刻。


简短搜索后,我遇到了Mikrotik官方网站Cloud Hosted Router下载页面。在此之前,我曾多次听说过CHR,但假设它们是一些棘手的“铁”路由器,具有启动虚拟路由器的功能。但是,事实证明,CHR只是VDI / VMDK / OVA等。包含完善的RouterOS的映像,可以立即使用。


这些测试需要至少两个同时运行的OS版本,即6.42和最新版本(当时为6.44)。


事实是,在6.43中,RouterOS开发人员通过API更改了授权算法,因此旧的授权逻辑停止在新版本的操作系统上运行,结果,新的逻辑在旧版本的OS上不起作用。


VirtualBox , .


?


, .


?


Travis-CI, , VirtualBox Travis-CI , Travis "" .


… Docker!


?


Docker , , .


, " RouterOS Docker ?", QEMU, PC .


QEMU // , headless , Docker .


RouterOS QEMU - , , API.


image, Alpine Linux.


Version 0


:


Dockerfile
FROM alpine:3.8

RUN mkdir /routeros
WORKDIR /routeros
ADD [".", "/routeros"]

RUN apk add --no-cache --update netcat-openbsd qemu-x86_64 qemu-system-x86_64 \
 && wget "https://download.mikrotik.com/routeros/6.42.7/chr-6.42.7.vdi"

ENTRYPOINT ["/routeros/entrypoint.sh"]

WORKDIR , mkdir .


Dockerfile , alpine 3.8, , Mikrotik.


entrypoint.sh
#!/bin/sh

qemu-system-x86_64 \
    -vnc 0.0.0.0:0 \
    -m 256 \
    -hda /routeros/chr-6.42.7.vdi \
    -device e1000,netdev=net0 \
    -netdev user,id=net0,hostfwd=tcp::22-:22,hostfwd=tcp::23-:23,hostfwd=tcp::8728-:8728,hostfwd=tcp::8729-:8729

Entrypoint , , 256 , VNC 5900 , , .


, Docker, , . , , QEMU, Docker .


hostfwd , Docker , , .


Version 1


, URL , .


Dockerfile
FROM alpine:3.8

ENV ROUTEROS_VERSON="6.42.7"
ENV ROUTEROS_IMAGE="chr-$ROUTEROS_VERSON.vdi"
ENV ROUTEROS_PATH="https://download.mikrotik.com/routeros/$ROUTEROS_VERSON/$ROUTEROS_IMAGE"

RUN mkdir /routeros
WORKDIR /routeros
ADD [".", "/routeros"]

RUN apk add --no-cache --update netcat-openbsd qemu-x86_64 qemu-system-x86_64 \
 && echo ">>> $ROUTEROS_PATH" \
 && if [ ! -e "$ROUTEROS_IMAGE" ]; then wget "$ROUTEROS_PATH"; fi

# For access via VNC
EXPOSE 5900

# Default ports of RouterOS
EXPOSE 21
EXPOSE 22
EXPOSE 23
EXPOSE 80
EXPOSE 443
EXPOSE 8291
EXPOSE 8728
EXPOSE 8729

ENTRYPOINT ["/routeros/entrypoint.sh"]

EXPOS , best practice .


Dockerfile, , GitHub Docker Hub.


, Dockerfile , crontab.


cron.sh
#!/bin/bash

# Cron fix
cd "$(dirname $0)"

function getTarballs
{
    curl https://mikrotik.com/download/archive -o - 2>/dev/null | \
        grep -i vdi | \
        awk -F\" '{print $2}' | \
        sed 's:.*/::' | \
        sort -V
}

function getTag
{
    echo "$1" | sed -r 's/chr\-(.*)\.vdi/\1/gi'
}

function checkTag
{
    git rev-list "$1" 2>/dev/null
}

getTarballs | while read line; do
    tag=`getTag "$line"`
    echo ">>> $line >>> $tag"

    if [ "x$(checkTag "$tag")" == "x" ]
        then

            url="https://download.mikrotik.com/routeros/$tag/chr-$tag.vdi"
            if curl --output /dev/null --silent --head --fail "$url"; then
                echo ">>> URL exists: $url"
                sed -r "s/(ROUTEROS_VERSON=\")(.*)(\")/\1$tag\3/g" -i Dockerfile
                git commit -m "Release of RouterOS changed to $tag" -a
                git push
                git tag "$tag"
                git push --tags
            else
                echo ">>> URL don't exist: $url"
            fi

        else
            echo ">>> Tag $tag has been already created"
    fi

done

, , .


Travis-CI, , GitHub.


Version 2


, , , , RouterOS ICMP ( ) .


hostfwd, .


Qemu Docker, TAP eth0.


Debian, Alpine, , multistage . KVM, QEMU, .


VPS KVM, - KVM in KVM, Docker RouterOS KVM QEMU .


Dockerfile :


Dockerfile
FROM alpine:3.11

# For access via VNC
EXPOSE 5900

# Default ports of RouterOS
EXPOSE 21 22 23 80 443 8291 8728 8729

# Different VPN services
EXPOSE 50 51 500/udp 4500/udp 1194/tcp 1194/udp 1701 1723

# Change work dir (it will also create this folder if is not exist)
WORKDIR /routeros

# Install dependencies
RUN set -xe \
 && apk add --no-cache --update \
    netcat-openbsd qemu-x86_64 qemu-system-x86_64 \
    busybox-extras iproute2 iputils \
    bridge-utils iptables jq bash python3

# Environments which may be change
ENV ROUTEROS_VERSON="6.46.5"
ENV ROUTEROS_IMAGE="chr-$ROUTEROS_VERSON.vdi"
ENV ROUTEROS_PATH="https://download.mikrotik.com/routeros/$ROUTEROS_VERSON/$ROUTEROS_IMAGE"

# Download VDI image from remote site
RUN wget "$ROUTEROS_PATH" -O "/routeros/$ROUTEROS_IMAGE"

# Copy script to routeros folder
ADD ["./scripts", "/routeros"]

ENTRYPOINT ["/routeros/entrypoint.sh"]

best practice.


, , , , :


  • python3 — , udhcpd,
  • jq — ip addr -json
  • netcat-openbsd — ,

entrypoint :


entrypoint.sh
#!/bin/sh

###
###         ,
###      ,  
###    .
###

# Generate udhcpd configuration
/routeros/generate-dhcpd-conf.py $QEMU_BRIDGE > $DHCPD_CONF_FILE

# Get name of default interface
default=`ip -json route show | jq -r '.[] | select(.dst == "default") | .dev'`

# Finally, start udhcpd server
udhcpd -I $DUMMY_DHCPD_IP -f $DHCPD_CONF_FILE &

# And run the VM!
exec qemu-system-x86_64 \
    -nographic -serial mon:stdio \
    -vnc 0.0.0.0:0 \
    -m 256 \
    -nic tap,id=qemu0,script=$QEMU_IFUP,downscript=$QEMU_IFDOWN \
    "$@" \
    -hda $ROUTEROS_IMAGE

, , TAP . Docker RouterOS, RouterOS .


, udhcpd DNS ( 127.0.0.11) Docker Compose.


?


  • RouterOS Docker
  • , API Travis-CI
  • images RouterOS

, , . Docker Host RouterOS.


- ( ).


?



, udhcpd python - , bash.



, .



VDI RouterOS, Docker . , , RouterOS Linux Kernel , RouterOS .


Docker Host , , .



, 2010 , , LOR ON^W^W^W . Docker RouterOS , read-only mode .


, , , , , .


, , .




All Articles