Показаны сообщения с ярлыком pppoe. Показать все сообщения
Показаны сообщения с ярлыком pppoe. Показать все сообщения

воскресенье, 25 августа 2019 г.

IPv6 от Дом.ру (ЭР-Телеком) в Debian Stretch

Отключение IPv6

До сих пор мне приходилось лишь отключать поддержку IPv6 на компьютерах, т.к. она скорее создавала дополнительные риски для безопасности системы, чем приносила какую-то практическую пользу. Напомню, что для отключения IPv6 на уровне операционной системы нужно выполнить команду:
# sysctl -w net.ipv6.conf.all.disable_ipv6=1
Чтобы поддержка IPv6 не включалась при перезагрузке системы, нужно прописать в файл /etc/sysctl.conf такую строчку:
net.ipv6.conf.all.disable_ipv6=1
При этом интерфейсам не будут присваиваться адреса IPv6, однако различные сетевые демоны по-прежнему будут готовы обслужить запрос, поступивший через стек IPv6. Чтобы полностью отключить весь стек IPv6, нужно в файле /etc/default/grub добавить в переменную GRUB_CMDLINE_LINUX опцию, которая сообщит ядру о необходимости отключить весь стек IPv6:
GRUB_CMDLINE_LINUX="ipv6.disable=1"
После этого нужно обновить файлы конфигурации загрузчика GRUB при помощи следующей команды:
# update-grub
И перезагрузить систему.

Однако, недавно в личном кабинете Дом.ru моё внимание привлёк переключатель поддержки IPv6. Нельзя сказать, что в IPv6 и сейчас есть много пользы, однако поддержка IPv6 со стороны провайдера побудила меня изучить вопрос. Я достал с полки когда-то купленную книжку IPv6. Администрирование сетей и стал почитывать вечерами.

Надо сказать, что принципы организации IPv6 значительно отличаются от принципов организации ныне используемого протокола IPv4. Это не просто новая версия IPv4 с увеличенной длинной поля IP-адреса. Разработчики протокола подошли к задаче основательно, пытаясь решить множество проблем, накопившихся в IPv4. На мой взгляд, IPv6 напоминает чем-то гибрид IPv4 и IPX.

Организация сетей IPv6 с точки зрения магистрального сетевого администратора

С точки зрения сетевого администратора, работающего в компании-провайдере, IPv6 в целом отличается от IPv4 довольно мало. Провайдер обращается к региональному регистратору для получения блока IPv6-адресов. Регистраторы выдают провайдерам блоки с префиксами /32 из адресного пространства 2000::/3 - это «белые» IPv6-адреса.

Следующие 32 бита - это номера сетей внутри блока. Провайдерам настоятельно рекомендуется анонсировать по протоколу BGP префиксы не длиннее /48, чтобы глобальные таблицы маршрутов не разрослись сверх меры. Клиентам рекомендуется выдавать префиксы сетей с маской /56. Это значит, что из 32 бит 24 бита остаются в распоряжении провайдера, а следующие 8 бит клиент может использовать по своему усмотрению. То есть провайдер может раздать по 256 сетей каждому из максимум 16 миллионов (2^24) клиентов, имея всего один блок /32. При этом у клиента остаётся возможность организовать адресное пространство таким образом, чтобы выделить каждому из филиалов по несколько сетей для различных нужд. Например, 16 филиалам по 16 сетей, или 64 филиалам по 4 сети.

Наконец, оставшиеся 64 бита используются в качестве идентификатора интерфейса сетевого устройства внутри одной сети. Одна сеть может содержать столько устройств, сколько необходимо. Для формирования идентификатора интерфейса используются идентификаторы EUI-64. Идентификатор EUI-64 получается из MAC-адреса следующим образом:
  1. у первого октета MAC-адреса выставляется в единицу бит 1 (выполняется операция «побитовое или» со значением 0x02),
  2. между первыми и последними тремя октетами вставляется два октета - ff fe.

Организация сетей IPv6 с точки зрения сетевого администратора

Для сетевого администратора есть несколько интересных отличий IPv6 от IPv4.

Во-первых, в IPv6 встроены функции автоконфигурации сетевых интерфейсов. Каждый интерфейс назначает себе IPv6-адрес с префиксом fe80::/10, который не подлежит маршрутизации. Эти автоконфигурируемые IPv6-адреса используются для общения с маршрутизаторами и соседями по сети. Благодаря этому минимальная связность сети обеспечивается автоматически, а протоколы конфигурирования значительно упрощаются.

Во-вторых, т.к. автоконфигурирование обеспечивает минимальную связность сети, упрощаются протоколы обнаружения соседей и более полного автоконфигурирования. В IPv6 функции ARP и частично DHCP включены в протокол ICMPv6. Вместо ARP в ICMPv6 встроен протокол обнаружения соседей NDP - Neighbor Discovery Protocol. Вместо DHCP для получения маршрутов используется функция ICMPv6 под названием RA - Router Advertisement. Для получения адресов DNS-серверов и доменного суффикса по умолчанию в ICMPv6 существуют аналогичные функции RDNSS - Recursive DNS Servers и DNSSL - DNS Search List. Для более сложных случаев можно использовать DHCPv6, роль которого в IPv6 значительно снизилась - он используется для получения узлами различных настроек, таких как списки DNS или NTP-серверов, но не используется для конфигурирования адресов интерфейсов или раздачи информации о маршрутах.

В-третьих, IPv6 не использует широковещательные рассылки, а усиленно использует мультикаст-адресацию. Например, в протоколе NDP, чтобы узнать MAC-адреса устройства в сети, запрос отправляется на мультикаст-адрес, сформированный из части IPv6-адреса искомого устройства. Т.к. коммутаторам необходимо помнить, какие из портов относятся к каждому мультикаст-адресу, увеличиваются требования к максимальному объёму таблицы коммутации, но при этом снижается паразитная нагрузка на каналы связи, коммутаторы и конечные узлы, возникавшая из-за необходимости рассылать широковещательные пакеты. В IPv6 отпадает всякий смысл в делении крупных сетей на мелкие широковещательные домены. Остаётся осмысленным только выделение сети по организационным соображениям или из соображений безопасности. Например, можно выделять по отдельной сети для филиалов компании, или по сети для VoIP-шлюзов в филиале, с целью ограничить доступ к сети VoIP-шлюзов на маршрутизаторах, вне зависимости от количества оборудования в этой сети. В одной сети, благодаря использованию мультикаст-рассылок, могут уживаться хоть миллионы устройств - лишь бы коммутаторам хватало объёма таблицы коммутации.

Теперь можно перейти к практике.

Настройка одного интерфейса с "белым" адресом IPv6

Перед тем, как настраивать IPv6, сначала нужно настроить PPPoE-подключение с использованием IPv4. Сделать это можно одной из моих прошлых статей: Настройка PPPoE-подключения к ЭР-Телеком/Дом.ru (Уфанет, Башинформсвязь).

Добавим в файл /etc/ppp/peers/ertelecom одну дополнительную опцию:
+ipv6
Можно попробовать переустановить PPPoE-подключение:
# ifdown ertelecom
# ifup ertelecom
После переустановки подключения на интерфейсе ppp0 можно будет увидеть IPv6-адрес. Посмотрим его при помощи такой команды:
# ip addr show ppp0
Однако, этот IPv6-адрес начинается с префикса fe80::/10, который аналогичен IPv4-адресам из сети 169.254.0.0/16. Это самоконфигурируемые IPv6-адреса, которые действуют только в пределах одного сегмента сети и не маршрутизируются в другие сегменты. В случае с Ethernet-интерфейсами самоконфигурируемый адрес назначается следующим образом:
  1. в качестве префикса выбирается префикс fe80::/10,
  2. в качестве идентификатора интерфейса используется идентификатор EUI-64, полученный из MAC-адреса интерфейса.
