Назад | Перейти на главную страницу

В Linux есть ли способ записать порты, через которые программа пытается обмениваться данными?

Проблема: Я пытаюсь определить, какие порты открывать для конкретных программ

У меня есть несколько программ, которым необходим доступ к службам на удаленных хостах, но я не знаю, какие порты они пытаются использовать для этой цели. Вместо того, чтобы открывать брандмауэр до 0-1024 (или 0-65k), Я хотел бы определить, какие порты использует программа во время работы.

Первая программа для проверки - kinit. Из документация Я так понимаю, мне нужно открыть порт 88 для входящего udp-трафика и порта 88 для исходящего трафика TCP и UDP. Но этого, похоже, недостаточно, так как программа отвечает

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 и ss для получения открытых портов для процессов, которые привязаны к портам на более длительный период времени, но особенно kinit кажется, ускользает от этого списка, даже когда используется вместе с таким инструментом, как watch.

редактировать: Принятый ответ сразу показал мне виновника: 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

Вы можете попробовать 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.

Вы можете настроить свои правила 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

Есть еще много вариантов и функций, если вы хотите усложнить задачу.