Когда IP-псевдонимы как ОС определяет, какой IP-адрес будет использоваться в качестве источника для исходящих соединений TCP / IP?


15

У меня есть сервер под управлением Ubuntu Server с четырьмя IP-адресами с псевдонимом на одной сетевой карте.

eth0       192.168.1.100
eth0:0     192.168.1.101
eth0:1     192.168.1.102
eth0:2     192.168.1.103

(Используя в качестве примера 192.168.xx, предположим, что они настроены на диапазон общедоступных IP-адресов)

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

Учитывая, что мой сервер логически имеет четыре IP-адреса на одном адаптере, как операционная система определяет, какой IP-адрес используется в качестве источника для исходящих соединений TCP / IP?

Допустим, я подключился к моему серверу 192.168.1.101 и запустил FTP в интерактивном режиме. Будет ли исходящее TCP / IP-соединение использовать 192.168.1.101, потому что ОС знает, что это интерфейс, через который подключена моя оболочка?

Что если задача FTP запускается неинтерактивно через задание cron, где нет оболочки?

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

редактировать

Чтобы выяснить, почему я спрашиваю - я не внес никаких изменений в таблицу маршрутизации, и она фактически перечисляет «eth0» в качестве IFace для маршрутов 0.0.0.0. Однако все указывает на то, что он на самом деле использует eth0: 0 в качестве источника.

Destination    Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
0.0.0.0        192.168.1.1     0.0.0.0         UG    100    0        0 eth0

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

Благодарность

Ответы:


12

По умолчанию в Linux, если интерфейс имеет несколько адресов, которые находятся в разных подсетях, трафик, предназначенный для соответствующих подсетей, будет иметь правильный исходный IP-адрес. То есть, если eth0 имеет два адреса 192.168.1.1/24 и 10.1.1.1/8, то трафик к чему-либо в подсети 10.0.0.0 будет иметь источник 10.1.1.1, а трафик ко всему в подсети 192.168.1.0 будет иметь источник 192.168.1.1. В этом случае вы также можете явно назначить адреса источника, используя опцию «src 1.2.3.4» для «ip route».

Однако в вашем случае все ваши адреса находятся в одной подсети, поэтому «основной» (как показывает «ip addr list dev eth0») используется в качестве исходного IP-адреса для трафика, выходящего через этот интерфейс. Я думаю, что в этом случае можно контролировать исходные IP-адреса, просто используя «ip route», но я обнаружил, что проще использовать iptables для перезаписи исходных адресов для интересующего трафика.

Если вы хотите принудительно использовать конкретный адрес источника для определенных мест назначения, вы можете сделать это с помощью правила SNAT:

iptables -t nat -I POSTROUTING -o eth0 -d dest-IP-or-net/mask -s primary-IP-of-eth0 -j SNAT --to-source desired-source-IP

Итак, если ваш «первичный» eth0 IP - 192.168.100.1, но вы хотите, чтобы трафик до 1.2.3.4 имел источник 192.168.100.2, то сделайте следующее:

iptables -t nat -I POSTROUTING -o eth0 -d 1.2.3.4/0 -s 192.168.100.1 -j SNAT --to-source 192.168.100.2

Обратите внимание, что «-s 192.168.100.1» важен: он предотвращает перезапись исходных адресов пересылаемого трафика этим правилом.

Если вы собираетесь реализовать сложные сетевые конфигурации в Linux, вам следует прочитать документацию Linux Advanced Routing and Traffic Control, http://lartc.org


В примере можно заменить «-d 1.2.3.4/0» на «-d 1.2.3.4/332» или «-d 1.2.3.4»
Кристиан,

5

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

Вы уверены, что на самом деле вы используете несколько адресов, а не просто имеете 4 IP-псевдонима?

если последнее имеет место, то вы можете установить исходный IP на маршруте с чем-то похожим на это

/ sbin / ip route show 192.168.222.0/24 dev eth0 протокольная область видимости ядра src 192.168.222.178 169.254.0.0/16 dev eth0 область видимости ссылка по умолчанию через 192.168.222.1 dev eth0

sudo / sbin / ip route заменяет значение по умолчанию через 192.168.222.1 src 192.168.222.178

/ sbin / ip route show
192.168.222.0/24 dev eth0 протокольная область видимости ядра src 192.168.222.178 169.254.0.0/16 dev eth0 область видимости ссылка по умолчанию через 192.168.222.1 dev eth0 src 192.168.222.178

смотрите man интерфейсы о том, как сделать его постоянным между перезагрузками


Ты прав. Возможно, я злоупотребляю термином мульти-хоминг. Наш центр обработки данных предоставляет нам четыре IP-адреса в одной подсети.
Джо Холлоуэй

