通过中间/跳转服务器的 VPN

通过中间/跳转服务器的 VPN

以下是我想做的事情的粗略情况:

客户端 -> |VPN| -> 服务器 A -> |VPN| -> 服务器 B -> 互联网。

服务器 A 和服务器 B 都位于公共互联网上,具有公共 IP,而且我对这两台服务器都有 root 访问权限。客户端位于防火墙后面,但可以访问服务器 A。客户端无法直接访问服务器 B。服务器 A 可以访问服务器 B。我希望数据包从服务器 B 流出到互联网。我需要加密从客户端到 A 以及从 A 到 B 的通信,因为 A 和 B 不在同一个 LAN 中,所以 A 和 B 之间的流量通过公共基础设施传输。

我已经能够在 A 上设置 IPSec VPN 服务器并能够连接到它。但我无法找到从 A 到 B 建立另一个 VPN 并将来自 A 的流量从客户端重新路由到 B 的正确方法。

尖端?

ps 我最初考虑使用 SSH 隧道连接 A 和 B,然后通过这样的隧道将来自客户端的相关数据包路由到 B。但正如人们在评论中指出的那样,这不是一个好主意。所以我愿意接受任何建议。谢谢!

编辑#1

服务器 A 上的 VPN 服务使用 strongswan 设置,它处理客户端和服务器 A 之间的任何连接。我通过以下方式完成ipsec.conf

# ipsec.conf - strongSwan IPsec configuration file

# basic configuration
config setup
        charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2, mgr 2"
        strictcrlpolicy=no
        uniqueids=yes
        cachecrls=no
conn ipsec-ikev2-vpn
      auto=add
      compress=no
      type=tunnel  # defines the type of connection, tunnel.
      keyexchange=ikev2
      fragmentation=yes
      forceencaps=yes
      dpdaction=clear
      dpddelay=300s
      rekey=no
      left=%any
      leftid=47.112.200.xxx    # if using IP, define it without the @ sign
      leftcert=vpn-server.cert.pem  # reads the VPN server cert in /etc/ipsec.d/certs
      leftsendcert=always
      leftsubnet=0.0.0.0/0
      right=%any
      rightid=%any
      rightauth=eap-mschapv2
      rightsourceip=10.10.10.0/24  # IP address Pool to be assigned to the clients
      rightdns=1.1.1.1,8.8.8.8  # DNS to be assigned to clients
      rightsendcert=never
      eap_identity=%identity  # defines the identity the client uses to reply to an EAP Identity request.

使用ufw(我所遵循的教程使用了 ufw,但我iptables也可以使用基本规则)设置/etc/ufw/before.rules;我省略了 ufw 自动生成的部分,并且我还手动允许端口 500/4500 上的 udp 和端口 22 上的 tcp:

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# Don't delete these required lines, otherwise there will be errors
*nat
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT

*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT

*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT

这就是我所取得的进展。由于端口 500 和 4500 被阻止/篡改,在 A 和 B 之间通过 strongswan IPSec 设置站点到站点 VPN 的单独尝试失败:客户端可以通过 500/4500 访问 A,A 无法通过 500/4500 访问 B,并且我已将 B 的所有端口暴露给开放互联网进行测试。

编辑2

目前,我设法在 A 和 B 之间建立的唯一隧道是 SSH socks(ssh -N -f -4 -D 1080 [server B ip]来自服务器 A)。我正在考虑通过该 SSH 隧道将离开 A 的流量(其目的地不是我的客户端设备)重定向到 B。

类似于:-A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 1080在 ufw/iptables 中。(这实际上不起作用,服务器 A 的 ip 仍然显示在 ip 检查器中,被阻止的网站仍然无法访问)

答案1

在评论中扩展我的提示。

在此处输入图片描述

我知道如何在 OpenVPN 中建立隧道,因为我使用它来连接到 IPv6 网络,但对于 IPSec 来说,其理念应该是一样的。

我将从我熟悉的(IPv6)开始,并展示如何将其转换为 IPv4。

不过这里有一个友好的免责声明:

我还没有尝试过在 IPv4 上进行多主路由,所以您的情况可能会有所不同。


服务器 A-IPv6 版本

在我的服务器上,OpenVPN 隧道网络接口被称为tun0

服务器 A编辑/etc/iproute2/rt_tables,因此您有以下条目:

200     openvpn

这将创建一个专用的路由表,我们可以使用它来进行 VPN 路由。默认路由表称为main

该表openvpn将处理所有向上游发送的数据包(您 -> 互联网),而路由表main将处理所有向下游发送的流量(互联网 -> 您)。

ip -6 rule add priority 32000 iif tun0 to 2000::/3 table openvpn
ip -6 route add default via <ipv6 address> dev tun1 table openvpn

请注意,您必须为属于您的任何 IP 范围添加规则。

假设 IPv6 范围 2001:db8:cafe::/48 属于您,并且您具有以下设置:

  • 客户端 VPN 链接位于 2001:db8:cafe:1::/64,客户端的 IP 地址为 2001:db8:cafe:1::100
  • 客户端本地网络是 2001:db8:cafe:100::/64,其将给出规则:
