Новости из Блогов Пробрасывание внешнего ip на виртуальный сервер

Discussion in 'Мировые новости. Обсуждения.' started by Suicide, 12 Sep 2012.

  1. Suicide

    Suicide Super Moderator
    Staff Member

    Joined:
    24 Apr 2009
    Messages:
    2,373
    Likes Received:
    6,619
    Reputations:
    693
    Пробрасывание внешнего 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

    [​IMG]

    На внешнем сервере был запущен минимальный 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 адреса и названия серверов заменены на вымышленные и любое совпадение с реальными - случайность.
     
  2. z0mbyak

    z0mbyak Active Member

    Joined:
    10 Apr 2010
    Messages:
    536
    Likes Received:
    200
    Reputations:
    293
    Суи, это старо как мир. самый первый вариант дабл впн... Который я узнал)