Linux iptablesでは、アウトバウンド接続を開始するプロセス/コマンド名を記録できますか?


27

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

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

これにより、接続を開始するuid / gidが記録されますが、プロセス/コマンド名、またはpidさえ記録されません。pidを取得できれば、おそらくログが書き込まれたときにプロセス名を取得するスクリプトを作成することができますが、それも不可能なようです。

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

Linuxボックス上のiptables(または他の何か)でこれがどのように可能になるか考えはありますか?


この質問はserverfaultで回答されたと確信しています(完全にはわかりません)。
niXar

個人的には、この仕事にsysdigを使用します。
チャールズダフィー

回答:


7

/ 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ノードに関連付けることができます。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を実行して、一致するinodeを見つけます。それを見つけると、特にプロセスアカウンティングをオンにしている場合は、所有するpidがあり、そこから必要なものを入手できます。

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


2
オプションを提供してくれてありがとう!ただし、毎回、開いているすべてのファイル記述子にポーリングとクエリを要求することは、それほど堅牢ではなく、非常に非効率的です。私はまだ誰かがより良い解決策を見つけるか、これがもはやiptablesの一部ではない理由、および--cmd-ownerが修正不能と見なされる理由を明確にすることを望んでいます。
-nealmcb

カーネルが/ procのレイアウトを変更しない限り、またはnetstatとreadlinkまたはpsが変更される可能性が低い場合を除き、これは非常に堅牢だと思います。どのような効率の問題に関心がありますか?瞬時の処理が必要な場合は、iptablesで使用するカーネルモジュールを作成する必要があります。
ベンコリンズ

拒否された接続をログに記録している場合、ソケットはカーネルによってすぐに破棄されるため、/ procで確認する機会はほとんどありません。接続をタイムアウトさせるために、REJECTをDROPに変更するだけかもしれません
...-Marki555

このシナリオでは、非常に小さな時間ウィンドウのために役立ちませんが、/ procの解析の脆弱性に関しては、「lsof -F -i」を使用して、ネットワークの適切に抽象化されたダンプを取得することもできます。データ。また、(たとえば、特定のポートでのみ)フィルタリングすることもでき、すでにすべてのファイル名/ pid /ユーザーマッピングが行われています。
ダニーザウアー

9

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

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

1
iptablesのログコマンドは、この方法で変数を設定および補間できますか?私にはうまくいかないようです。また、2.6.15以降のカーネルでは--cmd-ownerオプションが削除されたようです。これは便利なオプションのように見えるため、残念です。

4
はい、-cmd-ownerは削除されました:「unfixable broken」
-guettli

1
情報をありがとう、@ guettli。でより詳細あるpermalink.gmane.org/...は、その複数の変更ログの引用:「[NETFILTER]:IPTで削除にtasklist_lock乱用{6}所有者、リップアウトCMD / SID / PID、その修正不可能が破壊とに立つためのマッチングtasklist_lockへの変更をロックする方法。」 しかし、私はまだいくつかの背景、またはより良い代替案が欲しいです。
-nealmcb

5

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

http://sourceforge.net/projects/nethogs

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


nethogsは信頼できない統計情報を提供することがわかりましたが、2の上(+ netatop)はこれをうまく行います。
東武

1

スカイプをスピード制限しようとして、同様の質問を探していると、私は見つけました

$ 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エントリを追加するのが最も簡単でした

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.