Закрытие порта из командной строки вручную

Я хочу, чтобы закрыть открытый порт, который находится в режиме прослушивания между моим клиентом и сервером приложений.

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

Примечание: я узнал, что " только приложение, которому принадлежит подключенный сокет, должно закрыть его, что произойдет, когда приложение завершится."

Я не понимаю, почему это возможно только приложением, которое его открывает ... Но я все еще хочу знать, есть ли другой способ сделать это.

6
задан Glorfindel
09.02.2023 13:54 Количество просмотров материала 2474
Распечатать страницу

13 ответов

у меня была та же проблема, процесс должен оставаться живым, но сокет должен закрыться. Закрытие сокета в запущенном процессе не невозможно, но трудно:

  1. найти процесс :

    netstat -np
    

    вы получаете source/destination ip:port portstate pid/processname карта

  2. найдите файловый дескриптор сокета в процессе

    lsof -np $pid
    

    вы получаете список: имя процесса, pid, пользователь, fileDescriptor,... строка подключения.

    найдите соответствие количество файл для подключения.

    теперь подключите процесс:

    gdb -p $pid
    
  3. теперь закройте сокет:

    call close($fileDescritor)
    
    //does not need ; at end.
    

    затем снимите:

    quit
    

    и гнездо закрыто.

114
отвечен Dankó Dávid 2023-02-10 21:42

вы задаете здесь неправильный вопрос. На самом деле невозможно просто "закрыть порт" извне приложения, которое открыло сокет, слушая его. Единственный способ сделать это-полностью уничтожить процесс, которому принадлежит порт. Затем, примерно через минуту или две, порт снова станет доступен для использования. Вот что происходит (если вам все равно, перейдите к концу, где я покажу вам, как убить процесс, владеющий определенным портом):

порты-ресурсов выделяется ОС для различных процессов. Это похоже на запрос указателя файла в ОС. Однако, в отличие от указателей файлов, порт может принадлежать только одному процессу. Через интерфейс сокета BSD процессы могут сделать запрос на прослушивание порта, который затем предоставит ОС. ОС также будет убедиться, что никакой другой процесс не получает тот же порт. В любой момент процесс может освободить порт, закрыв сокет. Затем ОС восстановит порт. Альтернативно, если процесс заканчивается без освобождая порт, ОС в конечном итоге восстановит порт (хотя это произойдет не сразу: это займет несколько минут).

теперь то, что вы хотите сделать (просто закройте порт из командной строки), невозможно по двум причинам. Во-первых, если бы это было возможно, это означало бы, что один процесс может просто украсть ресурс другого процесса (порт). Это была бы плохая политика, если не ограничено привилегированными процессами. Вторая причина-неясно, что произойдет с процесс, которому принадлежит порт, если мы позволим ему продолжать работать. Код процесса написан при условии, что он владеет этим ресурсом. Если мы просто заберем его, он в конечном итоге рухнет сам по себе, поэтому ОС не позволит вам это сделать, даже если вы привилегированный процесс. Вместо этого, вы должны просто убить их.

во всяком случае, вот как убить процесс, которому принадлежит определенный порт:

sudo netstat -ap | grep :<port_number>

которое выведет наружу линия соответствие отростчатый порт удерживания, для пример:

tcp  0  0 *:8000   *:* LISTEN  4683/procHoldingPort

в этом случае procHoldingPort это имя процесса, который открыл порт,4683 это его pid, и 8000 (обратите внимание, что это TCP) - номер порта, который он содержит.

затем, посмотрите в последней колонке, вы увидите /. Затем выполните следующее:

kill  <pid>

если это не работает (вы можете проверить, повторно запустив команду netstat). Делать это:

kill -9 <pid>

в общем, лучше избегать отправки SIGKILL, если вы можете. Вот почему я говорю вам попробовать kill до kill -9. Просто используйте kill посылает более мягкий SIGTERM.

как я уже сказал, для повторного открытия порта потребуется несколько минут, если вы это сделаете. Я не знаю, как это ускорить. Если это сделает кто - то другой, я с удовольствием послушаю.

74
отвечен Guy Avraham 2023-02-10 23:59

Термоблок также может быть использован

fuser -k -n *protocol portno*

здесь протокол tcp / udp и portno номер, который вы хотите закрыть. Например:

fuser -k -n tcp 37

Подробнее fuser man страница

18
отвечен RedBaron 2023-02-11 02:16

вы также можете использовать iptables:

iptables -I INPUT -p tcp --dport 80 -j DROP

Он в основном выполняет то, что вы хотите. Это отбросит весь трафик TCP к порту 80.

5
отвечен supercheetah 2023-02-11 04:33
netstat -anp | grep 80

