воскресенье, 6 декабря 2009 г.

IPSEC туннель между модемом Asus AM604g и FreeBSD 7.0

Исходные данные:
Сервер живёт на реальном IP=ххх.ххх.ххх.ххх , внутренний интерфейс 10.10.122.4 на котором сеть 10.10.122.0/24, на сервере установлены ipsec-tools-0.7.3.

Модем на динамическом, но также реальном IP, интернет подключен через СТРИМ, внутренняя сеть 10.10.133.0/24, внутренний фейс модема 10.10.133.4 (на модеме 4 Lan порта и WiFi, поднят dhcp, маршрутизация статическая).

Генерим самоподписные сертификаты для сервера и модема приведёнными ниже скриптами.
Серверный сертификат:

server$ cat ./gencrt_bsd.sh
#!/bin/sh
openssl req -new -nodes -newkey rsa:1024 -sha1 -keyform PEM -keyout server.test.ru.private -outform PEM -out server.test.ru.pem

openssl x509 -days 9999 -req -in server.test.ru.pem -signkey server.test.ru.private -out server.test.ru.public

openssl x509 -in server.test.ru.public -text


Сертификат для модема:

server$ cat ./gencrt_adsl.sh
#!/bin/sh
openssl req -new -nodes -newkey rsa:1024 -sha1 -keyform PEM -keyout adsl.test.ru.private -outform PEM -out adsl.test.ru.pem

openssl x509 -days 9999 -req -in adsl.test.ru.pem -signkey adsl.test.ru.private -out adsl.test.ru.public

openssl x509 -in adsl.test.ru.public -text


В настройках модема:
1. Идём в раздел Advanced Setup->Certificate->Trusted CA, жмём Import Certificate и через copy/paste добавляем публичный сертификат сервера (server.test.ru.public).
У меня он называется "server.test.ru".

2. В разделе Advanced Setup->Certificate->Local, говорим Import Certificate и добавляем сертификаты модема (публичный и приватный - adsl.test.ru.public/adsl.test.ru.private), называем "adsl".

3. В разделе Advanced Setup->IPsec, создаём подключение: Add New Connection,
где выставляем
IPSec Connection Name = myconnection,
Remote IPSec Gateway Address (IP or Domain Name) = ххх.ххх.ххх.ххх,
Tunnel access from local IP addresses = subnet,
IP Address for VPN = 10.10.133.4,
IP Subnetmask = 255.255.255.0,
Tunnel access from remote IP addresse = subnet,
IP Address for VPN = 10.10.122.4,
IP Subnetmask = 255.255.255.0,
Key Exchange Method = auto(ike),
Authentication Method = certificate(x.509),
certificates = adsl,
Perfect Forward Secrecy = enable,

Advanced IKE Settings
Phase 1
Mode = aggressive,
Encryption Algorithm = 3des,
Integrity Algorithm = sha1,
Select Diffie-Hellman Group for Key Exchange = 1024bit,
Key Life Time = 3600seconds,
Phase 2
Encryption Algorithm = 3des,
Integrity Algorithm = sha1,
Select Diffie-Hellman Group for Key Exchange = 1024bit,
Key Life Time = 3600seconds
Жмакаем Save/Apply и на свежесозданном подключении ставим галку Enable.

Для тестирования и отладки, разделе Management->System Log можно выставить уровень debug. Логи очень информативны и помогут разобраться в проблемах подключения.


Теперь настройки сервера:
Публичные и приватные сертификаты сервера, а также публичный ключ модема кладём в /usr/local/etc/racoon/cert и выставляем корректные права:

server$ ls -AlFGo /usr/local/etc/racoon
drwx------ 2 root wheel - 512 1 дек 00:53 cert/
-rw------- 1 root wheel - 8523 3 дек 00:05 racoon.conf

server$ ls -AlFGo /usr/local/etc/racoon/cert
-rw------- 1 root wheel - 948 1 дек 00:46 adsl.test.ru.public
-rw------- 1 root wheel - 1034 7 окт 12:46 server.test.ru.public
-rw------- 1 root wheel - 733 29 июл 2008 server.test.ru.pem
-rw------- 1 root wheel - 887 29 июл 2008 server.test.ru.private
-rw------- 1 root wheel - 1013 29 июл 2008 server.test.ru.public


Дальше правим /usr/local/etc/racoon/racoon.conf

server$ cat /usr/local/etc/racoon/racoon.conf

path include "/usr/local/etc/racoon";
path certificate "/usr/local/etc/racoon/cert";

log debug2;
#log info;
padding
{
maximum_length 20; # maximum padding length.
randomize off; # enable randomize length.
strict_check off; # enable strict check.
exclusive_tail off; # extract last one octet.
}

