Назад | Перейти на главную страницу

Nginx Transparent IP - маршрутизировать ответ сервера через балансировщик нагрузки, а не напрямую клиенту

Мне дали задание настроить прозрачный IP-адрес на Nginx, чтобы передать адрес и порт клиента на вышестоящий сервер. Настройка выглядит так:

Client --> Nginx (listens for udp on 90009) --> Service (listens on localhost:59153)

Nginx и Сервис установлены на одном хосте.

Базовая настройка работает без проблем - запрос перехватывается nginx, направляется в службу, служба отвечает на nginx и обратно клиенту.

Предполагаемое поведение - передать IP-адрес источника запроса в службу, поэтому я настраиваю nginx следующим образом:

stream {
  upstream upstream_servers {
      server 127.0.0.1:59153;
  }

  server {
      listen 90009 udp;
      proxy_bind $remote_addr:$remote_port transparent;
      proxy_pass upstream_servers;

  }
}

proxy_bind $remote_addr:$remote_port transparent; делает свою работу правильно - ip/port передается за nginx в сервис. Однако служба (что неудивительно) пытается напрямую отвечать на заданные ip/port. Связь с внешним миром разрешена только через порт 90009, поэтому ответ никогда не доставляется.

Что я пытался сделать, так это направить ответ на основе Прозрачность IP и прямой возврат сервера с NGINX и NGINX Plus в качестве прозрачного прокси. Итак, я сделал следующее:

iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p udp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p udp -m socket -j TPROXY --tproxy-mark 1 --on-port 90009
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

Но это приводит к любому из двух результатов, в зависимости от того, как я определяю iptables -t mangle -A PREROUTING -p udp -m socket -j TPROXY --tproxy-mark 1 --on-port 90009:

  1. Доходные пакеты UDP маршрутизируются, и запрос никогда не достигает nginx
  2. Ни один из пакетов не маршрутизирован, ответ не доставлен

Мой вопрос в основном заключается в том, как маршрутизировать только ответ через loadbalancer или, если этот подход неверен, как попытаться решить эту проблему?