Linux では、プログラムが通信しようとするポートを記録する方法はありますか?

Linux では、プログラムが通信しようとするポートを記録する方法はありますか?

問題: 特定のプログラムに対してどのポートを開くかを決めようとしています

リモート ホスト上のサービスにアクセスする必要のあるプログラムがいくつかありますが、その目的でどのポートを使用しようとしているのかわかりません。ファイアウォールを0-1024(または0-65k) に開くのではなく、プログラムの実行中に使用されるポートを識別したいと思います。

最初にチェックするプログラムは ですkinitドキュメンテーション88受信UDPトラフィック用のポートと、送信TCPおよびUDPトラフィック用のポートを開く必要があるようです88。しかし、プログラムが次のように応答するので、これだけでは不十分のようです。

kinit: Resource temporarily unavailable while getting initial credentials

すべてのポートを開くと、次の認証フローが正しく実行されますkinit

Using default cache: /tmp/krb5cc_16381
Using principal: *****@******.******.***
Password for *****@******.******.***:
Authenticated to Kerberos v5

長期間ポートにバインドするプロセスの開いているポートを取得するために、、およびを使用する方法については知っていますが、などのツールと一緒に使用した場合でも、特にlsofこのnetstatリストには含まれないようです。sskinitwatch

編集: 受け入れられた回答により、犯人がすぐにわかりました: DNS;

strace -e trace=connect kinit <user>@<kdc>
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("<kdc_ip>")}, 16) = 0

このポートを開くとKerberosの問題は解決しました

答え1

strace を試すこともできます:

strace -e trace=connect your_program with arguments

出力例を次に示します。

$ strace -e trace=connect ssh somehost -p 8081
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.1.1")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(8081), sin_addr=inet_addr(<host ip address>)}, 16) = 0
connect(4, {sa_family=AF_LOCAL, sun_path="/run/user/1000/keyring/ssh"}, 110) = 0

必要な行は の付いた行ですsa_family=AF_INET

答え2

iptables ルールを設定してトラフィックをログに記録し、特定のプログラムを実行したときに送信されたトラフィックを正確に確認できます。これは、どのプログラムがどのトラフィックを送信したかを実際に知らせないため、ビジー状態のシステムではうまく機能しませんが、負荷が軽い場合は、何が起こっているかを把握できるはずです。

入力と出力の例:

iptables -A INPUT -j LOG --log-prefix "INPUT:DROP:" --log-level 6
iptables -A INPUT -j DROP
iptables -A OUTPUT -j LOG --log-prefix "OUTPUT:DROP:" --log-level 6
iptables -A OUTPUT -j DROP

さらに複雑な設定をしたい場合には、さらに多くのオプションと機能があります。

関連情報