Некоторое время назад была показана конфигурация шлюза для небольшого офиса, с возможностью доступа в офис из вне по PPTP. Однако описанная конфигурация предусматривала статическое подключение к интернет и при подключении к интернет по PPP (например PPPoE или PPTP) она оказывалась не работоспособной.
В случае подключения к интернет с использованием PPP нужно немного усложнить конфигурацию. Ниже будет показано как именно это сделать.
Основная проблема в ситуации с PPTP-сервером, подключенным к интернет через PPP, заключается в том что нужно как-то различать ppp-интерфейсы: собственно соединение с провайдером, и соединения клиентов сервера. Кроме того скрипты настройки iptables предусматривают фиксированное имя "внешнего" интерфейса, что вобщем не соответствует действительности при использовании PPP.
К счастью на все вопросы есть ответы. Для того чтобы различать интерфейсы можно использовать PPP-параметр "ipparam", а для привязки PPP-подключения к конкретному интерфейсу опцию "unit". Рассмотрим конкретное решение:
Допустим что подключение к провайдеру выполняется по PPPoE и имя файла-описания этого провайдера в /etc/ppp/peers - "dsl-provider". Добавим в конец этого файла строки:
# Номер используемого интерфейса. # Для соединения с провайдером будет использован интерфейс ppp999 unit 999 # Присваиваем значение параметру ipparam ipparam provider
Так же добавим в файл /etc/ppp/pptpd-options строки:
# Присваиваем значение параметру ipparam ipparam pptp
А в файл /etc/pptpd.conf:
# Не передавать скриптам IP-адрес клиента в качестве ipparam noipparam
После этого надо перезапустить PPTP-сервер:
invoke-rc.d pptpd restart
Теперь мы можем различать PPP-соединения по параметру ipparam. Теперь адаптируем скрипты из предыдущей статьи к новым условиям:
Обновлённый /root/scripts/firewall.sh:
#!/bin/sh
# Минимальные настройки скрипта
# Внешний интерфейс
IF_EXT="eth0"
# Внутренний интерфейс
IF_INT="eth1"
# Локальная сеть
NET_INT="192.168.2.0/255.255.255.0"
# На всякий случай сбрасываем все правила
iptables -F
iptables -F -t nat
# Устанавливаем политики по умолчанию:
# Никого не пускать
iptables -P INPUT DROP
# Всех выпускать
iptables -P OUTPUT ACCEPT
# Мимо нас никто не ходит
iptables -P FORWARD DROP
# Впускаем ответы на запросы, которые сами отправили
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Разрешаем весь трафик на внутреннем интерфейсе
iptables -A INPUT -i lo -j ACCEPT
# Разрешаем весь трафик со стороны локальной сети
iptables -A INPUT -i ${IF_INT} -s ${NET_INT} -j ACCEPT
# Разрешаем весь трафик, который необходим для работы PPTP-сервера
iptables -A INPUT -m tcp -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -j ACCEPT
# NAT для локальной сети на внешнем интерфейсе
iptables -t nat -A POSTROUTING -s ${NET_INT} -j MASQUERADE -o ${IF_EXT}
# Разрешаем пересылку пакетов из локальной сети наружу
iptables -A FORWARD -i ${IF_INT} -o ${IF_EXT} -s ${NET_INT} -j ACCEPT
# Разрешаем пересылку в локальную сеть ответов на исходящие запросы
iptables -A FORWARD -i ${IF_EXT} -o ${IF_INT} -d ${NET_INT} -m state --state RELATED,ESTABLISHED -j ACCEPT
/etc/ppp/ip-up.d/99_pptp_vpn:
#!/bin/sh
# Извлекаем из переменных окружения имя интерфейса и IP-адрес клиента
IF_PPTP=${PPP_IFACE}
IP_PPTP=${PPP_REMOTE}
# Если создаётся интерфейс для PPTP-туннеля
if [ ${PPP_IPPARAM} = "pptp" ]; then
# Интерфейсы, через которые мы готовы пускать клиента
# Здесь нужно как минимум указать внутренний интерфейс
# Однако если мы хотим так же выпустить клиента в Интернет - нужно указать и внешний интерфейс
OUT_IFACES="eth0 eth1"
# Разрешаем использование нашего DNS-сервера
iptables -A INPUT -m udp -p udp --dport 53 -i ${IF_PPTP} -s ${IP_PPTP} -j ACCEPT
# Перебираем интерфейсы
for IF_EXT in ${OUT_IFACES}; do
# Разрешаем трафик с клиента через этот интерфейс
iptables -A FORWARD -i ${IF_PPTP} -o ${IF_EXT} -s ${IP_PPTP} -j ACCEPT
# Разрешаем трафик с этого интерфейса в сторону клиента
iptables -A FORWARD -i ${IF_EXT} -o ${IF_PPTP} -d ${IP_PPTP} -m state --state RELATED,ESTABLISHED -j ACCEPT
done
fi
/etc/ppp/ip-down.d/99_pptp_vpn:
#!/bin/sh
# Извлекаем из переменных окружения имя интерфейса и IP-адрес клиента
IF_PPTP=${PPP_IFACE}
IP_PPTP=${PPP_REMOTE}
# Если создаётся интерфейс для PPTP-туннеля
if [ ${PPP_IPPARAM} = "pptp" ]; then
# Интерфейсы, через которые мы были готовы пускать клиента
OUT_IFACES="eth0 eth1"
# Удаляем правило, разрешающее клиенту использование нашего DNS
iptables -D INPUT -m udp -p udp --dport 53 -i ${IF_PPTP} -s ${IP_PPTP} -j ACCEPT
# Перебираем интерфейсы
for IF_EXT in ${OUT_IFACES}; do
# Удаляем правила, которые разрешали клиенту пересылку пакетов между интерфейсами
iptables -D FORWARD -i ${IF_PPTP} -o ${IF_EXT} -s ${IP_PPTP} -j ACCEPT
iptables -D FORWARD -i ${IF_EXT} -o ${IF_PPTP} -d ${IP_PPTP} -m state --state RELATED,ESTABLISHED -j ACCEPT
done
fi
Всё остальное делается так же как и в предыдущей статье и потому здесь описано не будет.
На этом задачу можно считать решённой. Приятной работы!

sungreen 2010-05-18 07:23:06 (#)