如何绕过每个应用程序的 OpenVPN

roy*_*lee 4 linux vpn proxy iptables openvpn

我有一台 linux 机器,它通过 openVPN 连接路由其整个互联网流量。它被明确配置为以这种方式工作。

但是,该机器有一些应用程序不应使用 VPN 连接 (tun+) 并通过开放连接 (eth0)。

由于它不是基于目标 ip 的路由,我的第一个不过是创建一个本地 socks5 代理,应用程序应该使用它来避免 openVPN 通道。但是,我使用 ssh -D 或其他 sw) 执行此操作的尝试失败了(可能是我的错),我现在想知道是否有其他更好的解决方案。

Kri*_*Dev 5

我最近发布了另一个解决这种特定情况的答案,但问题不是重复的,因为这个问题更针对 OpenVPN。由于有些人喜欢对答案链接投反对票,而不是将答案直接放在问题中,因此我将其复制/粘贴到此处。

我一直在努力解决这个问题,所以这里有一个完整的解决方案。它在 Ubuntu 15 到 19.10 上进行了测试。您尤其可以将它与 OpenVPN 结合使用,以在 VPN 隧道接口之外路由某些应用程序。

完整的“cgroup”解决方案

那是怎么工作的?

  • Linux 内核会将应用程序放入一个控制组。来自此 cgroup 中的应用程序的网络流量将在网络控制器级别由它们的类 ID 标识。
  • iptables 将标记此流量并强制它以正确的 IP 退出
  • ip route 将处理不同路由表中标记的流量,默认路由到您想要的任何网关 IP。

自动化脚本

我制作了一个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