Идентификатор EUI-64 получается из MAC-адреса следующим образом:
  1. у первого октета MAC-адреса выставляется в единицу бит 1 (выполняется операция «побитовое или» со значением 0x02),
  2. между первыми и последними тремя октетами вставляется два октета - ff fe.
В случае с PPP-подключениями не существует MAC-адреса, из которого можно было бы сгенерировать младшие 64 бита адреса, поэтому стороны генерируют случайные идентификаторы и согласовывают их друг с другом: соглашаются на предложенные идентификаторы или отказываются, предлагая другие. Именно такие адреса и были настроены на интерфейсе ppp0.

Для получения «белого» префикса потребуется установить и настроить клиент DHCPv6, который запросит через интерфейс ppp0 префикс IPv6 и настроит его на Ethernet-интерфейсе. Я пробовал сначала воспользоваться демоном dhcpcd5, однако он не желал настраивать Ethernet-интерфейсы, для которых в файле /etc/network/interfaces не указан метод настройки dhcp:
Sep 11 22:39:19 stupin systemd[1]: Starting LSB: IPv4 DHCP client with IPv4LL support...
Sep 11 22:39:19 stupin dhcpcd[30762]: Not running dhcpcd because /etc/network/interfaces ... failed!
Sep 11 22:39:19 stupin dhcpcd[30762]: defines some interfaces that will use a DHCP client ... failed!
Sep 11 22:39:19 stupin systemd[1]: Started LSB: IPv4 DHCP client with IPv4LL support.
Я попытался включить настройку интерфейса по DHCPv6, вписав в файл /etc/network/interfaces следующие настройки:
iface eth0 inet6 dhcp
  request_prefix 1
Однако даже с такими настройками dhcpcd5 запускаться отказывался. Поэтому я решил попробовать другой DHCP-клиент, которым оказался клиент из проекта WIDE-DHCPv6.

Установим DHCPv6-клиент:
# apt-get install wide-dhcpv6-client
Пропишем настройки DHCPv6-клиента в файле /etc/wide-dhcpv6/dhcp6c.conf:
interface ppp0 {
  send ia-pd 0;
};

id-assoc pd 0 {
  prefix-interface eth0 {
    sla-len 0;
    ifid 1;
  };
};
Пропишем в файле /etc/default/wide-dhcpv6-client список интерфейсов, через которые DHCPv6-клиент должен запрашивать настройки:
INTERFACES="ppp0"
Включим автозапуск wide-dhcp6-client при загрузке системы и перезапустим его, чтобы новые настройки вступили в силу:
# systemctl enable wide-dhcpv6-client
# systemctl restart wide-dhcpv6-client
Теперь DHCPv6-клиент получает через интерфейс ppp0 префикс вида 2a02:2698:882X:XXXX::/64 и настраивает на интерфейсе eth0 «белый» IPv6-адрес с использованием этого префикса. Что характерно, выдаваемый IPv6-префикс - динамический, т.к. при каждом переподключении выдаётся другой.

В рецепте настройки DHCPv6-клиента написано, что для корректного удаления IPv6-адреса с Ethernet-интерфейса нужно соорудить дополнительные «костыли» в файлах /etc/ppp/ipv6-up.d/20-wide-client-start и /etc/ppp/ipv6-down.d/20-wide-client-stop. Я, однако, «костыли» немного преобразовал, чтобы при отключении PPPoE останавливался только тот экземпляр клиента DHCPv6, который получает настройки через подключение PPPoE.

Также при установке подключения нужно присвоить sysctl-переменной net.ipv6.conf.ppp0.accept_ra значение 2, чтобы система добавляла в таблицу маршрутизации IPv6-маршруты, анонсированные провайдером через интерфейс PPPoE. Присваивать это значение нужно именно через эти скрипты, т.к. интерфейс ppp0 появляется только после установки подключения и по умолчанию значение sysctl-переменной net.ipv6.conf.ppp0.accept_ra равно единице - система принимает анонсы маршрутов, но не добавляет их в таблицу маршрутизации.

В результате мои «костыли» приняли несколько другой вид. Содержимое файла /etc/ppp/ipv6-up.d/route:
#!/bin/sh

case "$PPP_IPPARAM" in
        ertelecom)

        sysctl -w net.ipv6.conf.$PPP_IFACE.accept_ra=2
        dhcp6ctl -C start interface $PPP_IFACE
        ;;

        *)
        echo "No PPP_IPPARAM defined"
        ;;
esac
Содержимое файла /etc/ppp/ipv6-down.d/route:
#!/bin/sh

case "$PPP_IPPARAM" in
        ertelecom)

        dhcp6ctl -C stop interface $PPP_IFACE
        ;;

        *)
        echo "No PPP_IPPARAM defined"
        ;;
esac
На обоих файлах нужно выставить бит исполнимости:
# chmod +x /etc/ppp/ipv6-up.d/route
# chmod +x /etc/ppp/ipv6-down.d/route

Настройка фильтрации пакетов IPv6

Хотя пока мало кто пользуется IPv6, всё же не стоит выставлять свой компьютер в «дикий» интернет, не прикрыв его пакетным фильтром. Базовая настройка пакетного фильтра такова:
# ip6tables -A INPUT -i lo -j ACCEPT
# ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# ip6tables -A INPUT -p icmpv6 -m icmpv6 ! --icmpv6-type redirect -j ACCEPT
# ip6tables -A INPUT -i ppp0 -p udp -m udp -s fe80::/10 --sport 547 --dport 546  -j ACCEPT
# ip6tables -A INPUT DROP
В настроенных выше правилах пакетного фильтра разрешается:
  1. любой трафик через локальный петлевой интерфейсе lo,
  2. любой входящий ICMPv6-трафик, кроме переадресаций,
  3. разрешается принимать настройки по протоколу DHCPv6 через интерфейсе ppp0.
Сохраним настроенные правила фильтрации пакетов IPv6 в файл /etc/network/ip6tables:
# ip6tables-save > /etc/network/ip6tables
И пропишем их автоматическую загрузку в файл /etc/network/interfaces при поднятии локального петлевого интерфейса:
auto lo
iface lo inet loopback
  pre-up iptables-restore < /etc/network/iptables
  pre-up ip6tables-restore < /etc/network/ip6tables

Настройка BIND и openresolv для работы с IPv6

В одной из моих прошлых заметок описана Настройка кэширующего DNS-сервера BIND в связке с openresolv. Т.к. я продолжаю использовать эту связку, мне нужно приспособить её для работы с IPv6.

Первым делом нужно включить обслуживание запросов на IPv6-адресах в bind9. Для этого открываем файл /etc/bind/named.conf.options и вписываем опцию для прослушивания всех IPv6-адресов компьютера:
listen-on-v6 { any; };
Чтобы bind9 отвечал на запросы с IPv6-адреса ::1 - аналога IPv4-адреса 127.0.0.1, нужно добавить этот адрес в список адресов, которые могут выполнять рекурсивные запросы. В моём случае список адресов, которым разрешается выполнять рекурсивные запросы к DNS-серверу, выглядит следующим образом:
allow-recursion { 127.0.0.1; 169.254.253.0/24; 169.254.254.0/24; ::1; };
Осталось перезапустить bind9, чтобы он начал принимать запросы на IPv6-адресах:
# systemctl restart bind9
Теперь нужно настроить openresolv так, чтобы он прописывал в файл /etc/resolv.conf IPv6-адрес DNS-сервера - ::1. Для этого открываем на редактирование файл /etc/resolvconf.conf и приводим опцию name_servers к следующему виду:
name_servers="127.0.0.1 ::1"
Осталось обновить файл /etc/resolv.conf в соответствии с новыми настройками openresolv. Сделать это можно при помощи следующей команды:
# resolvconf -u

