一个关于 iptables 的问题

2019-09-16 05:19:44 +08:00
 KasuganoSoras

最近在研究用 OpenVPN + iptables 实现内网穿透,比传统 Frp 内网穿透有一个好处就是可以转发访客真实 IP,但是目前遇到一个问题,如何让 OpenVPN 客户端以非全局模式连接?目前内网穿透测试过已经没有问题,但是客户端的所有流量也会经过服务器,我的想法是让客户端只用于内网穿透,而不是代理上网。

环境信息

OpenVPN 服务器配置

port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-auth ta.key 0
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 223.5.5.5"
push "dhcp-option DNS 223.6.6.6"
keepalive 10 120
cipher AES-256-CBC
user openvpn
group openvpn
persist-key
persist-tun
status openvpn-status.log
log openvpn-tc.log
verb 3
crl-verify crl.pem
client-config-dir /etc/openvpn/server/clients/
script-security 2
down-pre
up /etc/openvpn/server/tc.sh
down /etc/openvpn/server/tc.sh
client-connect /etc/openvpn/server/tc.sh
client-disconnect /etc/openvpn/server/tc.sh

尝试过的操作

服务器上 iptables 配置:

iptables -t nat -A PREROUTING -d 123.123.123.123 -p tcp --dport 1:1023 -j DNAT --to-destination 10.8.0.181
iptables -t nat -A PREROUTING -d 123.123.123.123 -p udp --dport 1:1023 -j DNAT --to-destination 10.8.0.181

以上这个配置,内网穿透正常,可以转发真实 IP,但是客户端所有流量都会经过服务器。

然后经过我一晚上摸索,做了以下尝试:

注释掉 OpenVPN 服务器的这一行配置:

push "redirect-gateway def1 bypass-dhcp"

在服务器配置中增加一行:

push "route 10.0.0.0 255.0.0.0"

重新启动 OpenVPN 服务器和客户端,在客户端本地 curl 了一下 ip138,发现 IP 地址不再是服务器的 IP 了,也就说明此时是以非全局模式在运行的。

但是接着又遇到个问题,我发现内网穿透无法连接了,经过 tcpdump 抓包发现数据包已经到达了客户端主机,但是在返回的时候出不去,于是又照着网上教程在服务器上加了一个 iptables 规则:

iptables -t nat -A POSTROUTING -d 10.8.0.0/24 -j SNAT --to 10.8.0.1

加入这个规则后,内网穿透正常了,但是不能转发真实 IP,显示的访客 IP 都是来自 10.8.0.1 也就是 OpenVPN 的网关 IP。

有没有大佬知道如何解决这个问题?谢谢!

