用RouterOS/QEMU在Tinc TAP VPN内部实现DHCP

我有一个把世界各地的服务器连接起来构建一个内网的需求。Tinc是一个不错的Mesh VPN,但是它的三层自动配置用起来总是觉得有点不爽。如果用二层配置呢,我又一点都不想把Linux改造成路由器(配置太烦了)。所以有一天突发奇想,我能不能用QEMU启动一个RouterOS,然后在上面跑DHCP服务器,把它和二层的Tinc连接起来呢?经过一些尝试,这么做是可行的。

以下所有配置基于Ubuntu 16.10。

准备工作:安装所需的包

接入点

apt install qemu-kvm qemu-utils tinc bridge-utils wget

客户端

apt install tinc

配置Tinc TAP VPN

Tinc需要你给每个网络取一个名字,然后给你的每个节点取一个名字。本文中网络名用<network_name> 表示,当前节点名用<node_name> 表示,接入点的节点名用<server_name> 表示。为了简单起见,这个架构使用一台服务器作为Tinc认证服务器(即所有设备都需要先连接到这台服务器才能接入Mesh网络),DHCP服务器将部署在这台服务器上。

接入点(认证服务器)

创建网络配置

mkdir -p /etc/tinc/<network_name>/hosts

/etc/tinc/tinc.conf 填入:

AddressFamily = any
Broadcast = mst
DecrementTTL = yes
DirectOnly = no
Forwarding = internal
Hostnames = yes
LocalDiscovery = yes
Mode = switch
Name = <server_name>
PriorityInheritance = yes
ProcessPriority = high
StrictSubnets = no
TunnelServer = no

创建节点配置

/etc/tinc/<network_name>/hosts/<server_name> 填入:

Address = <your public IP>
#Address = xxx
Compression = 11
IndirectData = no

生成密钥

tincd -n <network_name> -K4096

接受所有默认设置即可。

客户端

创建网络配置

mkdir -p /etc/tinc/<network_name>/hosts

/etc/tinc/tinc.conf 填入:

AddressFamily = any
Broadcast = mst
ConnectTo = <server_name>
DecrementTTL = yes
DirectOnly = no
Forwarding = internal
Hostnames = yes
LocalDiscovery = yes
Mode = switch
Name = <node_name>
PriorityInheritance = yes
ProcessPriority = high
StrictSubnets = no
TunnelServer = no

创建节点配置

/etc/tinc/<network_name>/hosts/<node_name> 填入:

Address = <your public IP>
#Address = xxx
Compression = 11
IndirectData = no

(如果设备在NAT后,不需要填写Address 字段,并且设置IndirectData = yes )

生成密钥

tincd -n <network_name> -K4096

接受所有默认设置即可。

交换认证信息

把服务器上的/etc/tinc/<network_name>/hosts/<server_name> 复制到所有客户端的对应位置,把每个客户端上的/etc/tinc/<network_name>/hosts/<node_name> 复制到服务器上对应位置。

启动Tinc

测试方式启动:

tincd -D -v -N <network_name>

以服务方式启动:

systemctl enable [email protected]<network_name>
systemctl start [email protected]<network_name>

在Tinc认证服务器上配置RouterOS的DHCP服务器

下载RouterOS CHR

mkdir /var/chr-qemu/
cd /var/chr-qemu
wget https://download2.mikrotik.com/routeros/6.38.3/chr-6.38.3.img.zip
unzip chr-6.38.3.img.zip

创建差分磁盘镜像

qemu-img create -o backing_file=chr-6.38.3.img,backing_fmt=raw -f qcow2 chr-tinc-edge-0.cow
qemu-img resize chr-tinc-edge-0.cow +10G

配置网桥

brctl addbr bridge0
mkdir /etc/qemu
echo "allow bridge0" > /etc/qemu/bridge.conf

启动QEMU完成初始配置

qemu-system-x86_64 -m 256 -curses -device virtio-net-pci,netdev=bridge0 -netdev bridge,id=bridge0,br=bridge0 -device virtio-net-pci,netdev=ether2 -netdev tap,id=ether2,ifname=chr-tap0 -monitor telnet:localhost:7100,server,nowait,nodelay chr-tinc-edge-0.cow

使用用户名admin ,密码为空登录,然后配置IP和DHCP:

/ip address add address=192.168.95.1/24 interface=ether1
/ip pool add name=dhcp ranges=192.168.95.10-192.168.95.254
/ip dhcp-server add address-pool=dhcp interface=ether1 name=dhcp1 disabled=no
/ip dhcp-server network add address=192.168.95.0/24 dns-server=8.8.8.8 gateway=192.168.95.1

最后关机

/system shutdown
y

配置QEMU自动启动

/etc/systemd/system/qemu-chr.service 文件中填入

[Unit]
Description=QEMU virtual machine

[Service]
ExecStart=/usr/bin/env qemu-system-x86_64 -name chr-tinc-edge-0 -nographic -m 256 -device virtio-net-pci,netdev=bridge0 -netdev bridge,id=bridge0,br=bridge0 -device virtio-net-pci,netdev=ether2 -netdev tap,id=ether2,ifname=chr-tap0 -monitor telnet:localhost:7100,server,nowait,nodelay /home/james/chr/chr-tinc-edge-0.cow
ExecStop=/bin/sh -c "echo 'system_powerdown' | nc localhost 7100"
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target

启动服务

systemctl start qemu-chr
systemctl enable qemu-chr

配置DHCP

认证服务器上

/etc/network/interfaces.d/<network_name>.cfg 填入:

allow-hotplug <network_name>
iface <network_name> inet manual
iface <network_name> inet6 auto

/etc/network/interfaces.d/bridge0.cfg 填入:

allow-hotplug bridge0
iface bridge0 inet dhcp
bridge_ports <network_name> tap0
bridge_stp 1

/etc/tinc/tinc-up 填入:

#!/bin/sh

ifup $INTERFACE &
ifup bridge0 &

/etc/tinc/tinc-down 填入:

#!/bin/sh

ifdown bridge0
ifdown $INTERFACE

设置脚本权限

chmod +x /etc/tinc/<network_name>/tinc-*

客户端上

/etc/network/interfaces.d/<network_name>.cfg 填入:

allow-hotplug <network_name>
iface <network_name> inet dhcp
iface <network_name> inet6 auto

/etc/tinc/tinc-up 填入:

#!/bin/sh

ifup $INTERFACE &

/etc/tinc/tinc-down 填入:

#!/bin/sh

ifdown $INTERFACE

设置脚本权限

chmod +x /etc/tinc/<network_name>/tinc-*

重启所有Tinc服务,应该能DHCP成功了。

让虚拟机里的RouterOS连接互联网

主机配置TAP设备IP

/etc/network/interfaces.d/chr-tap0.cfg填入

allow-hotplug chr-tap0
iface chr-tap0 inet static
address 192.168.96.1
netmask 255.255.255.248

然后执行

ifup chr-tap0

主机配置IPv4 NAT

(假设互联网连接在eth0 上)

apt install iptables-persistent
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o chr-tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i chr-tap0 -o eth1 -j ACCEPT

RouterOS配置路由表

/ip address=192.168.96.2/30 interface=ether2
/ip route add distance=1 gateway=192.168.96.1

参考资料:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据