En Linux, ¿hay alguna forma de registrar los puertos por los que un programa intenta comunicarse?

En Linux, ¿hay alguna forma de registrar los puertos por los que un programa intenta comunicarse?

Problema: Estoy tratando de determinar qué puertos abrir para programas específicos

Tengo varios programas que necesitan acceder a servicios en hosts remotos, pero no sé qué puertos están intentando utilizar para ese propósito. En lugar de abrir el firewall hasta 0-1024(o 0-65k), me gustaría identificar qué puertos utiliza un programa mientras se ejecuta.

El primer programa a comprobar es kinit. Desde eldocumentaciónSupongo que necesito abrir el puerto 88para el tráfico udp entrante y el puerto 88para el tráfico tcp y udp saliente. Pero esto no parece suficiente, ya que el programa responde con

kinit: Resource temporarily unavailable while getting initial credentials

Abrir todos los puertos da como resultado un flujo de autenticación correcto para kinit:

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

Sé cómo usar lsofy netstatrecuperar sslos puertos abiertos para procesos que se vinculan durante períodos más prolongados a los puertos, pero especialmente kinitparece eludir esta lista, incluso cuando se usa junto con una herramienta como watch.

Editar: La respuesta aceptada me mostró inmediatamente al culpable: 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 este puerto solucionó el problema con Kerberos

Respuesta1

Podrías probar strace:

strace -e trace=connect your_program with arguments

A continuación se muestra un resultado de ejemplo:

$ 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

Las líneas que necesitas son aquellas con el sa_family=AF_INET.

Respuesta2

Puede configurar sus reglas de iptables para registrar el tráfico y ver exactamente qué tráfico se envió en el momento en que ejecutó un programa determinado. Esto no funcionará bien en un sistema ocupado, ya que en realidad no le dice qué programa envió qué tráfico, pero con una carga ligera, debería poder reconstruir lo que está sucediendo.

Ejemplo de entrada y salida:

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

Hay muchas más opciones y funciones si también quieres volverte más complejo.

información relacionada