我在使用 VPN 的同一台服务器上运行着一个 Web 服务器。我希望能够在 VPN 开启或关闭时访问 Web 服务器。在 FreeBSD 上这很简单,在我看来,PF 比 IPTables 更容易使用。
我正在尝试重新路由来自端口 80/443 的流量tun0到端口 80/44eth0我一直在阅读手册页iptables但没有任何运气。
答案1
问题标题没有相当按照书面形式理解。流量没有被路由到或者从首先是 TCP 端口(最好将它们视为标签),并且 TCP 端口与接口没有任何关联。并且这些都与 VPN 开启和关闭时能否使用 Web 服务器无关。
数据包的路由主要根据其目标 IP 地址进行选择,方法是在路由表中查找。常见的问题 – FreeBSD普法(据我所知,Windows 也有)有额外的内置机制来避免这种情况,但 Linux 坚持基本原则——即出站“回复”数据包的路由完全独立于入站“原始”数据包。因此,如果您有两个默认路由(通过 LAN 网关和通过 VPN),Linux 将始终选择同一条路由。
在这种情况下,您通常需要的是源相关路由或策略路由。操作系统需要知道传出的“回复”数据包 a)从给定的源 IP 地址,或 b)属于某些已建立的连接,必须使用不同的路由选择。
按照“但 Linux 是关于选择的”这一伟大传统,您必须通过拼凑各种机制来手动配置这一点。我假设您也需要 IPv4,因此不能完全依赖“子树”机制(这是很多更容易使用,但不幸的是仅实现 IPv6)。
首先确保您有两个路由表,每个路由表都有不同的默认路由:
ip -4 route add default via 192.168.1.1 dev eth0 table 2
ip -4 route add default dev tun0 table 3
(快捷方式:假设“主”表已经有通过 VPN 的默认路由,则这里不需要表 3,您可以直接使用“主”表,而不必创建表 3。)
然后添加策略路由规则,根据源 IP 地址查找该表:
ip -4 rule add pref 200 from 192.168.1.0/24 lookup 2
ip -4 rule add pref 300 from <vpnnet> lookup 3
(同样,如果“主”表已经优先选择通过 VPN 的默认路由,则可以跳过后一条规则。此处将其包含在此处是为了完整性。)
然后使用以下命令检查结果:
ip -4 route get 8.8.8.8 from 192.168.1.x
ip -4 route get 8.8.8.8 from <vpnip>