Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> главная —> Архив —> IPsec

Настройка туннеля между двумя сетями

Автор: lissyara.


Эта статья в архиве. Новая версия доступна по адресу: http://www.lissyara.su/?id=1328

  Возникла, как-то, необходимость соединить два офиса. Оба в Москве, у обоих есть инет и "белый" IP. Просто из одного офиса человеки должны были удалённо работать в 1с. Покупать кошку, ради двух компов, - как-то несерьёзно на мой взгляд. Да и не дал бы никто денег столько :) Зато и там, и у меня на шлюзовом компе стояли фряхи. Вот и решил замутить между ними туннель, заодно и окучить новую для меня тему.
   Изыскания в поисковиках, по ключевым словам "vpn freebsd" принесли много интересного, но самое интересное нашлось уже в самом конце, когда всё было сделано. Это статья на родном сайте FreeBSD... А я настривал по куче кривых мануалов :( Ну да ладно, тем более, что в этой статье тоже нехватает некоторых мелких моментов, из-за которых я проковырялся два дня.
   Итак. Дано: два компа с FreeBSD4.11, на обоих по две сетевухи, на первом IP - 192.168.20.254 и 222.222.222.222, а на втором соответственно 192.168.30.254 и 111.111.111.111 - а какой относится к частной сети, какой к инету - думаю сами догадаетесь. Для начала надо включить в ядре поддержку устройства gif - generic interface, такой вот хитрый сетевой интерфейс. Заодно, чтобы не пересобирать ядро три раза, сразу включаем туда поддержку IPsec:
/usr/home/lissyara/>cd /usr/src/sys/i386/conf/
/usr/src/sys/i386/conf/>ls
GENERIC         LINT
/usr/src/sys/i386/conf/>cp GENERIC IPSec
/usr/src/sys/i386/conf/>ls
GENERIC         LINT            IPSec
/usr/src/sys/i386/conf/>ee IPSec

И вносим туда строки:
# firewall
options         IPFIREWALL
options         IPFIREWALL_VERBOSE
options         IPFIREWALL_VERBOSE_LIMIT=1000
options         TCP_DROP_SYNFIN

# IPSEC
options         IPSEC
options         IPSEC_ESP
options         IPSEC_DEBUG

Также проверяем наличие этого самого gif`a, должна быть строка
pseudo-device   gif             # IPv6 and IPv4 tunneling
учтите, если у Вас фря до версии 4.2 то надо указать число интерфейсов, т.е она будет такой:
pseudo-device   gif       2      # IPv6 and IPv4 tunneling
После чего пересобираем ядро и перезагружаемся:
/usr/src/sys/i386/conf/>cd ../../../
/usr/src/>make buildkernel KERNCONF=IPSec && make installkernel KERNCONF=IPSec
..............
/usr/src/>shutdown -r now

После перезагрузки создаём туннель и тестируем его (пока только между машинами, и нешифрованный) Для первой машины:
/usr/home/lissyara/>ifconfig
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=1<RXCSUM>
        inet 222.222.222.222 netmask 0xffffff00 broadcast 222.222.222.255
        ether 00:0a:5e:3c:e9:ba
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.20.254 netmask 0xffffff00 broadcast 192.168.20.255
        ether 00:11:d8:e7:a6:41
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000
/usr/home/lissyara/>ifconfig gif0 create
/usr/home/lissyara/>ifconfig
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=1<RXCSUM>
        inet 222.222.222.222 netmask 0xffffff00 broadcast 222.222.222.255
        ether 00:0a:5e:3c:e9:ba
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.20.254 netmask 0xffffff00 broadcast 192.168.20.255
        ether 00:11:d8:e7:a6:41
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
/usr/home/lissyara/>gifconfig gif0 222.222.222.222 111.111.111.111
/usr/home/lissyara/>ifconfig
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=1<RXCSUM>
        inet 222.222.222.222 netmask 0xffffff00 broadcast 222.222.222.255
        ether 00:0a:5e:3c:e9:ba
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.20.254 netmask 0xffffff00 broadcast 192.168.20.255
        ether 00:11:d8:e7:a6:41
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000
gif0: flags=8050<POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet 222.222.222.222 --> 111.111.111.111
/usr/home/>ifconfig gif0 192.168.20.254 192.168.30.254 netmask 255.255.255.0
/usr/home/lissyara/>ifconfig
xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=1<RXCSUM>
        inet 222.222.222.222 netmask 0xffffff00 broadcast 222.222.222.255
        ether 00:0a:5e:3c:e9:ba
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.20.254 netmask 0xffffff00 broadcast 192.168.20.255
        ether 00:11:d8:e7:a6:41
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet 222.222.222.222 --> 111.111.111.111
        inet 192.168.20.254 --> 192.168.30.254 netmask 0xffffff00
/usr/home/lissyara/>ipfw add 1 allow ipencap from any to any
/usr/home/lissyara/>

Ну и для второй машины:
/usr/home/lissyara/>ifconfig gif0 create
/usr/home/lissyara/>gifconfig gif0 111.111.111.111 222.222.222.222
/usr/home/>ifconfig gif0 192.168.30.254 192.168.20.254 netmask 255.255.255.0
/usr/home/lissyara/>ifconfig
ed0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 111.111.111.111 netmask 0xffffff00 broadcast 111.111.111.255
        ether 52:54:05:f0:fb:27
fxp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 192.168.30.254 netmask 0xffffff00 broadcast 192.168.30.255
        ether 00:20:ed:51:7d:d0
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000
sl0: flags=c010<POINTOPOINT,LINK2,MULTICAST> mtu 552
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet 111.111.111.111 --> 222.222.222.222
        inet 192.168.30.254 --> 192.168.20.254 netmask 0xffffff00
/usr/home/lissyara/>ping 192.168.20.254
PING 192.168.20.254 (192.168.20.254): 56 data bytes
^C
--- 192.168.20.254 ping statistics ---
8 packets transmitted, 0 packets received, 100% packet loss
/usr/home/lissyara/>ipfw add 1 allow ipencap from any to any
00001 allow ipencap from any to any
/usr/home/lissyara/>ping 192.168.20.254
PING 192.168.20.254 (192.168.20.254): 56 data bytes
64 bytes from 192.168.20.254: icmp_seq=12 ttl=64 time=11.709 ms
64 bytes from 192.168.20.254: icmp_seq=13 ttl=64 time=18.066 ms
64 bytes from 192.168.20.254: icmp_seq=14 ttl=64 time=11.074 ms
64 bytes from 192.168.20.254: icmp_seq=15 ttl=64 time=11.068 ms
64 bytes from 192.168.20.254: icmp_seq=16 ttl=64 time=11.099 ms
64 bytes from 192.168.20.254: icmp_seq=17 ttl=64 time=11.268 ms
64 bytes from 192.168.20.254: icmp_seq=18 ttl=64 time=15.273 ms
^C
--- 192.168.20.254 ping statistics ---
7 packets transmitted, 7 packets received, 0% packet loss
round-trip min/avg/max/stddev = 11.068/12.794/18.066/2.571 ms

Некоторые вещи, я так думаю, надо пояснить. Во-первых, команда
ifconfig gif0 create - нигде, в процессе поиска мануалов по сети я про неё не встречал упоминания. Согласно всем руководствам получается, что интерфейс gif0 создаётся сам. Тока вот у меня он почему-то не создавался.... Второе,
gifconfig gif0 main_external_IP some_external_IP
ifconfig gif0 main_int_IP some_int_IP netmask 255.255.255.0
- мы создаём собственно туннель, по которому и будут перемещаться пакеты. Затем добавляем правило в файрволл, разрешающее ходить пакетам по протоколу ipencap (протокол работающий поверх IP и в котором передаются инкапсулированные пакеты - т.е. один внутри другого)
ipfw add 1 allow ipencap from any to any - правило, конечно грубое, и оставлять его в таком виде нельзя, но, в данный момент, для тестирования - сойдёт.
   Итак, мы создали туннель между двумя компами, и оно даже работает :) Правда в таком виде не видно внутренних сетей, за компами, да и работать оно будет ровно до первой перезагрузки, но уже прогресс. Теперь надо зашифровать канал. Для этого надо поставить демона racoon - он будет "договариваться" о шифровании. Ставим:
/usr/home/lissyara/>cd /usr/ports/security/racoon
/usr/ports/security/racoon/>make && make install && make clean
....................................
/usr/ports/security/racoon/>cd /usr/local/etc/rc.d
/usr/local/etc/rc.d/>echo 'racoon_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/>./racoon.sh start
./racoon.sh: WARNING: /usr/local/etc/racoon/racoon.conf is not readable.
/usr/local/etc/rc.d/>cp ../racoon/racoon.conf.dist ../racoon/racoon.conf
/usr/local/etc/rc.d/>./racoon.sh start
Starting racoon.
/usr/local/etc/rc.d/>sockstat | grep raco
root     racoon   10396    6 udp4   192.168.20.254:500     *:*
root     racoon   10396    7 udp4   127.0.0.1:500         *:*
root     racoon   10396    8 udp4   222.222.222.222:500   *:*
root     racoon   10396    3 dgram  syslogd[167]:3

После чего редактируем файл /usr/local/etc/racoon/racoon.conf до такого состояния:
path include "/usr/local/etc/racoon" ;
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;
# "log" specifies logging level.  It is followed by either "notify", "debug"
# or "debug2".
#log notify;
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.
}

listen
{
        #isakmp ::1 [7000];
        isakmp 222.222.222.222 [500];
        #admin [7002];          # administrative's port by kmpstat.
        #strict_address;        # required all addresses must be bound.
}

timer
{
        # These value can be changed per remote node.
        counter 5;              # maximum trying count to send.
        interval 20 sec;        # maximum interval to resend.
        persend 1;              # the number of packets per a send.

        # timer for waiting to complete each phase.
        phase1 30 sec;
        phase2 15 sec;
}

remote anonymous
{
        #exchange_mode main,aggressive;
        exchange_mode aggressive,main;
        doi ipsec_doi;
        situation identity_only;

        my_identifier address;
        #certificate_type x509 "mycert" "mypriv";

        #nonce_size 16;
        lifetime time 2 min;    # sec,min,hour
        initial_contact on;
        #support_mip6 on;
        proposal_check obey;    # obey, strict or claim

        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key ;
                dh_group 2 ;
        }
}

sainfo anonymous
{
        pfs_group 1;
        lifetime time 2 min;
        encryption_algorithm 3des ;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate ;
}

Различие файлов на машинах заключается только в строке  
isakmp 222.222.222.222 [500]; - в ней надо вбить IP той машины на которой конфиг и располагается. Теперь надо создать файл с паролем:
/usr/local/etc/rc.d/>cd /usr/local/etc/racoon/
/usr/local/etc/racoon/>echo '222.222.222.222 my_secret_password' > psk.txt
/usr/local/etc/racoon/>chmod 600 *

IP должны быть зеркально, т.е. на машине 222.222.222.222 в файле /usr/local/etc/racoon/psk.txt будет строка
111.111.111.111 my_secret_password

и наоборот. Не забудьте поставить права на файл - иначе туннель не заработает! Далее создаём скрипт запуска туннеля:
/usr/local/etc/racoon/>cd /usr/local/etc/rc.d
/usr/local/etc/rc.d/>touch tunnel.sh
/usr/local/etc/rc.d/>chmod +x tunnel.sh
/usr/local/etc/rc.d/>ee tunnel.sh

такого вида (машина 1):
#!/bin/sh
case "$1" in
start)

/sbin/ifconfig gif0 create
/usr/sbin/gifconfig gif0 222.222.222.222 111.111.111.111
/sbin/ifconfig gif0 192.168.20.254 192.168.30.254 netmask 255.255.255.0
/sbin/ifconfig gif0 mtu 1500
/sbin/route delete 192.168.30.0
/sbin/route add 192.168.30.0 192.168.30.254

;;
esac

и такого (машина 2):
#!/bin/sh
case "$1" in
start)

/sbin/ifconfig gif0 create
/usr/sbin/gifconfig gif0 111.111.111.111 222.222.222.222
/sbin/ifconfig gif0 192.168.30.254 192.168.20.254 netmask 255.255.255.0
/sbin/ifconfig gif0 mtu 1500
/sbin/route delete 192.168.20.0
/sbin/route add 192.168.20.0 192.168.20.254

;;
esac

Различие только в том, что поменяны местами IP. Также там добавляется маршрут, в таблицу роутинга, чтоб компы одной сети могли достучаться до другой. MTU задан 1500 чтобы небыло проблем (изначально он по-умолчанию 1280) - icmp-пакеты и по 1280 бегают без проблем, а вот TCP начинает работать "по настроению" - когда захочет, и как захочет. Теперь надо заняться IPsec, создаём файл /etc/ipsec.conf, на первой машине он будет таким:
spdadd 222.222.222.222/32 111.111.111.111/32 ipencap -P out ipsec
 esp/tunnel/222.222.222.222-111.111.111.111/require;
spdadd 111.111.111.111/32 222.222.222.222/32 ipencap -P in ipsec
 esp/tunnel/111.111.111.111-222.222.222.222/require;

а на второй таким
spdadd 111.111.111.111/32 222.222.222.222/32 ipencap -P out ipsec
 esp/tunnel/111.111.111.111-222.222.222.222/require;
spdadd 222.222.222.222/32 111.111.111.111/32 ipencap -P in ipsec
 esp/tunnel/222.222.222.222-111.111.111.111/require;

и добавляем в /etc/rc.conf такие строки
ipsec_enable="YES"
ipsec_file="/etc/ipsec.conf"

также вверху файрволла, до запретов и всяких divert, forward и прочего добавляем такие правила (одинаковые, т.к. они симметричны):

allow ip from any to any via gif0
allow udp from 222.222.222.222 to 111.111.111.111 500
allow udp from 111.111.111.111 to 222.222.222.222 500
allow esp from 222.222.222.222 to 111.111.111.111
allow esp from 111.111.111.111 to 222.222.222.222

Перезагружаемся и пробуем, завелось ли всё это хозяйство:
/usr/home/lissyara/>ping 192.168.20.254
PING 192.168.20.254 (192.168.20.254): 56 data bytes
64 bytes from 192.168.20.254: icmp_seq=2 ttl=64 time=18.622 ms
64 bytes from 192.168.20.254: icmp_seq=3 ttl=64 time=16.424 ms
^C
--- 192.168.20.254 ping statistics ---
4 packets transmitted, 2 packets received, 50% packet loss
round-trip min/avg/max/stddev = 16.424/17.523/18.622/1.099 ms
/usr/home/lissyara/>

Всё нормально (первый пакет всегда теряется - т.к. на установление соединения нужно время). Если не заработало, то пробуем запустить racoon с отладкой
racoon -F -f /usr/local/etc/racoon/racoon.conf
Также смотрим роутинг:
netstat -rn
и чё там у нас шифруется
setkey -D
Для просмотра того, что гуляет по интерфейсам юзаем:
tcpdump -i gif0 (можно и другой интерфейс подставить)
По поводу setkey -D - она выводит данные только в случае установленного соединения (канал уже существует) - если не было ни одного пакеты в нужном направлении, то она ничего не выведет.
   Учтите, в данном случае всё упирется в пароль, конечно, лучше бы сделать на сертификатах, но это уже повод для другой статьи :)

P.S. В современных портах порт racoon входит в состав /usr/ports/security/ipsec-tools/



размещено: 2005-11-03,
последнее обновление: 2007-11-23,
автор: lissyara


Art, 2005-12-16 в 18:01:30

Ага, а как с кошками траблы так ко мне?

lissyara, 2005-12-16 в 22:18:49

Одно дело - сиськи, а другое - черти :)))

Ну нету на цисках tcpdump - а все проблемы я решал именно им...

Abigor, 2006-03-08 в 9:12:07

Вопрос, а будет ли это работать, если первый сервер имеет белый ip а второй сидит за натом? и как в такм случае должны выглядить правила для ната?

lissyara, 2006-03-08 в 9:17:18

В таком варианте, лучше поставить, poptop например...

0rion, 2006-09-24 в 17:20:54

в кисках есть замечательная штука - debug.

Sergey, 2006-11-10 в 11:34:00

хех начнем с того что в Freebsd 6.1 не gifconfig а ifconfig
во вторых racoon нету а есть racoon2
почемуто при установке у меня из портов не скриптов запуска не конфигов нету!!!
и после конфигурирования
команда ifconfig выводит не  
ifconfig

gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
       tunnel inet 111.111.111.111 --> 222.222.222.222
       inet 192.168.30.254 --> 192.168.20.254 netmask 0xffffff00

а выводит
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
       inet 192.168.30.254 --> 192.168.20.254 netmask
т.е. тунель не поднимаеться почемуто кто что может посоветовать?

Stradivarius, 2006-12-10 в 23:39:47

Tut u nego verno prosto tebe nujno zdelat
ifconfig gif0 tunnel aaaa bbbb

Алёшенька, 2007-01-22 в 12:30:19

Кто нибудь настраивал ipsec на основе сертификатов?? Если да то поделитесь своими впечатлениями и измышлениями.

alex3, 2007-03-15 в 14:09:37

To Sergey
racoon в составе ipsec-tools, 2-й racoon не удалось пустить
туннель не поднимается потому что (сам наступил на те же грабли) надо
ifconfig gif0 tunnel 111.111.111.111 222.222.222.222
а в остальном все верно

PokerFlat, 2009-10-23 в 14:52:15

/usr/src/sys/i386/conf/IPSec: unknown option \"IPSEC_ESP\"
*** Error code 1

Stop in /usr/src.
*** Error code 1

Stop in /usr/src.

Как быть? Голая 6.4 фряха соит!

vadim64, 2010-11-03 в 14:42:37

1. а где ссылка на обсуждение?
2. а как щас в 2010 с этим обстоят дела? меньше костылей можно использовать? в хэндбуке тоже про IPSEC_ESP пишут(((
3. to PokerFlat: читать /usr/src/UPDATING нада

carnivore, 2010-11-05 в 11:01:13

а если на одном из роутеров 2 подсети и нужно все это объеденить через ВПН??

weec, 2013-02-14 в 17:49:55

объясните для чего gif интерфейс?
без него прекрасно работает

Гость, 2013-08-16 в 18:04:43

gif для того, чтобы прекрасно работало не только в локальной сети, но и через Интернет.



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.0684 секунд
Из них PHP: 46%; SQL: 54%; Число SQL-запросов: 63 шт.
Исходный размер: 75073; Сжатая: 12016