Проверка правильности настройки IPv6

Проверим правильность настройки IPv6, открыв веб-страницу для тестирования IPv6 - Проверьте ваше IPv6 подключение. Результат проверки в моём случае выглядел следующим образом:

Ещё один тест IPv6, более подробный и требовательный - IPv6 test - IPv6/4 connectivity and speed test. Результат этой проверки оказался следующим:

К сожалению, настроить PTR-запись для IPv6-адреса может только провайдер, но нельзя настроить PTR-запись для IPv6-адреса, префикс которого провайдер выдаёт каждый раз разный. Я задавал вопрос в техподдержку ЭР-Телекома о том, возможно ли выдавать один и тот же «статический» префикс IPv6 подобно тому, как это организовано в случае «статического» адреса IPv4. Мне ответили, что такой возможности в настоящее время у них нет. Поэтому в этом тесте мне удалось добиться максимально возможного количества баллов - 19 из 20. Для получения 20 баллов уже потребуются телодвижения со стороны провайдера.

Раздача "белых" IPv6-адресов устройствам в локальной сети

Провайдер выдал нам «белый» префикс IPv6 с маской /64, а это значит, что у нас имеется целая сеть, IPv6-адреса из которой мы можем раздавать своим устройствам. Даже самое крупное предприятие с сотнями тысяч компьютеров может уместиться в одной такой сети, выдав каждому сетевому узлу по одному адресу IPv6. Нет никакой необходимости использовать NAT, а задача защиты устройств от «дикого» интернета решается фильтрацией пакетов. У крупных предприятий может возникнуть потребность в получении от провайдера более коротких префиксов лишь при необходимости логически организовать свою сеть: выделить отдельные сети своим подразделениям (например, филиалам в разных городах), а в подразделениях - выделить отдельные подсети для разных целей (например, отдельная сеть для компьютеров сотрудников, отдельная - для голосовых шлюзов и т.д).

Я лично столкнулся с необходимостью иметь хотя бы две сети. Одну из них я хотел бы использовать на Ethernet-интерфейсе, а другую - на WiFi-интерфейсе. Вообще, RFC6177 рекомендует выдавать клиентам префиксы длиной от /48 до /56, но провайдер не следует рекомендациям, жадничает и выдаёт префиксы /64. Сначала я попробовал запросить у провайдера сразу два префикса, изменив файл конфигурации /etc/wide-dhcpv6-client/dhcp6c.conf следующим образом:
interface ppp0 {
  send ia-pd 0;
  send ia-pd 1;
};

id-assoc pd 0 {
  prefix-interface eth0 {
    sla-len 0;
    ifid 1;
  };
};

id-assoc pd 1 {
  prefix-interface wlan0 {
    sla-len 0;
    ifid 1;
  };
};
Но в ответ на такой трюк DHCPv6-сервер провайдера просто перестал отвечать на мои запросы. Пробовал воспользоваться NDP-прокси ndppd - аналогом ARP-прокси для IPv6 и демоном ndprbrd. Вместе они должны были перехватывать NDP-запросы, транслировать их на другой интерфейс, а при получении ответа добавлять маршрут к обнаруженному соседу через конкретный интерфейс. Но по не понятным мне причинам этот вариант тоже не взлетел. Остаётся только ждать и надеяться, что в ЭР-Телекоме когда-нибудь реализуют делегирование префиксов короче /64. Даже /60, позволяющей выделить 16 сетей /64 мне для дома хватило бы с головой.

Поскольку на Ethernet-интерфейсе у меня нет оборудования, имеющего полноценную поддержку IPv6, но есть нотубук с Debian, который может подключаться к WiFi-сети, то я решил повесить эту сеть на интерфейс wlan0.

Т.к. на моём компьютере установлен DNS-сервер, я решил в анонсах RA раздавать его адрес. Правда, поскольку выдаваемый провайдером IPv6-префикс - динамический, придётся воспользоваться локальными самосконфигурированными на интерфейсах IPv6-адресами. Первым делом разрешим DNS-серверу обслуживать запросы на локальных адресах. Для этого откроем в текстовом редакторе файл /etc/bind/named.conf.options и отредактируем список адресов, для которых будут обслуживаться рекурсивные запросы. В этот список я добавил сеть fe08::/10:
allow-recursion { 127.0.0.1; 169.254.253.0/24; 169.254.254.0/24; ::1; fe08::/10; };
Это не очень хорошо, т.к. провайдер тоже сможет через PPPoE-подключение обращаться с рекурсивными запросами к моему DNS-серверу. Педант в моей душе немного негодует, однако сумел договориться с практиком, который не нашёл других выходов из этой ситуации. Сообщим DNS-серверу об изменившихся настройках:
# systemctl reload bind9
Для того, чтобы раздавать IPv6-адреса из выделенной нам сети, установим и настроим демона radvd - Router ADVertisement Daemon - демона объявления маршрутизатора. Установим одноимённый пакет:
# apt-get install radvd
Создадим файл /etc/radvd.conf со следующим содержимым:
interface wlan0
{
  AdvSendAdvert on;
  MaxRtrAdvInterval 60;

  prefix ::/64
  {
    AdvValidLifetime 600;
    AdvPreferredLifetime 120;
  };

  RDNSS fe80::c24a:ff:fe9f:89fc {};
  DNSSL stupin.su {};
};
Включим и запустим демона:
# systemctl enable radvd
# systemctl start radvd
Теперь устройства в локальной сети могут запрашивать префикс у нашего компьютера. Если на компьютере настроена фильтрация пакетов, то для того, чтобы клиенты смогли обращаться к radvd, нужно разрешить входящие UDP-пакеты на порт 58:
# ip6tables -A INPUT -i eth0 -p udp -m udp --dport 58  -j ACCEPT
Если устройства в локальной сети должны иметь доступ к DNS-серверу, то нужна пара правил, полностью аналогичных таковым для IPv4:
# ip6tables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
# ip6tables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
Чтобы разрешить пропускать трафик из локальной сети во внешнюю сеть, нужно при помощи команды sysctl выставить несколько настроек:
# sysctl -w net.ipv6.conf.all.forwarding=1
# sysctl -w net.ipv6.conf.default.forwarding=1
Чтобы эти настройки применялись автоматически при перезагрузке компьютера, нужно вписать их в файл /etc/sysctl.conf:
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
Если на компьютере настроена фильтрация пакетов, можно разрешить движение трафика между локальным и внешним интерфейсами. Например, я разрешил только движение пакетов ICMPv6:
# ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# ip6tables -A FORWARD -p icmpv6 -m icmpv6 ! --icmpv6-type redirect -j ACCEPT
# ip6tables -P FORWARD DROP
Ноутбуку, который будет подключаться к сети, кое-что всё-таки разрешим:
# ip6tables -A FORWARD -i wlan0 -p tcp -m multiport --dports 21,22,25,43,80,110,143,443,587,993,995,5222,5223 -j ACCEPT
После изменения настроек фильтрации пакетов не забудьте записать их:
# ip6tables-save > /etc/network/ip6tables
Теперь настала очередь настройки системы на ноутбуке. Во-первых, поставим rdnssd для получения адресов DNS-серверов:
# apt-get install rdnssd
Включим и запустим его:
# systemctl enable rdnssd
# systemctl start rdnssd
Для правильной работы rndssd понадобится также пакет resolvconf. Если он ещё не установлен в системе, нужно его поставить:
# apt-get install resolvconf
Теперь пропишем в файле /etc/network/interfaces, как нужно настраивать IPv6 на интерфейсе wlan0:
iface wlan0 inet6 auto
  privext 2