# if no listen directive is specified, racoon will listen on all
# available interface addresses.
listen
{
isakmp xxx.xxx.xxx.xxx [500];
}

# Specify various default timers.
timer
{
# These value can be changed per remote node.
counter 5; # количество повторов отправки 5 = дефолт
interval 20 sec; # интервал между попытками отправки 10 = дефолт
persend 1; # количество отправляемых пакетов 1 = дефолт
phase1 90 sec; # максимальное время отведённое на завершение фазы 1
phase2 90 sec; # то-же для 2й фазы
}

remote anonymous
{
exchange_mode main,aggressive;# режим обмена для фазы 1, когда racoon
# выступает инициатором, также определяет
# допустимые режимы обмена, когда racoon-
# responder.Описываются через запятую,
# первое значение в списке используется
# когда racoon инициатор (main,aggressive,base)
doi ipsec_doi; # использовать расширение по RFC 2407
situation identity_only;# использовать SIT_IDENTITY_ONLY по RFC 2407
passive on; # инициируем соединения или ждём подключений
generate_policy on; # генерим политики ибо IP противоположной стороны неизвестен
nonce_size 16;# default = 16, размер nonce = (8-256), подробности в RFC2409...
lifetime time 60 min;
initial_contact on; # включение отправки сообщения INITIAL-CONTACT при рестарте
# default = on, это сообщение полезно
# если responder оставляет старый SA при реконнекте.
# Если сообщение не послать, то responder будет
# использовать старый SA даже когда уже существует новый.
# можно юзать net.key.preferred_oldsa в sysctl, чтобы
# принудительно оставлять старый SA
proposal_check obey;# obey- при выборе pfs,lifetime и длине ключей,
# использовать значения предлагаемые инициатором
# strict,claim- если наши значения серьёзней, то ок,
# иначе отклоняем... или наоборот при claim
# exact- если не совпадают с нашими то не принимаем ...
my_identifier asn1dn; # идентификатор сервера отправляемый
# удалённому хосту будет взят из поля
# Subject сертификата
peers_identifier asn1dn;
certificate_type x509 "server.test.ru.public" "server.test.ru.private";
peers_certfile x509 "adsl.test.ru.public";

# конфигурация параметров предложения первой фазы
proposal {
encryption_algorithm 3des;# алгоритм шифрования
hash_algorithm sha1; # метод хеширования
authentication_method rsasig; # метод аутентификации- по сертификатам
dh_group 2; # длина ключа Диффи-Хеллмана 1024бит (1-768бит)
}
}

# конфигурация параметров предложения второй фазы
sainfo anonymous
{
pfs_group 2;
lifetime time 60 min; # время жизни ключа 2 фазы
encryption_algorithm 3des; # алгоритм шифрования 2 фазы
authentication_algorithm hmac_sha1,hmac_md5; # алгоритм хэширования 2 фазы
compression_algorithm deflate; # алгоритм сжатия 2 фазы
}



Теперь правим /etc/rc.conf:

server$ echo "ipsec_enable="YES" >> /etc/rc.conf
server$ echo "racoon_enable="YES" >> /etc/rc.conf

Стартуем в консоли сервера racoon -vFdddddd, пингуем любой живой хост с обратной стороны туннеля и смотрим дебаг -всё должно взлететь...
Если нет, то смотрим настройки файерволла на сервере - должен пропускаться udp на 500 порт (isakmp) а также протокол esp.

Я использую pf, правила такие:
pass in on $ext_if proto udp from any to $ext_ip port {isakmp}
pass in on $ext_if proto esp from any to $ext_ip

При описанной схеме подключения, FreeBSD кидает пакеты в туннель без указаний маршрутов и настройки политик в /etc/ipsec.conf. Модем также не нуждается в прописывании дополнительных маршрутов. (Но если вы например планируете использовать для аутентификации на модеме, radius сервер находящийся в сети по ту сторону туннеля, то маршрут прописать всё таки придётся - указывать он должен на внутренний интерфейс модема -10.10.133.4)

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

Полезности при обновлении системы и портов FreeBSD

Настройка обновления через make update:

server$ cat /etc/make.conf

SUP_UPDATE=yes
SUP=/usr/local/bin/cvsup
SUPFLAGS= -g -L 2
SUPHOST=cvsup3.ru.FreeBSD.org
SUPFILE=/usr/share/examples/cvsup/standard-supfile
PORTSSUPFILE=/usr/share/examples/cvsup/ports-supfile
DOCSUPFILE=/usr/share/examples/cvsup/doc-supfile

Для обновления:

server$ cd /usr/ports
server$ make update