ip -6 route add unreachable 2001:db8:cafe::/48 table main
ip -6 route add 2001:db8:cafe:100::/64 via 2001:db8:cafe:1::100 dev tun0

服务器 A-IPv4 版本

IPv4 版本为:

我们仍然需要一个专用的路由表,因为我们需要根据来源路由流量,因此/etc/iproute2/rt_tables仍然需要以下条目:

200     openvpn

假设 IPv4 规则与 IPv6 非常类似,为操作系统提供以下命令用于 openvpn 路由表:

ip rule add priority 32000 iif tun0 to 0.0.0.0/0 table openvpn
ip route add default via <ipv4 address> dev tun1 table openvpn

现在我不确定是否有任何需要在此时捕获的 IPv4 范围(例如 RFC1918 地址),因为一般的想法基本上是转发接口上进入的所有内容tun0并将其发送到tun1上图中。


服务器 B-IPv6 版本

现在有两种将 IPv6 流量转发到 Internet 的方法:

  • 如果您从连接到 的 ISP 处获得了可路由的 IPv6 池Server B,那么对您来说就太好了。默认路由表main可能可以为您完成所有事情。

  • 如果您有来自 Hurricane Electric 的 IPv6 块,那么您基本上需要与上相同的设置,即Server A使用专用路由表作为上游,使用默认路由表作为下游。

服务器 B-IPv4 版本

这里最简单的解决方案可能是Server B将其视为 NAT,因此您需要在将来自您网络的所有数据包发送到 Internet 之前对其进行伪装。

答案2

如果您在 Linux(StrongSwan)上使用 IPSec,则使用 执行策略路由ip xfrm policy:带有 的策略dir out用于决定将数据包转发到哪个隧道,而带有dir in和 的策略dir fwd用于决定是否允许或丢弃数据包。

假设serverA有公有 IP192.0.2.1和私有 IP 10.0.10.1(你可以把它附加到环回设备上),serverB有公有 IP198.51.100.1和私有 IP 10.0.20.1,而 VPN 客户端在网络中获得一个 IP 。你可以像这样在 serverA 上10.0.30.0/24使用建立隧道:swanctl.conf

connections {
  serverB {
    version = 2
    local_addrs=192.0.2.1
    remote_addrs=198.51.100.1
    local {
        # serverA auth parameters
    }
        # serverB auth parameters
    }
    children {
      tunnel {
        local_ts = 10.0.10.0/24
        remote_ts = 10.0.20.0/24
        start_action = start
        reqid = 10
        priority = 1000
      }
    }
  }
}

在服务器B上也有类似的配置,local*并且remote*反转。

请注意,reqidpriority参数是固定的,因此可以在策略中使用。在中无法做到这一点ipsec.conf

要配置策略路由,您需要在服务器 A 上执行以下操作:

  1. 允许从 IP 到任意 IP 的加密流量。如果您在 VPN 客户端的连接配置中10.0.30.0/16设置,则此操作会自动完成。local_ts = 0.0.0.0/0
  2. 允许加密流量10.0.30.0/24与 serverB 建立隧道:

    ip xfrm policy add src 0/0 dst 10.0.30/24 \
        dir fwd priority 2000 \
        tmpl src 198.51.100.1 dst 192.0.2.1 \
        proto esp reqid 10 mode tunnel
    

    这与IP 链ACCEPT中的规则类似FORWARD

  3. 转发流量10.0.30.0/24到服务器B:

    ip xfrm policy add src 10.0.30/24 dst 0/0 \
        dir out priority 2000 \
        tmpl src 192.0.2.1 dst 198.51.100.1 \
        proto esp reqid 10 mode tunnel
    

优先级高于 StrongSwan 自动安装的优先级,因此如果安装了这些策略,则允许转发。如果删除这些策略,StrongSwan 安装的策略将仅允许10.0.10.0/24和之间的流量10.0.20.0/24。在 serverB 上,您可以使用相同的策略,只需dir out与交换即可dir fwd

附言:当然,您还需要一些 iptables 规则,以便服务器 A 和服务器 B 允许 ESP 和 IKE 流量:

iptables -I INPUT -p esp -j ACCEPT
iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IKE" -j ACCEPT

并设置一些丢弃规则,以便隧道断开时数据包不会以未加密的形式退出:

iptables -A OUTPUT -o <external_interface> -s 10.0.0.0/16 -m policy --dir out --policy ipsec -j ACCEPT
iptables -A OUTPUT -o <external_interface> -s 10.0.0.0/16 -j DROP

编辑:由于您正在使用ipsec配置文件与上述等效的配置swanctl.conf是:

conn servers {
    left=192.0.2.1
    right=198.51.100.1
    # The appropriate authentication leftauth, leftid, ...
    leftsubnet = 10.0.10.0/24
    rightsubnet = 10.0.20.0/24
    auto = start
    reqid = 10
}

就其而言,swanctl.conf它的优点是无需在两个主机上进行修改即可工作,但它不允许设置策略priority,因此您需要检查 StrongSwan 选择设置更高的优先级。

相关内容