Т.к. к префиксу, полученному через RA, добавляется идентификатор интерфейса, полученный из MAC-адреса компьютера, то MAC-адрес служит отличным идентификатором, по которому можно отслеживать интернет-активность конкретного устройства. Этот идентификатор остаётся постоянным даже при смене провайдера. Опция privext включает генерацию случайного идентификатора интерфейса, а также приоритетное использование IPv6-адреса, полученного из этого идентификатора. Таким крупным компаниям как Google это нисколько не помешает отслеживать активность устройства, но и облегчать задачу всем подряд тоже не стоит.

Осталось отключиться от WiFi-сети и снова подключиться к ней и проверить доступность IPv6-ресурсов с ноутбука:
# ifdown wlan0
# ifup wlan0
Заходим на указанные выше ресурсы для тестирования IPv6 и любуемся результатами. В этом случае по второй ссылке удалось набрать лишь 17 баллов, т.к. ICMPv6-запросы были слишком медленными и не успевали отрабатывать за отведённое время.

Использованные материалы

IPv6 от Дом.ru (ЭР-Телеком) на сервере Ubuntu/Debian

воскресенье, 2 сентября 2018 г.

Настройка кэширующего DNS-сервера BIND в связке с openresolv

Обнаружил, что заметка Настройка кэширующего DNS-сервера BIND в связке с resolvconf в новых релизах Debian больше не работает. Вспомнил об аналоге resolvconf под названием openresolv, который я когда-то нашёл, но воспользоваться которым пока не доводилось. Решил попробовать и openresolv заработал как надо. Спешу поделиться рецептом.

Первым делом установим openresolv:
# apt-get install openresolv
Приведём его файл конфигурации /etc/resolvconf.conf к следующему виду:
resolv_conf=/etc/resolv.conf
name_servers=127.0.0.1
named_options=/var/run/named/named.options
Обновим файлы с DNS-серверами при помощи следующей команды:
# resolvconf -u
В файле /var/run/named/named.options можно увидеть фрагмент конфигруации BIND, которую можно подключить к основной конфигурации. В моём случае он выглядит следующим образом:
# Generated by resolvconf
forward first;
forwarders {
 109.195.144.4;
 5.3.3.3;
 81.30.199.5;
 81.30.199.94;
};
Чтобы включить этот фрагмент в конфигурацию BIND, впишем в файл /etc/bind9/named.conf.options одну строчку:
include "/var/run/named/named.options";
Ещё раз обновим файлы с DNS-серверами при помощи команды:
# resolvconf -u
В процессе обновления BIND будет автоматически перезапущен, так что в его файл конфигурации будет вписан актуальный список вышестоящих рекурсивных DNS-серверов.

Список интерфейсов, с которых взяты DNS-серверы, можно узнать при помощи следующей команды:
# resolvconf -i
В моём случае она вывела такой список:
ppp0 vlan3
Список DNS-серверов, полученных через эти интерфейсы, можно узнать при помощи такой команды:
# resolvconf -l
В моём случае вывод был таким:
# resolv.conf from ppp0
# Generated by ppp.ip-up for ppp0
nameserver 109.195.144.4
nameserver 5.3.3.3

# resolv.conf from vlan3
# resolv.conf for vlan3
domain ipoe3.ufanet.ru
nameserver 81.30.199.5
nameserver 81.30.199.94

воскресенье, 26 августа 2018 г.

Настройка PPPoE-подключения к ЭР-Телеком/Дом.ru (Уфанет, Башинформсвязь)

Заметка простая, но решил выложить, т.к. думаю, что многим может пригодиться. В прошлом я уже использовал подобную конфигурацию для настройки подключений к провайдерам Уфанет и Башинформсвязь (см. примечания в конце заметки), однако описать настройку тогда не удосужился.

Установим пакет RP-PPPoE, при помощи которого можно устанавливать подключения:
# apt-get install pppoe
Создадим файл /etc/ppp/peers/ertelecom и впишем в него настройки подключения:
user "login"
plugin rp-pppoe.so
eth0
noipdefault
usepeerdns
defaultroute
persist
noauth
maxfail 0
unit 0
Где:
  • login - ваш логин по договору,
  • eth0 - имя Ethernet-интерфейса, к которому подключен кабель провайдера.
Теперь откроем файл /etc/ppp/chap-secrets и впишем в него логин и пароль для подключения.
# Secrets for authentication using CHAP
# client server secret   IP addresses
login         *       password                *
Первые две строчки - это комментарии, которые уже есть в файле. В третьей строчке указаны учётные данные для подключения: login - логин, password - пароль.

Осталось вписать настройки в файл /etc/network/interfaces, чтобы связь с провайдером устанавливалась при загрузке компьютера:
# ertelecom ethernet
auto eth0
iface eth0 inet manual

# ertelecom pppoe
auto ertelecom
iface ertelecom inet ppp
  provider ertelecom
Установить подключение или разорвать его из командной строки можно такими командами:
# ifup ertelecom
# ifdown ertelecom

Настройка подключения к Уфанет по технологии PPPoE была полностью аналогична рассмотренной выше, однако в последнее время Уфанет переводит всех клиентов на технологию IPoE. При этом абонент просто получает настройки Ethernet-интерфейса по протоколу DHCP, а попытка открыть любую веб-страницу в браузере приведёт к попаданию на страницу авторизации. После того, как абонент введёт на странице авторизации свои учётные данные, доступ в интернет открывается. Повторно авторизация запрашивается при смене MAC-адреса компьютера.

Настройка подключения к Башинформсвязи аналогична рассмотренной выше за исключением того, что в Башинформсвязи используется аутентификация по протоколу PAP, а не CHAP, из-за чего логин и пароль нужно вписывать в файл /etc/ppp/pap-secrets, а не в файл /etc/ppp/chap-secrets, как это описано выше.

воскресенье, 7 июня 2009 г.

Настройка PPPoE-релея в Debian

Хочется наконец закрыть тему с настройкой RP-PPPoE и описать описать настройку PPPoE-релея. Одной из нерассмотренных плюшек останется настройка PPPoE-сервера в связке с RADIUS-сервером, но это уже не относится напрямую к пакету RP-PPPoE, а скорее относится именно к RADIUS-серверу.

Напоминаю, что PPPoE-релей является своего рода шлюзом между PPPoE-сервером и PPPoE-клиентом, находящихся в разных Ethernet-сетях. PPPoE-релей устанавливается на компьютер, подключенный к обеим Ethernet-сетям. Для Ethernet-сети с клиентами он выглядит как сервер, а для Ethernet-сети с серверами выглядит как клиент.

И так, одной из проблем, которая мне мешала попытаться настроить PPPoE-релей было отсутствие третьего компьютера. Эту проблему я тогда наметил обойти с помощью эмуляции необходимого количества компьютеров с помощью какой-нибудь виртуальной машины. В одной из прошлых заметок я остановился на эмуляторе QEmu.

Для начала настроим PPPoE-сервер в соответствии с прошлыми статьями: Настройка PPPoE-сервера в Debian и deb-пакет и сценарии для запуска PPPoE сервера.

С настройкой PPPoE-клиента на этот раз я решил соригинальничать. У меня есть готовый образ диска QEmu, с установленной на него NetBSD 5.0. В NetBSD имеется PPPoE-клиент, работающий на уровне ядра. Его и настроим. В файл /etc/ifconfig.pppoe0 пропишем следующее:
create
!/sbin/ifconfig ne2 up
!/sbin/pppoectl -e ne2 $int
!/sbin/pppoectl $int myauthproto=chap 'myauthname=test' 'myauthsecret=testpasswd' hisauthproto=none max-auth-failure=1
0.0.0.0 0.0.0.1 up
Более подробно настройка QEmu и сети в QEmu описаны в двух моих статьях: Эмуляторы VirtualBox и QEmu в Debian и QEmu и настройка сети. О начальной настройке NetBSD можно почитать вот тут: Раскручиваем свежеустановленную NetBSD

