TunTap路由器
TunTap路由器是为运行在一个专用网络名字空间中的linux进程提供网络连接的ad-hoc方案。好吧,显然它有其他用途,但是非常有可能这是最有趣的,也是为什么会开发它的原因。目前,它只构建在Linux平台上。
TunTap路由器默认不编译。
要一次性拥有它:
- UWSGI_EMBED_PLUGINS=tuntap make
(是哒,这个插件只命名为’tuntap’,因为它有效公开了各种tuntap设备特性)
使用它的最佳方式是将其绑定到一个unix socket上,允许新的名字空间中的进程访问它 (一般来说,unix socket是用于linux名字空间的最佳通信通道)。
第一个配置
我们想要让我们的vassal使用192.168.0.0/24网络,并且将192.168.0.1作为默认网关。
默认网关 (也就是说,tuntap路由器) 是由Emperor自身管理的
- [uwsgi]
- ; create the tun device 'emperor0' and bind it to a unix socket
- tuntap-router = emperor0 /tmp/tuntap.socket
- ; give it an ip address
- exec-as-root = ifconfig emperor0 192.168.0.1 netmask 255.255.255.0 up
- ; setup nat
- exec-as-root = iptables -t nat -F
- exec-as-root = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
- ; enable linux ip forwarding
- exec-as-root = echo 1 >/proc/sys/net/ipv4/ip_forward
- ; force vassals to be created in a new network namespace
- emperor-use-clone = net
- emperor = /etc/vassals
由这个Emperor生成的vassal将在无网络连接的情况下产生。
要让它们访问公共网络,我们创建一个新的tun设备 (它将只存在于vassal网络名字空间中),指示它路由流量到Emperor的tuntap unix socket:
- [uwsgi]
- ; we need it as the vassal have no way to know it is jailed
- ; without it post_jail plugin hook would be never executed
- jailed = true
- ; create uwsgi0 tun interface and force it to connect to the Emperor exposed unix socket
- tuntap-device = uwsgi0 /tmp/tuntap.socket
- ; bring up loopback
- exec-as-root = ifconfig lo up
- ; bring up interface uwsgi0
- exec-as-root = ifconfig uwsgi0 192.168.0.2 netmask 255.255.255.0 up
- ; and set the default gateway
- exec-as-root = route add default gw 192.168.0.1
- ; classic options
- uid = customer001
- gid = customer001
- socket = /var/www/foobar.socket
- psgi-file = foobar.pl
- ...
内嵌防火墙
TunTap路由器由一个非常简单的防火墙,用来管理vassal的流量
防火墙基于2个链 (入链和出链),而每条规则是由3个参数组成的:<action> <src> <dst>
会将这个防火墙应用于从客户端到tuntap设备(out)以及反过来(in)的流量
第一条匹配的规则终止这个链,如果没有规则应用上,那么策略就是”allow”
以下规则允许从vassal到互联网的访问,但是阻塞vassal的内部通信
- [uwsgi]
- tuntap-router = emperor0 /tmp/tuntap.socket
- tuntap-router-firewall-out = allow 192.168.0.0/24 192.168.0.1
- tuntap-router-firewall-out = deny 192.168.0.0/24 192.168.0.0/24
- tuntap-router-firewall-out = allow 192.168.0.0/24 0.0.0.0
- tuntap-router-firewall-out = deny
- tuntap-router-firewall-in = allow 192.168.0.1 192.168.0.0/24
- tuntap-router-firewall-in = deny 192.168.0.0/24 192.168.0.0/24
- tuntap-router-firewall-in = allow 0.0.0.0 192.168.0.0/24
- tuntap-router-firewall-in = deny
- exec-as-root = ifconfig emperor0 192.168.0.1 netmask 255.255.255.0 up
- ; setup nat
- exec-as-root = iptables -t nat -F
- exec-as-root = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
- ; enable linux ip forwarding
- exec-as-root = echo 1 >/proc/sys/net/ipv4/ip_forward
- ; force vassals to be created in a new network namespace
- emperor-use-clone = net
- emperor = /etc/vassals
安全性
TunTap路由器的“切换”部分 (即,映射ip地址到vassal)是灰常简单的:TunTap路由器接收到的第一个来自于vassal的包为vassal注册那个ip地址。一个好方法 (从安全的角度来说) 是在vassal中的网络设置之后立即发送一个ping包:
- [uwsgi]
- ; create uwsgi0 tun interface and force it to connect to the Emperor exposed unix socket
- tuntap-device = uwsgi0 /tmp/tuntap.socket
- ; bring up loopback
- exec-as-root = ifconfig lo up
- ; bring up interface uwsgi0
- exec-as-root = ifconfig uwsgi0 192.168.0.2 netmask 255.255.255.0 up
- ; and set the default gateway
- exec-as-root = route add default gw 192.168.0.1
- ; ping something to register
- exec-as-root = ping -c 1 192.168.0.1
- ; classic options
- ...
在注册了一个vassal/ip对之后,只有那个组合才是有效的 (因此,其他vassal将不能够使用那个地址,直到持有该地址的vassal死掉)
未来
这正成为unbit.it网络栈的一个非常重要的部分。我们现在致力于:
- 动态防火墙规则 (luajit搞了一个用于编写快速网络规则的很棒的工具)
- tuntap路由器的联合/代理 (tuntaprouter可以在一个tcp连接上多路传输vassal网络到一个外部的tuntap路由器 [这就是为什么你可以绑定一个tuntap路由器到一个tcp地址上])
- vassal鉴权 (或许老的UNIX配套凭证就够了)
- 用于网络统计数据(rx/tx/errors)的统计数据服务器
- 基于blastbeat项目的bandwidth shaper