Увеличьте количество эфемерных портов, добавив дополнительный интерфейс Ethernet

Есть ли способ удвоить количество эфемерных портов и обойти ограничение в 16 бит? Я пробовал создавать виртуальные интерфейсы Ethernet через eth0 и надеюсь, что это снимет ограничения. Хотя приложение использует новые виртуальные IP-адреса в исходящем трафике, похоже, что оно все еще достигает того же ограничения на количество эфемерных портов. Я полагаю, что виртуальные порты имеют сопоставление 1 к 1 с портами физического интерфейса.

ifconfig eth0: 1 10.10.10.210 сетевая маска 255.255.255.192 ifconfig eht0: 2 10.10.10.211 сетевая маска 255.255.255.192

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

(К вашему сведению, я попытался увеличить открытый файл ulimit / max, изменить диапазон портов, включить повторный цикл / временные метки tcp, уменьшить тайм-аут tcp fin ... Я полагаю, нам просто нужно более 65 тыс. Портов для этой прокси-машины.)


person unjc    schedule 09.09.2013    source источник
comment
Возможно, мне стоит уточнить, что мне нужно. Я не собираюсь увеличивать ограничение на 16-битный порт для одного IP. Я действительно хочу создать дополнительный (виртуальный) IP-адрес, чтобы разрешить использование большего количества портов для прокси (или ОС Linux). Если это сработает, исходящие соединения будут привязаны к разным IP-адресам. Надеюсь, это имеет смысл.   -  person unjc    schedule 10.09.2013
comment
Целевой сервер видит, что TCP-соединения привязаны к виртуальным IP-адресам. Должна ли ОС разрешать повторно использовать один и тот же локальный порт, пока 5-кортеж (протокол, адрес источника, порт источника, адрес назначения, порт назначения) еще не существует?   -  person unjc    schedule 10.09.2013
comment
У меня точная проблема. После добавления 10 виртуальных IP-адресов и привязки к ним сокетов сокеты по-прежнему ограничены временным диапазоном портов. Я не уверен, требуется ли SO_REUSEPORT. Вы решили эту проблему?   -  person Ning Sun    schedule 20.06.2014


Ответы (4)


Если вы создаете виртуальные интерфейсы через eth0, вы сможете назначать этим интерфейсам разные IP-адреса. При этом вы можете использовать одни и те же временные номера портов (они выделены в ядре, поэтому у вас нет особого контроля) для нескольких сокетов, каждый из которых привязан к разным адресам - вам, вероятно, потребуется установить параметр SO_REUSEADDR. Причина, по которой это будет работать, заключается в том, что для входящих пакетов (UDP / TCP) поток идентифицируется путем просмотра как локального IP-адреса источника, так и номера порта.

И, как упоминал @Duck, поскольку заголовки TCP / UDP выделяют только 16 бит для номеров портов, нет особого смысла увеличивать эфемерный диапазон в локальном стеке.

person Manoj Pandey    schedule 09.09.2013
comment
Спасибо, Манодж. Я использую squid в прокси. Я просто проверяю их сайт; S_REUSEADDR, похоже, уже является параметром по умолчанию. - person unjc; 10.09.2013

Это ограничение сетевых протоколов. И TCP, и UDP, например, имеют 16-битные порты источника и назначения. Даже если вы можете увеличить количество портов, никто не сможет к ним обратиться.

person Duck    schedule 09.09.2013
comment
Когда сокет привязывается к виртуальному IP-адресу, удаленная машина видит виртуальный IP-адрес как исходный IP-адрес соединения. Теоретически мы все еще придерживаемся 16-битного ограничения порта, но дополнительный виртуальный интерфейс должен создать новый временный пул портов для использования. Я прав? - person unjc; 09.09.2013
comment
Вы знаете, я не уверен на 100%. Я немного удалю свой ответ, если у меня не будет времени провести какое-то исследование. - person Duck; 09.09.2013

Вроде способ есть, но не бесплатно. Это называется «привязать перед подключением». См. эту короткую, но содержательную статью, в которой очень мило.

Наличие нескольких виртуальных IP-адресов - это только начало. Цитата по связанной статье:

В Linux временный диапазон портов - это глобальный ресурс, а не конкретная настройка, локальная для IP-адреса.

Так что это плохо, и вам нужно улучшить свою исходную позицию с помощью нескольких правильных настроек (большинство из которых вы уже нашли) и обойти глобальный предел с помощью умной техники распределения сокетов. В результате вы будете контролировать все исходящие IP-адреса вручную. Это также, похоже, не очень хорошо справляется с другими приложениями в системе, использующими традиционный способ «подключения».

person tlwhitec    schedule 23.03.2015

Оказывается, вы не можете использовать 0 для привязки эфемерного порта, если хотите превысить лимит 65535. Вместо этого вам нужно использовать явный номер порта.

Также может оказаться полезным включение tcp_tw_reuse: http://krenel.org/tcp-time_wait-and-ephemeral-ports-bad-friends.html

person Ning Sun    schedule 20.06.2014