Поскольку локально я располагаю достаточным количеством практически даровых ресурсов, то мне нужно организовать временный сервер локально, а 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 не светил подключение для всех - закрываю его на файерволе
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:
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 интерфейса.
#!/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 соединения нужно добавить вызов скрипта
... 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 адреса и названия серверов заменены на вымышленные и любое совпадение с реальными - случайность.
Комментариев нет:
Отправить комментарий