Теперь нужно заняться настройкой PPPoE-релея. Во-первых, создадим на компьютере, выполняющем роль релея, tap-интерфейс, который будет использоваться для связи с виртуальной машиной-клиентом в QEmu. Для этого в файл /etc/network/interfaces добавляем следующие строчки:
auto tap1
iface tap1 inet manual
  up ifconfig tap1 up
  down ifconfig tap1 down
  tunctl_user stupin
Где stupin - это тот пользователь, под которым вы работаете и от имени которого запускаете QEmu.

Теперь, устанавливаем пакет pppoe_3.8-3_i386.deb, сборка которого рассмотрена мной в статье deb-пакет и сценарии для запуска PPPoE сервера:
# wget http://stupin.su/files/pppoe_3.8-3_i386.deb
# dpkg -i pppoe_3.8-3_i386.deb
И зафиксируем установленный пакет, чтобы он не был замещён версией из репозитория при следующем обновлении:
# aptitude hold pppoe
Создадим сценарий для запуска PPPoE-релея, создав файл /etc/init.d/pppoe-relay:
#!/bin/sh

### BEGIN INIT INFO
# Provides:          pppoe-relay
# Required-Start:    $network $syslog
# Required-Stop:     $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Roaring Peguin PPPoE relay
# Description:       Roaring Peguin PPPoE relay
### END INIT INFO

CONFIG=/etc/default/pppoe-relay

if test -f $CONFIG
then
  . $CONFIG
else
  echo "PPPoE relay: No config-file!"
fi

if test x$RUN = xno
then
  echo "PPPoE relay: disabled."
  exit
fi

if test x"$OPTIONS" = x
then
  echo "PPPoE relay: no options defined!"
  exit
fi

if test x$PIDFILE = x
then
  PIDFILE=/var/run/pppoe-relay.pid
fi

case $1 in
  start)
    echo -n "Starting PPPoE relay: "
    /usr/sbin/pppoe-relay -F $OPTIONS &
    echo $! > $PIDFILE
    echo "pppoe-relay."
    ;;
  stop)
    echo -n "Stopping PPPoE relay: "
    kill `cat $PIDFILE`
    rm $PIDFILE
    echo "pppoe-relay."
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "Usage: $0 start|stop|restart"
    ;;
esac
Сделаем его исполняемым:
# chmod +x /etc/init.d/pppoe-relay
И добавим на уровни запуска по умолчанию:
# update-rc.d pppoe-relay defaults
Теперь создадим файл настроек PPPoE-релея /etc/default/pppoe-relay:
# Run pppoe-relay at startup
RUN="yes"

# Options, that provided to pppoe-relay
OPTIONS="-S br0 -C tap1"

# File with PID of pppoe-relay
PIDFILE="/var/run/pppoe-relay.pid"
Как видно из файла настроек, сеть с PPPoE-сервером подключена к интерфейсу br0, а сеть с PPPoE-клиентом - к интерфейсу tap1.

Запускаем pppoe-relay:
# invoke-rc.d pppoe-relay start
Или по-старинке:
# /etc/init.d/pppoe-relay start
Теперь пришло время запустить настроенную QEmu. Запускать её нужно с помощью следующей командной строки (она у меня прописана в сценарии netbsd.sh):
$ qemu -M pc -m 128 -no-kqemu -no-acpi -hda /home/stupin/netbsd-disk.bin -net nic,vlan=0 -net tap,vlan=0,ifname=tap1 -boot c
Смотрим на клиенте (в NetBSD под QEmu) список интерфейсов:
$ ifconfig -a
Если в списке появился интерфейс pppoe0 с адресами 192.168.0.2 и 192.168.0.1, значит PPPoE-подключение установлено. Если не появился - пробуем перезапустить сетевую подсистему:
# /etc/rc.d/network restart
На сервере проверить установку связи можно по появившемуся интерфейсу с именем ppp0 (или ppp1 или ppp2) с адресами 192.168.0.1 и 192.168.0.2.

Для более-менее окончательного завершения разбора RP-PPPoE в Debain осталось:
  1. переписать сценарии запуска на использование start-stop-daemon,
  2. добавить в deb-пакет сценарии pppoe-server и pppoe-relay,
  3. добавить в deb-пакет post-install-сценарии вызывающие update-rc.d для добавления в систему сценариев pppoe-server и pppoe-relay,
  4. добавить в deb-пакет файлы настроек pppoe-server, pppoe-relay, pppoe-server-options,
  5. отправить мэнтейнеру пакета pppoe все эти скрипты и файлы настроек,
  6. написать на основе этой и предыдущих статей подробное руководство по настройке PPPoE-клиента, сервера и релея.

понедельник, 23 февраля 2009 г.

deb-пакет и сценарии для запуска PPPoE сервера

На всякий случай решил разместить собранный мною в предыдущей статье deb-пакет pppoe_3.8-3_i386.deb. Если кому понадобится, но лень собирать - можете взять готовый пакет по этой ссылке, он собран с pppoe-server, поддерживающим работу в режиме ядра.

Теперь продолжим настройку pppoe-server. Для запуска и остановки pppoe-server я набросал следующий сценарий /etc/init.d/pppoe-server:
#!/bin/sh

### BEGIN INIT INFO
# Provides:          pppoe-server
# Required-Start:    $network $syslog
# Required-Stop:     $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Roaring Peguin PPPoE server
# Description:       Roaring Peguin PPPoE server
### END INIT INFO

CONFIG=/etc/default/pppoe-server

if test -f $CONFIG
then
  . $CONFIG
else
  echo "PPPoE server: No config-file!"
fi

if test x$RUN = xno
then
  echo "PPPoE Server: disabled."
  exit
fi

if test x"$OPTIONS" = x
then
  echo "PPPoE server: no options defined!"
  exit
fi

if test x$PIDFILE = x
then
  PIDFILE=/var/run/pppoe-server.pid
fi

case $1 in
  start)
    echo -n "Starting PPPoE server: "
    /usr/sbin/pppoe-server -F $OPTIONS &
    echo $! > $PIDFILE
    echo "pppoe-server."
    ;;
  stop)
    echo -n "Stopping PPPoE server: "
    kill `cat $PIDFILE`
    rm $PIDFILE
    echo "pppoe-server."
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "Usage: $0 start|stop|restart"
  ;;
esac
Сразу же сделаем его исполняемым:
# chmod +x /etc/init.d/pppoe-server
Можно также сразу прописать ссылки на его запуск и остановку в каталоги rcX.d:
# update-rc.d pppoe-server defaults
Теперь займёмся настройкой сервера. Тут всё просто - все настройки сервера хранятся в файле /etc/default/pppoe-server. Настройки являются обычными переменными оболочки и их всего три:
# Run pppoe-server at startup
RUN="yes"

# Options, that provided to pppoe-server
OPTIONS="-k -I eth1 -L 192.168.0.1"

# File with PID of pppoe-server
PIDFILE="/var/run/pppoe-server.pid"
Переменная RUN задаёт, нужно ли запускать PPPoE сервер при загрузке системы (no - не запускать, yes или любое другое значение означает запускать).

Переменная OPTIONS задаёт опции, которые будут переданы напрямую в pppoe-server. Все настройки указанные в этой переменной были взяты из моей предыдущей статьи.

Переменная PIDFILE задаёт расположение файла, в котором хранится идентификатор работающего процесса pppoe-server. Если эта переменная не задана, по умолчанию будет использоваться файл /var/run/pppoe-server.pid.

На этом пока всё. Следующая цель - настройка pppoe-relay, хотя мне не на чем его тестировать: нужно три компьютера и две изолированные Ethernet-сети, подключенные к компьютеру, на которм будет запускаться pppoe-relay.

