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

Предоставлять публичный доступ к локальному веб-серверу через VPN

У меня есть VPN-туннель, установленный между двумя серверами: VPS-A и VPS-B с (вымышленными) общедоступными IP-адресами: 66.55.44.33 и 77.88.55.66 и конечными точками VPN 10.0.1.1 и 10.0.2.1 соответственно.

На VPS-A работает веб-сервер. Я могу без проблем подключиться к VPS-B по SSH и получить ответ при отправке HTTP-запроса на 10.0.1.1 через curl, например:

curl http://10.0.1.1/

Я также могу открыть браузер на любом компьютере, подключенном к Интернету, и успешно открыть

http://66.55.44.33/

... но я также хочу иметь возможность подключиться к веб-серверу на VPS-A, отправив запрос на VPS-B, т.е.

http://77.88.55.66/

Теперь я добавил следующее правило на VPS-B (отредактировано, чтобы показать правильное правило)

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.1.1:80

... и когда я делаю tcpdump на порту 80 я ясно вижу, как запросы к http://77.88.55.66/ должным образом направляются в http://10.0.1.1. Однако веб-сервер на VPS-A, похоже, не подтверждает запрос TCP. Вот что именно показывает tcpdump:

2013-04-27 03:45:15.001564 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:15.252571 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670
2013-04-27 03:45:18.001526 IP 45.248.82.171.51377 > 10.0.1.1.80: S 791893048:791
2013-04-27 03:45:18.258666 IP 45.248.82.171.51378 > 10.0.1.1.80: S 670490211:670

..в то время как для запроса, поступающего через VPN:

2013-04-27 04:26:57.464859 IP 10.0.2.1.33258 > 10.0.1.1.80: S 2369100373:2369100373(0) win 5744 <mss 1436,sackOK,timestamp 121795122 0,nop,wscale 7>
2013-04-27 04:26:57.464913 IP 10.0.1.1.80 > 10.0.2.1.33258: S 3524730589:3524730589(0) ack 2369100374 win 5744 <mss 1436,nop,nop,sackOK,nop,wscale 7>
2013-04-27 04:26:57.532428 IP 10.0.2.1.33258 > 10.0.1.1.80: . ack 1 win 45

Я новичок в Linux, поэтому уверен, что что-то делаю неправильно, но не знаю, что именно. Я пытался найти похожие вопросы, но ничего не нашел. Если кто-то может указать мне полезный ресурс или привести практический пример - это было бы здорово.

Спасибо, что уделили время чтению моего сообщения!

Ваше описание должно быть неполным. Правила в INPUT и FORWARD не будут направлять пакеты для 77.88.55.66 на 10.0.1.1. Это возможно с DNAT цель в PREROUTING цепочка nat только таблица. Очевидно, есть такое правило.

Для успешного перенаправления вам все равно не нужны правила в INPUT, поскольку эти пакеты не должны приниматься системой перенаправления.

Проблема с DNAT без SNAT (как в вашем случае) заключается в том, что система обычно не заботится о том, через какой интерфейс она была достигнута при маршрутизации ответа. Ваш VPS-A видит открытие соединения с 45.248.82.171, и если он желает общаться с этим клиентом, он отправляет ответ - да, 45.248.82.171. Клиент отправил SYN-пакет на 77.88.55.66 и получил SYN ACK от 66.55.44.33 и, очевидно, просто думает, что это за WTF? Почему с 66.55.44.33? Потому что ответ не отправляется через туннель, потому что конфигурация маршрутизации VPS-A предписывает ему не отправлять пакеты в этот пункт назначения через туннель. Если они вернутся через туннель, VPS-B перезапишет исходный адрес на свой, и все будет в порядке.

Таким образом, вам нужно либо использовать iptables, чтобы отмечать соединения, которые проходят через туннель (почему все равно через туннель?), Переписывать метку соединения на метку пакета и использовать расширенную маршрутизацию с этой меткой пакета, чтобы эти пакеты отправлялись через туннель. Или вы используете обе стороны NAT, выполняете SNAT перед отправкой их с VPS-B через туннель и получаете их обратно с VPS-A простым способом. Недостаток: журналы веб-сервера показывают «неправильный» IP-адрес (всегда 10.0.2.1).

Кстати: 10.0.2.1 и 10.0.1.1 - странные адреса конечных точек одной и той же VPN, не так ли?