Twi*_*fty 7 networking linux dns vpn routing
在 ubuntu 16.04 上,我想根据在浏览器中输入的域名通过直接互联网eth0或我的 VPN路由我的流量tun0。本地站点的原因要么速度慢,要么取决于位置。
我意识到内核路由表是基于 IP 的,域名通常在软件层解析,但由于 linux 是一个脚本友好的平台,我希望有一个解决方法。虽然,我不知道如何编写这样的脚本。
到目前为止,我发现该dig example.com +short @8.8.8.8命令将列出与域关联的 IP,并且我发现该sudo route add -net 8.8.8.8 netmask 255.255.255.255 gw 192.168.2.1命令将绕过给定 IP 的 VPN(其中 192.168.2.1 是我的默认值eth0)。有人会友好地为脚本模板化,该脚本读取包含域名的文件并在系统启动时输入路由规则。允许屏蔽子域的奖励积分*.example.com。
如果这种疯狂有更简单的方法,我会接受它作为解决方案。
注意:我可以很容易地将 IP 硬编码到其中,/etc/network/interfaces但随后它们变得难以管理。我还尝试将我所在国家/地区的所有已知 IP 硬编码到此文件中,但它非常受欢迎,并且启动时间延迟。
Pos*_*sum 14
基于目标域的路由并非不可能,而且,使用正确的工具,也不是那么难。
我将介绍一些需要很少或不需要特殊客户端配置的方法。这些都假设您使用 OpenVPN 进行连接。这应该可以通过其他 VPN 实现,但在 VPN 启动后可能需要更多的手动配置。
出于示例目的,我将使用域“example.com”、“us1.example.com”、“us2.example.com”和“geoblocked.com”作为我们要通过非 VPN 路由的域界面。
所有命令都应以 root 身份运行。
如果您确定要路由的 IP 地址具有永不更改的静态 IP,我只会推荐此方法。
优点:
缺点:
方法:
将以下行添加到您的 OpenVPN 配置中:
route example.com 255.255.255.255 net_gateway
route us1.example.com 255.255.255.255 net_gateway
route us2.example.com 255.255.255.255 net_gateway
route geoblocked.com 255.255.255.255 net_gateway
Run Code Online (Sandbox Code Playgroud)
重新启动 OpenVPN。
就是这样,但是如果这些 IP 地址发生变化,您将不得不再次重新启动 VPN。
注意:一些消息来源说您还需要指定allow-pull-fqdn,但根据我的经验,情况似乎并非如此。天啊。
基于策略的路由是基于特定标准进行路由的能力;通常是源地址或协议,但在这种情况下,我们将在路由之前检查目标域名并使用标记的数据包(“fwmark”)。
所以我们首先需要做的是为你的 VPN 路由数据包创建一个单独的表,以便我们可以标记那些通过 VPN 的数据包,并通过非 VPN 接口传递标记的数据包。(请记住,这是一种方法,还有许多其他方法可以解决这个问题,例如让 VPN 通过主表正常进行路由,并为非 VPN 流量创建一个单独的表。)
您的内核必须足够新并具有适当的模块,尽管现代系统可能在其默认内核中包含它们。
名称“vpn_table”(路由表名称)、数字“201”(路由表ID)和“3”(fwmark)是任意选择的。
创建新的路由表(以 root 身份):
echo 201 vpn_table >> /etc/iproute2/rt_tables
Run Code Online (Sandbox Code Playgroud)
配置 OpenVPN:
在某处创建以下脚本(我称之为“/etc/openvpn/client/setup-routing”)并使其可执行:
#!/bin/bash
ip route add 0.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table
ip route add 128.0.0.0/1 via $route_vpn_gateway dev $dev scope global table vpn_table
sysctl -w net.ipv4.conf.$dev.rp_filter=2
# You can optionally leave the next two lines out but run the `ip rule add`
# command at each boot instead
ip rule del fwmark 3 table vpn_table &>/dev/null # This might fail but that's ok
ip rule add fwmark 3 table vpn_table
Run Code Online (Sandbox Code Playgroud)
上述脚本中的变量将被 OpenVPN 填充为环境变量。另请注意,这将通过“vpn_table”路由表中的 VPN 网关设置到所有地址的路由。如果您的 VPN 设置需要更复杂的路由,请参阅 OpenVPN 文档并进行相应调整。
将以下内容添加到您的 OpenVPN 配置中:
## Policy routing
route-noexec
script-security 2
route-up /etc/openvpn/client/setup-routing
Run Code Online (Sandbox Code Playgroud)
“route-noexec”行允许 OpenVPN 从服务器获取路由,但阻止它实际填充路由。而是调用路由脚本。“script-security 2”是调用用户定义脚本所必需的。
这是路由标记数据包的所有必要设置,但我们需要设置一种方法来实际标记数据包。两个选项是将 dnsmasq 与 ipset 一起使用,或者设置一个 squid 代理。
如果您已经在基于 dnsmasq 的路由器上运行此方法,或者您的客户端不支持代理配置,我会推荐此方法。这实际上与在查找域名时更新路由表的缓存 DNS 相同。
优点:
缺点:
这假设您已经配置和设置了 dnsmasq,并充当连接到专用接口“eth1”的客户端的网关和 DNS 服务器。
创建ipset:
ipset create SKIP_VPN_IPSET iphash
Run Code Online (Sandbox Code Playgroud)
告诉 iptables 标记 ipset 数据包(注意,这必须在创建 ipset 列表后完成):
# Mark ALL packets coming in on eth1 - change this to the interface dnsmasq listens on
iptables -A PREROUTING -i eth1 -t mangle -j MARK --set-mark 3
# REMOVE mark on any addresses that match our ipset
iptables -A PREROUTING -t mangle -m set --match-set SKIP_VPN_IPSET dst -j MARK --set-mark 0/3
Run Code Online (Sandbox Code Playgroud)
注意:必须在每次启动时运行上述命令(ipset和iptables)。或者,您的操作系统可能会提供一些用于保存/恢复 iptable 规则和 ipsets 的选项。
NOTE2:有记录是相反的,! --match-set但是当我尝试它时导致所有数据包都消失了。
将以下内容添加到您的 dnsmasq.conf 中:
ipset=/example.com/geoblocked.com/SKIP_VPN_IPSET
Run Code Online (Sandbox Code Playgroud)
显然,无论您想要路由哪个域名,都要调整该行。这也会将所有子域添加到 ipset,因此您无需明确指定它们。即使使用 TLD 也能工作。
重新启动 dnsmasq 并设置您的客户端以将 VPN 连接的系统用作网关和 DNS(如果它被设置为 DHCP 服务器,则应该暗示它)。
这是我最喜欢的方法,适用于我的 PS4 和我用来连接的其他设备。
优点:
缺点:
这假设您有一个有效的鱿鱼设置和鱿鱼配置的基本知识。
将以下行添加到 squid.conf:
# redirect example domains
acl domain_to_remote_proxy dstdomain .example.com
acl ref_to_remote_proxy referer_regex [^.]*\.example.com.*
# redirect geoblocked domain
acl domain_to_remote_proxy dstdomain .geoblocked.com
acl ref_to_remote_proxy referer_regex [^.]*\.geoblocked.com.*
# mark packets that we want routed through the VPN
tcp_outgoing_mark 0x03 !ref_to_remote_proxy !domain_to_remote_proxy
Run Code Online (Sandbox Code Playgroud)
请注意,每个域有 2 行,并且子域是匹配的。第一行检查目标域,第二行匹配“Referer”标头。这很有用,因为浏览器在获取网页上的内容(如图像、CSS 或 javascript)时会发送引用;这意味着站点请求的内容也将通过非 VPN 地址路由,即使它托管在不同的域(例如 example-cdn.com)上。
在客户端上,像往常一样设置连接,但设置代理设置以使用该系统的代理服务器和端口。大多数设备(包括游戏机)允许系统范围的配置。在 PC 上,大多数浏览器都可以配置为使用独立于系统设置的代理。
最后一点 - 我的用例实际上是通过 VPN 路由特定域,通过非 VPN 路由其他所有域。方法与上述类似,但颠倒了。
小智 4
我建议您避免基于域名管理路由(顺便说一句,解析通配符子域也是不可能的,无论它是否是奖励点:D)
\n为了更具描述性,您不应该这样做,因为:
\n有些域名会不时更改其 IP,
\n无法匹配子域中的通配符
\n不可能知道/获取任何域的所有子域
\n任何随机子域都可以有任何随机 IP 地址。
\n因此,作为浏览器插件(和/或自定义本地代理,如鱿鱼)的解决方案是解决您的问题的最佳选择。
\n但是,我想,“FoxyProxy”插件(它最初是 Firefox 插件,但 AFAIRC,也存在 Chrome 版本)正是您想要的。
\n并且,另外,回答您的通知“FoxyProxy 是付费服务,您已经拥有您的 VPN”:
\nFoxyProxy Plus是付费服务,但不是 FoxyProxy。
\nFoxyProxy 是插件,可用于主要浏览器:
\n\n标准版 (Chrom{e,ium}) | 基础版(Chrom{e,ium})
\n因此,如果您想通过 VPN 访问某些域,您应该:
\n为 Foxyproxy 编写规则以通过您的鱿鱼实例获取域列表
\n和/或编写鱿鱼的规则列表
\n使用 iptables 捕获不属于鱿鱼的http/https 流量,并按如下规则将其指向鱿鱼:
\niptables -m owner -m multiport -t nat -A OUTPUT ! -o lo ! --uid-owner $squid_user_id -p tcp --dports 80,443,8080,... -j REDIRECT --to-ports $SQUID_PORT\nRun Code Online (Sandbox Code Playgroud)\n(--syn可能需要选项-p tcp)
iptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11\nRun Code Online (Sandbox Code Playgroud)\necho 11 forcevpn >> /etc/iproute2/rt_tables\nip rule add fwmark 11 table forcevpn\nip route add default via 10.0.0.1 table forcevpn\nRun Code Online (Sandbox Code Playgroud)\n10.0.0.1你的 VPN 内网关在哪里?或者,如果您没有网关并且只想将所有流量推送到 VPN 接口中,则可以使用dev $VPN_IF代替。via 10.0.0.1
sudo sysctl ipv4.conf.all.rp_filter =0===
\n还有一件事情:
\n如果您想对非 http(s) TCP 流量执行相同的魔法,您将需要诸如代理链之类的东西,并执行类似的捕获魔法。
\n而且,如果你想用 UDP 实现这个魔法,我有一个坏消息:我不知道有任何代理能够代理 UDP(由于该协议的性质):)
\n\xe2\x87\x93\xe2\x87\x93\xe2\x87\x93 编辑 \xe2\x87\x93\xe2\x87\x93\xe2\x87\x93
\n如果您想要相反的东西(默认 gw = vpn,并直接通过 ISP 规则某些域),它可以是:
\n为 Foxyproxy 编写规则以通过您的鱿鱼实例获取域列表
\n捕获鱿鱼拥有的流量,并将其标记为下一次路由,规则如下:
\niptables -A OUTPUT -m owner --uid-owner $squid_user_id -j MARK --set-mark 11\nRun Code Online (Sandbox Code Playgroud)\necho 11 novpn >> /etc/iproute2/rt_tables\nip rule add fwmark 11 table novpn\nip route add default via ${ISP_GW} table novpn\nRun Code Online (Sandbox Code Playgroud)\n其中ISP_GW是将流量路由到 VPN 服务器的网关。某些用户可能希望使用dev ppp0(或ppp1, ..., pppN),而不是via ${ISP_GW}使用 pptp 连接到互联网。