Ссылки:
How to LSBize an Init Script - как составить мета-теги в сценарии инициализации

Последнее редактирование: 10 мая 2009 года.

воскресенье, 22 февраля 2009 г.

Настройка PPPoE-сервера в Debian

Продолжаю тему пакета RP-PPPoE. На этот раз я решил настроить PPPoE-сервер из этого пакета. PPPoE-сервер, как и клиент, может работать в двух режимах: в режиме ядра и в пространстве пользователя.

Но прежде чем перейти к описанию настройки сервера, опишу настройки клиента. И клиент и сервер находятся в пакете pppoe Debian. Таким образом установка сервера и клиента весьма просты:
# aptitude install pppoe
1. Настройка тестового PPPoE-клиента

Клиент настраивался в режиме ядра, маршрут по-умолчанию не устанавливался, номер создаваемого интерфейса был прописан постоянным - 2.

Ниже - содержимое файла /etc/ppp/peers/dsl-provider, содержащий настройки тестового клиента:
user test
plugin rp-pppoe.so
eth1
noipdefault
usepeerdns
persist
noauth
#defaultroute
unit 2
Для пользователя test в файл /etc/ppp/chap-secrets добавим такую строчку:
test            *               testpasswd      *
На этом настройка клиента закончена. После того, как будет настроен сервер, мы установим подключение при помощи команды:
# pon dsl-provider
2. Настройка PPPoE-сервера в пространстве пользователя

Тут особых сложностей тоже не возникло. В файле /etc/ppp/pppoe-server-options были прописаны следующие опции:
auth
require-chap
ms-dns 81.30.199.5
ms-dns 81.30.199.94
noipdefault
noipx
nodefaultroute
noproxyarp
netmask 255.255.255.255
logfile /var/log/pppoe-server.log
Опция auth заставляет потребовать у удалённого клиента аутентификации, опция require-chap указывает способ аутентификации CHAP.

Опции ms-dns передают клиенту IP-адреса DNS-серверов, которые клиент воспринимает если в его настройках указазана опция usepeerdns.

Опция noipdefault не позвояет соглашаться с настройками IP-адресов, полученных от клиента, noipx отключает согласование протокола IPX, nodefaultroute запрещает добавлять маршрут по умолчанию через клиента, noproxyarp запрещает серверу создавать для клиентов ARP-записи на Ethernet-интерфейсах (эта опция нужна только если клиентам выдаются IP-адреса, пересекающиеся с IP-адресами Ethernet-сети, чтобы PPPoE-клиенты и компьютеры в локальной сети могли беспрепятственно обмениваться трафиком).

Опция "netmask 255.255.255.255" задаёт маску PPP-соединения у клиента и сервера, опция "
logfile /var/log/pppoe-server.log" предписывает вести серверу журнал. Пользы от этого журнала не очень много, т.к. в нём нет отметок времени.

По-умолчанию сервер передаёт в pppd также ещё и следующие опции: nodetach, noaccomp, nobsdcomp, nodeflate, nopcomp, novj, novjccomp, default-asyncmap.

Все опции по-умолчанию имеют приоритет над опциями из файла /etc/ppp/pppoe-server-options. Все опции, кроме первой и последней, отключают различные виды сжатия. Первая и последняя опции, на мой взгляд, спорные. Первая указывает pppd не отделяться от управляющего терминала. Какой может быть управляющий терминал, если pppd запущен из демона, то есть из программы, которая сама не имеет управляющего терминала? Последняя опция предписывает pppd не согласовывать параметр asyncmap и принудительно экранировать все управляющие символы, что не имеет особого смысла, поскольку Ethernet-среда ни коим образом не интерпретирует управляющие символы. Возможно эта опция предназначена для DSL-линии. Она, будучи последовательной линией, может использовать асинхронный режим приёма/передачи, в котором приёмник сообщает передатчику о готовности или неготовности к приёму информации с помощью специальных символов XON или XOFF.

Заведём тестового пользователя в файле /etc/ppp/chap-secrets на PPPoE-сервере, добавив строчку:
test            *               testpasswd              192.168.0.2
Последнее поле сообщает IP-адрес, который будет назначен этому клиенту в случае успешной аутентификации.

Теперь запустим сервер. У сервера есть несколько важных опций:
-I - задаёт имя интерфейса, на котором сервер будет ожидать соединений,
-L - задаёт собственный IP-адрес сервера внутри канала PPP,
-p - позволяет задать файл, содержащий список IP-адресов, выдаваемых клиентам внутри канала PPP,
-O - позволяет задать другой файл вместо используемого по умолчанию /etc/ppp/pppoe-server-options,
-N - позволяет указать максимальное количество одновременных соединений, по умолчанию 64.
Я запустил так:
# pppoe-server -I eth1 -L 192.168.0.1
Сервер запускается и переходит в фоновый режим. После этого запускаем на другом компьютере PPPoE-клиента:
# pon dsl-provider
Связь успешно установилась и на клиенте был создан интерфейс ppp2 с IP-адресами 192.168.0.2 и 192.168.0.1, на на сервере был создан интерфейс ppp0 с IP-адресами 192.168.0.1 и 192.168.0.2.
Теперь можно проверить работу связи. Для этого я на клиенте запустил команду:
$ ping -S 192.168.0.2 192.168.0.1
А на сервере запустил команду:
# tcpdump -i ppp0
Можно было увидеть, что клиент получает от сервера отклики на эхо-запросы, а сервер принимает и отправляет ICMP-сообщения "echo request" и "echo reply".

3. Настройка PPPoE-сервера в режиме ядра

Здесь, казалось бы, всё просто: добавляем серверу опцию -k и вперёд, но оказалось всё не так просто. В Debian pppoe-server собран без поддержки режима ядра и наотрез отказывается принимать опцию -k. Я решил собрать pppoe самостоятельно из deb-src. Направление для мыслей задал вот этот багрепорт: #298185 - pppoe-server: invalid option -- k - Debian Bug report logs. После долгого процесса копания по опциям получилось такое mini-how-to:

Устанавливаем зависимости для построения pppoe:
# apt-get build-dep pppoe
Скачиваем и распаковываем в текущий каталог исходники:
# apt-get source pppoe
Переходим в каталог rp-pppoe-3.8/src и выполняем конфигурирование:
# cd rp-pppoe-3.8/src
# ./configure
Теперь в только что созданном файле config.h нужно заменить строчку
/* #undef HAVE_LINUX_KERNEL_PPPOE */
на строчку
#define HAVE_LINUX_KERNEL_PPPOE 1
Теперь выходим из каталога src и выполняем сборку, указав путь к плагину rp-pppoe.so, который как раз и реализует поддержку PPPoE-сеансов на уровне ядра:
# cd ..
# ./debian/rules PLUGIN_PATH=/usr/lib/pppd/2.4.4/rp-pppoe.so
Собираем пакет и устанавливаем его:
# ./debian/rules binary
# cd ..
# dpkg -i pppoe_3.8-3_i386.deb
Заморозим пакет в системе, чтобы предотвратить его автоматическое обновление:
# echo pppoe hold | dpkg --set-selections
С этого момента нужно как минимум при каждом обновлении системы просматривать список обновлений. Если для pppoe будет выпущено обновление, закрывающее уязвимость, необходимо будет собрать пакет из свежих исходников заново, снять фиксацию пакета в системе с помощью команды:
# echo pppoe install | dpkg --set-selections
Затем заменить пакет новым и заново зафиксировать. Всё это - неизбежная плата за использование самосборного пакета. Конечно можно автоматизировать пересборку пакета, написав shell-скрипт, запускающий в нужной последовательности все указанные команды и заменяющий нужную строчку с помощью sed.

