Одному клиенту нужно достучаться до службы SSH другого клиента, а остальная часть пула должна оставаться такой же изолированной, как сейчас. Заманчивый переключатель — client-to-client, который включает доступ между узлами сразу для всех и передаёт решение OpenVPN вместо ядра. Более узкий ответ оставляет этот переключатель выключенным и позволяет собственному маршрутизатору и межсетевому экрану сервера нести ровно один поток.

Механизм важнее текста правила, потому что два подхода помещают пакет в разные места. Понимание того, какой вы выбрали, объясняет и правило, которое вроде бы ничего не делает, и соседа, который подключается без него.

Куда client-to-client переносит пакет

Когда client-to-client включён, сервер пересылает пакет соседа внутренне, вместо того чтобы отправить его обратно через туннельное устройство, поэтому пакет никогда не попадает на путь пересылки ядра. Это удобно, и это также значит, что ваш межсетевой экран никогда не видит поток, который должен контролировать. Оставьте параметр выключенным, и сервер направит пакет обратно через тот же интерфейс, что ставит его перед netfilter. Тот же интерфейс на входе, тот же на выходе, и цепочка FORWARD получает голос.

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

Путь, который пакет соседа действительно проходит

Предположим службу Linux Community OpenVPN 2.6, обработку TUN в пользовательском пространстве, а не DCO, топологию подсети, tun0 и пул 10.44.0.0/24 с клиентом A на 10.44.0.21 и клиентом B на 10.44.0.37. При топологии подсети адрес и маска, полученные A, уже покрывают пул, поэтому A отправляет пакет на туннельное устройство без дополнительного проталкиваемого маршрута. Проверьте фактический маршрут на A, а не предполагайте его.

На сервере пакет приходит адресованным B, а это не локальный адрес, поэтому он пересылается. Пересылка IPv4 должна быть включена, чтобы это вообще произошло, и поиск маршрута должен отправить пакет обратно через tun0. Поэтому межсетевой экран видит пересылаемый поток с одним и тем же интерфейсом с обеих сторон, и это та деталь, которую упускает большинство наборов правил. Здесь не нужна трансляция источника, и именно сохранение адреса A в целости позволяет B применить собственное правило по источнику.

Два правила на сервере, в этом порядке

Три правила несут всё разрешение: пересылка, исключение для пары и сброс по умолчанию для туннельной пары. Правило принятия называет пару и службу, поэтому разрешение переживает растущий пул. Поставьте его перед любым сплошным запретом трафика туннель-в-туннель, потому что побеждает первое совпадение:

sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o tun0 -s 10.44.0.21 -d 10.44.0.37 -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -i tun0 -o tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i tun0 -o tun0 -j DROP

Эти команды иллюстративны и относятся к тому механизму, которым ваш хост сохраняет правила; вставка во время работы исчезает при следующей загрузке. Именно правило с состоянием позволяет ответам B и рукопожатию TCP вернуться без второго, зеркального разрешения.

Проверяйте счётчики, а не список правил, потому что правило, которое никогда не срабатывает, выглядит так же, как работающее. Если счётчики остаются на нуле, пакет идёт не тем путём, каким вы думаете.

Что B всё ещё должен разрешить

B запускает службу SSH, поэтому B решает, слушает ли что-нибудь туннельный адрес и принимает ли источник собственный межсетевой экран хоста. Разрешение на уровне сети на сервере не является разрешением для какой-либо учётной записи на B, а проверка ключа хоста и аутентификация пользователя по-прежнему действуют, как и откуда угодно ещё.

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

Запишите назначенные адреса, фактические маршруты на обоих клиентах и точные правила на сервере и на B. Успешный ping до шлюза или открытый порт на сервере ничего из этого не доказывает, поскольку и то и другое может быть верно, пока пересылка между соседями всё ещё заблокирована. Запишите эти числа, пока туннель поднят, потому что адрес, который клиент получает после переподключения, может быть другим.

Похожие статьи