Как вручную закрыть порты SSH / привязки портов?

Вопрос или проблема

Я работаю на системе Mac 15.1 и открываю соединение с jumpserver, чтобы иметь возможность подключаться к нескольким другим серверам. Обычно скрипт работает прекрасно, но иногда он зависает, и ничто, кроме полной перезагрузки моего Mac, не помогает снова открыть привязанные порты. Я использую iTerm2 в качестве терминала на Mac OS 15.1.

Вот скрипт:

#!/bin/sh

username="myusername"
jumpServer="vl-com-jfd-p01.example.com"
# shellcheck disable=SC2039
hosts=("gl-d-foo.d.gcp.example.com" "192.168.0.234" "vl-web-int-d02" "10.40.13.44" "172.16.20.88" "10.245.131.226" "gl-p-foo.p.gcp.example.com" )

destSshPort=22
destMysqlPort=3306

x=10021
y=10022

for i in "${hosts[@]}"; do
  :
  server=$i
  sshTunnel="$sshTunnel -L $x:$server:$destMysqlPort -L $y:$server:$destSshPort"
  echo "Сервер: $server -- MYSQL: $x -- SSH: $y"
  x=$((x + 2))
  y=$((y + 2))
done

if [ -z "$sshTunnel" ]
then
  echo "ssh туннели пусты"
else
  ssh $sshTunnel $username@$jumpServer
fi

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

ssh -p10022 -L 9994:10.239.244.31:3306 myusername@localhost

Все это работает хорошо, так что с самим скриптом ничего не так.

Но иногда я теряю соединение с jumpserver, и после повторного запуска процесса я получаю сообщения, вроде:
bind [127.0.0.1]:10021: Адрес уже используется channel_setup_fwd_listener_tcpip: не удается прослушать порт: 10021
Даже после закрытия iTerm2 и его повторного запуска.

Итак, вот мой вопрос:

как я могу освободить порты, не перезагружая Mac или ожидая, пока они закроются сами?

Есть ли какая-нибудь команда, с помощью которой я могу вручную закрыть порты?

Благодаря комментарию от @Gordon Davisson я смог решить свою проблему. Она снова возникла после сбоя iTerm2 после обновления.

$ netstat -an -f inet | grep 10021
tcp4       0      0  127.0.0.1.10021        *.*                    LISTEN

Так что я взглянул на результаты ps:

$ ps
  PID TTY           TIME CMD
 1747 ttys004    0:00.03 -bash
 1807 ttys005    0:00.03 -bash
 2030 ttys006    0:00.03 -bash
 2096 ttys007    0:00.06 -bash
78235 ttys007    1:59.37 ssh -p10022 -L 9994:10.239.244.31:3306 p325111@localhost
 2162 ttys008    0:00.05 -bash
68850 ttys008    0:01.69 ssh -p10022 -R 9003:127.0.0.1:9003 p325111@localhost
 2231 ttys009    0:00.07 -bash
68834 ttys009    0:00.01 /bin/sh ./tunnel.sh
68835 ttys009    4:35.26 ssh -L 10021:foo.d.example.com:3306 -L 10022:foo.d.gcp.puc-mobile.de:22 -L 10023:192.168.0.234
77772 ttys010    0:00.13 -bash
82148 ttys011    0:00.02 -bash
82314 ttys014    0:00.02 -bash
82386 ttys015    0:00.02 -bash
82446 ttys016    0:00.03 -bash
82515 ttys017    0:00.03 -bash
82653 ttys017    0:00.01 /bin/sh ./tunnel.sh
82654 ttys017    0:00.08 ssh -L 10021:foo.d.gcp.puc-mobile.de:3306 -L 10022:foo.d.gcp.puc-mobile.de:22 -L 10023:192.168.0.234

После завершения обоих процессов, которые содержали 10021, в моем случае 68835 и 82654, я смог снова запустить свое соединение, и все порты стали доступны. Так просто!

Ответ или решение

Закрытие SSH-портов или привязок портов вручную может быть необходимым в ситуациях, когда удаленная сессия завершилась некорректно, и порт остается занят, что мешает дальнейшей работе. Это распространённая проблема, особенно в средах с использованием SSH-туннелей, как в вашем сценарии с macOS 15.1 и iTerm2. В этом ответе мы подробно рассмотрим, как освободить заблокированные порты без необходимости перезагрузки компьютера.

Шаг 1: Определение занятых портов

Для начала, вам необходимо узнать, какие порты заняты. Узнать это можно с помощью команды netstat, которая отображает текущие сетевые подключения. Запустите в терминале следующую команду:

netstat -an -f inet | grep 10021

Эта команда фильтрует результаты netstat, показывая состояние порта 10021, который, судя по вашему описанию, может быть занятым. Если вы видите строку с LISTEN, это означает, что порт уже занят каким-то процессом.

Шаг 2: Найдите PID процесса

Чтобы выяснить, какой процесс использует порт, вам необходимо получить его идентификатор (PID). Запустите команду:

lsof -i TCP:10021

Эта команда покажет все процессы, использующие указанный порт, вместе с их PID. Обратите внимание на идентификаторы процессов, которые будут в выводе команды.

Шаг 3: Закрытие процесса

Теперь, зная PID процесса, который занимает порт, вы можете завершить его с помощью команды kill. Допустим, вы нашли, что PID процесса, занимающего 10021, равен 68835. Для его завершения выполните:

kill 68835

Если процесс не завершился, можно использовать более "агрессивный" метод:

kill -9 68835

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

Шаг 4: Проверка освобождения порта

После завершения процесса проверьте снова, освободился ли порт, повторив команду netstat:

netstat -an -f inet | grep 10021

Если вывод не содержит строки с LISTEN, это означает, что порт успешно освобожден и вы можете заново запустить свой скрипт SSH.

Заключение

Закрытие портов в macOS через SSH — это простой процесс, который может значительно упростить вашу работу. Вы всего лишь должны следовать четырём шагам: определить занятые порты, найти PID процесса, завершить соответствующий процесс и проверить освобождение порта. Надеемся, что эта информация сделает вашу работу с SSH-туннелями более стабильной и надежной.

Оцените материал
Добавить комментарий

Капча загружается...