Пробрасывание внешнего ip на виртуальный сервер понедельник, 10 сентября 2012 г. Автор: Andrey Tataranovich http://blog.tataranovich.com/2012/09/ip.html http://blog.tataranovich.com/ Редко, но метко в моей практике возникает задача, когда нужно быстро поднять сервер с "белым ip" для демонстрации результатов работы или просто для целей тестирования нового функционала перед выкатыванием его в продакшен. Каждый раз арендовать VDS для этого накладно, а связываться с облаками для подобных целей мне не хочется. Поскольку локально я располагаю достаточным количеством практически даровых ресурсов, то мне нужно организовать временный сервер локально, а ip адрес прокинуть с любого внешнего сервера. Чтобы решить задачу наиболее общим способом были пославлены следующие цели: получить на тестовом сервере (srv-test), который находится за NAT, ip адрес, который доступен извне; на тестовом сервере не должно быть артефактов реализации. После небольшой пробежки по поисковикам я так и не нашел решение, которое устроило бы меня целиком. Потому пришлось планировать решение самостоятельно. После прикидывания различных вариантов получился VPN туннель с двойным NAT На внешнем сервере был запущен минимальный openvz контейнер, в котором крутится только openvpn. Чтобы отличать этот контейнер от других серверов, я буду называеть его srv-ovpn. Первичный IP адрес контейнера - 212.78.101.113 - он же по совместительству "белый" ip, по которому должен быть доступен тестовый сервер (буду называть его srv-test) из интернета. Также у srv-ovpn есть дополнительный ip адрес 212.78.101.114 - на этот адрес подключается VPN клиент. В принципе от второго адреса можно отказаться, если немного усложнить policy routing, но у меня были свободные ip и было лениво заморачиваться с подобной экономией. Адрес шлюза, через который сервер виртуальных машин подключен к интернету - 93.100.17.39. Чтобы srv-ovpn не светил подключение для всех - закрываю его на файерволе Code: root@srv-ovpn # iptables -A INPUT -p udp -s 93.100.17.39 --dport 1194 -j ACCEPT root@srv-ovpn # iptables -A INPUT -p udp --dport 1194 -j REJECT root@srv-ovpn # iptables-save > /etc/sysconfig/iptables Теперь OpenVPN сервер доступен только для меня и надежно скрыт от посторонних глаз. Далее поднимаю на локальном сервере виртуалок (назову этот сервера - srv-virt) VPN соединение до openvz контейнера srv-ovpn: Code: root@srv-virt # service openvpn start vpntunnel После окончания инициализации появился новый интерфейс tun0, который получил адрес 10.117.9.6. Второй конец туннеля имеет адрес 10.117.9.1. Сетевой адаптер, входящий в VLAN srv-test, виден на сервере srv-virt с именем veth3 и имеет адрес 212.78.101.112. Чтобы автоматизировать процесс настройки VPN соединения я использовал скрипт /etc/openvpn/vpntunnel.sh, который вызывается OpenVPN при инициализации/деинициализации VPN интерфейса. Code: #!/bin/sh TUN_DEV="$2" TUN_IP="$5" REMOTE_IP="212.78.101.113" IPR_BIN="/bin/ip" IPT_BIN="/sbin/iptables" if [ ! -r /etc/iproute2/rt_tables ]; then echo "File not found: /etc/iproute2/rt_tables" echo "iproute2 package must be installed" exit 1 fi case $1 in start) grep -q '^100\tvpntunnel' /etc/iproute2/rt_tables || echo '100\tvpntunnel' >> /etc/iproute2/rt_tables ${IPR_BIN} rule add from ${REMOTE_IP} table vpntunnel ${IPR_BIN} route add default via ${TUN_IP} dev ${TUN_DEV} table vpntunnel ${IPR_BIN} route flush cache ${IPT_BIN} -t nat -A PREROUTING -d ${TUN_IP} -j DNAT --to-destination ${REMOTE_IP} ${IPT_BIN} -t nat -A POSTROUTING -o ${TUN_DEV} -j SNAT --to-source ${TUN_IP} ;; stop) ${IPT_BIN} -t nat -D PREROUTING -d ${TUN_IP} -j DNAT --to-destination ${REMOTE_IP} ${IPT_BIN} -t nat -D POSTROUTING -o ${TUN_DEV} -j SNAT --to-source ${TUN_IP} ${IPR_BIN} route del default via ${TUN_IP} dev ${TUN_DEV} table vpntunnel ${IPR_BIN} route flush cache ${IPR_BIN} rule del from ${REMOTE_IP} table vpntunnel ;; *) echo "Incorrect usage" exit 1 esac В конфиг VPN соединения нужно добавить вызов скрипта Code: ... up "/etc/openvpn/vpntunnel.sh start" down "/etc/openvpn/vpntunnel.sh stop" down-pre ... Аналогичный конфиг OpenVPN должен быть и на сервере srv-ovpn. Осталось настроить на сервере srv-test адрес 212.78.101.113/31 со шлюзом 212.78.101.112 и все должно заработать. В этом посте все ip адреса и названия серверов заменены на вымышленные и любое совпадение с реальными - случайность.