我观察到一种有点奇怪的行为,我无法完全理解。因此,我设置了一个 OpenVPN 连接,如下图所示。(这是一个 TUN 和客户端到客户端设置)。我的想法是针对此场景中的 ping 路由: 我的 openvpn 连接
from client: 192.168.200.102 to LAN: 10.198.0.16
总的来说,这个 ping 成功并不奇怪,但就我的理解而言,如果我将服务器上的 iptables 设置更改为
-P FORWARD DROP
然后甚至
net.ipv4.ip_forward = 0.
使用上述设置,流量永远无法到达目的地。虽然流量成功了,但它似乎永远无法到达 LAN 接口。问题是我看不到流量(通过运行 tcpdump 数据网络数据包分析器)到达 LAN 接口 eth0 10.198.0.16。更确切地说,tun 接口似乎在自行应答流量,就像 LAN IP 绑定到 tun 接口一样,如下所示:
sudo tcpdump -i tun0 tcpdump: 16:34:21.391381 IP 192.168.200.102 > 10.198.0.16: ICMP echo request, id 14, seq 1885, length 64 16:34:21.391514 IP 10.198.0.16 > 192.168.200.102: ICMP echo reply, id 14, seq 1885, length 64
这是怎么回事?据我了解,来自客户端的请求将发送到服务器上的 tun 接口,最终已转发由内核分配给 eth0,对吗?通常通过运行以下命令可以看到:sudo tcpdump -i tun0
或者sudo tcpdump -i eth0
?
我之所以对这件事如此挑剔,是因为我认为如果没有办法实施规则来阻止客户端访问服务器上的 LAN,那么它就会存在安全风险。我在这里遗漏了什么,是否有一个 OpenVPN 进程本身将数据包转发到 eth0 接口(如客户端到客户端配置所预期的那样)?
为了让您更好地帮助我解决我的问题,我在下面附上了一些诊断。
对于服务器
ip addr
`1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether b8:27:eb:5c:a6:e6 brd ff:ff:ff:ff:ff:ff inet 10.198.0.16/24 brd 10.198.0.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::ba27:ebff:fe5c:a6e6/64 scope link valid_lft forever preferred_lft forever 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether b8:27:eb:09:f3:b3 brd ff:ff:ff:ff:ff:ff 4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500 link/none inet 192.168.200.1/24 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::87cd:fedd:92fc:cde/64 scope link stable-privacy valid_lft forever preferred_lft forever
`
ip route
default via 10.198.0.1 dev eth0 proto static 10.198.0.0/24 dev eth0 proto kernel scope link src 10.198.0.16 192.168.200.0/24 dev tun0 proto kernel scope link src 192.168.200.1 192.168.178.0/24 via 192.168.200.1 dev tun0 scope link
server openvpn.conf
tls-server mode server dev tun local 10.198.0.16 proto tcp-server port 1234 user openvpn group openvpn ca /etc/openvpn/cacert.pem cert /etc/openvpn/servercert.pem key /etc/openvpn/serverkey dh /etc/openvpn/dh2048.pem ifconfig-pool 192.168.200.2 192.168.200.103 255.255.255.0 client-config-dir /etc/openvpn/ccd ifconfig 192.168.200.1 255.255.255.0 keepalive 10 120 comp-lzo client-to-client push "topology subnet" topology "subnet" log /var/log/openvpn.log
对于客户
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/ether 38:af:d7:a0:52:ec brd ff:ff:ff:ff:ff:ff 3: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:28:f8:8d:1c:6f brd ff:ff:ff:ff:ff:ff inet 192.168.178.79/24 brd 192.168.178.255 scope global dynamic noprefixroute wlp2s0 valid_lft 859868sec preferred_lft 859868sec inet6 2a0a:a540:d54:0:bd79:eb10:5e26:548a/64 scope global temporary dynamic valid_lft 7190sec preferred_lft 3590sec inet6 2a0a:a540:d54:0:6086:b044:dff:2694/64 scope global dynamic mngtmpaddr noprefixroute valid_lft 7190sec preferred_lft 3590sec inet6 fe80::ad5c:6e18:87fa:dff4/64 scope link noprefixroute valid_lft forever preferred_lft forever 4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100 link/none inet 192.168.200.102/24 brd 192.168.200.255 scope global tun0 valid_lft forever preferred_lft forever inet6 fe80::5dfc:6b3a:3c4d:e9a4/64 scope link stable-privacy valid_lft forever preferred_lft forever
ip route
default via 192.168.178.1 dev wlp2s0 proto dhcp metric 600 169.254.0.0/16 dev wlp2s0 scope link metric 1000 10.198.0.0/24 via 192.168.200.1 dev tun0 192.168.200.0/24 dev tun0 proto kernel scope link src 192.168.200.102 192.168.178.0/24 dev wlp2s0 proto kernel scope link src 192.168.178.79 metric 600
client openvpn.conf
dev tun client nobind remote 11.22.33.44 proto tcp port 1234 ca /etc/openvpn/cacert.pem cert /etc/openvpn/user_cert.pem key /etc/openvpn/user comp-lzo verb 3 keepalive 10 120 log /var/log/openvpn.log
ccd for client
iroute 192.168.178.0 255.255.255.0
答案1
VPN 与网络其余部分之间的流量当然要经过tun0
。对于此流量,FORWARD
将照常查询链,您可以控制谁可以连接到哪里。如果ip_forward
未启用 ,则不会转发流量。
当client-to-client
不使用时,客户端之间的流量使用相同的路径:它从tun0
接口出现在服务器操作系统中,使用操作系统路由表正确路由,穿过防火墙,唯一的区别是它确定目的地在后面tun0
,因此数据包通过它传出。
它的效率不高,因为OpenVPN进程在用户空间,而tun0在内核空间,这会导致每个数据包至少发生两次上下文改变。
但是,当client-to-client
使用时,客户端之间的数据包不会出现在 上,并且不会咨询tun0
服务器的防火墙链,控制不会影响它们的转发。OpenVPN 进程本身成为一个路由器,拥有自己的路由表,独立于托管操作系统。您可以使用管理界面的命令查看它,也可以将其转储到状态文件中。您可以使用指令(我相信它代表“内部路由”)控制此“路由器”内的路由,该指令仅在客户端的文件或脚本生成的动态配置中有效。FORWARD
ip_forward
status
iproute
client-config-dir
最简单的方法就是不要将 VPN 视为特殊事物。一旦隧道建立,就忘掉它,它现在只是每台计算机(服务器和客户端)中的一个额外的常规接口,所有这些接口都连接到一些常规的简单路由器。并考虑通常的路由和防火墙。
我终于注意到你 ping 了VPN 服务器本身尽管分配给了其他接口。此数据包不会被转发无论如何,因为它的目的地是服务器本身,所以ip_forward
不会影响此数据包的处理方式,并且它会穿越INPUT
防火墙链,回复也会穿越OUTPUT
(例如,FORWARD
如果它们不是发往系统本身,它们会穿越防火墙链)。数据包将从进入系统tun0
(并将在那里看到),但您不会在上看到它,eth0
因为它不会被发送出去。它将在本地处理。回复也是如此。
对于路由相关代码来说,地址在系统的哪个位置(哪个接口)或使用系统的哪个地址访问它并不重要。重要的是它是否属于系统。
相关的安全问题是,有些人认为,如果他们将服务绑定到分配给某个接口的某个 IP 地址,他们就会切断通过其他接口对该服务的访问。这是错误的。如果其他接口后面的系统有到服务绑定的 IP 的路由,它们仍然将能够访问服务。这不是确保服务安全的正确方法;正确的防火墙设置才是。
另一个相关问题是,有些人甚至使用ping -I <local-address> <address-to-ping>
或ping -I <interface> <address-to-ping>
认为他们可以直接选择要发送哪些接口 ping。同样,这是错误的。这样,您只能选择要发送哪些源地址ping 会有,但没有发送它们的接口;路由代码将严格根据基于数据包目标地址的路由表来选择接口(我假设没有完成 VRF 或 RPDB 设置,但这是高级的东西,设置它的人无论如何都知道这个功能)。