Немного предисловия. Началось с того, что pptp перестал устраивать, т.к. многие провайдеры не очень, мягко говоря, дружат с gre. Поэтому рещено было перейти на l2tp. Решение оправдало себя, скажу я вам. Если по- быстрому, то меняем все pptp на l2tp в mpd и все работает. Как клиент,так и сервер. Статей по настройке mpd куча, дублировать не вижу смысла. Тут вопрос возник с вендой. В ХР впн только двух вариантов - pptp и l2tp/IPSec. На скорую руку решается созданием ключа
Код: Выделить всё
ProhibitIpSec в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters\ типа DWORD со значением "1".
Итак, IPSec. Долго думал, какая же все-таки связь между IPSec и l2tp. Искал строчки с названием первого в конфигах второго и наоборот. Раз позиционируется как одно, значит, связь должна же быть. Ответ оказался прост. Связь примерно такая же, как у стола с табуреткой. Вроде, и можно использовать вместе, но обе совершенно независимые вещи, не имеющие никакой реальной связи между собой. Может быть l2tp/IPSec, может быть smtp/IPSec, telnet/IPSec и, даже, окошмар, icmp/IPSec. На кой хрен в венде это как одно нераздельное - непонятно.
Вообще IPSec вещь универсальная. Если в кратце, то ядро берет пакеты соответствующие определенным правилам и шифрует их перед отправкой в сеть. А другая сторона, получив эти пакеты, расшифровывает и отдает приложению так, как будто они пришли по сети нешифрованными. Физически это можно представить, как если бы из вашего сервера сетевой шнурок шел в черную коробочку, а из нее уже в свич. И у соседа так же. Ваша черная коробочка шифрует пакеты, исходящие от вас и расшифровывает пакеты, приходящие от соседа, которые в свою очередь шифрованы его коробочкой. Коробочки аутентифицируются, обмениваются ключами, параметрами шифрования и т.п. сами, а вы с соседом видите друг друга, как если бы были просто в одном свиче (ну, или просто оба воткнуты в интернет). Дак вот, эти коробочки и есть IPSec. Какой-то трафик пропускается так, какой-то шифруется. Что и как - вы устанавливаете сами. Отсюда и нет никакой прямой связи с тунелями или еще чем-либо. Для приложений работа IPSec прозрачна. В самом простом исполнении тунелей с IPSec создается простой нешифрованный тунель с помощью gif интерфейсов и в правилах IPSec-у указывается, что трафик этого тунеля (или просто - весь трафик между машинами,создающими тунель) надо шифровать.
Я для работы с ipsec использовал ipsec-tools. Еще немного теории.
У IPSec есть 2 режима работы - тунель и транспорт.
В режиме тунеля шифруется пакет целиком, включая заголовки. Т.е. создается виртуальный тунель. В конечном итоге невозможно понять, откуда и куда идет инкапсулированный пакет. Но тут возникает проблема, если клиент находится за натом. Т.к. нат меняет заголовки пакета, то все перестает работать. Решение - NAT-T. На семерку есть патч, на восьмерке.1 нужно просто собрать с ним ядро. При этом не забудьте собрать с поддержкой порт.
В режиме транспорта шифруется только часть с данными и проблем с натом быть не должно.Я использую транспорт.
Раз уж про ядро, то в ядро добавляем
Код: Выделить всё
options IPSEC # непосредственно поддержка.
options IPSEC_ESP # Encapsulating Security Payload — инкапсуляция зашифрованных данных.
options IPSEC_DEBUG # дебаг. кому надо - кому нет.
device crypto # по желанию.
Собрали-пересобрали-поставили. Конфиг сервера. Впринципе, его же можно и на клиента.
racoon/racoon.conf
Код: Выделить всё
path pre_shared_key "/usr/local/etc/racoon/psk.txt";
#path pidfile "/var/run/racoon/racoon.pid";
#path certificate "/etc/ssl/certs";
#path script "/etc/ssl/certs";
log info;
# Не останавливаетсяю
#privsep {
# user 2000;
# group 2000;
#}
# Задает параметры формирования пакетов
# Лучше не трогать. man(c)
padding {
maximum_length 20;
randomize off;
strict_check off;
exclusive_tail off;
}
# Что слушаем и как. Что б не забивалось на тунельные адреса
listen {
isakmp 1.1.1.1;
isakmp_natt 1.1.1.1 [4500];
}
# Значения таймеров.
# На всех серверах должны быть идентичны. Иначе возможны варианты зависиния тунеля.
timer {
# Максимальное количество повторов
counter 5;
# Интервал между повторами
interval 20 sec;
# Количество передаваемых пакетов за "посылку"
persend 1;
# Максимальное время для завершения фазы 1
phase1 30 sec;
# Максимальное время для завершения фазы 2
phase2 15 sec;
#natt_keepalive 10sec;
}
# Удаленные клиенты. Можно написать ip, для остальных anonymous.
# Указываем IKE phase 1 для каждого удаленного клиента. Если
# указан anonymous секция будет применена к каждому клиенту,
# не попавшему под конкретную секцию (адрес вместо anonymous)
remote anonymous {
# Метод обмена, если мы инициаторы. Так же принимать данный
# вид, если клиент. Можно несколько через запятую.
exchange_mode aggressive,main;
# exchange_mode aggressive;
#eans to use IPsec DOI as specified in RFC 2407. You can
# omit this statement.
# doi- область интерпретации ISAKMP (IKE).
# В данном случае для ipsec.
# doi ipsec_doi;
# Переидентификация узлов и сравнение политик раз в
# 24 часа.
# !! На обоих узлах должно быть одинаково. win - ? !!
# !! Иначе тонель виснет. фаза1 > фаза2. !!
lifetime time 24 hour;
# Если не хотим инициировать согласование, ставим off.
# Применимо только для сервера.
passive off;
# Генерировать policy из proposal. Это используется для
# клиентов с динамическими адресами. (on | off | require | unique)
# Имеет смысл только на сервере.
#!generate_policy on;
generate_policy off;
# The below line makes it work with other devices that propose
# a lifetime longer than the racoon default of 28800.
# Alternatively, set a longer lifetime. "proposal_check claim" may
# work suboptimally with frequent renegotiation of phase 2.
proposal_check obey;
# Включаем вкомпиленный в ядро NAT-T для клиентов за натом.
# Можно сделать force для всех.
nat_traversal on;
# Включаем IKE фрагментацию на принимающей стороне. В случае, если
# работает через кривой фаер, имеющий проблемы с фрагментацией udp.
ike_frag on;
# situation identity_only;
# my_identifier asn1dn;
# peers_identifier asn1dn;
# Методы аутентификации - шифрования клиентов.
proposal {
# Алгоритм для фазы 1. Можно использовать
# des, 3des, blowfish, cast128, aes, camellia
encryption_algorithm 3des;
# Хэш-алгоритм для фазы 1. Можно использовать
# md5, sha1, sha256, sha384, sha512
hash_algorithm sha1;
# Метод аутентификации для фазы 1. Можно использовать
# pre_shared_key, rsasig (for plain RSA authentication), gssapi_krb,
# hybrid_rsa_server, hybrid_rsa_client, xauth_rsa_server, xauth_rsa_client,
# xauth_psk_server or xauth_psk_client.
authentication_method pre_shared_key;
# Определяем группу для Diffie-Hellman exponentiations. Группа должна
# быть одной из: modp768, modp1024, modp1536, modp2048, modp3072,
# modp4096, modp6144, modp8192. Или можно использовать 1, 2, 5, 14, 15, 16,
# 17, или 18 в качестве DH-номера группы. Если используется
# aggressive mode, необходимо установить индивидуальную группу
# для каждого proposal.
dh_group 2;
}
}
# construct phase 2 proposals by combining sainfo specifications in
# racoon.conf, and policies in the kernel.
sainfo anonymous {
# encryption_algorithm aes, 3des;
encryption_algorithm 3des;
# sha1 - немного секюрней, md5 немного быстрее. Можно
# принудительно назначить какой-либо.
# see http://www.ciscopress.com/articles/article.asp?p=25473
authentication_algorithm hmac_md5, hmac_sha1;
# Поскольку фаза 2 отвечает за ключи шифрования - время ее жизни
# час. Раз в час меняем ключи.
# !! На обоих узлах должно быть одинаково. win - ? !!
# !! Иначе тонель виснет. фаза1 > фаза2. !!
lifetime time 1 hour ;
compression_algorithm deflate;
}
Теперь по конфигу.
Коменты сверху и секция privsep для запуска ракуна под непривилегированным пользователем. Но штатный rc.d скрипт под это не рассчитан. Он его тупо не тормозит.
Все строки с natt коментим, если его нет в ядре. Или если собрано без его поддержки.
Секция timer. Тут интересно, что такое фаза 1 и 2.
Фаза 1.
узлы договариваются о методе шифрования, алгоритме, хэш-алгоритме и группе Diffie Hellman. Так же идентификация. Путем обмена 3 нешифрованными пакетами - aggressive mode, или шестью - main mode. В результате создается SA первой фазы (IKE SA).
Фаза 2.
Генерятся ключи, узлы договариваются о используемой политике. Все пакеты этой фазы шифруются. В результате создается phase 2 SA (IPSec SA).
SA - связь (ассоциация) безопасности. Это термин IPSec для обозначения соединения.
remote anonymous - мы предполагаем, что не знаем, с какого ип к нам будут конектиться. Если знаем, вместо anonymous пишем ип.
generate_policy off - заслуживает отдельного внимания, но о нем в разделе setkey.
proposal - может быть сколько угодно. Я для венды и фри использую одинаковые параметры.
Ну вот, собственно, по конфигу и все. Для аутентификации можно использовать сертификаты, можно парольную фразу. Я выбрал для начала второе, но по первому примеров масса и делается 2-5 строчками в конфиге. Пример тут http://www.lissyara.su/articles/freebsd/security/ipsec/. И так, парольная фраза. Алгоритм работы примерно таков. Узлы идентифицируют друг друга по парольной фразе, генерят сертификаты, обмениваются ими и создают шифрованный тунель. Обмен ключами осуществляется по протоколу IKE - итнтернет кей эксчейндж. Так же осуществляется переодическая смена ключей. Таким образом, если врагом будет получен один ключ, то расшифровать им он сможет только часть трафика до смены ключей. После смены старый ему никак не поможет, в .т.ч и в получении или перехвате нового. Парольные фразы хранятся в /usr/local/etc/racoon/psk.txt
В виде соответствия хост (ip) - пароль. Пример идет вместе с портом. например,
1.1.1.1 password
Тут возникает некая засада. А если клиенты на динамических адресах? Тут скажу спасибо некому человеку, который придумал следующее. К сожалению, автора не нашел. делаем make extract порта и правим:
Код: Выделить всё
# IMPORTANT:If you really need wildcard PSK (Pre-Shared Key) as well as main mode IP address identity support during PSK authentication
# (for Microsoft Windows XP clients etc.), you may want to apply the following changes to ipsec-toolsbefore compiling the package.
#
# Wildcard PSK (An asterisk "*" matches all IPs)
#
# In ipsec-tools/src/racoon/localconf.c, locate the function named "getpsk(str, len)"; then in the while loop, find the line that looks like:
#
# if (strncmp(buf, str, len) == 0 && buf[len] == '\0') {
# Replace it with:
# if (strcmp(buf, "*") == 0 || (strncmp(buf, str, len) == 0 && buf[len] == '\0')) {
# Save and exit.
# Recompile and reinstall if necessary.
#
# Main mode IP address identity
#
# In ipsec-tools/src/racoon/ipsec_doi.c, locate the function named "ipsecdoi_checkid1(iph1)"; then find the lines that look like:
#
# if (iph1->etype == ISAKMP_ETYPE_IDENT &&
# iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_PSKEY) {
# if (id_b->type != IPSECDOI_ID_IPV4_ADDR
# && id_b->type != IPSECDOI_ID_IPV6_ADDR) {
# plog(LLV_ERROR, LOCATION, NULL,
# "Expecting IP address type in main mode, "
# "but %s.\n", s_ipsecdoi_ident(id_b->type));
# return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
# }
# }
#
# Change LLV_ERROR into LLV_WARNING; comment out the return statement using /* */.
#
# Save and exit.
#
# Recompile and reinstall if necessary.
И так, мы настроили конфиг, создали парольную фразу. Можно попробовать запустить ракун и убедиться,что все работает. Не забудьте добавить racoon_enable="YES" и racoon_create_dirs="YES" в rc.conf.
Теперь еще немного теории. Есть 2 базы. SAD и SPD. С обеими работаем через setkey. Лучше использовать тот, что идет вместе с портом - /usr/local/sbin/setkey, т.к. стандартный неккоректно работал с SAD лично у меня.
SA [/usr/local/sbin/setkey -D] - связь (ассоциация) безопасности. Это термин IPSec для обозначения соединения.При установленном соединении для каждого используемого протокола создается пара SA. Пара, т.к. SA - это днонаправыленное соединение, а данные передаются в обоих направлениях. SA- пары хранятся на каждом узле. Если есть SA - соединение установлено. На практике же можно шифровать трафик только в одном направлении. Просто попробовал ради интереса. От меня шел ESP (шифрованный), ко мне шел обычный l2tp. И тунель нормально работал)
SPD [/usr/local/sbin/setkey -PD] - база политик безопасности. Политики безопасности указывают, какой именно трафик надо шифровать. И какой трафик приходит шифрованным. Если на одном сервере укажем, например, что исходящий трафик на порту 1701 надо шифровать, а на соседе не указаем, что на порт 1701 приходит шифрованный трафик, то них работать не будет.
Данная база может заполняться из setkey.conf путем setkey -f setkey.conf. Как говорил выше, в конфиге есть интересная опция generate_policy off;. Если на СЕРВЕРЕ ее поставить в on, то на сервере будут создаваться политики, соответствующие политикам на клиенте. Например, если на клиенте мы укажем, что исходящий трафик на порт 1701 шифровать, то на сервере автоматом создастся правило, что входящий трафик с данного хоста(клиента) на порт 1701 будет шифрованным. Для начала рекомендую поставить on и оставить политики на сервере пустыми. Они заполнятся в соответствии с клиентом. Если взаимодействие политик будет настроено неправильно, шифрование не заработает и SA не создастся, насколько я помню.
Пример файла на клиенте.
Код: Выделить всё
# Чистим все.
flush;
spdflush;
# А вот и сами правила, что шифровать.
# добавляем правило на трафик от клиента(ип 2.2.2.2) с любым портом на сервер (ип 1.1.1.1) порт 1701 по протоколу udp, трафик является исходящим, шифруется, используется esp в режиме транспорта, обязательно.
spdadd 2.2.2.2[0] 1.1.1.1[1701] udp -P out ipsec esp/transport//require;
# то же самое, только уже входящий (обратный) трафик. Параметры те же. Если убрать одну их этих строк - шифрование будет только в одном направлении.
spdadd 1.1.1.1[1701] 2.2.2.2[0] udp -P in ipsec esp/transport//require;
Код: Выделить всё
path pre_shared_key "/usr/local/etc/racoon/psk.txt";
log info;
padding {
maximum_length 20;
randomize off;
strict_check off;
exclusive_tail off;
}
listen {
isakmp 2.2.2.2;
strict_address;
adminsock "/var/db/racoon/racoon.sock";
}
timer {
counter 5;
interval 20 sec;
persend 1;
phase1 30 sec;
phase2 15 sec;
}
remote 1.1.1.1 {
exchange_mode aggressive,main;
lifetime time 24 hour;
my_identifier address;
peers_identifier address;
passive off;
generate_policy on;
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
sainfo anonymous {
encryption_algorithm 3des;
authentication_algorithm hmac_md5, hmac_sha1;
lifetime time 1 hour ;
compression_algorithm deflate;
}
При появлении трафика, попадающего под соответствующее правило, создадутся ключи и правила на сервере. Для теста, на клиенте можно попробовать racoonctl vc 1.1.1.1 (если собрано с админским контролем), а лучше запустить mpd.
Что б писались логи, добавляем в /etc/syslog.conf
Код: Выделить всё
!racoon
*.* /var/log/racoon.log
Пример баз на работающем клиенте
/usr/local/sbin/setkey -D
Код: Выделить всё
2.2.2.2 1.1.1.1
esp mode=transport spi=176271203(0x0a81af63) reqid=0(0x00000000)
E: 3des-cbc c81782e2 cb844f5b 78c44a17 a9f1f815 a1a0e116 e0922af7
A: hmac-md5 d8702bf1 ac42b5d9 aa93e0a6 d29be244
seq=0x000000a3 replay=4 flags=0x00000000 state=mature
created: Dec 8 11:06:28 2010 current: Dec 8 11:23:54 2010
diff: 1046(s) hard: 3600(s) soft: 2880(s)
last: Dec 8 11:23:45 2010 hard: 0(s) soft: 0(s)
current: 19344(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 163 hard: 0 soft: 0
sadb_seq=1 pid=1389 refcnt=2
1.1.1.1 2.2.2.2
esp mode=transport spi=78827330(0x04b2cf42) reqid=0(0x00000000)
E: 3des-cbc 4878e5af fa657ba6 38524d4f 0ef4781a a7897aec f1d9b5fe
A: hmac-md5 f30c6fae ad7d3235 84d18049 8d380ea8
seq=0x00000057 replay=4 flags=0x00000000 state=mature
created: Dec 8 11:06:28 2010 current: Dec 8 11:23:54 2010
diff: 1046(s) hard: 3600(s) soft: 2880(s)
last: Dec 8 11:23:39 2010 hard: 0(s) soft: 0(s)
current: 5246(bytes) hard: 0(bytes) soft: 0(bytes)
allocated: 87 hard: 0 soft: 0
sadb_seq=0 pid=1389 refcnt=1
[cod1.1.1.1[1701] 2.2.2.2[any] udp
in ipsec
esp/transport//require
created: Dec 8 11:24:44 2010 lastused: Dec 8 11:25:10 2010
lifetime: 0(s) validtime: 0(s)
spid=16407 seq=1 pid=1543
refcnt=2
2.2.2.2[any] 1.1.1.1[1701] udp
out ipsec
esp/transport//require
created: Dec 8 11:24:44 2010 lastused: Dec 8 11:25:10 2010
lifetime: 0(s) validtime: 0(s)
spid=16406 seq=0 pid=1543
refcnt=2e]
[/code]
А tcpdump на внешнем инт-е показывает
Код: Выделить всё
10:27:07.106514 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0348e9f1,seq=0x54), length 140
10:27:07.106617 IP 1.1.1.1 > 2.2.2.2: ESP(spi=0x02e88b28,seq=0x4c), length 140
10:27:08.107413 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0348e9f1,seq=0x55), length 140
10:27:08.107524 IP 1.1.1.1 > 2.2.2.2: ESP(spi=0x02e88b28,seq=0x4d), length 140
10:27:09.108299 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0348e9f1,seq=0x56), length 140
10:27:09.108390 IP 1.1.1.1 > 2.2.2.2: ESP(spi=0x02e88b28,seq=0x4e), length 140
10:27:10.109189 IP 2.2.2.2 > 1.1.1.1: ESP(spi=0x0348e9f1,seq=0x57), length 140
10:27:10.109311 IP 1.1.1.1 > 2.2.2.2: ESP(spi=0x02e88b28,seq=0x4f), length 140
Имена и фамилии изменены (с)
Это то,как я понял. Если есть чо добавить - поправить, с удовольствием выслушаю.