Случай 1: SSH-хост имеет ОДИН сетевой интерфейс
Таблица маршрутизации для хоста SSH
:
[SSH] $ ip route
default via 192.168.211.1 dev eth0
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119
Инициировать ssh-соединение из SSH_Client
принимать гостей SSH
на LAN_0
работает плавно:
[SSH_CLIENT] $ ssh user@192.168.211.119 -p 22
Случай 2: SSH-хост имеет ДВА сетевых интерфейса
Таблица маршрутизации для хоста SSH
:
[SSH] $ ip route
default via 192.168.0.1 dev eth1
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.113
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119
Инициировать ssh-соединение из SSH_Client
принимать гостей SSH
на LAN_0
работает отлично:
[SSH_Client] $ ssh user@192.168.0.113
Инициировать ssh-соединение из SSH_Client
принимать гостей SSH
на LAN_211
работает несколько секунд и после этого зависает:
[SSH_Client] $ ssh user@192.168.211.119
Это случай асимметричной маршрутизации, вызванной модель слабого хоста используется в Linux: любой интерфейс может использоваться для любого IP-адреса, принадлежащего хосту.
Если хост SSH было включен Строгая пересылка по обратному пути, это вообще не сработало бы, что, вероятно, было бы лучше, учитывая текущий результат, потому что SSH затем отбросил бы все пакеты, имеющие IP из LAN 0, полученные на интерфейсе LAN 211.
Решение - использовать маршрутизацию политики на хосте. SSH чтобы исправить поведение этой многосетевой системы Linux: пусть она отвечает, используя ту же сторону, где назначен IP. Это делается путем создания дополнительных таблиц маршрутизации, в которых специально присутствует только частичная (и, возможно, упрощенная) копия основной таблицы, так что каждая таблица игнорирует интерфейс, который не следует использовать. Хотя обычно для этого требуется только одна дополнительная таблица, использование симметричной конструкции с двумя таблицами более чистое.
Кроме того, маршрут по умолчанию (через pfSense) добавляется обратно в конкретную таблицу LAN 211.
Затем правила ip будут вызывать эти таблицы маршрутизации перед тем, как по умолчанию перейти к основной таблице.
Воспользуемся таблицами с произвольно выбранными значениями 10000 и 10211 для обработки LAN 0 и LAN 211 соответственно.
# ip route add table 10000 192.168.0.0/24 dev eth1
# ip route add table 10000 default via 192.168.0.1 dev eth1
# ip route add table 10211 192.168.211.0/24 dev eth0
# ip route add table 10211 default via 192.168.211.1 dev eth0
# ip rule add from 192.168.0.113 lookup 10000
# ip rule add from 192.168.211.119 lookup 10211
Теперь можно проверить, что каждый исходный IP-адрес будет использовать правильный путь, спросив ядро, какой путь оно выберет:
# ip rule
0: from all lookup local
32764: from 192.168.211.119 lookup 10211
32765: from 192.168.0.113 lookup 10000
32766: from all lookup main
32767: from all lookup default
# ip route get 192.168.0.136 from 192.168.0.113
192.168.0.136 from 192.168.0.113 dev eth1 table 10000 uid 0
cache
# ip route get 192.168.0.136 from 192.168.211.119
192.168.0.136 from 192.168.211.119 via 192.168.211.1 dev eth0 table 10211 uid 0
cache
В SSH Теперь хост может принимать соединения с двух сторон одновременно: на каждый из двух своих IP-адресов и при этом правильно направлять каждый трафик на правильный интерфейс.
В качестве дополнительного примечания, эти правила не будут соответствовать, если IP-адрес еще не привязан к сокету (пример: исходящее соединение, инициированное с хоста SSH как стандартный клиент). В основной таблица будет по-прежнему использоваться:
# ip route get 192.168.0.136
192.168.0.136 dev eth1 src 192.168.0.113 uid 0
cache
Вы должны сами решить, как интегрировать эти настройки в сетевой менеджер, используемый в вашей конкретной системе. Часто это зависит от дистрибутива или инструмента. Обратите внимание, что когда IP-адрес удаляется (затем добавляется обратно) или интерфейс отключается (затем включается), таблицы 10000 и 10211 будут сброшены: они должны обновляться каждый раз после того, как такое событие произойдет, в отличие от записей в основная таблица, в которой ядро автоматически обрабатывает маршруты LAN (но еще не маршрут по умолчанию).
Поскольку настройка была исправлена, возможно, пора в принципе включить Strict Reverse Path Forwarding (две последние команды необходимы в случае, если раньше было установлено значение 2, а не 0: как документация для rp_filter
говорит, что более высокое значение преодолевает более низкое значение):
# sysctl -w net.ipv4.conf.all.rp_filter=1
# sysctl -w net.ipv4.conf.eth0.rp_filter=1
# sysctl -w net.ipv4.conf.eth1.rp_filter=1