|
Обозначилась у меня задача, объединить два удаленных офиса. Центральный офис выходит в инет через оптическое подключение, адрес внешнего интерфейса 100.100.100.1 (условно), внутренний интерфейс имеет адрес 192.168.0.254, удаленный офис подключен к инету через ADSL роутер, внешний адрес 120.120.120.1, внутренний интерфейс 192.168.10.254. Таким образом необходимо создать туннель между сетями 192.168.0.0/24 и 192.168.10.0/24 через интернет. Первое, что пришло на ум - GRE туннель, но этот вариант был отброшен сразу. Такой туннель не шифруется, а по туннелю будут ходить пароли пользователей, репликация AD и много еще чего... Вторым вариантом рассматривался OpenVPN. Но он меня тоже не устроил. Это целый сервер, а мне хотелось получить решение без лишнего софта, используя только функционал ядра. Таким образом я остановился на IPSEC.
В Slackware ядро собрано таким образом, что все, что необходимо для создания IPSEC туннеля в нем уже есть. Но в самом дистрибутиве не хватает утилиты ipsec-tools, которая позволяет создавать и управлять IPSEC туннелями. Странно, что Патрик ее не включил.
Скачаем пакет ipsec-tools и установим его:
wget http://dfn.dl.sourceforge.net/sourceforge/ipsec-tools/ipsec-tools-0.6.7.tar.bz2
tar xjvf ipsec-tools-0.6.7.tar.bz2
cd ./ipsec-tools-0.7.tar.bz2
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
sudo make
sudo make install DESTDIR=/tmp/ipsec-tools-0.6.7
cd /tmp/ipsec-tools-0.6.7
sudo makepkg ipsec-tools-0.6.7-i486-1.tgz
sudo installpkg ipsec-tools-0.6.7-i486-1.tgz
Готово!
Дальше за все происходящее отвечает команда setkey. Реализация IPSEC в ядре Linux позволяет использовать различные протоколы шифрования. Я выбрал следующую схему:
- содержимое пакетов шифруется по протоколу 3des-cbc с длинной ключа 192 бит
- аутентифицируются хосты по протоколу hmac-md5 с длинной ключа 128 бит
На этом моя паранойя была удовлетворена... Осталось только реализовать это на деле...На чтение манов, понимание механизма работы и прилагаемых рюшечек ушло два дня. Итак IPSEC может работать в двух режимах:
В первом случает шифруется трафик между двумя хостами разделенными враждебной сетью, и этот трафик предназначен конкретно этим хостам.
Во втором случае шифруется трафик между двумя хостами разделенными враждебной сетью, но этот трафик предназначен сетям расположенным за этими хостами. При этом по отношению к этим сетям, эти хосты являются маршрутизаторами.
Меня интересовал второй вариант. Он в свою очередь может быть реализован двумя способами:
- хосты шифруют трафик используя сертификаты
- хосты шифруют трафик используя статичные ключи
Первый способ предпочтительней, но он несколько громоздок и больше предназначен для мобильных пользователей. Не мудрствуя лукаво я остановился на втором способе.
Сначала генерируем ключи:
для 3des-cbc:
dd if=/dev/random count=24 bs=1| xxd -ps
a028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
24+0 записей считано
24+0 записей написано
скопировано 24 байта (24 B), 0.000216027 c, 111 kB/c
a028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23 — это наш ключ
для hmac-md5:
dd if=/dev/random count=16 bs=1| xxd -ps
358f23ebbabce1d9de74bccd9d39b92d
16+0 записей считано
16+0 записей написано
скопировано 16 байт (16 B), 0.000149673 c, 107 kB/c
358f23ebbabce1d9de74bccd9d39b92d — наш ключик
Загрузим необходимые модули:
/sbin/modprobe ah4
/sbin/modprobe esp4
Если если эти модули уже включены в ядро статически, то грузить их не надо.
Скрипт которым поднимается туннель выглядит так:
#!/usr/sbin/setkey -f
flush;
spdflush;
add 100.100.100.1 120.120.120.1 esp 0x201 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.0.0/24 192.168.10.0/24 any -P out ipsec esp/tunnel/100.100.100.1-120.120.120.1/require;
add 120.120.120.1 100.100.100.1 esp 0x301 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.10.0/24 192.168.0.0/24 any -P in ipsec esp/tunnel/120.120.120.1-100.100.100.1/require;
Разберемся, что тут происходит:
#!/usr/sbin/setkey -f
flush;
spdflush;
Первым делом уничтожаются все туннели, что уже есть... Затем подымаются заново:
add 100.100.100.1 120.120.120.1 esp 0x201 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
Конфигурируется шифрование протоколом esp между конечными точками туннеля 100.100.100.1 120.120.120.1. Затем задается алгоритм аутентификации. Заметим, что ключи должны начинаться с символа 0x.
Затем задается собственно туннель:
spdadd 192.168.0.0/24 192.168.10.0/24 any -P out ipsec esp/tunnel/100.100.100.1-120.120.120.1/require;
Мы указываем ядру шифровать весть трафик который идет из сети 192.168.0.0/24 в сеть 192.168.10.0/24.
Вторая часть скрипта делает тоже самое только для трафика идущего в другую сторону. На другом конце туннеля скрипт должен выглядеть зеркально:
#!/usr/sbin/setkey -f
flush;
spdflush;
add 100.100.100.1 120.120.120.1 esp 0x201 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.0.0/24 192.168.10.0/24 any -P in ipsec esp/tunnel/100.100.100.1-120.120.120.1/require;
add 120.120.120.1 100.100.100.1 esp 0x301 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.10.0/24 192.168.0.0/24 any -P out ipsec esp/tunnel/120.120.120.1-100.100.100.1/require;
Найдите два различия ;)
Соберем это все вместе:
Создадим скрипт который сначала грузит модули, а потом вызывает скрипт который подымает туннель:
sudo touch /etc/rc.d/rc.ipsec
Откроем его в любом редакторе и наполним его таким содержимым:
#!/bin/sh
#
# Грузим необходимые модули.
/sbin/modprobe ah4
/sbin/modprobe esp4
# Заводим туннель
/etc/rc.d/rc.ipsec-office1
Создаем скрипт который поднимает туннель:
sudo touch /etc/rc.d/rc.ipsec-office1
Его содержимое было приведено выше:
#!/usr/sbin/setkey -f
flush;
spdflush;
add 100.100.100.1 120.120.120.1 esp 0x201 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.0.0/24 192.168.10.0/24 any -P out ipsec esp/tunnel/100.100.100.1-120.120.120.1/require;
add 120.120.120.1 100.100.100.1 esp 0x301 -m tunnel -E 3des-cbc
0xa028581bd1aa66e83a920ab0374270f0ceb7ae4fa8e08a23
-A hmac-md5 0x358f23ebbabce1d9de74bccd9d39b92d;
spdadd 192.168.10.0/24 192.168.0.0/24 any -P in ipsec esp/tunnel/120.120.120.1-100.100.100.1/require;
Права на чтение, выполнение и запись должны быть только у root. Раздадим необходимые права:
sudo chown root:root /etc/rc.d/rc.ipsec
sudo chown root:root /etc/rc.d/rc.ipsec-office1
sudo chmod 700 /etc/rc.d/rc.ipsec
sudo chmod 700 /etc/rc.d/rc.ipsec-office1
Ну и последний штрих, мы будем вызывать скрипт /etc/rc.d/rc.ipsec из /etc/rc.d/rc.local:
sudo echo /etc/rc.d/rc.ipsec >> /etc/rc.d/rc.local
Таким образом последовательность происходящих событий такова:
При загрузке системы в последнюю очередь выполняется скрипт /etc/rc.d/rc.local, последней командой в нем вызывается скрипт /etc/rc.d/rc.ipsec, который грузит нужные модули ядра и вызывает скрипт /etc/rc.d/rc.ipsec-office1, который в свою очередь подымает туннель. Вот и все. Никаких ppp интерфейсов, демонов и возни с маршрутизацией больше не нужно. Единственный недостаток, если на каком либо из транзитных маршрутизаторах теряются пакеты, даже пусть 1 — 2%, туннель начинает жутко тормозить. Благо у меня это случается очень редко.
Basmach
19.10.2007
|