我最近发布了另一个解决这种特定情况的答案,但问题不是重复的,因为这个问题更针对 OpenVPN。由于有些人喜欢对答案链接投反对票,而不是将答案直接放在问题中,因此我将其复制/粘贴到此处。
我一直在努力解决这个问题,所以这里有一个完整的解决方案。它在 Ubuntu 15 到 19.10 上进行了测试。您尤其可以将它与 OpenVPN 结合使用,以在 VPN 隧道接口之外路由某些应用程序。
我制作了一个novpn.sh脚本来自动安装和运行依赖项。在 Ubuntu 15 到 19.10 上测试。
首先启动您的VPN。
wget https://gist.githubusercontent.com/kriswebdev/a8d291936fe4299fb17d3744497b1170/raw/novpn.sh
# If you don't use eth0, edit the script setting.
sudo chmod +x novpn.sh
./novpn.sh traceroute www.google.com
./novpn.sh --help
Run Code Online (Sandbox Code Playgroud)
首先,安装 cgroup 支持和工具:
sudo apt-get install cgroup-lite cgroup-tools
Run Code Online (Sandbox Code Playgroud)
你需要 iptables 1.6 .0+。获取 iptables 1.6.0 release source,提取它,然后--disable-nftables从 iptables 源目录运行这个(标志将避免错误):
iptables --version
sudo apt-get install dh-autoreconf bison flex
./configure --prefix=/usr \
--sbindir=/sbin \
--disable-nftables \
--enable-libipq \
--with-xtlibdir=/lib/xtables
make
sudo make install
iptables --version
Run Code Online (Sandbox Code Playgroud)
现在,真正的配置。定义一个名为 的控制组novpn。此 cgroup 中的进程将具有0x00110011(11:11)的 classid 。
sudo su
mkdir /sys/fs/cgroup/net_cls/novpn
cd /sys/fs/cgroup/net_cls/novpn
echo 0x00110011 > net_cls.classid
Run Code Online (Sandbox Code Playgroud)
现在,我们假设您要用于特定应用程序的真实接口eth0的网关 IP 为10.0.0.1. 用你真正想要的东西替换它们(从 中获取信息ip route),尤其是在较新的 Ubuntu 版本中,接口具有奇怪的名称。仍然以 root 身份运行:
# Add mark 11 on packets of classid 0x00110011
iptables -t mangle -A OUTPUT -m cgroup --cgroup 0x00110011 -j MARK --set-mark 11
# Force the packets to exit through eth0 with NAT
iptables -t nat -A POSTROUTING -m cgroup --cgroup 0x00110011 -o eth0 -j MASQUERADE
# Define a new "novpn" routing table
# DO THIS JUST ONCE !
echo 11 novpn >> /etc/iproute2/rt_tables
# Packets with mark 11 will use novpn
ip rule add fwmark 11 table novpn
# Novpn has a default gateway to the interface you want to use
ip route add default via 10.0.0.1 table novpn
# Unset reverse path filtering for all interfaces, or at least for "eth0" and "all"
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done
Run Code Online (Sandbox Code Playgroud)
最后,在特定界面上运行您的应用程序:
exit
sudo cgcreate -t $USER:$USER -a $USER:$USER -g net_cls:novpn
cgexec -g net_cls:novpn traceroute www.google.com
# Close all Firefox windows first
killall firefox; cgexec -g net_cls:novpn firefox
Run Code Online (Sandbox Code Playgroud)
或者,如果您想将已经运行的进程移动到 cgroup,那么……您不能!这似乎是由于 NAT(伪装)功能:iptables -nvL -t nat切换 cgroup 时iptables -nvL -t mangle不匹配,但确实匹配。
# Get PID of the process (we'll then suppose it's 1234)
pidof firefox
# Add to cgroup - THIS DOESN'T WORK! Silently fails to produce the final result.
sudo echo 1234 > /sys/fs/cgroup/net_cls/novpn/tasks
# Remove - but this works...
sudo echo 1234 > /sys/fs/cgroup/net_cls
Run Code Online (Sandbox Code Playgroud)
积分: 没有答案按预期工作,但它们的组合做到了: chripell answer evolware 文章Per process routing take 2: using cgroups, iptables and policy routing,如何使特定进程不通过 OpenVPN 连接?,基于iptables的OpenVPN的kill switch
| 归档时间: |
|
| 查看次数: |
5778 次 |
| 最近记录: |