UNIXプログラムを特定のネットワークインターフェイスにバインドする


40

質問: ネットワークアクセスが特定のネットワークインターフェイスを介してバインドされていることを確認しながら、プログラムを起動するにはどうすればよいですか?

ケース: 同じIP(192.168.1.1)で2つの異なるマシンにアクセスしたいが、2つの異なるネットワークインターフェイス(eth1およびeth2)を介してアクセスしたい。

例:

net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}

上記は、primusrunoptirunを介して行われたハードウェアバインディングに触発された、私が望むものの近似です。

課題:関連するスレッドで示唆されているように使用されるインターフェースはプログラムによってではなく、カーネルによって選択されます(したがって、上記の例の事前バインディング構文です)。

私はいくつかの関連する解決策を見つけましたが、それは不十分です。これらは、ユーザー固有のネットワークブラックリスト登録によるネットワークインターフェイスのバインドに基づいています。つまり、単一の特定のネットワークインターフェイスにのみアクセスできるユーザーとしてプロセスを実行します。


マシンが2つの異なるネットワーク、両方とも192.168.1.0に接続されていることを意味していますか?ルーティングテーブルはどのように見えますか?プロセスから見えるインターフェースを制限したい場合、最も軽いソリューションはcgroupsで、より重い1つのコンテナーになります。
lgeorget

はい、同じIP範囲にある2つの異なるネットワーク。目に見えるインターフェースを制限したくないのは確かではありません。デフォルトとして使用するインターフェースを指定するだけですか?:)
スケーン

3
理由は1つだけです。同じIPドメインを使用して相互に接続された2つのネットワークを持つことは、同じ番号の2階建ての建物にエレベーターがあるようなものです。IP範囲は、出力インターフェイスではなくドメインを識別するものです。それでも、iptablesを使用して欠陥のあるネットワーク設計を回避する方法が必要です。
lgeorget

システムを2つの異なるインプレースインフラストラクチャに接続しています。これらのインフラストラクチャは相互作用するように設計されていなかったため、その点でネットワーク設計に欠陥があります。
スケーン

1
NATに対する私の主張は、アドレス空間全体が通常NATの背後に隠されており、2つのNATで接続されたインフラストラクチャを接続しているときに衝突が発生するというものでした。-私はインフラストラクチャを変更する立場にありません。-仮想名前空間インターフェイスのペア(名前空間に1つ、ルート名前空間に1つ)を持つネットワーク名前空間を使用して、ルート名前空間を物理インターフェイスにブリッジし、ネットワーク名前空間内でプログラムを実行しようとしました。-これは機能しているようですが、ルート名前空間を超えてアクセスできません(つまり、マシン自体の外部からアクセスできません)。
スケーン

回答:


35

Linuxの場合、これはすでにスーパーユーザーで回答されています- プロセスごとに異なるネットワークインターフェイスを使用する方法は?

最も一般的な答えは、LD_PRELOADプログラムのネットワークバインディングを変更するトリックを使用しますが、最新のカーネルは、ipプログラムを通じて公開される「ネットワーク名前空間」と呼ばれるはるかに柔軟な機能をサポートします。この答えは、これを使用する方法を示しています。私自身の実験から、次のことを(ルートとして)行いました。

# Add a new namespace called test_ns
ip netns add test_ns

# Set test to use eth0, after this point eth0 is not usable by programs
# outside the namespace
ip link set eth0 netns test_ns

# Bring up eth0 inside test_ns
ip netns exec test_ns ip link set eth0 up

# Use dhcp to get an ipv4 address for eth0
ip netns exec test_ns dhclient eth0

# Ping google from inside the namespace
ip netns exec test_ns ping www.google.co.uk

unshareおよびnsenterコマンドを使用して、ネットワーク名前空間をある程度管理することもできます。これにより、PID、ユーザー、マウントポイント用に個別のスペースを作成することもできます。詳細については、以下を参照してください。


「この時点以降、eth0は名前空間外のプログラムでは使用できません」-だから、これを行う他のすべての問題のために接続をプルダウンしていますか?
スケーン

1
@Skeen、はい、だからおそらく他のプログラムが名前空間に使用していないインターフェイスをプッシュし、通常はメインのものを使用するでしょう。
グレアム

1
@Graerne; 両方のインターフェイスがアクティブに使用されています。インターフェイスを削除する余裕はありません。
スケーン

そして、デフォルトゲートウェイとは何ですか?wvdialそれは、名前空間自体に定義する必要がありますので、例えば...すべてでそれを設定していないようだ
フラッシュサンダー

それを元に戻す方法に関する指示を含めていただけますか?ただip netns remove test_ns普通に戻りますか?それとも特別なことをする必要がありますか?
マルチハンター

17

Graemeの回答を受け入れています。これは、私の問題を解決するために彼の提案に対して行った変更を説明するための単なるフォローアップです。

名前空間内の物理インターフェイスをバインドする代わりに、仮想ネットワークインターフェイスのペアを作成しました。一方の端はネットワークの名前空間に、もう一方はルートにあります。パッケージは、この仮想ネットワークを介して、名前空間からルート名前空間、そして物理インターフェイスにルーティングされます。-そのため、通常のデータ転送をすべて実行でき、さらに特定のインターフェイスにのみアクセスできるプロセスを開始できます。