4965 次点击
所在节点    问与答
29 条回复
hangvane
2019-09-16 08:12:24 +08:00
同一个世界,同一个问题,我也遇到过了最后选择 frp https://www.v2ex.com/t/580901
huangya
2019-09-16 08:23:42 +08:00
请再详细描述一下你的内网穿透是什么意思。你最终的应用场景是什么
KasuganoSoras
2019-09-16 08:25:29 +08:00
@hangvane #1 hhh 我就是做 Frp 的,因为苦于 Frp 不能转发访客真实 IP 所以想试试用 OpenVPN,结果又遇到了你遇到过的问题......
KasuganoSoras
2019-09-16 08:27:13 +08:00
@huangya #2 就是和 Frp 一样的用法,只不过是想借助 VPN 协议可以转发访问者 IP 的特性(用 Frp 转发后的访问者 IP 全都是 127.0.0.1,目的就是解决这个问题),最终用途还是将内网的服务通过 VPN 暴露到公网。
KasuganoSoras
2019-09-16 08:29:05 +08:00
目前遇到的技术难题就是,如何让 VPN 只作为内网穿透使用,而不是所有流量都经过服务器代理,同时还要能够转发访问者的真实 IP,这就是 1 楼之前遇到过的问题,没想到我又踩坑了。
yibei
2019-09-16 08:41:45 +08:00
@KasuganoSoras 这种只能对特定的端口进行转发才能实现吧
paradislover
2019-09-16 08:45:28 +08:00
不推送网关,推送 route,客户端 iroute
xduanx
2019-09-16 08:55:18 +08:00
客户端 tcpdump 的时候看到的源 IP 是什么
如果不在 10.0.0.0 255.0.0.0 这里面(比如 192.168.0.0/16 或者 172.16.0.0/12 ),那就 push "route XXXX XXXX"
KasuganoSoras
2019-09-16 09:04:19 +08:00
@paradislover #7 能具体说一下如何操作吗?看了下谷歌找的文档,不太理解这个 iroute 怎么用
KasuganoSoras
2019-09-16 09:05:13 +08:00
@xduanx #8 客户端 tcpdump 看到的是访问者的源 IP
zbinlin
2019-09-16 09:08:00 +08:00
这是路由问题,你删除了 `ip route add 0.0.0.0/1 via 10.8.0.1` 就要加上 `ip route add 10.8.0.0/24 via 10.8.0.1` 呀
KasuganoSoras
2019-09-16 09:17:10 +08:00
@zbinlin #11 我试了一下,还是之前的问题,OpenVPN 传递到客户端的 IP 地址是访客的源 IP,客户端这边由于没有了 0.0.0.0/1 这条规则,就没办法将数据包再传回给 VPN 网关,也就是上面说的数据只能进不能出的问题。
huangya
2019-09-16 09:21:03 +08:00
@KasuganoSoras 有看了下你的问题,基本弄清楚了需求。
>但是接着又遇到个问题,我发现内网穿透无法连接了,经过 tcpdump 抓包发现数据包已经到达了客户端主机,但是在返回的时候出不去,于是又照着网上教程在服务器上加了一个 iptables 规则:

前面步骤保留,在这里不要在服务器上添加 iptables 规则,建议在客户端上用策略路由。我写了一些没有验证过的命令,你可以在客户端试试看(用 root 权限执行),有什么问题可以后续交流。
iptables -t mangle -A OUTPUT -p udp -m udp --sport 1:1023 -j MARK --set-xmark 0x1/0xffffffff
iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 1:1023 -j MARK --set-xmark 0x1/0xffffffff
echo 1 openvpn-tun >>/etc/iproute2/rt_tables
ip route add default via 192.168.5.1 dev tun0 table openvpn-tun
ip rule add from all fwmark 0x1 lookup openvpn-tun
huangya
2019-09-16 09:22:50 +08:00
@huangya
不好意思,有个命令 ip 写错了
ip route add default via 192.168.5.1 dev tun0 table openvpn-tun
改为
ip route add default via 10.8.0.1 dev tun0 table openvpn-tun
wwqgtxx
2019-09-16 09:23:06 +08:00
提个尝试性建议,把你的 server 绑定在 tun 端口上,强制其在 tun 端口上收发数据,这样应该就能不受数据只进不出的影响(其实只是数据出的时候没走 OVN 而是直接从网卡出去了,所以被外层丢包)
KasuganoSoras
2019-09-16 09:27:39 +08:00
@huangya #13 感谢感谢,我去测试一下

@wwqgtxx #15 好的,可以尝试一下
Meltdown
2019-09-16 09:31:34 +08:00
用 docker 或者虚拟机跑服务,docker 或者虚拟机连 openvpn…
KasuganoSoras
2019-09-16 10:00:58 +08:00
经过了 N 次尝试均以失败告终……甚至还两次把机器搞断网 😓
算了,还是老实用全局模式吧……感谢各位提供的帮助,谢谢!
acess
2019-09-16 12:06:54 +08:00
这个就是路由表里默认网关的问题吧……
gowa
2019-09-16 12:14:04 +08:00
楼主我有个疑问。vpn 你确定你是用的 隧道形式 还是 nat 形式。在 nat 形式 是在网络层 转发 你怎么可能获取真实 ip。 只有在隧道形式 对原始报文进行包裹的才可以

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/601016

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX