Страница 1 из 1

Создание VPN во FreeBSD на базе IPSEC и racoon.

Добавлено: 14 июн 2010, 15:34
Raven
Исходим из предположения, что вам понадобилось объединить два офиса, шлюзами для которых в интернет являются машины с установленными на них FreeBSD. Я проделывал все это на FreeBSD 4.8.

Исходим из таких адресов на шлюзах:

Шлюз 1.
Внешний IP (смотрящий в инет) - xxx.xxx.xxx.xxx
Внутренний IP (смотрящий в сеть) - 10.1.1.1
Внутренняя сеть - 10.1.1.0/24
Шлюз 2.
Внешний IP (смотрящий в инет) - yyy.yyy.yyy.yyy
Внутренний IP (смотрящий в сеть) - 10.1.2.1
Внутренняя сеть - 10.1.2.0/24

Приступим.

Для начала добавим в ядро поддержку IPSEC:

Код: Выделить всё

   options         IPSEC
   options         IPSEC_ESP
   options         IPSEC_DEBUG
для старых версий FreeBSD надо еще добавить количество gif интерфейсов,
к примеру вот так:

Код: Выделить всё

   pseudo-device   gif     4
В моем случае это не нужно, ибо 4.8 версия совсем не старая ;)

Пересобираем ядро.

Теперь добавим в rc.conf параметры отвечающие за поднятие тоннеля и
запуск IPSEC:

Шлюз 1.

Код: Выделить всё

gifconfig_gif0="xxx.xxx.xxx.xxx  yyy.yyy.yyy.yyy"
ifconfig_gif0="inet 10.1.1.1 10.1.2.1 netmask 255.255.255.0"
static_routes="vpn"
route_vpn="10.1.2.0/24 10.1.2.1"
export route_vpn
ipsec_enable="YES"
ipsec_file="/etc/ipsec.conf"
Шлюз 2.

Код: Выделить всё

gifconfig_gif0="yyy.yyy.yyy.yyy  xxx.xxx.xxx.xxx"
ifconfig_gif0="inet 10.1.2.1 10.1.1.1 netmask 255.255.255.0"
static_routes="vpn"
route_vpn="10.1.1.0/24 10.1.1.1"
export route_vpn
ipsec_enable="YES"
ipsec_file="/etc/ipsec.conf"

Одного поднятия тоннеля мало, нам надо настроить еще и IPSEC.
Создаем файл /etc/ipsec.conf, в который пишем следующее:

Шлюз 1.

Код: Выделить всё

flush;
spdflush;
spdadd 10.1.1.0/24 10.1.2.0/24 any -P out ipsec esp/tunnel/xxx.xxx.xxx.xxx-yyy.yyy.yyy.yyy/require;
spdadd 10.1.2.0/24 10.1.1.0/24 any -P in ipsec esp/tunnel/yyy.yyy.yyy.yyy-xxx.xxx.xxx.xxx/require;
Шлюз 2.

Код: Выделить всё

flush;
spdflush;
spdadd 10.1.2.0/24 10.1.1.0/24 any -P out ipsec esp/tunnel/yyy.yyy.yyy.yyy-xxx.xxx.xxx.xxx/require;
spdadd 10.1.1.0/24 10.1.2.0/24 any -P in ipsec esp/tunnel/xxx.xxx.xxx.xxx-yyy.yyy.yyy.yyy/require;
Осталось только поставить и настроить racoon, который будет заниматься
обменом ключей.

На обоих шлюзах:

Код: Выделить всё

cd /usr/ports/security/racoon; make install clean
Правим файл конфигурации /usr/local/etc/racoon/racoon.conf

Код: Выделить всё

# $KAME: racoon.conf.in,v 1.18 2001/08/16 06:33:40 itojun Exp $

# "path" must be placed before it should be used.
# You can overwrite which you defined, but it should not use due to confusing.
path include "/usr/local/etc/racoon" ;
#include "remote.conf" ;

# search this file for pre_shared_key with various ID key.
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;

# racoon will look for certificate file in the directory,
# if the certificate/certificate request payload is received.
path certificate "/usr/local/etc/cert" ;

# "log" specifies logging level.  It is followed by either "notify", "debug"
# or "debug2".
#log debug;

# "padding" defines some parameter of padding.  You should not touch these.
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 to all
# available interface addresses.
listen
{
        #isakmp ::1 [7000];
        #isakmp 202.249.11.124 [500];
        #admin [7002];          # administrative's port by kmpstat.
        #strict_address;        # required all addresses must be bound.
}

# Specification of default various timer.
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;
doi ipsec_doi;
        situation identity_only;

        #my_identifier address;
        #my_identifier user_fqdn "sakane@kame.net";
        #peers_identifier user_fqdn "sakane@kame.net";
        #certificate_type x509 "mycert" "mypriv";

        nonce_size 16;
        lifetime time 24 hour;  # 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 24 hour;
        encryption_algorithm 3des ;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate ;
}
Правим файл usr/local/etc/racoon/psk.txt:

Код: Выделить всё

#Шлюз 1.

yyy.yyy.yyy.yyy   password:)

#Шлюз 2.

xxx.xxx.xxx.xxx   password:)
Если у вас на шлюзах есть фаервол (а ведь он у вас есть, правда?) тогда
нам нужно разрешить трафик по нашему тоннелю, в ipf это делается так

Код: Выделить всё

pass in log quick proto esp from any to any
pass in log quick proto udp from any port = 500 to any port = 500
Желательно поставить это повыше в рулах.

Вот и все. Остается собственно только перегрузить шлюзы.

Попробуем теперь как это работает.
К примеру для Шлюза 1.

В одной консоли пишем

Код: Выделить всё

ping 10.1.2.1
,
во второй

Код: Выделить всё

tcpdump -i <внешний интерфейс> ip host yyy.yyy.yyy.yyy
Наблюдать мы должный что-то типа:

Код: Выделить всё

19:16:13.207380 yyy.yyy.yyy.yyy > xxx.xxx.xxx.xxx: ESP(spi=0x04406f1c,seq=0x11b2)
19:16:14.024904 xxx.xxx.xxx.xxx > yyy.yyy.yyy.yyy: ESP(spi=0x0e57fdd4,seq=0x1581)
Если наблюдаем, значит все у нас шифруется, а то что пинги идут
доказывает то, что racoon сделал свое темное дело и обменялся ключами :)

Возможно вам не захочется чтобы все машины из ваших подсеток видели друг
друга, у меня это решено с помощью ipf следующим образом:

Код: Выделить всё

pass in quick on xl1 from 10.1.1.51/32 to 10.1.2.0/24
pass in quick on xl1 from 10.1.1.58/32 to 10.1.2.0/24
block in quick on xl1 from 10.1.1.0/24 to 10.1.2.0/24
Здесь xl1 мой внутренний интерфейс. Мы пускаем в тоннель только машины
10.1.1.51 и 10.1.1.58 - остальные могут расслабиться :)