
Я пытаюсь выполнить проксирование SNI в подсеть на маршрутизаторе, сохраняя при этом исходный IP-адрес.
Предыстория: У меня есть маршрутизатор, который использует DNAT для переадресации портов для многих портов приложений, и он подключен к подсети (используя VPN на самом деле) с разными бэкендами. Для протоколов, у которых НЕТ чего-то вроде HTTP Host или TLS SNI, которые можно направить на разные IP-адреса в зависимости от запроса, я просто использую DNAT с фильтром портов TCP, и они работают хорошо.
Для TLS я используюSNIProxyдля мультиплексирования входящих соединений на разные серверы на основе TLS SNI. Работает довольно хорошо, но SINProxy отправляет пакеты TLS с самого маршрутизатора, отбрасывая адреса src. Это ломает некоторые внутренние службы, которые полагаются на IP src.
Таким образом, мне интересно, возможно ли, чтобы netfilter фильтровал трафик с помощью TLS SNI (опционально с внешними модулями) и маршрутизировал его с помощью DNAT (вместо того, чтобы просто отбрасывать). Если это невозможно, есть ли какие-либо альтернативы?
Кстати, я не хочу развертывать полный HTTP (или любые серверы L5) на своем маршрутизаторе по следующим причинам:
- Мне нужно расшифровать трафик и проксировать его на бэкэнд. Это огромные накладные расходы.
- Я не хочу развертывать сертификаты TLS на маршрутизаторах из-за сложности управления.
Заранее большое спасибо за любой полезный ответ.
решение1
Теоретически, используя -j NFQUEUE
userspace для изменения первого пакета и выполнения NAT, вы могли бы представить, что делаете что-то вроде этого. На практике вы не можете, потому что вам нужно получить полное сообщение ClientHello с расширением SNI, чтобы угадать новый адрес назначения, и поскольку первый пакет TCP будет пустым, или с UDP, DTLS в любом случае потребует несколько раундов, тогда будет слишком поздно выполнять NAT для потока, который теперь управляется conntrack.
Вам нужен прокси. Но прокси можно сделать прозрачным или использовать протокол PROXY с поддерживающими его бэкэнд-приложениями (хотя они должны поддерживать совместное использование протокола PROXY плюс TLS).
Например, haproxy
работа на шлюзе может выполнять либо: это проект, который предложилПРОКСИ-протокол, и он также может использовать Linuxtproxyцель для прозрачного (прозрачного как для источника, так и для назначения) проксирования.
Вот ссылка, которую я нашел на github gist, предлагающая оба варианта:Используйте HAProxy для прозрачной маршрутизации запросов к веб-сервисам, идентифицируемым по имени хоста. Вот несколько строк о настройке прозрачного прокси-сервера, который будет использоваться вместе с ядром Linux.tproxyдокументация (также в том же тексте):
Конфигурация сервера HAProxy будет выглядеть следующим образом. Она работает как для режимов TCP, так и для HTTP.
server app1-tls 192.0.2.10:3001 source * usesrc client weight 0
решение2
Таким образом, мне интересно, возможно ли, чтобы netfilter фильтровал трафик, используя TLS SNI (опционально с внешними модулями)
Это невозможно. NAT должен быть выполнен, начиная с первого пакета соединения, т. е. TCP SYN, который инициирует TCP-рукопожатие. Но SNI есть только в ClientHello TLS-рукопожатия, которое отправляется только после завершения TCP-рукопожатия. Другими словами: информация, необходимая для NAT, еще не доступна в то время, когда она нужна.
Если это невозможно, есть ли какие-то альтернативы?
haproxy может завершить TCP-соединение и затем переслать данные на основе SNI в ClientHello - без завершения TLS на прокси-сервере. Затем он может переслать исходный IP-адрес клиента внутри TCP-соединения, используя протокол PROXY (в основном заголовок в начале пересылаемого соединения). Если сервер восходящего потока не понимает сам протокол PROXY, можно использовать программное обеспечение, напримерммпроксидля SNAT-подключения из HAProxy, чтобы отображался исходный IP-адрес источника.