Перейти до

Рекомендованные сообщения

Опубликовано: (відредаговано)

Плагин авторизации для Stargazer, который работает напрямую с pppd


Общая информация

Страница проекта (NEW!): http://lion-simba.github.io/purestg2
Последняя версия (NEW!): 2.4 (04.04.2015)
Исходный код: https://github.com/lion-simba/purestg2
Лицензия: GPL

Предложения и пожелания принимаются.

 

Возможности

- простота конфигурации.
- возможность задавать минимальный номер ppp-интерфейса. Это удобно, когда на сервере висит несколько upstream-подключений к провайдеру на ppp0-pppX, и чтобы отличать подключения юзверей от upstream-подключений, им удобно выдавать интерфейсы начиная с pppY, где Y > X.
- возможность присваивать IP-адрес клиента прямо из Старгейзера.
- возможность сохранения номера ppp-интерфейса в любое поле userdata при подключении.
- возможность сохранения параметров ipparam и callingnumber из pppd в любое поле userdata.
- возможность проводить дополнительную аутентификацию пользователя по наличию ipparam и callingnumber из pppd в списке в указанном поле userdata.
- возможность автоматически отключать предыдущую сессию пользователя при открытии новой. Удобно, если у клиента есть несколько разных компьютеров, с которых он может подключаться, и он забыл закрыть сессию на одном из них.
- корректное закрытие ppp-сессии в случае отключения пользователя Старгейзером.
 


Требования

Stargazer не ниже 2.408. Версия purestg2 2.2 работает со Stargazer 2.407. Версии purestg2 до 2.2 работают со Stargazer 2.407-rc2.
pppd - 2.4.4-2.4.5 и возможно другие.





Обзор

Плагин состоит из двух частей - собственно модуля для Stargazer (mod_auth_purestg2.so) и плагина для pppd (purestg2.so). При старте старгейзера создается UNIX domain socket с адресом, указанном в конфиг-файле (например - /var/run/purestg.sock), который ожидает подключений от плагина для pppd.

Когда pppd с активированным плагином стартует, он подключается к этому сокету (адрес опять же настраивается в опциях pppd) и делает буквально следующее:

1. Запрашивает у Старгейзера номер ppp-интерфейса, который нужно присвоить клиенту (ppp5, ppp12 и т.п.). Номер выбирается из числа ещё не выданных номеров, начиная с некоторого номера minppp, который задаётся в настройках модуля.

2. Когда pppd становится известен логин подключающегося пользователя, он отправляет его Старгейзеру с вопросом: а может ли этот пользователь получить доступ? Если может, то Старгейзер в ответ отправляет пароль пользователя.

3. pppd, используя присланный старгейзером пароль, выполняет аунтентификацию пользователя. Поддерживаются как PAP, так и CHAP методы (включая MS-CHAP-v2).

4. Если аутентификация удалась, то pppd запрашивает у Старгейзера IP-адрес, который нужно присвоить пользователю, согласовывает его, а затем шлёт Старгейзеру команду "подключить пользователя". С этого момент пользователь в старгейзере считается online.

5. Каждые N секунд (N задаётся в опциях pppd) pppd шлёт Старгейзеру ПИНГ с вопросом "пользователь всё ещё имеет доступ?". Если старгейзер отвечает "Нет" или не отвечает в течение ещё N секунд, то PPP-соединение разрывается. Это нужно, например, если отключение пользователя происходит со стороны Старгейзера (скажем, из-за нехватки средств на счете).

Когда пользователь сам разрывает PPP-соединение, pppd шлёт команду старгейзеру "отключить" пользователя и аккуратно закрывается.

Получился этакий себе мини-RADIUS. :) Відредаговано Alexey Osipov
Вышла новая версия.
Опубліковано:

Неплохо!

Замечания по коду плагина к Stargazer'у (бегло посмотрел): он написан больше на C чем на C++. В C++ не стоит использовать malloc/free, вместо него есть new/delete. И вместо strtol лучше использовать str2x.

Собрать не смог пока из-за проблем с заголовочными файлами Stargazer'а. Видимо пора делать то что нужно было сделать давно: выделить интерфейс плагина в абстрактные классы и вынести их в include. Тогда можно будет без проблем сделать dev-пакет для Stargazer'а.

Опубліковано:

Замечания по коду плагина к Stargazer'у (бегло посмотрел): он написан больше на C чем на C++. В C++ не стоит использовать malloc/free, вместо него есть new/delete.

Угу. Я думал про new/delete, но у меня там ещё realloc, а в "man realloc" написано, что

void *realloc(void *ptr, size_t size);