он должен сказать вам, если вы используете apache, "httpd" (это просто пример, используйте порт, который использует ваше приложение вместо 80)

pkill -9 httpd 

или

killall -9 httpd
3
отвечен Ben 2023-02-11 06:50

вы могли бы просто узнать, какой процесс открыл сокет, порт связаны с, и убивают этот процесс.

но, вы должны понимать, что если у этого процесса есть обработчик, который деинициализирует весь материал, который он использовал (открыть файлы, сокеты, вилки, вещи, которые могут задерживаться, если он не закрыт должным образом по окончании) тогда вы бы создали, что перетащить на производительность системы. Плюс, сокет останется открывать до тех пор, пока ядро не поймет, что что процесс был убит. Обычно это займет около минуты.

Я полагаю, что лучший вопрос будет: какой порт (принадлежащий какой процесс) вы хотите остановить?

Если вы пытаетесь положить конец бэкдор или вирус, который вы нашли, то вы должны по крайней мере узнать, какие данные происходит взад и вперед прежде чем ты прекратишь это. (wireshark хорош для этого) (и имя исполняемого файла процесса, чтобы вы могли удалить его и предотвратить его возвращение перезагрузка) или, если это то, что вы установили (например, HTTPD или FTPD или что-то еще), тогда у вас уже должен быть доступ к самому процессу.

обычно это будет управляющая программа (HTTPD stop / start или что-то еще). Или, если это системная вещь, вы, вероятно, не должны с ней связываться. Во всяком случае, я подумал, что раз все остальные дают вам угол "как", я должен дать вам предостережения.

2
отвечен jackenheimer 2023-02-11 09:07

Я сначала искал процессы mongo и node, затем сделал следующее:

ps -A | grep node

10418 pts/23   00:00:05 node

10551 pts/23   00:00:00 node

ps -A | grep mongo

10490 pts/23   00:00:00 mongod

после идентификации, просто убить процессы с помощью команды kill.

kill -9 10418
kill -9 10490

и наконец, типа meteor и он должен работать снова.

2
отвечен Alejandro BR 2023-02-11 11:24

вы можете написать скрипт, который изменит iptables и перезапустит их. Один скрипт для добавления правила, отбрасывающего все пакеты на порт, другой скрипт для удаления указанного правила.

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

1
отвечен Michael Shimmins 2023-02-11 13:41

еще одна проблема: иногда ядро само владеет портами. Я знаю, что маршрутизация NAT содержит некоторые порты, открытые для использования NAT. Вы не можете убить процесс, это ядро, и требуется перенастройка и перезагрузка.

1
отвечен Rich Homolka 2023-02-11 15:58

Если вы хотите, чтобы ваш порт будет выпущен раньше, вы должны установить следующее значение:

echo 1 > /proc/sys/net/ipv4/tcp_fin_timeout

установить с 60 секунд (по умолчанию) на 1 секунду

1
отвечен Daniel 2023-02-11 18:15

вы можете использовать команду killcx, закрывающую соединение без прерывания процесса.

  • синтаксис:
killcx [dest_ip:dest_port] {interface}

  dest_ip              : remote IP
  dest_port            : remote port
  interface (optional) : network interface (eth0, lo etc).
  • пример:
killcx 120.121.122.123:1234
killcx 120.121.122.123:1234 eth0
1
отвечен shuaiming 2023-02-11 20:32

Я знаю, что этот ответ не отвечает на сам вопрос, строго говоря, но читая в это может быть соответствующая информация:

поведение по умолчанию привязки сокета к порту (и адресу) является то, что, когда сокет закрыт резким прекращением процесса, сокет останется в TIME_WAIT на некоторое время. Это будет означать, что вы не можете сразу повторно привязаться к этому адресу / порту. Если вы разрабатываете саму систему через стандартный интерфейс сокета BSD, вы может (по крайней мере, в некоторой степени) контролировать это поведение с помощью опции сокета SO_REUSEADDR. Это в основном позволит вам снова привязаться к одному и тому же адресу/порту, если сокет находится в состоянии TIME_WAIT. Все еще одно гнездо в порт однако!

тем не менее, эта информация должна использоваться только в качестве помощи в целях развития, так как существует причина существования TIME_WAIT, уже объясненная в других ответах.

1
отвечен Tommi Tuura 2023-02-11 22:49

Если вы не хотите никакого трафика через сокет, но хотите сохранить процесс: tcpkill.

tcpkill -i eth0 host xxx.xxx.xxx.xxx and port yyyy

запустит демон обнюхивания, который перехватывает и уничтожает весь трафик на этом порту. Очень удобно для тестирования приложений на разделение сети.

0
отвечен RickyA 2023-02-12 01:06

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх