从 OpenVPN 客户端到 OpenVPN 服务器后面的 LAN 的传出连接是否由服务器内核转发?

从 OpenVPN 客户端到 OpenVPN 服务器后面的 LAN 的传出连接是否由服务器内核转发?

我观察到一种有点奇怪的行为,我无法完全理解。因此,我设置了一个 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 接口(如客户端到客户端配置所预期的那样)?

为了让您更好地帮助我解决我的问题,我在下面附上了一些诊断。

对于服务器

  1. 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
    

`

  1. 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 
    
  2. 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
    

对于客户

  1. 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
    
  2. 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 
    
  3. 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
    
  4. 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 进程本身成为一个路由器,拥有自己的路由表,独立于托管操作系统。您可以使用管理界面的命令查看它,也可以将其转储到状态文件中。您可以使用指令(我相信它代表“内部路由”)控制此“路由器”内的路由,该指令仅在客户端的文件或脚本生成的动态配置中有效。FORWARDip_forwardstatusiprouteclient-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 设置,但这是高级的东西,设置它的人无论如何都知道这个功能)。

相关内容