web-dev-qa-db-ja.com

Linuxのプロセスの特定のインターフェイスを介してトラフィックをルーティングする

プロセスが使用するトラフィックを特定のインターフェースでルーティングすることは可能ですか?

たとえば、ダウンロードアプリケーションによるネットワークトラフィックは常にwlan0インターフェースを使用する必要がありますが、マシン上の他のすべてのアプリケーションはeth0を使用する必要があります。

Linuxでこの種のルールを持つことは可能ですか?

21
Suresh

Linuxネットワーク名前空間を使用して行うことができます。

こちらの記事 方法を説明しています。基本的に、異なるデフォルトルートでネットワーク名前空間を作成し、そこで必要なプロセスを実行します。新しく作成されたネットワーク名前空間をブリッジで物理アダプターに接続します(もちろん他のソリューションも可能です)。

更新: この記事 で説明されているように、カーネル3.14以降では、コントロールグループを使用する方が簡単です。必ず:

1)net_clsコントロールグループを定義して、特定のプロセスからのパケットにclassid(またはプロセスのグループ、それらの間に親子関係がある必要はないことに注意してください)で注釈を付ける

2)iptables cgroupモジュール(Linux 3.14で追加)を使用してパケットをfwmark

3)ポリシールーティング(ip rule add fwmark ....)を使用して、マークされたパケットの新しいルーティングテーブルを作成します。

利点は、ブリッジを行う必要がないことであり、cgroupのおかげですべてがはるかに動的になります。

22
chripell

私はこれに苦労しているので、ここに完全なソリューションがあります。 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

手動ハウツー

まず、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のキルスイッチ

15
KrisWebDev

これを達成するためにLinuxのLD_PRELOAD機能を使用するシムを書いた人が数人います:

4
user1686

MariusmatutiaeとKrisWebDevの優れた答えを組み合わせて、大幅に変更されたバージョンのKrisWebDevの優れたnovpn.shスクリプトを作成しました。 KrisWebDevのスクリプトは、より具体的なかゆみ(VPN内外のプロセスの実行と移動)をスクラッチするように設計されていますが、私のバージョンでは、指定したネットワーク環境で基本的にすべてのコマンドを実行できます。バインドするインターフェース、デフォルトルート、独自のiptablesルール、静的ルートを指定し、「テスト」を指定して、コマンドを実行する前にすべてが正常に動作していることを確認できます...など)。複数の構成ファイルを使用できるため、内部でコマンド/プロセスを実行できる特定のネットワーク環境をいくつでも定義できます。

ここに要点として投稿しました: https://Gist.github.com/level323/54a921216f0baaa163127d960bfebbf

後でcgroup/iptables /ルーティングテーブルをクリーンアップすることもできます!

フィードバックを歓迎します。

PS-Debian 8(Jessie)用に設計されています

3
allnatural

アプリケーションごとではありません。ポートごと、またはIPアドレスごとなどに実行できます。または、アプリケーション自体が特定のネットワークカードにバインド(および使用)できます。

ただし、それを行うルールを設定することはできません。

0
Majenko