...

Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc().

Поэтому я испугался и заюзал malloc и free. :) Впрочем, можно переехать на std::vector. А, я вспомнил, почему не выбрал std::vector. Массив struct pollfd* connections потом уходит в функцию poll, которая ждет на вход обычный СИ массив и с std::vector работать не умеет.

 

Впрочем, в других местах можно и std::vector использовать.

 

И вместо strtol лучше использовать str2x.

А чем лучше?

 

Собрать не смог пока из-за проблем с заголовочными файлами Stargazer'а. Видимо пора делать то что нужно было сделать давно: выделить интерфейс плагина в абстрактные классы и вынести их в include. Тогда можно будет без проблем сделать dev-пакет для Stargazer'а.

Ага. И эти заголовочные файлы должны по команде make install тоже устанавливаться куда-нибудь в ${prefix}/usr/include/stargazer/ по идее.

 

Сейчас система сборки purestg2 рассчитывает на то, что все заголовочные файлы старгейзера лежат в одной куче в /usr/include/stargazer/, либо можно указать другую папку, но они должны быть в куче.

Опубліковано:

не собирается под Debian Lenny

ip-test:/home/purestg2-2.0# make
make  all-recursive
make[1]: Entering directory `/home/purestg2-2.0'
Making all in pppd
make[2]: Entering directory `/home/purestg2-2.0/pppd'
/bin/sh ../libtool --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer   -g -O2 -MT purestg2.lo -MD -MP -MF .deps/purestg2.Tpo -c -o purestg2.lo purestg2.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer -g -O2 -MT purestg2.lo -MD -MP -MF .deps/purestg2.Tpo -c purestg2.c  -fPIC -DPIC -o .libs/purestg2.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer -g -O2 -MT purestg2.lo -MD -MP -MF .deps/purestg2.Tpo -c purestg2.c -o purestg2.o >/dev/null 2>&1
mv -f .deps/purestg2.Tpo .deps/purestg2.Plo
/bin/sh ../libtool --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..  -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer   -g -O2 -MT pureclient.lo -MD -MP -MF .deps/pureclient.Tpo -c -o pureclient.lo pureclient.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer -g -O2 -MT pureclient.lo -MD -MP -MF .deps/pureclient.Tpo -c pureclient.c  -fPIC -DPIC -o .libs/pureclient.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I/usr/include/pppd -I/usr/include/stargazer -g -O2 -MT pureclient.lo -MD -MP -MF .deps/pureclient.Tpo -c pureclient.c -o pureclient.o >/dev/null 2>&1
mv -f .deps/pureclient.Tpo .deps/pureclient.Plo
/bin/sh ../libtool --tag=CC   --mode=link gcc  -g -O2 -module -avoid-version -shared -s  -o purestg2.la -rpath /usr/local/usr/lib/pppd/2.4.4 purestg2.lo pureclient.lo
libtool: link: gcc -shared  .libs/purestg2.o .libs/pureclient.o      -Wl,-soname -Wl,purestg2.so -o .libs/purestg2.so
libtool: link: ( cd ".libs" && rm -f "purestg2.la" && ln -s "../purestg2.la" "purestg2.la" )
make[2]: Leaving directory `/home/purestg2-2.0/pppd'
Making all in stargazer
make[2]: Entering directory `/home/purestg2-2.0/stargazer'
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..  -I.. -I../include -I/usr/include/stargazer   -g -O2 -MT purestg2.lo -MD -MP -MF .deps/purestg2.Tpo -c -o purestg2.lo purestg2.cpp
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I/usr/include/stargazer -g -O2 -MT purestg2.lo -MD -MP -MF .deps/purestg2.Tpo -c purestg2.cpp  -fPIC -DPIC -o .libs/purestg2.o
In file included from purestg2.cpp:30:
/usr/include/stargazer/user.h:41:27: error: user_property.h: Нет такого файла или каталога
In file included from purestg2.h:36,
                from purestg2.cpp:32:
