编辑:好的,我会尽量讲得更清楚。我试图实现的只是通过我的 OpenVZ 托管 openvpn 服务器将端口转发到客户端上运行的服务。我想转发几个不同的服务,比如 Web 服务器或 bittorent 客户端。为了便于讨论,假设我只想与此拓扑建立功能性 netcat 连接:
internet --->[-->server(1.2.3.4:15555)]-nat-/->openvpn-server(10.8.0.1)--\ -> 运行 web 服务器的客户端 (10.8.0.6:15555)
或者 ....
(inet) --->|(公共 ip)-nat-through-openvpn-server--|->to-client-\ 10.8.0.6(目的地)
其中 inet 代表互联网上的任何主机,1.2.3.4 代表我的服务器的公共 IP,10.8.0.6 代表将托管服务器的 ovpn 客户端,我希望可以从 VPN 后面访问该服务器,地址/端口为 1.2.3.4:15555
这是我的 ifconfig:
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:1037374 errors:0 dropped:0 overruns:0 frame:0
TX packets:1037374 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:141887598 (141.8 MB) TX bytes:141887598 (141.8 MB)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.1 P-t-P:10.8.0.2 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:1746329 errors:0 dropped:0 overruns:0 frame:0
TX packets:3193026 errors:0 dropped:117 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:104945794 (104.9 MB) TX bytes:4356609743 (4.3 GB)
venet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:127.0.0.2 P-t-P:127.0.0.2 Bcast:0.0.0.0 Mask:255.255.255.255
UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
RX packets:43166195 errors:0 dropped:0 overruns:0 frame:0
TX packets:44728488 errors:0 dropped:11647 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:34214141842 (34.2 GB) TX bytes:43166888251 (43.1 GB)
venet0:0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:1.2.3.4 P-t-P:1.2.3.4 Bcast:1.2.3.4 Mask:255.255.255.255
UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
venet0:1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:1.2.3.5 P-t-P:1.2.3.5 Bcast:1.2.3.5 Mask:255.255.255.255
UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
因此,我希望互联网上的主机能够通过 openvpn 服务器进行 NAT,到达服务器公共 IP 地址的 netcat 侦听器(或 Web 服务器),再到达 openvpn 客户端。
我昨晚问了这个问题然后删除了它,因为我以为我已经找到了答案,但结果却不是。如果这看起来是一个重复的问题,我深表歉意。我已经搜索并尝试遵循此主题其他帖子中的建议。情况是,我有一个 Ubuntu Minimal vps。它是一个 OpenVZ 容器。它主要用作 openvpn 服务器。网络拓扑是 p2p。我试图通过服务器的公共 IP(例如 1.2.3.4)将端口转发到客户端(例如 10.8.0.6,p2p 10.8.0.5),以便可以从 VPN 地址 1.2.3.4 访问某个服务(比如 apache)。
我知道因为服务器是一个 OpenVZ 容器,所以需要使用某些 iptables 解决方法,例如对于 openvpn:
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s $VPN_SN -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s $VPN_SN -o venet0 -j SNAT --to-source $OUTIP
这很好用。我还可以将发往服务器的流量从一个端口重定向到另一个端口:
iptables -A INPUT -i venet0 -d $EXTIP -p tcp --dport 80 -m state --state NEW -j ACCEPT
$IPT -t nat -A PREROUTING -p tcp -d $EXTIP --dport 80 -j REDIRECT --to-port 9001
iptables -A INPUT -i venet0 -p tcp --dport 9001 -j ACCEPT
这也行得通,尽管我更希望不要将目标端口 (9001) 向世界开放,但否则我无法让它工作。我根本无法做到的是将发往服务器公共 IP ($EXT_IP) 的流量转发到某个端口上的 VPN 客户端之一。我尝试过几种不同的方法。(我也想知道点对点拓扑是否会使这变得复杂?)我尝试使用另一个线程中描述的规则:
$IPT -A INPUT -p tcp -d $OUTIP --dport 15555 -j ACCEPT
$IPT -A FORWARD -i venet0 -p tcp --dport 15555 -j ACCEPT
$IPT -t nat -A PREROUTING -i venet0 -p tcp -m tcp --dport 15555 -j DNAT --to-destination 10.8.0.6:15555
(OUTIP 表示传出 IP 地址,或 venet0:1 的地址。VPN 流量通过 venet0:0 路由到 venet0:1)
接下来我设置了一个 netcat 监听器:nc -l 0.0.0.0 -p 15555
并利用这个网站测试了连接,终于有了些进展:
invalid connection to [10.8.0.6] from (UNKNOWN) [66.240.174.69] 55814
现在至少我知道流量正在被转发,这是一个开始。所以我想我可能需要添加一个后路由规则,这样流量就知道要被发回哪里
$IPT -A POSTROUTING -t nat -p tcp -d 10.8.0.6 --dport 15555 -j SNAT --to-source $OUT_IP:15555
我得到了相同的结果。我是所以我花了好几个小时试图将一个该死的端口转发给客户端,这让我很沮丧。我真的很感激有人能给我一些帮助!
答案1
我终于让它工作了。结果发现数据包没有被转发到服务器。我最终需要以下这些规则。我写了这个小脚本来启用/禁用端口转发规则。
## Port Forwarding to Client ##
fwd_EN="false" # Change to 'true' to enable
ext_if="venet0" #
int_if="tun0" #
int_ip="10.9.0.6" # client to forward to
int_PRT="15555"
if [[ $fwd_EN == "true" ]]; then
echo Warning: Port Forwarding enabled
$IPT -t nat -A PREROUTING -p tcp -i $ext_if --dport $int_PRT -j DNAT --to-dest $int_ip:$int_PRT
$IPT -A FORWARD -p tcp -i $ext_if -o $int_if -d $int_ip --dport $int_PRT -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $ext_if -o $int_if -d $int_ip -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $int_if -s $int_ip -o $ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
else echo Info: Port Forwarding Disabled
fi
现在我可以在客户端上设置一个 nc 监听器,并从远程主机运行,nc 1.2.3.4 15555
并且连接就可以正常工作了!
anon@vpnclient:~$ nc -l -v -p 15555
Listening on [0.0.0.0] (family 0, port 15555)
Connection from [x.x.x.x] port 15555 [tcp/*] accepted (family 2, sport 58939)
Can you see me?
yes, I can!
答案2
我也在 OpenVZ 服务器上使用 OpenVPN。我尝试了您的脚本,但我无法通过公共服务器地址访问我家里的树莓派 :(。
我可以通过 tun0 地址 10.8.0.2:8080 从我的服务器连接到我的 raspi(通过 OpenVPN 连接到我的服务器)。
但当我想通过服务器地址连接到 raspi 时,却无法实现
这是我的 iptables -L 输出:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:openvpn
ACCEPT all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere 10.8.0.2 tcp dpt:http-alt state NEW
ACCEPT all -- anywhere 10.8.0.2 state RELATED,ESTABLISHED
ACCEPT all -- 10.8.0.2 anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere 10.8.0.2 tcp dpt:http-alt state NEW
ACCEPT all -- anywhere 10.8.0.2 state RELATED,ESTABLISHED
ACCEPT all -- 10.8.0.2 anywhere state RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT)
target prot opt source destination