PPTP-сервер, подключенный к интернет через PPP

()

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

Всё остальное делается так же как и в предыдущей статье и потому здесь описано не будет.

На этом задачу можно считать решённой. Приятной работы!

Ключевые слова: pptp, pppoe, ppp, ipparam, unit, vpn.

Подписаться на обновления: RSS-лента Канал в TamTam Telegram канал Канал в ICQ

Комментарии:

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

выделенный ip для этого нужен?

MooSE 2010-05-18 10:39:27 (#)

Для сервер? Желателен. Хотя можно всякие no-ip.org использовать.
Новый комментарий

Жирный текстКурсивный текстПодчёркнутый текстЗачёркнутый текстПрограммный кодСсылкаИзображение




© 2006-2024 Вадим Калинников aka MooSE
Политика конфиденциальности