Здравствуйте, уважаемыее.
Наверняка многие из Вас, как и я, сталкивались с той самой проблемой, когда нам нужно прокинуть порт(ы) через Iptables на наши с Вами виртуальные физические машины, но наш провайдер выдает нам реальный (не серый) динамический IP адрес, как например в случаях с VPN или PPPoE.
У меня PPPoE, и IP меняется провайдером раз в трое суток. При этом тестовый сервер должен быть доступен всегда в независимости от того, какой у меня внешний IP.
Предлагаю свой вариант решения данной проблемы.
Итак, имеем: сервер на Ubuntu 10.04: (Linux nwserver 2.6.32-40-server #87-Ubuntu SMP Tue Mar 6 02:10:02 UTC 2012 x86_64 GNU/Linux, iptables v1.4.4) и второй сервер, которому мы должны прокинуть порты.
Наши действия:
1.) Создадим файл, который будет нужен скрипту для работы (обозвать можно как угодно, только в скрипте не забудьте его тогда переназвать). В него будет записываться наш динамический реальный IP и использоваться скриптом.
touch /tmp/ip_old
2. Теперь пишем скрипт, я его обозвал 0iptup:
IPT="/sbin/iptables -v"
REAL_IP=`cat /tmp/ip_old`
# Адрес нашего виртуального или тестового сервера
VSERV_IP=192.168.200.2
# Я хочу, чтобы всё, что там нём на 80ом порту шло на основной сервер на 81ый порт, дальше - только в пределах Вашей фантазии
$IPT -t nat -A PREROUTING -d $REAL_IP -p tcp -m tcp --dport 81 -j DNAT --to-destination $VSERV_IP:80
$IPT -t nat -A POSTROUTING -d $VSERV_IP -p tcp -m tcp --dport 81 -j SNAT --to-source $REAL_IP
# На тестовую машин мы, допустим, будем ходить по стандартному порту ssh, а там уж на Ваше усмотрение
$IPT -t nat -A PREROUTING -d $REAL_IP -p tcp -m tcp --dport 22 -j DNAT --to-destination $VSERV_IP:22
$IPT -t nat -A POSTROUTING -d $VSERV_IP -p tcp -m tcp --dport 22 -j SNAT --to-source $REAL_IP
# Все остальные порты пробрасываются по аналогии, не забудьте включить их в правила файрволла (таблица фильтров)
# Предпоследняя строка отлавливает наш внешний IP с интерфейса ppp0, если у вас другой, укажите свой
ip addr show ppp0 | grep "inet" | grep "peer" | awk '{print $2}' > /tmp/ip_old
# Последняя сохраняет айпи во временный файл
REAL_IP=`cat /tmp/ip_old`
3.) Скрипт делаем исполняемым: chmod +x 0iptup
Помещаем его в папку /etc/init.d/, далее даём ему разрешение на загрузку средствами update-rc.d: update-rc.d 0iptup defaults
Создаем символическую ссылку на него в /etc/ppp/ip-up.d/
4.) Там же, в /etc/init.d/ создаём второй скрипт 0iptdown:
#!/bin/sh
iptables-restore < /etc/iptables.up.rules
Делаем исполняемым, даём ему разрешение на загрузку средствами update-rc.d: update-rc.d 0iptdown defaults
Создаем символическую ссылку на него в /etc/ppp/ip-down.d/
Правила для Iptables у всех разные, указывайте путь к своему файлу конфигурации, но при этом не забудьте в нём указать разрешение на пробрашиваемые порты в таблице фильтров:
*filter
-A FORWARD -i ppp0 -p tcp -m tcp --dport 22 -j ACCEPT
-A FORWARD -i ppp0 -p tcp -m tcp --dport 81 -j ACCEPT
COMMIT
Как это работает на практике: при поднятии интерфейса ppp0 автоматически запускается скрипт, добавляет правила в таблицу файрволла ровно до того момента, пока интерфейс ppp0 активен, как только он деактивируется, скрипт возвращает настройки на исходные, что, как раз очень удобно при динамическом IP адресе.
Далее посредством dyn-dns, no-ip, или как Вам будет угодно, Вы всегда сможете заходить на свои виртуальные тестовые машины.
Возможные недостатки: если у Вас на боевой машине крутится, скажем, VPN-сервер, и люди получают от него ppp1, ppp2, и т.д., и происходит сбой соединения с провайдером, а в данный момент кто-то займёт интерфейс ppp0 — проброс произойдёт на Вашего клиента.
Вот, собственно плод полуторонедельных мучений и курения man iptables.
Дополнения и улучшения приветствуются.
Автор: netwatcher