после обновления портов через cvsup, необходимо сделать построение индекса: portsdb -Uu

Если хотим указать постоянные опции сборки порта, то в /etc/make.conf:


server$ cat /etc/make.conf

.if ${.CURDIR:N*/ports/mail/mutt-devel} == ""
NOPORTDOCS=yes
WITH_MUTT_NCURSES=yes
WITHOUT_MUTT_SGMLFORMAT=yes
WITH_MUTT_XFACE=no
WITH_MUTT_SIGNATURE_MENU=yes
WITH_MUTT_MAILDIR_MTIME_PATCH=yes
WITH_MUTT_NNTP=yes
WITH_MUTT_HTML=yes
WITH_MUTT_IMAP_HEADER_CACHE=yes
WITH_MUTT_MAILDIR_HEADER_CACHE=yes
.endif


Опции make:
fetchindex Скачать индекс- альтернатива portsdb -Uu
fetch Загрузить исходные тексты
fetch-list Показать список файлов, какие будут загружены командой fetch
fetch-recursive Загрузить исходные тексты рекурсивно, т. е. со всеми зависимостями
fetch-recursive-list Показать список файлов, какие будут загружены командой fetch-recursive
fetch-required Загрузить еще не установленные части/зависимости для данного пакета
fetch-required-list Показать список еще не установленных частей/зависимостей для данного пакета
readmes Сгенерировать readme.html с описаниями портов
rmconfig удалить сохранённую информацию об опциях выбранных ранее при make configure
search name = Поиск пакета по названию пакета
search key = Поиск пакета по ключевому слову
checksum Проверить контрольные суммы.
depends Перестроить зависимости
extract Извлечь файлы пакета в каталог ./files
patch Приложить "заплатки"
configure Запустить сценарий configure (если есть)
build собрать приложение из исходных тестов.
install Установить пакет
reinstall Переустановить пакет
deinstall Удалить пакет
package Собрать двоичный пакет (*.tbz) из уже установленного
package-recursive Собрать двоичные пакеты (*.tbz) из уже установленного и всех его зависимостей
clean "почистить" исходники после сборки.


Полезные утилиты по работе с портами:
pkg_info -xL порт Отобразит все установленные файлы для пакета
pkg_info -xc имя Выведет однострочный комментарий для всех приложений, начинающихся с "имя"
pkg_info -xD Показать установочное сообщение для указанного пакета
pkg_info -R порт Покажет какие приложения зависят от указанного
pkg_which файл Определить какому порту принадлежит файл
pkg_which -o порт показать где расположен порт в дереве портов
portupgrade -rR порт -l logfile проапгрейдить порт и направить вывод в файл, названный logfile
portsclean -D Удаление старых дистфайлов

fastest_cvsup Поиск ближайшего cvsup сервера
и например такой скрипт:

#!/bin/sh
if SRV=`fastest_cvsup -q -c ru,uk`; then
cvsup -g -L 2 -h $SRV /root/scripts/ports-supfile
fi

Сборка документации:

server$ cd /usr/ports/textproc/docproj && make install clean
А после этого соберем саму документацию. Например в формате html:

server$ cd /usr/doc && make FORMATS="html" install clean

Автоматизировать процесс установки FreeBSD на несколько машин:
Для автоматической установки достаточно создать профайл инсталляции
install.cfg, скопировать его на дискету, а в sysinstall при установке
выбрать пункт меню "Load Config".
Пример install.cfg можно найти в /usr/src/release/sysinstall/install.cfg



Использования nc (netcat) в качестве прокси для cvsup и csup.
rc.conf:
inetd_enable="YES"

inetd.conf:
cvsup stream tcp nowait root /usr/bin/nc nc -xA.B.C.D:8080 -Xconnect cvsup2.ru.freebsd.org 5999

supfile:
*default host=127.0.0.1

Отключение сборки модулей ядра:
Практически любой системный администратор, который сталкивался с FreeBSD,
компилировал ядро под себя, выбрасывая оттуда лишние "детали" или вставляя недостающие.
Между тем выброшенная из ядра "деталька" никуда не девается и при повторной компиляции
превращается в модуль (за редким исключением), который всегда можно подгрузить.

Бороться с этим можно с помощью опций в файле make.conf:

# не компилировать все модули
NO_MODULES="YES"
# компилировать только указанные модули
# названия модулей пишутся через пробел
MODULES_OVERRIDE=acpi ipfw
# компилировать все модули, за исключением указанных
WITHOUT_MODULES=pf ntfs_iconv


Материалы брались из разных источников, в том числе отсюда:
http://www.opennet.ru
http://unix-hobby.narod.ru