Вы знаете, что можете редактировать свой вопрос, верно?
Хаялчи

5

Он использует любой шлюз по умолчанию, указанный в таблице маршрутизации, если только нет определенного маршрута, говорящего ему использовать другой: route -n

РЕДАКТИРОВАТЬ: я прочитал ваш вопрос слишком быстро, кажется ...

Поскольку вы используете пассивный режим, и клиент всегда будет инициировать соединение, я думаю, что поле src ip в заголовке IP всегда будет отображаться как любой IP-адрес, к которому подключен клиент. Если бы это был активный режим, когда сервер инициировал соединение, я думаю, что это всегда был бы «Первичный» IP. Если ваши адреса находятся в одной подсети, Linux сделает первый добавленный вами адрес «Первичным», а остальные - вторичным.

Хотя я не совсем уверен, я бы запустил tcpdump -n и увидел бы то, что он видит как src IP.

РЕДАКТИРОВАТЬ 2: Хорошо, я написал выше с точки зрения того, что вы запустили сервер, так что, поскольку вы являетесь клиентом и инициируете соединение, я думаю, что оно всегда будет исходить от основного IP-адреса, но снова попробуйте и посмотрите с tcpdump.


Таблица маршрутизации используется только по умолчанию и имеет только одну подсеть. В другом плакате указано, что я неправильно использовал термин multihoming. Однако я все еще ожидаю, что он будет использовать псевдоним eth0. Я использовал wget для загрузки whatsmyip.net, и это показывает, что я почему-то вместо этого использую eth0: 0.
Джо Холлоуэй

Это не имеет никакого смысла для меня, whatsmyip.net должен показывать ваш публичный ip ...
Кайл Брандт

Чтобы быть более понятным, он показывает общедоступный IP-адрес, привязанный к NAT к частному IP, связанному с eth0: 0, тогда как я ожидаю, что он покажет общедоступный IP-адрес, привязанный к NAT к частному IP, связанному с eth0
Джо Холлоуэй

1
За этот ответ здесь проголосовали слишком много и он содержит много правок, смущает многие вещи и не помогает. Ответы tbman и jknapka превосходны и очень мне помогли.
Кристиан

4

Если в вашем задании FTP нет способа указать интерфейс для использования для соединений, я считаю, что по умолчанию используется первый физический интерфейс в соответствующей подсети (в данном случае eth0). Если у вас есть сервер с двумя сетевыми картами в разных подсетях, он определит, какой интерфейс использовать, на основе таблицы маршрутизации.

Поскольку в системе имеется только один физический интерфейс (eth0) и четыре виртуальных / псевдонима (от eth0: 0 до eth0: 2), исходящий трафик будет использовать IP-адрес eth0 в качестве источника, если приложение не достаточно умен. объявить исходящий интерфейс.


2
Это было мое предположение, но все мои тесты показывают, что он использует eth0: 0 в качестве источника.
Джо Холлоуэй

Тогда, возможно, маршрут по умолчанию настроен на использование интерфейса eth0: 0. У меня есть установка, которая использует мост Ethernet, и он был настроен на использование интерфейса виртуального моста для маршрута по умолчанию.
sysadmin1138

Я установил на другом компьютере тривиальную программу для печати IP-адреса, с которого получено соединение. Соединение с ним nc -s <ip of eth0:2>или с тем, что всегда показывает адрес источника, на самом деле является ip из eth0: 0, хотя netcat делал это bind(2)раньше connect(2). Таким образом, похоже, что псевдонимы не работают, чтобы дать машине возможность устанавливать соединения с нескольких исходных адресов.
Питер Кордес

4

Вы могли видеть, какое устройство и IP-адрес src будут использоваться командой ip route get, как показано ниже:

$ /sbin/ip route get 1.1.1.1
1.1.1.1 via 2.2.2.2 dev eth0  src 2.2.2.2 
    cache  mtu 1500 advmss 1460 hoplimit 64

Я не пробовал это в псевдониме, но надеюсь, что это поможет.


1

При установлении исходящего соединения ваш сервер будет смотреть в своей таблице маршрутизации, чтобы определить, какой из четырех ваших интерфейсов использовать; ваши TCP-соединения будут иметь исходный IP-адрес вашего интерфейса выхода.

netstat -rn

Даст вам вывод вашей таблицы маршрутизации; ищите какие-либо конкретные записи, соответствующие IP-адресу клиента, к которому вы пытаетесь подключиться. Если их нет, то вы будете использовать маршрут по умолчанию (0.0.0.0, маска 0.0.0.0). Если у вас есть несколько маршрутов по умолчанию, будет использоваться маршрут с наименьшей стоимостью.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.