Цель этой статьи - описать установку VPN сервера на шлюзе работающем
под OS FreeBSD.
Круг задач, выполняемых VPN сервером достаточно широк - от подсчёта
траффика, до контроля за работой пользователей в локальной сети.
Описанная система успешно работает в нескольких домашних сетях. Я
постараюсь подробно описать шаги необходимые для построения VPN шлюза.
Основная идея
Пользователи локальной сети могут свободно работать в пределах сети, в
случае необходимости получения доступа к внешнему трафику,
пользователь подключается к VPN серверу и авторизируется использую
свой логин/пароль.
Все необходимы средства для этого процесса имеются в наличии в ОС
Window 98 и старше. Авторизация пользователей производится через CHAP,
что обеспечивает должную безопастнось в локальных сетях.
Необходимы компоненты на шлюзовой машине
Для запуска VPN сервера необходимы следующие компоненты:
SQL сервер - PostgreSQL - хранение информации о пользователях
Radius сервер - GNU-Radius - авторизация и аккаунтинг
пользователей
VPN демон - poptop - обеспечение подключения через VPN туннель
ppp - модифицированая версия ppp, с поддержкой спецефичный
средств
Установка PostgreSQL
Все операции проводим от пользователя root.
noc# cd /usr/ports/databases/postgresql7
noc# make install
=========== BACKUP YOUR DATA! =============
As always, backup your data before
upgrading. If the upgrade leads to a higher
minor revision (e.g. 7.2.x -> 7.3), a dump
and restore of all databases is
required. This is *NOT* done by the port!
Press ctrl-C *now* if you need to pg_dump.
postgresql has several tunables that can be used to configure PostgreSQL:
WITHOUT_GNUGETOPT Don't install GNU getopt (will
still be used if already installed)
WITHOUT_GETTEXT Skips building with support for
internationalized error messages
WITHOUT_SERVER Installs the headers and libraries for
PostgreSQL clients
WITHOUT_SSL Builds without OpenSSL support
WITH_MIT_KRB5 Builds with MIT's kerberos support
WITH_HEIMDAL_KRB5 Builds with Heimdal's kerberos support
WITH_OPTIMIZED_CFLAGS Builds with compiler optimizations (-O3)
WITH_DEBUG Builds with debugging symbols
WITH_TESTS Allows the use of a "check" target
building the module
WITH_LIBC_R Link the binaries with libc_r.
Needed to run plpython
===> Extracting for postgresql-7.3.3_1
В случае если Вы собираетесь использовать этот SQL сервер только
локально можно использовать опцию WITHOUT_SSL.Это несколько облегчит
размер SQL сервера.
noc# make -DWITHOUT_SSL install
В случае успешной сборки Вы должны в результате увидеть что-то
подобное:
===> Registering installation for postgresql-7.3.3_1
===> SECURITY REPORT:
This port has installed the following files which may act as network
servers and may therefore pose a remote security risk to the system.
/usr/local/bin/postgres
This port has installed the following startup scripts which may cause
these network services to be started at boot time.
/usr/local/etc/rc.d/010.pgsql.sh
If there are vulnerabilities in these programs there may be a security
risk to the system. FreeBSD makes no guarantee about the security of
ports included in the Ports Collection. Please type 'make deinstall'
to deinstall the port if this is a concern.
For more information, and contact details about the security
status of this software, see the following webpage:
http://www.postgresql.org/
Очищаем порт командой:
noc# make clean
По умолчанию БД сервера будет находится /usr/local/pgsql
Следует произвести первоначальную инициализаци БД.
noc# su pgsql
$ initdb -D /usr/local/pgsql/data
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.
The database cluster will be initialized with locale ru_RU.KOI8-R.
This locale setting will prevent the use of indexes for pattern matching
operations. If that is a concern, rerun initdb with the collation order
set to "C". For more information see the Administrator's Guide.
creating directory /usr/local/pgsql/data... ok
creating directory /usr/local/pgsql/data/base... ok
creating directory /usr/local/pgsql/data/global... ok
creating directory /usr/local/pgsql/data/pg_xlog... ok
creating directory /usr/local/pgsql/data/pg_clog... ok
creating template1 database in /usr/local/pgsql/data/base/1... ok
creating configuration files... ok
initializing pg_shadow... ok
enabling unlimited row size for system tables... ok
initializing pg_depend... ok
creating system views... ok
loading pg_description... ok
creating conversions... ok
setting privileges on built-in objects... ok
vacuuming database template1... ok
copying template1 to template0... ok
Success. You can now start the database server using:
Редактируем файл /usr/local/pgsql/.cshrc :
Он должен иметь следующий вид:
set path = ( /usr/local/bin $path )
# note: PGDATA can be overridden by the -D startup option
setenv PGDATA $HOME/data
setenv LC_ALL ru_RU.KOI8-R
Следующий этап - запуск SQL сервера:
noc# /usr/local/etc/rc.d/010.pgsql.sh start
pgsqlnoc#
Проконтролировать запуск сервера можно в log файле /var/log/pgsql
Создание пользователя и БД для пользователей
Необходимо создать пользователя и БД для работы с VPN
noc# su pgsql
$ createuser
Enter name of user to add: vpn
Shall the new user be allowed to create databases? (y/n) y
Shall the new user be allowed to create more new users? (y/n) n
CREATE USER
$ createdb -U vpn vpn
CREATE DATABASE
$
Установим пароль для пользователя vpn - VPN (для примера)
$ psql vpn
Добро пожаловать в psql 7.3.3 - Интерактивный Терминал PostgreSQL.
Наберите: copyright для условий распространения
h для подсказки по SQL командам
? для подсказки по внутренним slash-командам (команда)
g или ";" для завершения и выполнения запроса
q для выхода
vpn=# ALTER USER vpn PASSWORD 'VPN';
ALTER USER
vpn-#
vpn-# q
$
И добавить поддержку языка plpgsql для БД vpn
$ createlang plpgsql vpn
$ exit
Далее следует создать таблицы в БД vpn. Файл vpn.sql содержит
описание необходимых нам таблиц. Файл vpn_fun.sql содержит описание
функций необходимых для работы.
http://www.opennet.ru/soft/vpn/vpn.sql
http://www.opennet.ru/soft/vpn/vpn_fun.sql
Устанавливаем их (используя привелегии root).
# psql vpn vpn -f vpn.sql
ERROR: table "users" does not exist
NOTICE: CREATE TABLE will create implicit sequence 'users_id_seq' for SERIAL c
olumn 'users.id'
CREATE TABLE
CREATE INDEX
ERROR: table "users_attribute" does not exist
NOTICE: CREATE TABLE will create implicit sequence 'users_attribute_id_seq' for SERIAL column 'users_attribute.id'
CREATE TABLE
ERROR: table "stat" does not exist
NOTICE: CREATE TABLE will create implicit sequence 'stat_id_seq' for SERIAL column 'stat.id'
CREATE TABLE
CREATE INDEX
# psql vpn vpn -f vpn_fun.sql
ERROR: RemoveFunction: function get_traffic_limit(character varying) does notexist
CREATE FUNCTION
ERROR: RemoveFunction: function check_lost(character varying) does not exist
CREATE FUNCTION
Сообщения на отсутсвие таблиц/функций слкдует проигнорировать в перый
раз.
На этом настройку PostgreSQL для наших целей следует считать
законченной.
За более подробной информацией касаемой PostgreSQL следует обратится к
документации
Установка GNU-Radius
Все операции проводим от пользователя root.
noc# cd /usr/ports/net/gnu-radius/
noc# make install
И выбираем поддержку PostgreSQL.
Все необходимые компоненты устанавливаются в /usr/local/etc/raddb
sqlserver
Файл sqlserver содержит настройки для работы с SQL сервером.
http://www.opennet.ru/soft/vpn/sqlserver
Рассмотрим его подробнее:
# Использовать postgresql модуль
interface postgres
login vpn
password VPN
Использовать модуль интерфейса PostgreSQL логин и пароль для доступа к
БД
keepopen yes
idle_timeout 14400
Удерживать неиспользуемые соеденеия 14400 сек.
для повышения общей производительности.
doauth yes
auth_max_connections 4
auth_db vpn
Использовать авторизацию, выделяя для этого макс 4 соеденений с SQL
сервером. Для авторизации использовать БД vpn ранее созданную нами.
# Авторизация пользователя
auth_query select passwd from users where user_name='%u' AND active = TRUE and
get_traffic_limit('%u') >= 0
SQL запрос возвращающий пароль пользователя при авторизации.
Внимание !!! Все пароли в БД хранятся в открытом виде. Это необходимое
условие для CHAP авторизации.
reply_attr_query SELECT attr,param
FROM users_attribute
WHERE op IS NULL AND user_name='%u'
SQL запрос производящий выборку RADIUS атрибутов для пользователя,
после успешной авторизации. Эти атрибуты определяют ограничение по
трафику, времени, шейпу для пользователя.
doacct yes
acct_max_connections 4
acct_db vpn
Использовать аккаунтинг, выделяя для этого макс 4 соеденений с SQL
сервером. Для аккаунтинга использовать БД vpn ранее созданную нами.
acct_start_query INSERT INTO stat(user_name,start,ip,frm,acct_s_id,pid,update)
VALUES('%u','%D','%C{Framed-IP-Address}',
'%C{Calling-Station-Id}','%C{Acct-Session-Id}','%C{Login-Service}','%D')
SQL запрос выполняемый при начале работы пользователя. В Таблицу stat
добавляется запись о начале работы пользователя.
acct_alive_query UPDATE stat
SET tm = %C{Acct-Session-Time},
update = '%D',
inp = %C{Acct-Input-Octets},
out = %C{Acct-Output-Octets}
WHERE user_name = '%u' AND acct_s_id = '%C{Acct-Session-Id}'
SQL запрос обновляющий информацию о работающем пользователе.
acct_stop_query UPDATE stat
SET tm = %C{Acct-Session-Time},
update = '%D',
stop = '%D',
inp = %C{Acct-Input-Octets},
out = %C{Acct-Output-Octets}
WHERE user_name = '%u' AND acct_s_id = '%C{Acct-Session-Id}';
UPDATE users_attribute
SET param = INT8(param) - %C{Acct-Input-Octets} - %C{Acct-Output-Octets}
WHERE user_name = '%u' AND attr = 'Traffic-Limit';
UPDATE users
SET active = false WHERE get_traffic_limit('%u') <= 0 AND user_name = '%u';
SELECT check_lost('%u')
SQL запрос выполняемый при окончании работы пользователя.
users
Файл users содержит DEFAULT пользователя и правила его обработки.
http://www.opennet.ru/soft/vpn/users
Для работы нам необходим словарь содержащий дополнительные
аттрибуты. http://www.opennet.ru/soft/vpn/dictionary.ppp
Для подключения его к словарям RADIUS нам нужно положить его в
какталог /usr/local/etc/raddb/dict и в файле
/usr/local/etc/raddb/dictionary добавить строку:
$INCLUDE dict/dictionary.ppp
Остальные настройки
Для получени логов RADIUS сервера, следует раскоментировать следующие
строки в файле /usr/local/etc/raddb/config:
option {
usr2delay 30;
max-requests 1024;
# Uncomment and edit these if you need to:
log-dir "/var/log";
acct-dir "/var/acct";
};
Далее следует отредактировать файл clients, и изменить пароль:
localhost testPW
127.0.0.1 testPW
Внимание !!! - пароль testPW взят только для примера.
Следующий шаг - создать файл /etc/radius.conf с правами доступа 0600.
Проконтролировать запуск можно в файле: /var/log/radius.info:
июл 16 14:39:18: [27501]: ready
июл 16 14:39:18: [27501]: /usr/local/etc/raddb/users reloaded.
июл 16 14:39:18: [27501]: SQL auth: no group_query specified
июл 16 14:39:18: [27501]: SQL acct: no acct_nasdown_query specified
июл 16 14:39:18: [27501]: SQL acct: no acct_nasup_query specified
июл 16 14:39:18: [27502]: Ready to process requests.
RADIUS сервер запущен.
Установка PopTop
Все операции проводим от пользователя root.
noc# cd /usr/ports/net/poptop/
noc# make patch
Копируем патч (http://www.opennet.ru/soft/vpn/pptpctrl.patch) в каталог: /usr/ports/net/poptop/work/poptop-1.1.4/ и
далее:
noc# cd /usr/ports/net/poptop/work/poptop-1.1.4
noc# patch < pptpctrl.patch
Hmm... Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** pptpctrl.c.orig Wed Jul 16 14:51:40 2003
|--- pptpctrl.c Mon Jul 14 15:51:35 2003
--------------------------
Patching file pptpctrl.c using Plan A...
Hunk #1 succeeded at 388.
done
noc# cd ../..
noc# make install
noc# make clean
noc# cp /usr/local/etc/pptpd.conf.sample /usr/local/etc/pptpd.conf
noc# mv /usr/local/etc/rc.d/pptpd.sh.sample /usr/local/etc/rc.d/pptpd.sh
И запускаем poptop
noc# /usr/local/etc/rc.d/pptpd.sh start
Установка PPP
Для наших целей берём модифицированую версию ppp демона,и
устанавливаем его. http://www.opennet.ru/soft/vpn/ppp.0-1.tar.gz
В файле /etc/ppp/ppp.conf создаём новый раздел касаемый VPN.
http://www.opennet.ru/soft/vpn/ppp.conf
pptp:
set radius /etc/radius.conf
Файл используемй для работ с RADIUS сервером
set ifaddr 192.168.0.1 192.168.1.1-192.168.1.200
Диапазон IP адресов для VPN клиентов
enable chap
Использовать только CHAP авторизацию
set rad_service_type 11
Устанавливать Service-Type
set vpn on
Включить режим VPN
set rad_alive 120
Временной интервал для посылки alive пакетов RADIUS серверу
set ip-up /etc/ppp/shape.ppp
set ip-down /etc/ppp/shape.ppp
Скрипты для установки шейпа VPN клиенту. Для шейпирования клиента, у
Вас в ядре должна быть включена опция DUMMYNET.
Пример файла shape.ppp (http://www.opennet.ru/soft/vpn/shape.ppp)
WEB interface
CGI скрипт vpnadmin.cgi представляет собой простейший интерфейс для
управления БД пользовтелей. http://www.opennet.ru/soft/vpn/vpnadmin.cgi
Пример работы: http://town.sumy.ua/cgi-bin/vpn.cgi