web-dev-qa-db-ja.com

Linux iptablesを使用して、アウトバウンド接続を開始するプロセス/コマンド名をログに記録することは可能ですか?

Linuxデスクトップでアウトバウンド接続を開始するプロセスを追跡したいと思います。私が思いつくことができる最高のものはこれです:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

これは、接続を開始するuid/gidをログに記録しますが、プロセス/コマンド名またはpidをログに記録しません。 pidを取得できただけで、ログが書き込まれたときにプロセス名をプルするスクリプトを作成できたかもしれませんが、それは不可能であるようです。

理想的には、着信接続も受け入れるプロセスもログに記録したいと思います。

Linuxボックスのiptables(またはその他)でこれがどのように可能になるかについてのアイデアはありますか?

27
Nack

/ proc/net/tcpを監視するプログラムを作成すると、その出力は次のようになります。

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

次に、開いたポートをiノードに関連付けることができます。これは、プロセスごとにリストされたファイル記述子でreadlinkを実行することにより、プロセスおよびファイル記述子に関連付けることができます。

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

ここで、iノード4847458が上記のリストの最初のTCPソケットに対応していることを確認してください。 netstat -tapnの出力は、これを確認します(0x50 == 80であることを思い出してください)。

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

モニタープログラムが/ proc/net/tcpの変更に気付いたら、データを解析し、その変更が新しく開いたソケットかどうかを判断します。次に、/ procにリストされている各プロセスのすべてのファイル記述子を列挙し、それぞれについてreadlinkを実行して、一致するiノードを見つけます。それを見つけたら、所有しているpidを取得します。特に、プロセスアカウンティングがオンになっている場合は、そこから必要なものをすべて取得できます。

通知を瞬時に送信する必要がない場合は、モニタープログラムで低速ポーリング(おそらく50ミリ秒または100ミリ秒、さらには1000ミリ秒の期間)を使用できます。

7
Ben Collins

所有者一致モジュールが必要です。これは、OUTPUTチェーンでのみ機能します(おそらくPREROUTING ...?)。ドキュメントを読みますが、次のように機能します。

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "
9
Don Werve

Iptablesやロギングとは何の関係もありません。しかし、これは/ proc /ディレクトリをポーリングし、プログラム/ pidごとの帯域幅を表示する「トップ」のようなインターフェースです。

http://sourceforge.net/projects/nethogs

「NetHogsは小さな「ネットトップ」ツールです。ほとんどのツールのようにプロトコルごとまたはサブネットごとにトラフィックを分類する代わりに、プロセスごとに帯域幅をグループ化します。NetHogsは、特別なカーネルモジュールのロードに依存していません。」

5
Lokal

私が同様の質問を調べているとき、スカイプを速度制限しようとしているので、

$ netstat -p | grep <mycmdname>

pid-owner/cmd-ownerがiptablesで直接サポートされなくなったため、ポート番号をpid/cmdにリンクする良い方法です。次に、結果を解析し、ポートに応じてiptablesルールを追加する必要があります。当然、後で/システムのシャットダウン/再起動時などに、いくつかのクリーンアップコードが必要になります。クリーンアップ時に参照できるように、ポート番号をファイルに保存します

実際、ポート番号の質問に対する良い答えは

$ Sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

必要に応じてgrep tcp要素を調整する必要があるかもしれません

次に、私の目的のために、ポート番号に従ってtc u32フィルタを追加し、ポート番号に従ってiptablesエントリを追加するのが最も簡単でした

1
Mark