プロセスが使用するトラフィックを特定のインターフェースでルーティングすることは可能ですか?
たとえば、ダウンロードアプリケーションによるネットワークトラフィックは常にwlan0
インターフェースを使用する必要がありますが、マシン上の他のすべてのアプリケーションはeth0
を使用する必要があります。
Linuxでこの種のルールを持つことは可能ですか?
Linuxネットワーク名前空間を使用して行うことができます。
こちらの記事 方法を説明しています。基本的に、異なるデフォルトルートでネットワーク名前空間を作成し、そこで必要なプロセスを実行します。新しく作成されたネットワーク名前空間をブリッジで物理アダプターに接続します(もちろん他のソリューションも可能です)。
更新: この記事 で説明されているように、カーネル3.14以降では、コントロールグループを使用する方が簡単です。必ず:
1)net_clsコントロールグループを定義して、特定のプロセスからのパケットにclassid(またはプロセスのグループ、それらの間に親子関係がある必要はないことに注意してください)で注釈を付ける
2)iptables cgroupモジュール(Linux 3.14で追加)を使用してパケットをfwmark
3)ポリシールーティング(ip rule add fwmark ....)を使用して、マークされたパケットの新しいルーティングテーブルを作成します。
利点は、ブリッジを行う必要がないことであり、cgroupのおかげですべてがはるかに動的になります。
私はこれに苦労しているので、ここに完全なソリューションがあります。 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
まず、cgroupサポートとツールをインストールします。
Sudo apt-get install cgroup-lite cgroup-tools
Iptables1.6。0+が必要です。 iptables 1.6.0リリースソースを取得 、それを抽出し、iptablesソースディレクトリからこれを実行します(--disable-nftables
フラグはエラーを回避します)。
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
さて、実際の設定です。 novpn
という名前のコントロールグループを定義します。このcgroupのプロセスには、0x00110011
(11:11)のクラスIDがあります。
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
であると仮定します。 [〜#〜] replace [〜#〜]これらを本当に欲しいもので置き換えます(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
最後に、特定のインターフェイスでアプリを実行します。
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
または、すでに実行中のプロセスをcgroupに移動する場合は、まあ...できません!これは、NAT(マスカレード)関数:cgroupが切り替えられたときにiptables -nvL -t nat
は一致しませんが、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 answer evolware記事 プロセスごとのルーティングテイク2:cgroups、iptables、およびポリシールーティングを使用 、- OpenVPN接続を経由しない特定のプロセスを作成するにはどうすればよいですか? 、 iptablesに基づいてOpenVPNのキルスイッチ
これを達成するためにLinuxのLD_PRELOAD機能を使用するシムを書いた人が数人います:
MariusmatutiaeとKrisWebDevの優れた答えを組み合わせて、大幅に変更されたバージョンのKrisWebDevの優れたnovpn.sh
スクリプトを作成しました。 KrisWebDevのスクリプトは、より具体的なかゆみ(VPN内外のプロセスの実行と移動)をスクラッチするように設計されていますが、私のバージョンでは、指定したネットワーク環境で基本的にすべてのコマンドを実行できます。バインドするインターフェース、デフォルトルート、独自のiptablesルール、静的ルートを指定し、「テスト」を指定して、コマンドを実行する前にすべてが正常に動作していることを確認できます...など)。複数の構成ファイルを使用できるため、内部でコマンド/プロセスを実行できる特定のネットワーク環境をいくつでも定義できます。
ここに要点として投稿しました: https://Gist.github.com/level323/54a921216f0baaa163127d960bfebbf
後でcgroup/iptables /ルーティングテーブルをクリーンアップすることもできます!
フィードバックを歓迎します。
PS-Debian 8(Jessie)用に設計されています
アプリケーションごとではありません。ポートごと、またはIPアドレスごとなどに実行できます。または、アプリケーション自体が特定のネットワークカードにバインド(および使用)できます。
ただし、それを行うルールを設定することはできません。