web-dev-qa-db-ja.com

Linuxで子プロセスを「オフライン」(外部ネットワークなし)で実行するコマンド

実際のネットワークを停止せずにオフラインモードでテストしたいプログラムがあります。このプログラムは、UNIXドメインソケットやループバックなどのローカルソケットに接続する必要があります。また、ループバックで listen を聞き、他のアプリから見えるようにする必要もあります。

ただし、リモートマシンに接続しようとすると失敗します。

strace/unshare/Sudoのように機能し、インターネット(およびLAN)を隠してコマンドを実行するだけで、他のすべてが機能しているユーティリティが欲しいのですが。

$ offline my-program-to-test

この質問には、答えのヒントがあります: プロセスのネットワークアクセスをブロックしますか?

そこでは別のユーザーとして実行してからiptablesを操作する、またはunshare -nなどの提案がいくつかあります。しかし、どちらの場合も、UNIXドメインソケットとループバックをメインシステムと共有するための呪文はわかりません。その質問への回答は、全体の共有を解除する方法を教えてくれるだけです。通信網。

私がテストしているプログラムは、Xサーバーとdbusに接続し、システム上の他のアプリからの接続をループバックでリッスンできる必要があります。

理想的には、chroot、ユーザー、VMなどの作成は避けたいと思います。ネットワークケーブルを抜くのと同じくらい面倒になるからです。つまり、質問のポイントは、これをSudoのように単純にする方法です。

非ローカルアドレスを指定するネットワーク呼び出しが失敗することを除いて、プロセスが100%正常に実行されることを望んでいます。理想的には、同じuid、同じhomedir、同じpwd、...を除くすべてをオフラインに保ちます。

私はFedora18を使用しているので、移植性のないLinuxの答えは問題ありません(予想通りですが)。

それが関係しているのであれば、Cプログラムを書くことでこれを解決することさえ嬉しいので、Cを書くことを含む答えは問題ありません。ローカルネットワークを維持しながら外部ネットワークアクセスを取り消すために、Cプログラムがどのようなシステムコールを作成する必要があるのか​​わかりません。

「オフラインモード」をサポートしようとしている開発者は、おそらくこのユーティリティを高く評価するでしょう。

15
Havoc P

従来の答えは、プログラムを別のユーザーとして実行し、iptables -m ownerを使用することです。このようにして、ネットワーク構成が共有されます。ただし、名前空間の出現により、もっと簡単な方法があります。

名前空間を使用すると、ネットワークの共有を解除し、ネットワークアクセスを制限する必要がある場合は仮想ネットワークリンクを作成します。

UNIXドメインソケットを共有するために必要なのは、 この2010パッチ の後に、2.6.36以上(これを書いている時点での現在のすべてのディストリビューションを除くRHEL/CentOS)。

独自のIP名前空間でプログラムを実行します。プログラムを開始する前に、仮想イーサネットインターフェイスを確立します。ドキュメントはあまりないようです。私はいくつかのブログで正しい呪文を見つけました:

以下のスニペットでは、ns_exec is manページにリストされているsetnsのラッパー を使用して、実行中のプロセスからネットワークリンクのホスト側を起動します。制限された名前空間。実際にはこれは必要ありません。制限された名前空間の外部からリンクのホスト側を設定できます。内部から実行すると、フロー制御が容易になります。そうでない場合は、リンクが確立された後、プログラムを開始する前に、リンクを設定するための同期が必要です。

unshare -n -- sh -c '
  # Create a virtual ethernet interface called "confined",
  # with the other end called "global" in the namespace of PID 1
  ip link add confined type veth peer name global netns 1

  # Bring up the confined end of the network link
  ip addr add 172.16.0.2/30 dev confined
  ip link set confined up

  # Bring up the global end of the network link
  ns_exec /proc/1/ns/net ifconfig global 172.16.0.1 netmask 255.255.255.252 up

  # Execute the test program
  exec Sudo -E -u "$TARGET_USER" "$0" "$@"
' /path/to/program --argument

これらすべてをrootとして実行する必要があります。 カーネル3.8でのユーザー名前空間の紹介 は、ネットワークリンクのグローバルエンドを設定することを除いて、特別な権限なしでこれを実行できるようにする可能性があります。

2つの名前空間間でローカルホストを共有する方法がわかりません。仮想イーサネットインターフェイスは、ポイントツーポイントブリッジを作成します。必要に応じて、iptables転送ルールを使用して、トラフィックをloとの間でリダイレクトできます。

これは、ctablesに一致するiptablesルールでも実現できます。手順を抽象化するツールを作成しました。初期セットアップにはroot権限が必要であり、それ以外はsetuidバイナリですが、問題の問題に対処するためのかなり簡単な方法を提供すると思います。十分に新しいiptablesバージョンが必要であり、適切なnetfilterモジュールが使用可能である必要があります。

https://github.com/quitesimpleorg/qsni

1
crtxcr

/ !! \これは、単一のpidのトラフィックだけでなく、すべてのトラフィックをダウンさせるため、おそらく有効な答えではありません。

私はそれを使用していませんが、Comcastを使用できる可能性があると思います。

https://github.com/tylertreat/Comcast

100%のパケット損失に設定

繰り返しますが、私はこれをテストしていませんが、理論的には、あなたができる彼らのreadmeから変更されています:


Linux

Linuxでは、iptablesを使用して着信パケットと発信パケットをドロップできます。

$ iptables -A INPUT -m statistic --mode random --probability 1 -j DROP
$ iptables -A OUTPUT -m statistic --mode random --probability 1 -j DROP

または、いくつかの追加オプションをサポートするtcを使用できます。

$ tc qdisc change dev eth0 root netem reorder 0 duplicate 0 corrupt 1

リセットするには:

$ tc qdisc del dev eth0 root netem
0
ThorSummoner