我有一个把世界各地的服务器连接起来构建一个内网的需求。Tinc是一个不错的Mesh VPN,但是它的三层自动配置用起来总是觉得有点不爽。如果用二层配置呢,我又一点都不想把Linux改造成路由器(配置太烦了)。所以有一天突发奇想,我能不能用QEMU启动一个RouterOS,然后在上面跑DHCP服务器,把它和二层的Tinc连接起来呢?经过一些尝试,这么做是可行的。
以下所有配置基于Ubuntu 16.10。
准备工作:安装所需的包
接入点
1 |
apt install qemu-kvm qemu-utils tinc bridge-utils wget |
客户端
1 |
apt install tinc |
配置Tinc TAP VPN
Tinc需要你给每个网络取一个名字,然后给你的每个节点取一个名字。本文中网络名用 <network_name> 表示,当前节点名用 <node_name> 表示,接入点的节点名用 <server_name> 表示。为了简单起见,这个架构使用一台服务器作为Tinc认证服务器(即所有设备都需要先连接到这台服务器才能接入Mesh网络),DHCP服务器将部署在这台服务器上。
接入点(认证服务器)
创建网络配置
1 |
mkdir -p /etc/tinc/<network_name>/hosts |
/etc/tinc/tinc.conf 填入:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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> 填入:
1 2 3 4 |
Address = <your public IP> #Address = xxx Compression = 11 IndirectData = no |
生成密钥
1 |
tincd -n <network_name> -K4096 |
接受所有默认设置即可。
客户端
创建网络配置
1 |
mkdir -p /etc/tinc/<network_name>/hosts |
/etc/tinc/tinc.conf 填入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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> 填入:
1 2 3 4 |
Address = <your public IP> #Address = xxx Compression = 11 IndirectData = no |
(如果设备在NAT后,不需要填写 Address 字段,并且设置 IndirectData = yes )
生成密钥
1 |
tincd -n <network_name> -K4096 |
接受所有默认设置即可。
交换认证信息
把服务器上的 /etc/tinc/<network_name>/hosts/<server_name> 复制到所有客户端的对应位置,把每个客户端上的 /etc/tinc/<network_name>/hosts/<node_name> 复制到服务器上对应位置。
启动Tinc
测试方式启动:
1 |
tincd -D -v -N <network_name> |
以服务方式启动:
1 2 |
systemctl enable tinc@<network_name> systemctl start tinc@<network_name> |
在Tinc认证服务器上配置RouterOS的DHCP服务器
下载RouterOS CHR
1 2 3 4 |
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 |
创建差分磁盘镜像
1 2 |
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 |
配置网桥
1 2 3 |
brctl addbr bridge0 mkdir /etc/qemu echo "allow bridge0" > /etc/qemu/bridge.conf |
启动QEMU完成初始配置
1 |
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:
1 2 3 4 |
/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 |
最后关机
1 2 |
/system shutdown y |
配置QEMU自动启动
在 /etc/systemd/system/qemu-chr.service 文件中填入
1 2 3 4 5 6 7 8 9 10 11 |
[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 |
启动服务
1 2 |
systemctl start qemu-chr systemctl enable qemu-chr |
配置DHCP
认证服务器上
在 /etc/network/interfaces.d/<network_name>.cfg 填入:
1 2 3 |
allow-hotplug <network_name> iface <network_name> inet manual iface <network_name> inet6 auto |
在 /etc/network/interfaces.d/bridge0.cfg 填入:
1 2 3 4 |
allow-hotplug bridge0 iface bridge0 inet dhcp bridge_ports <network_name> tap0 bridge_stp 1 |
在 /etc/tinc/tinc-up 填入:
1 2 3 4 |
#!/bin/sh ifup $INTERFACE & ifup bridge0 & |
在 /etc/tinc/tinc-down 填入:
1 2 3 4 |
#!/bin/sh ifdown bridge0 ifdown $INTERFACE |
设置脚本权限
1 |
chmod +x /etc/tinc/<network_name>/tinc-* |
客户端上
在 /etc/network/interfaces.d/<network_name>.cfg 填入:
1 2 3 |
allow-hotplug <network_name> iface <network_name> inet dhcp iface <network_name> inet6 auto |
在 /etc/tinc/tinc-up 填入:
1 2 3 |
#!/bin/sh ifup $INTERFACE & |
在 /etc/tinc/tinc-down 填入:
1 2 3 |
#!/bin/sh ifdown $INTERFACE |
设置脚本权限
1 |
chmod +x /etc/tinc/<network_name>/tinc-* |
重启所有Tinc服务,应该能DHCP成功了。
让虚拟机里的RouterOS连接互联网
主机配置TAP设备IP
在 /etc/network/interfaces.d/chr-tap0.cfg填入
1 2 3 4 |
allow-hotplug chr-tap0 iface chr-tap0 inet static address 192.168.96.1 netmask 255.255.255.248 |
然后执行
1 |
ifup chr-tap0 |
主机配置IPv4 NAT
(假设互联网连接在 eth0 上)
1 2 3 4 5 |
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配置路由表
1 2 |
/ip address=192.168.96.2/30 interface=ether2 /ip route add distance=1 gateway=192.168.96.1 |
参考资料: