Technical note

PVE中安装RouterOS CHR并完成基础网络配置

在PVE里运行RouterOS,直接使用官方CHR镜像比从x86 ISO安装更合适。CHR本来就是面向虚拟化环境的RouterOS版本,官方提供RAW磁盘镜像,也支持KVM里的Virtio网卡和磁盘。

这条安装链路还有一个好处:磁盘来自官方镜像,授权使用CHR自己的System ID和许可证体系,不需要伪造硬盘型号、修改MBR或导入来历不明的软件Key。免费许可证可以长期运行,但每个接口的上传速度限制为1Mbps;正式承担路由流量时,应当使用试用或购买合适的CHR许可证。

先分清PVE里的两个网络

RouterOS虚拟机至少需要两个网络接口:一个接外部网络,一个接内部网络。它们在PVE里分别连接到哪个Linux Bridge,取决于宿主机的物理网卡和现有拓扑,不能直接照抄vmbr0vmbr1

在PVE宿主机上先查看网桥和当前虚拟机配置:

ip -br link show type bridge
cat /etc/network/interfaces
qm list

如果PVE管理地址也在其中一个网桥上,不要在验证RouterOS之前迁移管理网关。比较稳妥的做法是保留原有管理路径,先让CHR的WAN接口保持断开,只通过LAN侧控制台完成密码和防火墙配置。

导入官方CHR磁盘镜像

先从MikroTik下载页确认当前Stable版本,再把版本号填入变量。下面以7.21.4说明下载地址格式,版本变化时只替换这一处:

chr_version="7.21.4"
work_dir="$(mktemp -d)"

cd "$work_dir"
curl -fLO "https://download.mikrotik.com/routeros/${chr_version}/chr-${chr_version}.img.zip"
unzip "chr-${chr_version}.img.zip"

创建虚拟机时先不添加网卡。vmid必须是当前PVE集群中尚未使用的编号,storage则替换为实际用于虚拟机磁盘的存储:

vmid="201"
storage="local-lvm"

qm create "$vmid" \
  --name routeros-chr \
  --ostype l26 \
  --memory 1024 \
  --sockets 1 \
  --cores 2 \
  --onboot 0

qm disk import "$vmid" "chr-${chr_version}.img" "$storage"
qm config "$vmid"

qm disk import会把外部镜像导入为unused0,还需要把它挂到虚拟机并设为启动盘:

disk_volume="$(qm config "$vmid" \
  | awk -F': ' '/^unused0:/ {print $2}' \
  | cut -d, -f1)"

test -n "$disk_volume"
qm set "$vmid" --virtio0 "$disk_volume"
qm set "$vmid" --boot order=virtio0

这里导入的是已经包含RouterOS的CHR磁盘。先用qemu-img create建立一块空盘,再执行qm importdisk,并不会自动把RouterOS安装进去;这是两种用途不同的操作。

添加网卡时先断开WAN

假设已经确认vmbr0连接外部网络、vmbr1连接内部网络,可以这样添加两块Virtio网卡:

qm set "$vmid" --net0 virtio,bridge=vmbr0,link_down=1
qm set "$vmid" --net1 virtio,bridge=vmbr1
qm config "$vmid"
qm start "$vmid"

link_down=1让WAN侧暂时保持断开。实际网桥名称必须按宿主机修改;如果外部网络通过VLAN进入,还要在PVE网卡配置中加入对应Tag,不能只凭net0net1的顺序判断用途。

启动后从PVE的NoVNC控制台进入RouterOS。默认用户是admin且没有密码,首次登录应立即按提示设置强密码。密码不要写进qm命令、RouterOS导出文件或博客示例。

继续配置前先看一眼当前状态。不同镜像和初始化方式可能带来不同的默认配置,已有同名接口列表、DHCP或防火墙规则时不能重复添加:

/export
/system default-configuration print
/interface list print
/ip firewall filter print

后面的命令按一台没有同名对象的新CHR编写。如果当前已经存在可用的默认配置,应当逐项合并,而不是为了套用示例先执行无默认配置的重置。

