No Linux, existe uma maneira de registrar as portas pelas quais um programa tenta se comunicar?

No Linux, existe uma maneira de registrar as portas pelas quais um programa tenta se comunicar?

Problema: Estou tentando determinar quais portas abrir para programas específicos

Tenho vários programas que precisam acessar serviços em hosts remotos, mas não sei quais portas eles estão tentando usar para esse fim. Em vez de abrir o firewall para 0-1024(ou 0-65k), gostaria de identificar quais portas um programa usa enquanto é executado.

O primeiro programa a verificar é o kinit. DedocumentaçãoPresumo que preciso abrir a porta 88para o tráfego UDP de entrada e a porta 88para o tráfego TCP e UDP de saída. Mas isto não parece ser suficiente, pois o programa responde com

kinit: Resource temporarily unavailable while getting initial credentials

A abertura de todas as portas resulta em um fluxo de autenticação correto para kinit:

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

Eu sei como usar lsofe netstatpara ssrecuperar as portas abertas para processos que se vinculam por períodos mais longos às portas, mas especialmente kinitparece escapar dessa listagem, mesmo quando usado em conjunto com uma ferramenta como o watch.

Editar: A resposta aceita me mostrou imediatamente o culpado: 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

Abrir esta porta corrigiu o problema com Kerberos

Responder1

Você poderia tentar strace:

strace -e trace=connect your_program with arguments

Aqui está um exemplo de saída:

$ 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

As linhas que você precisa são aquelas com a extensão sa_family=AF_INET.

Responder2

Você pode configurar suas regras de iptables para registrar o tráfego e ver exatamente qual tráfego estava sendo enviado no momento em que você executou um determinado programa. Isso não funcionará bem em um sistema ocupado, pois na verdade não informa qual programa enviou qual tráfego, mas em uma carga leve, você poderá entender o que está acontecendo.

Exemplo para entrada e saída:

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

Existem muito mais opções e recursos se você também quiser ser mais complexo.

informação relacionada