Рейтинг:0

Iptables Переадресация портов с сохранением IP-адреса клиента

флаг fr

TL;DR: Как я могу получить IP-адрес клиента, подключающийся к удаленно размещенному VPS, чтобы он был IP-адресом, который перенаправляется/нет через iptables на игровой сервер, работающий у меня дома?

У меня есть игровой сервер Rust, который я размещаю у себя дома. Я хочу, чтобы это было общедоступно, однако я не обязательно хочу раздавать свой IP-адрес всем. Поэтому я арендую небольшой VPS, который собираюсь использовать в основном как обратный прокси. В настоящее время я использую nginx для пересылки трафика через clinet-server VPN, который отлично работает. Однако на игровом сервере IP-адрес каждого игрока соответствует туннельному адресу VPS, а не фактическому IP-адресу клиента. я пытался использовать proxy_pass $remote_addr:28015 прозрачность; прокси_ответы 0 в моей конфигурации nginx никаких изменений. Поэтому я переключился на это через iptables.

Я могу заставить его работать на 99% так, как я хочу, делая именно это:

sysctl net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp --dport 28015 -j NAT --to-destination my_ip:28015
iptables -t nat -A PREROUTING -p udp --dport 28015 -j NAT --to-destination my_ip:28015
iptables -t nat -A PREROUTING -p tcp --dport 28016 -j NAT --to-destination my_ip:28016
iptables -t nat -A PREROUTING -p udp --dport 28016 -j NAT --to-destination my_ip:28016
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -p tcp -d my_ip --dport 28015 -m state --state НОВЫЙ, УСТАНОВЛЕННЫЙ, СВЯЗАННЫЙ -j ПРИНЯТЬ
iptables -A FORWARD -p ucp -d my_ip --dport 28015 -m state --state НОВЫЙ, УСТАНОВЛЕННЫЙ, СВЯЗАННЫЙ -j ПРИНЯТЬ
ufw отключить
ufw включить
перезагрузка впс \

Это в основном то же самое, что и nginx, где он работает нормально, но у всех просто есть общедоступный IP-адрес VPS (обратите внимание, что локальная сеть и общедоступный IP-адрес VPS одинаковы). Если я опускаю маскарад, он не работает.

Немного информации по настройке:
VPS имеет единый интерфейс: eth0
VPS работает Убунту 20.04
У меня дома модем находится в режиме сквозного доступа к pfsesne.В pfsense у меня есть правила переадресации портов для передачи 28015/28016 tcp/udp на игровой сервер.

Примечание: Я не уверен, почему nginx не работал для этого. Как будто nginx ничего не делал с proxy_pass $remote_addr директива.

Рейтинг:0
флаг us

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

Вам нужна поддержка протокола уровня 7, чтобы передать исходный IP-адрес вашему приложению. В HTTP/HTTPS это делается следующим образом:

  1. Обратный прокси nginx работает на вашем VPS.
  2. Обратный прокси добавляет заголовок X-Forwarded-For: <clientip> для запроса он отправляет на исходный сервер.
  3. Исходный сервер считывает заголовок и использует его в качестве IP-адреса клиента вместо использования IP-адреса, связанного с сокетом TCP.

Другая возможность — использовать SOCKS-прокси между VPS и исходным сервером. Прокси-сервер SOCKS инкапсулирует трафик от клиента и добавляет дополнительные метаданные, такие как IP-адрес клиента.

AAron avatar
флаг fr
Игровой сервер — это весь UDP-трафик. Работает ли `X-Forwarded-For` и для потоков UDP?
флаг us
Если у вас реализован какой-то протокол уровня 7, который имеет HTTP-подобную семантику с заголовками и т. Д., Тогда да. Но если вы реализуете собственный протокол приложения поверх UDP, то этот протокол должен поддерживать этот механизм, и вам также необходимо реализовать проксирование для этого протокола. Поскольку вы упомянули об использовании nginx `proxy_pass`, я предположил, что вы используете HTTP-подобный протокол.
AAron avatar
флаг fr
Я имею в виду, насколько я знаю, это стандарт UDP, единственное, что я с ним делаю, — это перенаправляю его в другое место.В моем nginx.conf после закрывающей скобки для блока сервера по умолчанию у меня есть это: `поток { сервер { слушать 28015 udp; proxy_pass my_ip:28015; proxy_bind $remote_addr:$remote_port прозрачный; прокси_ответы 0; } }`
флаг us
Хорошо, тогда это прокси-сервер bytestream, который предлагает nginx. Это концепция ретрансляции уровня 4, и она не имеет той функциональности, которую вы ищете. Мне кажется, что ваши единственные варианты - это переключиться на работу через HTTP/HTTPS или реализовать функциональность в вашем протоколе UDP, которая позволяет пользовательскому прокси-серверу добавлять IP-адрес клиента в сообщения протокола. Вам также необходимо реализовать собственный прокси. Однако, поскольку это общая функциональность, вероятно, существуют структуры протоколов, которые имеют эту функциональность.
AAron avatar
флаг fr
Есть ли у nginx нужная мне функциональность?
AAron avatar
флаг fr
Я хочу уточнить, что я не делаю свою собственную реализацию протокола, это не моя игра, это просто игра с возможностью размещения выделенного сервера самостоятельно. Таким образом, если функциональность не существует в UDP и/или nginx с одним или несколькими скомпилированными модулями, то это фактически невозможно.
флаг us
Протокол приложения должен поддерживать эту функциональность. nginx ic может действовать только как прокси-сервер байтового потока, он не может реализовывать какие-либо дополнительные функции, подобные этому.
AAron avatar
флаг fr
Хорошо, тогда, похоже, я либо буду иметь дело с одинаковыми IP-адресами, либо обработаю запреты на основе IP-адресов на VPS; или просто стисните зубы и разместите все это на удаленном VPS. У меня есть возможность сделать VPN-туннель от vps до игрового сервера, если это имеет значение. Прозрачность IP невозможна *вообще* с iptables или просто не в моем случае использования? Я просмотрел статьи, в которых обсуждаются такие вещи, как наличие правил переадресации на обоих концах, но я как бы игнорировал это, поскольку я не думал, что это применимо. Я определенно достиг точки, когда сок не стоит выжимать.
флаг us
IPTables работает только на уровне 3 и уровне 4 сетевого стека, и не существует механизма для обеспечения такой прозрачности IP-адресов, которую вы ищете. Прикладной уровень должен реализовать эту функцию. VPN-туннель, скорее всего, тоже не поможет.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.