根据MAC地址确认接口

PVE里的net0通常对应RouterOS的ether1,但增加、删除或重排网卡后不能继续依赖这个假设。先在PVE侧记录两块网卡的MAC地址,再到RouterOS控制台核对:

qm config 201 | grep -E '^net[0-9]+:'

RouterOS里查看接口详情:

/interface ethernet print detail

确认无误后再改成可读名称,并加入接口列表:

/interface ethernet set [find default-name=ether1] name=wan
/interface ethernet set [find default-name=ether2] name=lan

/interface list add name=WAN
/interface list add name=LAN
/interface list member add list=WAN interface=wan
/interface list member add list=LAN interface=lan

如果MAC地址与这里的ether1ether2对应关系不同,应当交换命令里的接口,不能为了保持示例顺序而把外网误认成内网。

在接通WAN前建立最小防火墙

先允许已有连接、ICMP、LAN管理和WAN侧DHCP应答,其余访问路由器自身的流量统一丢弃:

/ip firewall filter
add chain=input action=accept connection-state=established,related,untracked \
    comment="base: accept established, related and untracked"
add chain=input action=drop connection-state=invalid \
    comment="base: drop invalid"
add chain=input action=accept protocol=icmp \
    comment="base: accept ICMP"
add chain=input action=accept in-interface-list=LAN \
    comment="base: accept LAN management"
add chain=input action=accept in-interface-list=WAN protocol=udp \
    src-port=67 dst-port=68 comment="base: accept DHCP reply"
add chain=input action=drop \
    comment="base: drop everything else"

转发链只允许LAN主动访问外部网络:

/ip firewall filter
add chain=forward action=accept connection-state=established,related,untracked \
    comment="base: accept established, related and untracked"
add chain=forward action=drop connection-state=invalid \
    comment="base: drop invalid"
add chain=forward action=accept in-interface-list=LAN \
    comment="base: accept connections from LAN"
add chain=forward action=drop \
    comment="base: drop everything else"

这只是IPv4首次启动所需的最小范围。需要IPv6、端口映射或更细的网络分区时,再按RouterOS 7的IPv4与IPv6防火墙基线补充,不要为了让虚拟机先通网而临时放开整个WAN输入链。

配置LAN、DHCP和WAN

这里使用RFC文档网段192.0.2.0/24作为占位符,实际部署时应替换为自己的私有网段。先给LAN配置地址和DHCP:

/ip address add address=192.0.2.1/24 interface=lan
/ip pool add name=lan-pool ranges=192.0.2.100-192.0.2.199
/ip dhcp-server add name=lan-dhcp interface=lan address-pool=lan-pool disabled=no
/ip dhcp-server network add address=192.0.2.0/24 \
    gateway=192.0.2.1 dns-server=192.0.2.1
/ip dns set allow-remote-requests=yes

然后回到PVE,在虚拟机硬件页面编辑WAN网卡,把Disconnected选项取消。不要重新添加网卡,也不要用一条缺少原MAC地址的qm set --net0覆盖它,否则RouterOS里的接口对应关系可能跟着变化。

WAN通过DHCP获取地址时,在RouterOS中增加客户端和源地址转换:

/ip dhcp-client add interface=wan disabled=no use-peer-dns=yes
/ip firewall nat add chain=srcnat out-interface-list=WAN action=masquerade \
    comment="base: masquerade LAN traffic"

最后检查地址、默认路由、DNS和许可证状态:

/ip address print
/ip route print where dst-address=0.0.0.0/0
/ip dhcp-client print detail
/ip dns print
/system license print

CHR首次启动使用Free许可证。1Mbps限制足够完成配置和功能验证,不适合长期承担正常宽带出口;需要更高吞吐量时,通过MikroTik账户申请60天Trial或购买P1、P10、P-Unlimited许可证。许可证绑定CHR的System ID,复制磁盘不能重新获得一段试用期。

配置和连通性确认以后,再在PVE中启用Start at boot。RouterOS提供DHCP或网关服务时,还应设置启动顺序,让它早于依赖它的虚拟机启动。

参考资料