Некоторое время назад была показана конфигурация шлюза для небольшого офиса, с возможностью доступа в офис из вне по 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 (#)