/usr/include/stargazer/users.h:45:21: error: actions.h: Нет такого файла или каталога
In file included from purestg2.cpp:30:
/usr/include/stargazer/user.h:64: error: expected template-name before ‘<’ token
/usr/include/stargazer/user.h:64: error: expected `{' before ‘<’ token
/usr/include/stargazer/user.h:64: error: expected unqualified-id before ‘<’ token
make[2]: *** [purestg2.lo] Ошибка 1
make[2]: Leaving directory `/home/purestg2-2.0/stargazer'
make[1]: *** [all-recursive] Ошибка 1
make[1]: Leaving directory `/home/purestg2-2.0'
make: *** [all] Ошибка 2
ip-test:/home/purestg2-2.0#

Опубліковано:

не собирается под Debian Lenny

потому что:

Собрать не смог пока из-за проблем с заголовочными файлами Stargazer'а. Видимо пора делать то что нужно было сделать давно: выделить интерфейс плагина в абстрактные классы и вынести их в include. Тогда можно будет без проблем сделать dev-пакет для Stargazer'а.

 

Если поставить пакет stargazer-dev из моего репозитория, то должно собраться.

 

Либо можно руками все .h файлы из дистрибутива старгейзера скинуть в одну папку и при сборке purestg2 указать:

./configure --with-stg-headers=/путь/к/папке

 

Хотя да, надо бы configure подправить, чтобы выдавал ошибку, если не хватает каких-то заголовочных файлов.

Опубліковано:

Alexey Osipov, спасибо за быстрый ответ, я скорее поторопился, действительно мог бы и сам рабозраться :)

 

а ведь заработало :) под xl2tpd модуль тоже подходит?

 

удобно было бы чтобы интерфейс создавался не pppX, а с логином, например у меня ip_up обрабатывает и присваивает имя виртуального интерфейса vpn_LOGIN, где LOGIN это логин из базы, хотя это может быть моё ошибочное мнение

 

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

Опубліковано:

под xl2tpd модуль тоже подходит?

Если xl2tpd в итоге запускает pppd, то да - подходит. Просто я с ним не сталкивался.

Точно работает с PopTop (pptpd) и pppoe-server (из пакета pppoe).

 

удобно было бы чтобы интерфейс создавался не pppX, а с логином, например у меня ip_up обрабатывает и присваивает имя виртуального интерфейса vpn_LOGIN, где LOGIN это логин из базы, хотя это может быть моё ошибочное мнение

Бегло поглядел. Похоже, что такой возможности для плагинов pppd не предоставляет.

 

посмотрим как он себя покажет в работе

Отлично, чем больше отзывов, тем лучше. :)

Опубліковано: (відредаговано)

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

 

 

исправлено путём удаления /var/run/purestg.sock перед стартом

Відредаговано yKpon
Опубліковано:

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

 

исправлено путём удаления /var/run/purestg.sock перед стартом

Угу. По идее, повисшие сессии должны были оборваться сами по прошествии keepalivetimeout * 2 секунд.

Любопытно, что удаление сокета помогло. У меня не получилось удалением сокета сбросить повисших юзверей.

 

А по-хорошему, нужно делать нормальный двунаправленный обмен событиями между старгейзером и pppd, чтобы инициировать события мог не только pppd, но и старгейзер. А для этого, было бы неплохо в плагине старгейзера подписываться на изменение статуса пользователя IsInetable() как, скажем, на изменение настроек.

 

Вообщем, я ещё подумаю в эту сторону.

Опубліковано:

ещё хотелось бы иметь возможность привязки учётной записи к ip с которого разрешена авторизация

 

у меня это делается вручную через ip-up и поле userdata1 в котором перечислены адреса через пробел, если пускает интерфейс сразу после поднятия убивается, если поле пустое авторизоваться можно с любого адреса

Опубліковано:

ещё хотелось бы иметь возможность привязки учётной записи к ip с которого разрешена авторизация

 

А откуда этот IP берётся? Я вот знаю только, что PopTop (pptpd) передаёт IP подключающегося через ipparam в pppd. Но, допустим, pppoe-server этого не делает (хотя мог бы передавать MAC).

Опубліковано:

А откуда этот IP берётся? Я вот знаю только, что PopTop (pptpd) передаёт IP подключающегося через ipparam в pppd. Но, допустим, pppoe-server этого не делает (хотя мог бы передавать MAC).

я имею ввиду pptp, в xl2tp кстати тоже не передаётся ip через ipparam :)

Опубліковано:

Замечания по коду плагина к Stargazer'у (бегло посмотрел): он написан больше на C чем на C++. В C++ не стоит использовать malloc/free, вместо него есть new/delete.

Угу. Я думал про new/delete, но у меня там ещё realloc, а в "man realloc" написано, что

void *realloc(void *ptr, size_t size);

...

Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc().

Поэтому я испугался и заюзал malloc и free. :) Впрочем, можно переехать на std::vector. А, я вспомнил, почему не выбрал std::vector. Массив struct pollfd* connections потом уходит в функцию poll, которая ждет на вход обычный СИ массив и с std::vector работать не умеет.

 

Впрочем, в других местах можно и std::vector использовать.

Из std::vector можно взять указатель на первый элемент и передать его в poll. Он в памяти хранится как обычный массив.

 

И вместо strtol лучше использовать str2x.

А чем лучше?

Меньше вероятность ошибиться с типом. Это по сути обертки для различных целых типов (знаковых и беззнаковых) со встроенной обработкой ошибок.

 

Собрать не смог пока из-за проблем с заголовочными файлами Stargazer'а. Видимо пора делать то что нужно было сделать давно: выделить интерфейс плагина в абстрактные классы и вынести их в include. Тогда можно будет без проблем сделать dev-пакет для Stargazer'а.

Ага. И эти заголовочные файлы должны по команде make install тоже устанавливаться куда-нибудь в ${prefix}/usr/include/stargazer/ по идее.

 

Сейчас система сборки purestg2 рассчитывает на то, что все заголовочные файлы старгейзера лежат в одной куче в /usr/include/stargazer/, либо можно указать другую папку, но они должны быть в куче.

Ага, из-за кучи и не смог попробовать. Давно уже хочу интерфейс плагинов вынести отдельно.

Опубліковано:

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

 

исправлено путём удаления /var/run/purestg.sock перед стартом

Угу. По идее, повисшие сессии должны были оборваться сами по прошествии keepalivetimeout * 2 секунд.

Любопытно, что удаление сокета помогло. У меня не получилось удалением сокета сбросить повисших юзверей.

 

А по-хорошему, нужно делать нормальный двунаправленный обмен событиями между старгейзером и pppd, чтобы инициировать события мог не только pppd, но и старгейзер. А для этого, было бы неплохо в плагине старгейзера подписываться на изменение статуса пользователя IsInetable() как, скажем, на изменение настроек.

 

Вообщем, я ещё подумаю в эту сторону.

Можно подписаться на currIP. Пот отключении он обнуляется, а при подключении туда попадает IP абона.

Опубліковано:

А по-хорошему, нужно делать нормальный двунаправленный обмен событиями между старгейзером и pppd, чтобы инициировать события мог не только pppd, но и старгейзер. А для этого, было бы неплохо в плагине старгейзера подписываться на изменение статуса пользователя IsInetable() как, скажем, на изменение настроек.

 

Вообщем, я ещё подумаю в эту сторону.

Можно подписаться на currIP. Пот отключении он обнуляется, а при подключении туда попадает IP абона.

А вот и нельзя. :) currIP меняется в USER::Authorize() и USER::Unauthorize(). Если же отключение юзверя происходит со стороны старгейзера (disabled, passive, кончились деньги), то старгейзер делает USER::Disconnect(), а USER::Unauthorize() не происходит.

 

Ещё идеи?

 

---добавлено---

 

Вижу

USER_PROPERTY<bool> USER::connected;

но оно приватное. :)

Опубліковано:

А вот и нельзя. B) currIP меняется в USER::Authorize() и USER::Unauthorize(). Если же отключение юзверя происходит со стороны старгейзера (disabled, passive, кончились деньги), то старгейзер делает USER::Disconnect(), а USER::Unauthorize() не происходит.

 

Ещё идеи?

 

---добавлено---

 

Вижу

USER_PROPERTY<bool> USER::connected;

но оно приватное. :)

 

Мда, действительно. Надо, наверное, подписку на connected вынести наружу. На выходных посмотрю что можно сделать.

Опубліковано:

В принципе, quick&dirty - сделать как в mod_remote_script. Там с определенным интервалом происходит синхронизация состояния абонента на NAS'е - плагин смотрит IsInetable и шлет соответствующий пакет.

Опубліковано:

В принципе, quick&dirty - сделать как в mod_remote_script. Там с определенным интервалом происходит синхронизация состояния абонента на NAS'е - плагин смотрит IsInetable и шлет соответствующий пакет.

Можно, но это ничем не будет отличаться от тех же ПИНГ пакетов со стороны pppd в сторону старгейзера каждые N секунд (см. пункт 5 первого сообщения темы).

 

Вижу

USER_PROPERTY<bool> USER::connected;

но оно приватное. :)

 

Мда, действительно. Надо, наверное, подписку на connected вынести наружу. На выходных посмотрю что можно сделать.

Вот этот вариант мне гораздо больше нравится. :) Пока оставляю как есть, а когда будет на что подписываться - переделаю.

Опубліковано:

Последние изменения в git:

 

не собирается под Debian Lenny

...

Хотя да, надо бы configure подправить, чтобы выдавал ошибку, если не хватает каких-то заголовочных файлов.

Сделано.

 

ещё хотелось бы иметь возможность привязки учётной записи к ip с которого разрешена авторизация

 

у меня это делается вручную через ip-up и поле userdata1 в котором перечислены адреса через пробел, если пускает интерфейс сразу после поднятия убивается, если поле пустое авторизоваться можно с любого адреса

Сделано.

 

В конфиге появилось три новых необязательных опции:

ipparamsave = X
ipparamauth = Y    # X не равно Y
allowemptyipparam  # требует наличия опции ipparamauth

Если задан ipparamsave, то при подключении пользователя его ipparam (то, что передалось в pppd) будет записан в userdataX. При отключении пользователя userdataX НЕ изменяется.

Если задан ipparamauth, то на этапе аутентификации пользователя, если его ipparam отсутствует в userdataY (список через запятую), то аутентификация считается неудачной. Если поле userdataY пустое, то аутентификация всегда считается удачной. Если ipparam не был задан в pppd, то аутентификация всегда считается неудачной.

Если задана allowemptyipparam, то аутентификация пользователя с пустым ipparam (не заданным в pppd) всегда считается удачной.

Ни одна из этих опций не отменяет проверку пароля пользователя, а используется лишь как дополнительное средство.

 

Из std::vector можно взять указатель на первый элемент и передать его в poll. Он в памяти хранится как обычный массив.

Сделано.

 

Товарищ yKpon осилит сборку модуля из git или сделать релиз в tar.gz?

Опубліковано:

Изменения в git:

 

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

Исправлено. Теперь, при корректной остановке stargazer'а, все pppd соединения должны корректно закрыться.

 

Новые плюшки:

Опция kickprevious в плагине старгейзера. Определяет, что делать, если пользователь пытается подключиться повторно с тем же логином при наличии уже активного подключения. Если опция отсутствует в конфиге, то плагин не позволит установить второе соединение. Если опция присутствует в конфиге, то первое соединение будет разорвано, а второе, если пароль верный, будет установлено.

 

yKpon, ау? :)

Опубліковано:

Alexey Osipov, собирал из исходников, сейчас обновлюсь посмотрю, спасибо!

хотелось бы видеть обновление в исходниках :)

Опубліковано:

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

Исправлено. Теперь, при корректной остановке stargazer'а, все pppd соединения должны корректно закрыться.

корректно это как?

... если его ipparam отсутствует в userdataY (список через запятую), то аутентификация ...
эмм, лучше бы конечно через пробел, в мускуле проще общаться будет
Опубліковано:

Alexey Osipov, собирал из исходников, сейчас обновлюсь посмотрю, спасибо!

хотелось бы видеть обновление в исходниках :)

Скоро будет релиз 2.1. Я сейчас жду ответа madf на некоторые вопросы, и в зависимости от них, релиз 2.1 будет раньше или позже.

 

Но я хотел бы, чтобы до этого его немного потестили.

Получить последние исходники из git можно так:

git clone git://github.com/lion-simba/purestg2.git

Всё остальное как обычно:

./configure --prefix=/usr && make && sudo make install

 

замечен баг, юзеры авторизованы по впн, рестартим биллинг, после рестарта все кто были онлайн остаются запомнеными онлайн и после рестарта, авторизоваться не могут, ошибка 691

Исправлено. Теперь, при корректной остановке stargazer'а, все pppd соединения должны корректно закрыться.

корректно это как?

Корректно - это значит, что pppd не просто умирать будет, а перед смертью отправит клиенту пакет, что дескать соединение надо закрыть. Раньше клиенту приходилось об этом самому догадываться и отключаться по таймауту.

 

... если его ipparam отсутствует в userdataY (список через запятую), то аутентификация ...
эмм, лучше бы конечно через пробел, в мускуле проще общаться будет

А чем проще?

Опубліковано:

Новые плюшки в git:

 

Новая опция в плагине для старгейзера - pppunitsave. Позволяет сохранить номер ppp-интерфейса, выданного юзверю, в поле userdata<pppunitsave>.

Новая опция в плагине для pppd - latedisconnect. Управляет тем, когда плагин pppd пошлёт запрос старгейзеру на отключение юзверя. Если опция НЕ задана, то запрос на отключение будет послан ДО запуска скриптов auth-down и ip-down; иначе - после их выполнения.

 

Релиз purestg2 2.1 будет выпущен вскоре после выпуска stargazer-2.407-rc3.

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Вхід

Уже зарегистрированы? Войдите здесь.

Войти сейчас
  • Зараз на сторінці   0 користувачів

    • Немає користувачів, що переглядають цю сторінку.
×
×
  • Створити нове...