我所在国家的互联网限制使得 VPN 无法使用。因此,我想使用以下方法来规避这个问题。
尽管“住宅”互联网受到限制,但“商业”互联网却没有。这意味着服务器仍然可以使用各种方法连接到国外的其他服务器。
我有一个客户端、一个在国内的服务器(IN 服务器)和一个在国外的服务器(OUT 服务器)。我可以使用 l2tp 连接到 IN 服务器,但现在我想将所有流量重新路由到 OUT 服务器。本质上,模式是:客户端 --l2tp--> IN 服务器 --iptables--> OUT 服务器
我已经使用过 iptables,但无济于事。这是我使用的脚本(通过 gfw-report 来自https://github.com/net4people/bbs/issues/126):
#!/bin/bash
set -x
set -e
OUT_server_ip="2.2.2.2"
OUT_server_port="22"
IN_server="1.1.1.1"
IN_server_port="11111"
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
sudo iptables -t nat -A PREROUTING -p tcp --dport "${IN_server}" -j DNAT --to-destination "${OUT_server}:${OUT_server_port}"
sudo iptables -t nat -A PREROUTING -p udp --dport "${IN_server_port}" -j DNAT --to-destination "${OUT_server}:${OUT_server_port}"
sudo iptables -t nat -A POSTROUTING -p tcp -d "${OUT_server}" --dport "${OUT_server_port}" -j SNAT --to-source "${IN_server}"
sudo iptables -t nat -A POSTROUTING -p udp -d "${OUT_server}" --dport "${OUT_server_port}" -j SNAT --to-source "${IN_server}"
我该如何修改脚本才能让它工作? OUT_server 中已启用 IP 转发
答案1
通过 l2tp 的任何流量
iptables DNAT 不会这样做。如果您对数据包进行 DNAT,它将丢失有关其原始目的地的所有信息 - OUT_server 会将所有数据包视为发往其自身的地址,并且无法将它们转发到其他任何地方。
换句话说,你找到的脚本是为了完成一个稍微不同的任务。它只能应用于隧道本身– 即,如果您在这些 iptables 规则中指定 UDP 端口1701
,则第一台服务器会将所有“原始”L2TP 数据包中继到第二台服务器。(实际的隧道接口需要从服务器 1 中删除并在服务器 2 上设置,尽管您的客户端仍会认为它正在与服务器 1 通信。)
IN_SERVER 上的 NAT 配置:
-t nat -A PREROUTING -p udp --dport 1701 -j DNAT --to-destination ${OUT_SERVER}:1701 -t nat -A POSTROUTING -p udp --dport 1701 -j MASQUERADE
客户端上的隧道配置:remote = IN_SERVER
IN_SERVER 上的隧道配置:无
OUT_SERVER 上的隧道配置:remote = IN_SERVER
对于更标准的方法来转发隧道流量而不是隧道本身,您需要一个第二条隧道在两个服务器之间(L2TP 或任何其他类型),您需要配置“策略路由”以匹配通过隧道 1 到达的所有数据包并通过隧道 2 路由它们。(这可以使用ip route
和来完成ip rule
,通常不使用 iptables。)
IN_SERVER 上的 NAT 配置:无
客户端上的隧道配置:remote = IN_SERVER
IN_SERVER 上的隧道配置:1) remote=CLIENT;2) remote=OUT_SERVER
OUT_SERVER 上的隧道配置:remote=IN_SERVER
IN_SERVER上的路由配置:
ip route add default dev tunnel1 table 42
IN_SERVER 上的策略路由:
ip rule add iif tunnel1 lookup 42
请记住,iptables 不执行路由。链名称“前路由”和“邮政路由”应该表明;iptables 只应用过滤和转换(例如 NAT)之前或之后路由发生,但实际路由是不是在 iptables 中完成。