Answers:
可以使用Linux网络命名空间来完成。
这是一篇说明如何做的文章。基本上,您可以使用其他默认路由创建网络名称空间,然后在其中运行需要它的进程。您可以使用网桥将新创建的网络名称空间连接到物理适配器(当然也可以使用其他解决方案)。
更新:从内核3.14开始,使用控制组更加容易,如本文所述。你必须:
1)定义一个net_cls控制组,以使用classid(或进程组,请注意它们之间没有任何父子关系)注释来自给定进程的数据包
2)使用iptables cgroup模块(在Linux 3.14中添加)对数据包进行fwmark
3)使用策略路由(ip规则添加fwmark ....)为标记的数据包创建新的路由表
优点是我们不必做桥接工作,而且由于cgroups使得一切都更加动态。
我为此感到非常挣扎,所以这是一个完整的解决方案。它已在Ubuntu 15和16上进行了测试。您尤其可以将它与OpenVPN结合使用,以将某些应用路由到VPN隧道接口之外。
我制作了一个novpn.sh脚本来自动化依赖项的安装和运行。在Ubuntu上测试。
首先启动您的VPN。
wget https://gist.githubusercontent.com/kriswebdev/a8d291936fe4299fb17d3744497b1170/raw/cf8b37fbe6c3f50a0be825eb77cafa3e0134946f/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
首先,安装cgroup支持和工具:
sudo apt-get install cgroup-lite cgmanager cgroup-tools
重新启动(可能没有必要)。
您需要iptables 1.6 .0+。从iptables源目录获取iptables 1.6.0发布源,将其解压缩,然后运行此命令(--disable-nftables
标志将避免错误):
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
现在,真正的配置。定义一个名为的控制组novpn
。此cgroup中的进程的类标识为0x00110011
(11:11)。
sudo su
mkdir /sys/fs/cgroup/net_cls/novpn
cd /sys/fs/cgroup/net_cls/novpn
echo 0x00110011 > net_cls.classid
现在,我们假设您要用于特定应用的界面eth0
的网关IP为10.0.0.1
。将其替换为您真正想要的(从获取信息ip route
)。以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
最后,在特定界面上运行您的应用程序:
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
cgexec -g net_cls:novpn firefox
或者,如果您要将已经在运行的进程移至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
积分:没有答案按预期工作,但是混合了:chripell答案evolware文章每个进程路由需要2:使用cgroups,iptables和策略路由,如何使特定进程不通过OpenVPN连接?,在iptables的基础上终止OpenVPN的开关
apache2
直接从终端运行,您将得到相同的错误。那是因为apache2
通常是使用来启动的systemctl start apache2
。但是,这不适用于cgexec
。被调用程序必须是apache2
net_cls cgroup要传播的所需()进程的父级。因此,您需要找到启动脚本。在这种情况下为sudo cgexec -g net_cls:novpn /usr/sbin/apache2ctl start
。用检查./novpn.sh --list
。
eth0
的类似enp7s0
。从ifconfig
命令获取信息。
一些人编写了使用Linux的LD_PRELOAD功能来实现此目的的垫片:
结合mariusmatutiae和KrisWebDev的出色答案,我创建了一个广泛修改的版本KrisWebDev的出色novpn.sh
脚本。KrisWebDev的脚本旨在消除更具体的问题(在VPN内外运行和移动进程),而我的版本允许您在指定的网络环境中基本上运行任何命令。您可以指定要绑定的接口,默认路由,指定自己的iptables规则,静态路由,指定“测试”以确认一切正常,然后再运行命令...等等)。它允许您使用多个配置文件,以便您可以定义可在其中运行命令/进程的任意数量的特定网络环境。
我将其作为要点发布在这里:https : //gist.github.com/level323/54a921216f0baaa163127d960bfebbf0
之后它甚至可以清理cgroup / iptables / routing表!
欢迎反馈。
PS-专为Debian 8(Jessie)设计
不是每个应用程序,不是。您可以按端口或IP地址等进行操作,或者应用程序本身可以绑定(并使用)特定的网卡。
但是,您无法设置规则来执行此操作。
cgexec -g net_cls:novpn apache2
给了我完整的变量未定义错误列表!