
У нас есть пакетный процесс XYZ, который запускается в 2:00 утра каждый день. Этот XYZ настроен на запуск на порту 59070. После его завершения этот порт становится открытым. Но недавно у нас возникла проблема, когда другой процесс использовал 59070, и когда этот процесс XYZ запустился, он не смог запуститься.
В качестве обходного пути мы обновили конфигурацию на другой порт 59071 и запустили процесс нормально. Мой вопрос в том, есть ли возможность заблокировать этот порт 59070 и гарантировать, что никакой другой процесс его не использует? Мы используем Solaris 10.
решение1
Порт 59070 — этоэфемерный порт- тот, который можно использовать дляисходящийTCP-соединения любым процессом. (Как и порт 59071, так что это не совсем хороший способ решения проблемы...)
В Solaris диапазон эфемерных портов задаетсяиtcp_smallest_anon_port
tcp_largest_anon_port
настраиваемые параметры. Диапазон по умолчанию от 32 768 до 65 535. Любой порт в этом диапазоне может быть занятв любое времяпо исходящему TCP-соединению.
Как указано в ответе @Jeff Schaller, порты используются по принципу «первым пришел, первым обслужен», поэтому единственный способ «зарезервировать» порт — это иметь что-то привязанным к нему все время. Обратите внимание, что в этом ответе возможно, что другой процесс может захватить рассматриваемый порт в то время, когда завершается скрипт «сохранения порта» и «нормальный» процесс, который использует порт, фактически bind()
подключается к нему. Это невероятный, конечно, но это может случиться. И если ваша обработка критически важна, я думаю, вам стоит об этом беспокоиться.
Я бы не рекомендовал использовать временный порт и/или настраивать процесс на постоянную работу, илииспользуйте inetadm
для настройки службы, которая автоматически запускает ваш процесс. Это заставит inetd
процесс постоянно привязываться к «вашему» порту, фактически резервируя его для вашего использования.
решение2
Я не знаю способа заблокировать использование порта, кроме как проактивно использовать его самостоятельно. Общая идея, которую я бы предложил, заключается в том, чтобы изменить пакетную обработку на:
убейте скрипт "сохранения портов"
запустить обычную пакетную обработку
запустить новый скрипт «сохранения портов»
Этот обходной путь будетпомощьпредотвратить привязку вредоносного процесса к нужному вам порту (процесс может захватить порт между шагами 1 и 2 или между шагами 2 и 3), но этонетпредотвратить сбой в пакетном процессе, когда пакетный процесс, по-видимому, завершается, но не освобождает порт (путем выхода из всех его процессов).
Пример скрипта «сохранения портов» на Perl:
#!/usr/bin/env perl
# listens on the given port
use strict;
use IO::Socket;
my $port = shift or die "Usage: $0 <port>";
my $socket = new IO::Socket::INET(
LocalHost => '0.0.0.0',
LocalPort => $port,
Proto => 'tcp',
Listen => 1,
Reuse => 1,
)
or die "Cannot create socket: $!\n";
while (1) {
my $c = $socket->accept();
shutdown($c, 2);
}
Вам нужно будет либо сохранить PID скрипта, либо найти и завершить его, так как он выполняет бесконечный цикл, удерживая указанный порт открытым.