Так или иначе, теперь в системе установлен пакет с PPPoE-сервером, позволяющим поддерживать PPPoE-соединения на уровне ядра. Для запуска сервера в этом режиме, к команде описанной в предыдущем разделе нужно добавить опцию -k:
# pppoe-server -I eth1 -L 192.168.0.1 -k
Можно проверить связь так же, как это было описано выше, у меня всё заработало.

Осталось написать стартовые скрипты для запуска PPPoE-сервера и добавить их в систему.

среда, 11 февраля 2009 г.

Пакет RP-PPPoE

Решил объединить три своих заметки о пакете RP-PPPoE.

1. О пакете

RP-PPPoE (Roaring Peguin PPP over Ethernet) - это пакет программ, предназначенных для работы с PPPoE-соединениями. В пакет входят клиент, сервер, релей, различные служебные утилиты и сценарии, модуль для PPP-демона, обеспечивающий поддержку соединений PPPoE в режиме ядра Linux.

Пакет написан Дэвидом Сколлом, домашняя страница проекта находится по адресу http://www.roaringpenguin.com/pppoe/.

Клиента можно использовать для подключения к сети DSL-провайдера или Ethernet-провайдера, раздающего доступ к интернет через PPPoE-соединения. Сервер и агент ретрансляции можно использовать для построения серверов доступа небольших Ethernet-провайдеров.

2. Переводы man-страниц

2.1. man pppoe(8) - PPPoE-клиент пространства пользователя
2.2. man pppoe-server(8) - PPPoE-сервер пространства пользователя
2.3. man pppoe-relay(8) - PPPoE-агент ретрансляции пространства пользователя
2.4. man pppoe-sniff(8) - поиск в сети нестандартных кадров PPPoE
2.5. man pppoe-connect(8) - сценарий для управления каналом PPPoE
2.6. man pppoe-start(8) - сценарий для установки канала PPPoE
2.7. man pppoe-stop(8) - сценарий для закрытия канала PPPoE
2.8. man pppoe-setup(8) - сценарий для настройки PPPoE-клиента Roaring Penguin
2.9. man pppoe-status(8) - сценарий просмотра состояния канала PPPoE
2.10. man pppoe.conf(5) - файл конфигурации, используемый pppoe-start(8), pppoe-stop(8), pppoe-status(8) и pppoe-connect(8)
2.11. man pppoe-wrapper(1) − SUID-посредник для включения и отключения PPPoE-соединений

Переводы страниц руководства выполнены на сайте коллективных переводов http://translated.by. Несмотря на то, что это сайт коллективных переводов, в переводе мне никто не помогал, поэтому все переводы были выполнены мной.

Результаты перевода размещены на сайте http://manpages.ylsoftware.com/. Автор сайта http://ylsoftware.com/ Вадим Калинников aka MooSE любезно предложил место для размещения моих переводов man-страниц.

Несмотря на то, что в названии страниц 2.1-2.3 написано, что программы работают в пространстве пользователя, из самой документации чётко видно, что каждая программа может работать в связке с модулем ядра Linux.

На некоторых системах можно встретить сценарии 2.5-9 под именами, в которых pppoe заменено на adsl: adsl-connect, adsl-start, adsl-stop, adsl-setup и adsl-status. По содержанию это абсолютно те же самые сценарии.

Использования сценариев и конфигурационного файла, описанных в пунктах 2.5-2.11, на мой взгляд, следует избегать. В большинстве систем обычно имеются собственные сценарии настройки соединений точка-точка.

В частности, в Debian PPPoE-соединения нужно настраивать точно так же, как и любые другие PPP-соединения, создав соответствующий файл в каталоге /etc/ppp/peers. В этом файле нужно указать все необходимые опции демона pppd. Управлять соединениями можно с помощью сценариев pon и poff. Подробнее настройки рассмотрены ниже.

3. Модуль rp-pppoe.so

Перед тем, как приступить к описанию настройки, я хочу рассказать о модуле rp-pppoe.so демона pppd. Этот модуль работает в связке с модулем ядра Linux для поддержки PPPoE-соединений.

Так как при обработке пакетов PPPoE программой, работающей в пространстве пользователя, происходит постоянное переключение из режима ядра в режим пользователя и обратно, довольно большая часть процессорного времени уходит собственно на переключения: на сохранение и восстановление контекста ядра и контеста задачи.

При обработке PPPoE-пакетов драйвером ядра переключений контекста не происходит. Это позволяет добиться высокой производительности PPPoE-содеинений и сильно снизить нагрузку на центральный процессор.

Модуль rp-pppoe.so входит в состав пакета pppd, однако документацию на него мне найти не удалось. Поэтому я решил заглянуть в webgit и посмотреть исходники плагина. На странице по ссылке http://git.ozlabs.org/?p=ppp.git;a=blob;f=pppd/plugins/rp-pppoe/plugin.c;h=e94494b96cc08587e05def9f7f1ec5023dc8bd9a;hb=HEAD я нашёл следующие опции:

3.1. device name - PPPoE device name

Первая опция не имеет названия. Её значение должно быть указано сразу после строчки подключения плагина. В ней передаётся имя Ethernet-интерфейса, подключенного к ADSL-модему.

Эта опция соответствует опции -I pppoe-клиента, работающего в пространстве пользователя.

3.2. rp_pppoe_service - Desired PPPoE service name

Желаемое имя службы PPPoE.

Соответствует опции -S pppoe.

3.3. rp_pppoe_ac - Desired PPPoE access concentrator name

Желаемое имя концентратора доступа PPPoE.

Соответствует опции -C pppoe.

3.4. rp_pppoe_sess - Attach to existing session (sessid:macaddr)

Подключиться к существующему сеансу идентификатор_сеанса:mac_адрес.

Соответствует опции -e pppoe.

3.5. rp_pppoe_verbose - Be verbose about discovered access concentrators

Сообщать об обнаруженных концентраторах доступа.

Соответствует опции -A pppoe, однако не предназначена для интерактивного использования, т.к. информация будет оправляться в журнал, а не на стандартный вывод.

3.6. pppoe-mac - Only connect to specified MAC address

Подключаться только к указанному MAC-адресу.

У этой опции нет аналогов в pppoe.

4. Настройка PPPoE-интерфейсов в Debian

Произведём настройку интерфейсов. В файл /etc/network/interfaces впишем следующие строки:
auto eth0
iface eth0 inet manual

auto dsl-provider
iface dsl-provider inet ppp
  pre-up /sbin/ifconfig eth0 up
  provider dsl-provider
eth0 - Ethernet-интерфейс, к которому подключен кабель от провайдера.
dsl-provider - имя файла в каталоге /etc/ppp/peers/ с настройками подключения к провайдеру.

Эти настройки заставят систему пытаться установить PPPoE-соединение сразу после загрузки компьютера. Чтобы соединение было успешно установлено, нужно прописать настройки в файле /etc/ppp/peers/dsl-provider. Настроить PPPoE-соединение можно одним из двух способов: с использованием описанного выше модуля rp-pppoe.so, работающего совместно с PPPoE-модулем ядра или используя pppoe-клиент, работающий в пространстве пользователя.

5. Настройка подключения с использованием модуля rp-pppoe.so

Сначала нужно убедиться, что ваше ядро имеет поддержку модуля PPPoE. Попробуем загрузить PPPoE-модуль ядра вручную:
# modprobe -q pppoe
Теперь посмотрим, существует ли файл /proc/net/pppoe. Если модуль был вкомпилирован в ядро статически или модуль успешно загрузился, то этот файл должен появиться. Если нет - нужно разбираться с конфигурацией вашего ядра. Не будем отвлекаться на это, поскольку подавляющее большинство современных дистрибутивов Linux позволяет загрузить этот модуль приведённой выше командой.

