Постановка задачи.
1. Соединить VPN каналом два офиса, так чтобы пользователи офиса А могли ходить к ресурсам офиса Б, а пользователи офиса Б могли ходить к серверам офиса А
Анализ
Есть масса впн технологий: pptp, l2tp, gre, pppoe, ipsec, какую выбрать?
Я выбрал ipsec из-за того что нет необходимости настраивать отдельно сервер и клиента, соответственно нет проблем с дисконнектами (за исключением обрывов связи с провайдером), и потому что строится двунаправленый тоннель сеть ↔ сеть

Приступим...
На начальном этапе берем два компьютера и ставим туда Freebsd 7,2. Я нашел у себя диск с релизом (вы при желании можете выкачать версию 8,0), это меня не устроило и после установки я обновил ее до 7,2 stable и пересобрал ядро со следующими параметрами
Для фаервола
Код: Выделить всё
#PF
device pf
device pflog
device pfsync
#ALTQ
options ALTQ
options ALTQ_CBQ # Class Bases Queueing
options ALTQ_RED # Random Early Detection
options ALTQ_RIO # RED In/Out
options ALTQ_HFSC # Hierarchical Packet Scheduler
options ALTQ_CDNR # Traffic conditioner
options ALTQ_PRIQ # Priority Queueing
options ALTQ_NOPCC # Required for SMP build
options ALTQ_DEBUG
#для IPSEC
#IPSEC
options IPSEC #IP security
options IPSEC_DEBUG #debug for IP security
device crypto
device cryptodev
device enc
#На всякий случай добавил
#NetGraph
options NETGRAPH #netgraph(4) system
options NETGRAPH_ASYNC
options NETGRAPH_BPF
options NETGRAPH_CISCO
options NETGRAPH_ECHO
options NETGRAPH_ETHER
options NETGRAPH_FRAME_RELAY
options NETGRAPH_HOLE
options NETGRAPH_IFACE
options NETGRAPH_KSOCKET
options NETGRAPH_L2TP
options NETGRAPH_LMI
# MPPC compression requires proprietary files (not included)
#options NETGRAPH_MPPC_COMPRESSION
options NETGRAPH_MPPC_ENCRYPTION
options NETGRAPH_ONE2MANY
options NETGRAPH_PPP
options NETGRAPH_PPPOE
options NETGRAPH_PPTPGRE
options NETGRAPH_RFC1490
options NETGRAPH_SOCKET
options NETGRAPH_TEE
options NETGRAPH_TTY
options NETGRAPH_UI
options NETGRAPH_VJC
device gre #если в будущем буду строить gre тоннели
device carp #если в последующем понадобиться Load-BalansingКод: Выделить всё
device gif # IPv6 and IPv4 tunneling
Код: Выделить всё
make buildworld
make buildkernel KERNCONF=Ваше ядро
make installkernel KERNCONF=Ваше ядро
make installworld
reboot
итак у нас все готово
мы планируем подключаться по следующей схеме
где
A.A.A.A. Внешний ip адрес офиса А он же внешний интерфейс нашего впн сервера
192.168.0.1 внутренний интерфейс нашего впн сервера смотрящий в подсеть офиса А 192.168.0.0/24 (рассматривается плоская сеть)
B.B.B.B Внешний ip адрес офиса В он же внешний интерфейс нашего впн сервера
192.168.1.1 внутренний интерфейс нашего впн сервера смотрящий в подсеть офиса В 192.168.1.0/24 (рассматривается плоская сеть)
как видно из схемы наши VPN сервера являются так же и фаерволами
для настройки фаервола у нас используется пакетный фильтр PF
примем что в машинах установлены две сетевые карты em0 внешняя и em1 внутренняя
итак настраиваем pf
для начала копируем файл
/usr/src/tools/tools/tinybsd/conf/firewall/etc/pf.conf в директорию /etc
Код: Выделить всё
cp /usr/src/tools/tools/tinybsd/conf/firewall/etc/pf.conf /etc
Код: Выделить всё
:let wrapmode = 1
:imap <Up> <C-o>gk
:syntax enable
:set hlsearch
:abbreviate #i #include
:map <F12> <ESC>:if wrapmode == 1<CR>set nowrap<CR>let wrapmode = 0<CR>else<CR>set wrap<CR>let wrapmode = 1<CR>endif<CR><CR>
:imap <F12> <ESC>:if wrapmode == 1<CR>set nowrap<CR>let wrapmode = 0<CR>else<CR>set wrap<CR>let wrapmode = 1<CR>endif<CR><CR>i
:map <F10> <ESC>:q
:imap <F10> <ESC>:q
:imap <F2> <ESC>:w
:map <F2> <ESC>:w
:highlight Comment ctermfg=lightgreen
после установки vim у вас будет редактор с подсветкой синтаксиса)
Код: Выделить всё
/bin/sh]vim /etc/pf.confКод: Выделить всё
ext_if="em0" #внешний интерфейс
int_if="em1" #внутренний интерфейс
#Interface addres
ext_addr="A.A.A.A" #Внешний ip адрес сервера A
out_addr="В.В.В.В." #Внешний ip адрес сервера A
int_addr="192.168.0.1" #Внутренний ip адрес
#Nets
int_user="192.168.0.0/24" #Внутренняя сеть
out_user="192.168.1.0/24" #Удаленая сеть
set loginterface pflog0 #Устанавливаем лог интерфейс
set skip on lo #Не применяем настройки фаервола для адреса #127.0.0.1
set optimization normal #Устанавливаем политику нормализации правил #фаервола
set block-policy drop #Отбрасываем заблокированные пакеты
scrub in all #Нормализуем весь входящий трафик
nat on $ext_if from $int_user to any -> ($ext_if) #Натим наших юзеров в инет
block in log all #Блокируем и логируем весь входящий трафик
pass out all #Разрешаем весь исходящий трафик
# ПРАВИЛА ДЛЯ ВНУТРЕННЕЙ СЕТКИ
pass in on $int_if from $int_net_user to $out_user #разрешаем внутренним #юзерам ходить к юзерам из удаленной сетки
pass in on $int_if proto tcp from $int_net_user to any port { 80, 443 } #разрешаем нашим юзерам ходить на http и https ресурсы ( с ftp так просто проблема не решится надо будет поднять сквид или что-то подобное)
pass in on $int_if proto udp from $int_net_user to any port { 53, 123 } # разрешаем нашим пользователям отправлять в мир dns и ntp запросы
## ПРАВИЛА ДЛЯ ВНЕШНЕЙ СЕТКИ
pass in on $ext_if from $out_addr to $ext_addr #Открываем доступ с впн сервера офиса В до впн сервера (он же шлюз гейт …) офиса А
настройка фаервола на сервере В аналогична настройке на сервере А (только разумеется ip В.В.В.В. становиться внешним, а ip A.A.A.A. Становится удаленным) теперь идем в /etc/rc.conf и прописываем запуск нашего фаервола
Код: Выделить всё
###FIREWALL
pf_enable="YES"
pf_flags=""
pf_rules="/etc/pf.conf"
pf_program="/sbin/pfctl" # where the pfctl program lives
pflog_enable="YES"
pflog_flags=""
pflog_logfile="/var/log/pflog"
pflog_program="/sbin/pflogd" # where the pflogd program lives
pfsync_enable="NO" # Expose pf state to other hosts for syncing
pfsync_syncdev="" # Interface for pfsync to work through
Код: Выделить всё
pfctl -f /etc/pf.confpfctl -sn покажет правила ната
Теперь переходим к настройке непосредственно IPSEC
для начала установим на обоих серверах ipsec-tools
Код: Выделить всё
cd /usr/ports/security/ipsec-tools/
make
make installКод: Выделить всё
mkdir /usr/local/etc/racoonКод: Выделить всё
touch /usr/local/etc/racoon/psk.txt /usr/local/etc/racoon/racoon.confдля сервера А
В.В.В.В. preshared_key
для сервера В
А.А.А.А. preshared_key
Файл racoon.conf для обоих серверов в принципе одинаков за исключением одной строчки
Код: Выделить всё
path include "/usr/local/etc/racoon" ;
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;
log debug2;
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 A.A.A.A. [500]; #это строка для сервера A для сервера В она будет # выглядеть так isakmp В.В.В.В. [500];
}
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 60 sec;
phase2 60 sec;
}
remote anonymous {
exchange_mode aggressive,main;
doi ipsec_doi;
situation identity_only;
nonce_size 16;
lifetime time 36 hour; # sec,min,hour
initial_contact on;
support_proxy on;
proposal_check obey; # obey, strict or claim
proposal {
encryption_algorithm 3des;
hash_algorithm md5;
authentication_method pre_shared_key ;
dh_group 2;
}
}
sainfo anonymous {
pfs_group 1;
lifetime time 36 hour;
encryption_algorithm 3des;
authentication_algorithm hmac_sha1;
compression_algorithm deflate ;
}Теперь нам надо выбрать транспортную сетку по которой будут соединяться наши сервера. Я выбрал сеть 192.168.0.0/24 соответственно сервер А будет иметь транспортный ip 192.168.0.1, а сервер В транспортный ip 192.168.0.2
Создаем транспортную сеть между нашими серверами
На сервере А
Код: Выделить всё
ifconfig gif0 create
ifconfig gif0 tunnel А.А.А.А. В.В.В.В.
ifconfig gif0 inet 192.168.0.1 192.168.0.2 netmaks 255.255.255.255Код: Выделить всё
ifconfig gif0 create
ifconfig gif0 tunnel В.В.В.В. А.А.А.А.
ifconfig gif0 inet 192.168.0.2 192.168.0.1 netmaks 255.255.255.255
Код: Выделить всё
ping 192.168.0.2Код: Выделить всё
ping 192.168.0.1После того как транспортные ip запинговались прописываем их подъем в /etc/rc.conf на обоих серверах
На сервере А
Код: Выделить всё
gif_interfaces="gif0"
gifconfig_gif0="А.А.А.А. В.В.В.В."
ifconfig_gif0="inet 192.168.0.1 192.168.0.2 netmask 0xffffffff"
Код: Выделить всё
gif_interfaces="gif0"
gifconfig_gif0="В.В.В.В. А.А.А.А."
ifconfig_gif0="inet 192.168.0.2 192.168.0.1 netmask 0xffffffff"для этого создаем файл /etc/ipsec.conf
на сервере А
Код: Выделить всё
flush;
spdflush;
spdadd 192.168.1.0/24 192.168.100.0/24 any -P out ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;
spdadd 192.168.100.0/24 192.168.1.0/24 any -P in ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;
Код: Выделить всё
flush;
spdflush;
spdadd 192.168.100.0/24 192.168.1.0/24 any -P out ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;
spdadd 192.168.1.0/24 192.168.100.0/24 any -P in ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;
Код: Выделить всё
setkey -f /etc/ipsec.conf на сервере А
Код: Выделить всё
racoon_enable="YES"
racoon_flags="-f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log"
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/etc/ipsec.conf"
static_routes="b"
route_b="-net 192.168.100.0/24 192.168.0.2"Код: Выделить всё
racoon_enable="YES"
racoon_flags="-f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log"
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/etc/ipsec.conf"
static_routes="a"
route_a="-net 192.168.1.0/24 192.168.0.1"Код: Выделить всё
/usr/local/etc/rc.d/racoon startКод: Выделить всё
/etc/netstartесли у вас идет подключение по следующей схеме

то в файле /etc/ipsec.conf надо на сервере А добавить сетку
Код: Выделить всё
spdadd 192.168.10.0/24 192.168.100.0/24 any -P out ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;
spdadd 192.168.100.0/24 192.168.10.0/24 any -P in ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;Код: Выделить всё
spdadd 192.168.1.0/24 192.168.110.0/24 any -P out ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;
spdadd 192.168.110.0/24 192.168.1.0/24 any -P in ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;на сервере В добавляем
Код: Выделить всё
spdadd 192.168.100.0/24 192.168.10.0/24 any -P out ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;
spdadd 192.168.10.0/24 192.168.100.0/24 any -P in ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;Код: Выделить всё
spdadd 192.168.110.0/24 192.168.1.0/24 any -P out ipsec esp/tunnel/B.B.B.B.-A.A.A.A./unique ;
spdadd 192.168.1.0/24 192.168.110.0/24 any -P in ipsec esp/tunnel/А.А.А.А.-B.B.B.B./unique ;после этих дополнений выполняем команду
Код: Выделить всё
setkey -f /etc/ipsec.conf после подъема туннеля выполните команду
Код: Выделить всё
setkey -D