web-dev-qa-db-ja.com

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

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

ケース:同じ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 を介して行われたハードウェアバインディングに触発された、私が望むものの近似です。

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

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

42
Skeen

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

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

# 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、ユーザー、マウントポイント用に個別のスペースを作成することもできます。詳細については、以下を参照してください。

38
Graeme

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

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

# 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
18
Skeen

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

  • App-Route-Jail:インターフェイスゲートウェイを強制するためにld_preloadを使用します(素晴らしいアイデアですが、ルートまたはマーク機能)使用方法は以下のメモに詳しく記載されています

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

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

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

  • Bind-IP:方法が単純すぎて接続がリークします(信頼できません)

ソリューションII:Linuxユーザー空間

  • クラシックLinuxユーザースペース ip-netns :優れたソリューションですが、ルートとインターフェイスが必要ですが、単一のユーザースペースにしか存在できません

  • Firejail :Firejailはアプリケーションに特定のネットワークの使用を強制できますが、互換性は制限されています(たとえば、tunインターフェースと互換性がない)。 firejailはrootを必要としません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 masquerade の特定のインターフェースを使用するように強制できます。これは素晴らしいし、ルートを必要としませんbutこれはip_forwardを必要とし、セキュリティへの影響を示唆する可能性がありますfirejail --net=br0 firefox

ソリューションIII:Linux iptables

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

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

ワイヤーガード

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

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

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

$ 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
  • この例では、(jailされたアプリケーションの)将来マークされたパケットのルートを追加します192.168.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
7
intika

コメントできないので、誰かがコメントに移動することを望みます。現在(2020年3月)このソリューションはfirejailとWifiでは使用できません。詳細は https://github.com/netblue30/firejail/issues/30 を参照してください

0
Hannes