Теперь займёмся настройкой подключения. Для этого в файле /etc/ppp/peers/dsl-provider пропишем настройки подключения:
# Здесь указываем имя пользователя, с которым pppd будет подключаться к dsl-провайдеру.
# Пароль для соединения будет взят из файла /etc/ppp/pap-secrets или /etc/ppp/chap-secrets
user "ваш_логин"

# Указываем загрузить модуль
plugin rp-pppoe.so

# Указываем интерфейс, к которому подключен модем
eth0

# Говорим, что провайдер выдаёт IP-адрес динамически
noipdefault

# Пытаемся получить IP-адреса DNS-серверов провайдера
usepeerdns

# Использовать это соединение как маршрут по умолчанию
defaultroute

# Заставить pppd переподключаться при обрыве соединения
persist

# Не запрашивать пароль у удалённого партнёра
noauth

Далее в файле /etc/ppp/pap-secrets или /etc/ppp/chap-secrets нужно указать имя и пароль для подключения:
ваш_логин * ваш_пароль *
Имя используемого файла зависит от метода аутентификации, затребованного PPPoE-сервером, но в большинстве случаев это будет файл chap-secrets.

Теперь можно воспользоваться обычными для Debian командами pon для установки подключения и poff для закрытия подключения:
# pon dsl-provider
# poff dsl-provider
6. Настройка подключения с использованием pppoe-клиента, работающего в пространстве пользователя

Файл /etc/ppp/peers/dsl-provider в этом случае практически идентичен предыдущему, за исключением того, что теперь вместо опции plugin используется опция pty, запускающая программу-посредник pppoe:
user ваш_логин
pty "pppoe -I eth0 -T 80 -m 1452"
noipdefault
usepeerdns
defaultroute
persist
noauth
Как и в предыдущем случае, для установки и закрытия подключения можно воспользоваться командами pon и poff:
# pon dsl-provider
# poff dsl-provider
За кадром остались настройка PPPoE-сервера и релея. Возможно я когда-нибудь за них возьмусь и дополню статью соответствующими разделами.

Ссылки на использованные для подготовки статьи материалы:
  1. Домашняя страница RP-PPPoE
  2. Сайт коллективных переводов
  3. Страницы руководства Debian
  4. Мой проект перевода страниц руководства
  5. Web-интерфейс Git-репозитория программы pppd
  6. Настройка PPPoE-соединений в Debian
  7. Настройка pppoe в Debian GNU/Linux на примере провайдера TeNeT

вторник, 1 июля 2008 г.

Настройка ADSL-моста, PPPoE во FreeBSD, два провайдера

Сегодня я долго и со смаком занимался любовью с ADSL-модемом ZyXEL Prestige 660.

У нашей компании имеется собственный VPN-сервер (PPTP), к которому подсоединяются через Интернет наши сотрудники в других городах для получения доступа к корпоративной сети. Причём VPN-сервер подключен к Ethernet-провайдеру, а большинство сотрудников ходят через ADSL-провайдера.

Недавно мы узнали, что у ADSL-провайдера внутренний трафик бесплатный и не имеет ограничения по скорости. Поскольку платить за каждый мегабайт Интернет-трафика сразу двум провайдерам довольно дорого, то имеет смысл разместить VPN-сервер в сети ADSL-провайдера.

Конечно качество ADSL-связи не сравнится с качеством Ethernet. ADSL имеет максимальную входящую скорость 8Mbit/s, а исходящую - максимум 1Mbit/s. Таким образом два модема на разных концах соединения ограничивают и входящую и исходящую скорость соединения до 1Mbit/s в каждую сторону.

Подключение к ADSL-провайдеру у нас уже имелось, но до этого модем использовался только в режиме роутера. При этом любой компьютер, выходящий в Интернет через такой модем, автоматически оказывается за NAT'ом. Естественно за NAT'ом бесполезно запускать какой-либо сервер, к нему никто не сможет подключиться. Да, конечно, у многих модемов есть функция проброса TCP-соединений вовнутрь, которая во многих случаях может выручить. Но у VPN-сервера кроме управляющего TCP-соединения на 1723 порту есть ещё двунаправленный поток GRE-пакетов, которые несут полезную нагрузку в виде PPP-пакетов. В этом случае простым пробросом TCP-портов уже не обойтись, поэтому ADSL-модем нужно было перенастроить в режим моста.

В режиме моста модем выполняет разбивку и упаковку кадров Ethernet, поступивших на его Ethernet-порт, внутрь ячеек ATM. Ячейки ATM передаются в направлении провайдера, где и обрабатываются. Для ячеек ATM, приходящих от провайдера, модем выполняет обратные действия: извлекает и собирает частей кадр Ethernet, который отправляет через свой Ethernet-порт.

Но это ещё не всё! Быть может вы подумали, что достаточно на сетевой карте компьютера настроить IP-адрес, маску, шлюз, прописать DNS, как сразу же всё заработает? Нет, компьютер должен установить с провайдером соединение PPPoE, то есть PPP over Ethernet.

Вот именно с этим пунктом у меня и возникли трудности, ни с сервера FreeBSD ни с компьютера Windows соединение установить не удавалось. Я перерыл все настройки модема, перерыл по-интернета, перечитал различные варианты настройки PPPoE-клиента. Перечитал кучу инструкций по настройке различных ADSL-модемов в режиме моста, пробовал поменять модем. Ничего не помогало.

Огромное спасибо одному из специалистов ADSL-провайдера, который действительно вник в суть проблемы, а не предложил в очередной раз сбросить модем на заводские настройки и перепроверить VPI/VCI. В течение около пяти-восьми минут с моих слов он понял, что модем не хочет работать в режиме моста и попросил прверить настройки инкапсуляции. В настройках инкапсуляции должен был значиться RFC1483, у меня же стоял PPPoE.

Я как чайник в технологиях телефонии и как человек, до этого никогда не настраивавший ADSL-модем в режиме моста, совершенно спокойно игнорировал этот пункт. Как только я его поменял, соединение сразу же установилось. Так же легко установилось заранее настроенное соединение на FreeBSD.

От себя добавлю следующее. Чтобы легко и без глюков можно было пользоваться обоими провайдерами, нужно в фаерволл ipfw прописать правила PBR (Policy Based Routing):
ipfw add fwd Gateway1 ip from IP1 to any
ipfw add fwd Gateway2 ip from IP2 to any
Чтобы не получилось так, что в сеть одного из провайдеров уходили пакеты с IP-адресом другого.

Если же машинка выполняет функции NAT-шлюза, то на каждом внешнем интерфейсе нужно запустить по одному экземпляру natd. Кошерно это делается через rc.conf так:
natd_program="/sbin/natd"
natd_enable="YES"
natd_interface="rl0"
natd_flags="-s -f /etc/natd.conf"

ppp_enable="YES"
ppp_mode="ddial"
ppp_nat="YES"
ppp_profile="provider"
Только одно соединение должно устанавливать маршрут по умолчанию. Поэтому через второго провайдера можно назначить специальные маршруты, которые будут указывать на подсети этого провайдера. Выяснить подсети, принадлежащие провайдеру, можно покопавшись на его официальном сайте либо через whois.

Приведу несколько полезных, на мой взгляд, ссылок.
  1. Страница хэндбука FreeBSD, посвященная настройкам PPPoE:
    Использование PPP через Ethernet (PPPoE)
  2. Довольно доходчивое описание протокола PPPoE, позволяющее как минимум понять общие принципы его работы:
    Метод передачи РРР через Ethernet (PPPoE)
  3. Продвинутая настройка PPPoE на FreeBSD:
    Настройка PPPoE на FreeBSD (нужна регистрация на сайте)
  4. Статья в журнале "Системный администратор" об использовании двух каналов:
    Два канала – роскошь? Резервирование и балансировка трафика во FreeBSD