# Create the eth0 network namespace
ip netns add eth0_ns

# Create the virtual network pair
ip link add v_eth0a type veth peer name v_eth0b

# Move v_eth0a to the eth0_ns namespace, the virtual pair is now split
# between two network namespaces.
ip link set v_eth0a netns eth0_ns

# Configure the ends of the virtual network pairs
ip netns exec eth0_ns ifconfig v_eth0a up {{NAMESPACE_IP}} netmask {{NAMESPACE_NETMASK}}
ifconfig v_eth0b up {{ROOT_NS_IP}} netmask {{ROOT_NS_NETMASK}}

# Setup routing from namespace to root
ip netns exec eth0_ns route add default gw {{ROOT_NS_IP}} dev v_eth0a

# Setup IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s {{ROUTE_SOURCE}}/24 -o {{NETWORK_INTERFACE}} -j SNAT --to-source {{ROUTE_TARGET}}

eth0およびeth1のインターフェイスがそれぞれ名前空間eth0_nsおよびeth1_nsで設定されると、指定されたインターフェイスでプログラムを実行できます。

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish

4
よくやった!ブリッジデバイスを作成して、デフォルトネームスペースと仮想ペアを物理デバイスの1つとブリッジすることもできると思います。ただし、これは同等に見えます。
グレアム

1
仮想デバイスと物理デバイスをブリッジしてみました。そのソリューションを使用して外部ネットワークにアクセスできませんでした。
スケーン

2
しましたが、新しい名前空間からのみです。私が抱えていた問題はネットワーク管理者に関連していたと思いますが、私はそれを理解できませんでした、または私は答えを更新したでしょう。
グレアム

私は同じ問題を抱えていますが、そのソリューションを使用できませんでした。最後のステップで{{ROUTE_SOURCE}}と{{ROUTE_TARGET}}に正確に入力する必要があるものは何ですか?
リトフ16

@Graeme、少なくともUbuntuでは、dhclient <bridge>per を発行することで、名前空間とグローバル名前空間の両方で接続を取り戻すことができまし
クリスハント

4

解決策I:特定のライブラリをプリロードする

  • App-Route-Jail:ld_preloadを使用して、インターフェイスゲートウェイを強制します(素晴らしいアイデアですが、ルートまたはマーク機能が必要です)。

  • Proxybound:ld_preloadを使用して、特定のアプリケーションにプロキシを強制します(これは、インターフェイスの代わりにプロキシを使用しています)

  • Force-Bind:多くの機能がありますが、バインドリーク(信頼性はありません)

  • Bind-Interface-IP:接続が単純すぎて接続がリークしている(信頼性が低い)

  • Bind-IP:接続が単純すぎて接続がリークする(信頼できない)

ソリューションII:Linuxユーザースペース

  • 古典的なLinuxユーザー空間ip-netns:優れたソリューションですが、ルートとインターフェースが1つのユーザー空間にしか存在できないことを要求します

  • Firejail:Firejailは特定のネットワークを使用するようにアプリケーションを強制できますが、互換性は制限されます(例:tunインターフェースと互換性がありません)。firejailはルートを必要としませんfirejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Firejail with netns:Firejailは、アプリケーションに、個別に作成された特定のユーザースペースを強制的に使用させることができます。これにより、ルートなしでスペースに名前を付けることができます。firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • マスカレードとブリッジを使用するFirejail:Firejailは、アプリケーションにiptablesマスカレード特定のインターフェースを使用するように強制できます。これは素晴らしいことであり、rootを必要としませんがこれはip_forwardを必要とし、セキュリティへの影響を暗示する可能性がありますfirejail --net=br0 firefox

解決策III:Linux iptables

Iptables はこの目的に使用できますが、これにはip_forward 必要であり、正しく構成されていない場合はセキュリティへの影響があります。例1例2例3例4)

ソリューション(I、II、III)の注:

ワイヤーガード

VPN(特にワイヤーガード)を使用していて、このソリューションをワイヤーガードインターフェース(ユーザースペース付きのワイヤーガード)に適用する場合、リンクされた指示に従って、wgインターフェースを含むユーザースペースを作成できます(したがって、VPNインターフェースに限定されます) )また、これはと組み合わせることができますfirejail --netns=container、rootなしでユーザー空間を使用できるようにすることもできます。

インターフェイスゲートウェイを見つける方法

ここにゲートウェイを見つけるための多くの解決策があります。使用されたゲートウェイを見つけることを許可するいくつかのコマンドがあります

$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

App-Route-Jailの使用方法

  • App-Route-Jailのビルド
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • この例の将来のマークされたパケット(jailedアプリケーション用)の192.168.1.1ルートを強制ゲートウェイとして使用します。このルートルールは他のアプリケーションに影響を与えません。この操作は、たとえばシステムブート時に1回だけ行う必要があります。このソリューションを毎日使用する
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • 投獄するアプリケーションを起動します
MARK=10 LD_PRELOAD=./mark.so firefox
  • WAN IPアドレスのテスト
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.