将特定端口的请求转发到 VPN 客户端

将特定端口的请求转发到 VPN 客户端

我遇到了一个需要支持的问题,但困难的是我不知道问题出在哪里。我有一个在家庭网络上运行 Ubuntu Server 的 Raspberry Pi,以及在托管服务器上运行 Ubuntu Server 的 VPS。Raspberry Pi 有一个 OpenVPN 客户端,VPS 有一个 OpenVPN 服务器。客户端已连接到服务器,因为我可以在 /var/log/openvpn/openvpn-status.log 中看到它。

OpenVPN CLIENT LIST
Updated,Sun Feb 16 09:41:43 2020
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
client1,37.201.227.34:28237,3610,3478,Sun Feb 16 09:41:38 2020
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.6,client1,37.201.227.34:28237,Sun Feb 16 09:41:38 2020
GLOBAL STATS
Max bcast/mcast queue length,0
END

我想将对端口 9000 的 VPS 的请求转发到 VPN 客户端。但是它总是超时,就像没有转发请求一样。

我已经net.ipv4.ip_forward = 1在 sysctl 中设置了,这是内容/etc/ufw/before.rules(我也尝试将 37.201.xxx 与 10.8.0.6 交换,但没有任何运气)

#
# 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
#

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]

-A PREROUTING -i venet0 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 37.201.227.34:9000
-A PREROUTING -i venet0 -p udp -m udp --dport 9000 -j DNAT --to-destination 37.201.227.34:9000

# Allow traffic from OpenVPN client to venet0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o venet0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local

# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT

# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT

# START OPENVPN RULES
-A FORWARD -d 37.201.227.34/32 -p tcp -m tcp --dport 9000 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -d 37.201.227.34/32 -p udp-m udp --dport 9000 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
# END OPENVPN RULES

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

在我的路由器(AVM FritzBox 6591 电缆)中,我已将端口 9000 转发到我的树莓派,如您在屏幕截图中看到的那样

在此处输入图片描述

但是,当我在浏览器中输入“VPSIP:9000”时,它就超时了。哪里出了问题?

答案1

如果 Raspberry Pi 正在运行 OpenVPN 客户端,则无需打开 FritzBox 路由器上的端口。但是 PREROUTING 中的正确 iptables 规则是以 10.8.0.6 作为目标的规则

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i venet0 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 10.8.0.6:9000
-A PREROUTING -i venet0 -p udp -m udp --dport 9000 -j DNAT --to-destination 10.8.0.6:9000

连接超时的问题是因为 Raspberry Pi 通过具有公共 IP 的 VPN 接收请求,因此回复数据包将通过 Raspberry Pi 以太网(或 Wi-Fi 接口)发出,因为没有通过 VPN 接口回复的路由规则。为了不触及 RaspberryPi 上的任何东西,您可以通过使用 VPN 服务器 IP 伪装 VPS WAN 流量来解决这个问题,下面是一个简单示例:

-A POSTROUTING -o <vpn-server-interface> -j SNAT --to-source 10.8.0.1

Raspberry Pi 将看到来自 VPN 服务器 IP(假设为 10.8.0.1)的请求,因此 /etc/ufw/before.rules 文件中应该类似

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]

-A PREROUTING -i venet0 -p tcp -m tcp --dport 9000 -j DNAT --to-destination 10.8.0.6:9000
-A PREROUTING -i venet0 -p udp -m udp --dport 9000 -j DNAT --to-destination 10.8.0.6:9000

# Allow traffic from OpenVPN client to venet0 (change to the interface you discovered!)
-A POSTROUTING -o <vpn-server-interface> -j SNAT --to-source 10.8.0.1
-A POSTROUTING -s 10.8.0.0/8 -o venet0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

笔记:该解决方案的缺点是,在 portainer 应用程序的日志中,你会看到所有带有 VPN 服务器 IP 的请求

编辑:我认为实现此目的的最佳方法是在 VPS 上使用 nginx 或 apache 作为反向代理,这样您就不需要设置任何 iptables 预路由和后路由规则,而且您将在反向代理上拥有包含客户端真实 IP 的日志

相关内容