Создание VPN во FreeBSD 10.0 (IPSec, racoon, pf, nat)

Опубликовано:

В данной статье я приведу пример личного опыта по созданию защищённого туннеля между двумя сетями (офисами). Шлюзом для каждого из офисов будет выступать машина на FreeBSD 8.0. Процесс создания VPN через IPSec во FreeBSD 8.0 имеет несколько принципиальных различий, что и послужило толчком для написания данной статьи.

Будем считать, что система уже установлена и перейдем сразу к процессу настройки.
Внимание! Все действия, описанные в данной статье, необходимо выполнять с правами пользователя root.

Исходные данные:

офис #1:
внешний адрес сервера — 111.111.111.111;
внутренний адрес сервера — 192.168.1.1;
адрес внутренней офисной сети — 192.168.1.0/24.

офис #2:
внешний адрес сервера — 222.222.222.222;
внутренний адрес сервера — 192.168.2.1;
адрес внутренней офисной сети — 192.168.2.0/24.

Если Вы предполагаете, что поддержка IPSec уже установлена, то проверить это можно следующей командой:

sysctl -a | grep ipsec

1. Обновления системы и дерева портов

обновляем систему, используя утилиту для бинарного обновления системы — freebsd-update:
Код:

freebsd-update fetch && freebsd-update install

скачиваем и обновляем коллекцию портов
Код:

 

2. Пересборка ядра системы Для работы IPSec и pf на уровне ядра необходимо пересобрать ядро. Для этого скопируем файл настройки ядра GENERIC под некоторым именем.

Код:

 

cp /usr/src/sys/i386/conf/GENERIC /usr/src/sys/i386/conf/IPSECKERNEL

затем необходимо добавить в наш файл следующие строчки:

Код:
options IPSEC
device crypto

Внимание! Для работы IPSEC во FreeBSD, начиная с версии 7.0, необходимо указывать только эти строчки!

Как я уже упомянул выше, мы будем использовать фаервол pf, который также будет транслировать адреса (NAT) в нашу внутреннюю сеть. pf отличается простой настройкой и высокой скоростью работы, т.к. он работает на уровне ядра + в него встроена поддержка трансляции адресов NAT.

Добавляем поддержку нашего фаервола pf:

Код:
device pf
device pflog
device pfsync

и ОБЯЗАТЕЛЬНО включите следующие опции в ядро Вы хотите использовать приоритезацию и очереди ALTQ

<span style="color: orange;">options</span>         ALTQ
<span style="color: orange;">options</span>         ALTQ_CBQ        <span style="color: red;"># Class Bases Queuing (CBQ)</span>
<span style="color: orange;">options</span>         ALTQ_RED        <span style="color: red;"># Random Early Detection (RED)</span>
<span style="color: orange;">options</span>         ALTQ_RIO        <span style="color: red;"># RED In/Out</span>
<span style="color: orange;">options</span>         ALTQ_HFSC       <span style="color: red;"># Hierarchical Packet Scheduler (HFSC)</span>
<span style="color: orange;">options</span>         ALTQ_PRIQ       <span style="color: red;"># Priority Queuing (PRIQ)</span>
<span style="color: orange;">options</span>         ALTQ_NOPCC      <span style="color: red;"># Required for SMP build</span>


или

<span style="color: orange;">options</span>         ALTQ            </code><span style="color: red;"># включает подсистему ALTQ</span>

<code><span style="color: orange;">options</span>         ALTQ_CBQ        </code><span style="color: red;"># Class Bases Queuing (CBQ) позволяет распределять пропускную</span>
<span style="color: red;">                   способность соединений по классам или очередям для выставления приоритетов</span>
<span style="color: red;">                   трафика на основе правил фильтрации.</span>
<code><span style="color: orange;">options</span>         ALTQ_RED        </code><span style="color: red;"># Random Early Detection (RED) используется для предотвращения</span>
		<span style="color: red;"> перегрузки сети. RED вычисляет длину очереди и сравнивает ее с минимальным и максимальным</span>
		<span style="color: red;"> значением длины очереди. Если очередь превышает максимум, все новые пакеты будут</span>
		<span style="color: red;"> отброшены. В соответствии со своим названием, отбрасывает пакеты из различных </span>
		<span style="color: red;">соединений в произвольном порядке.</span>
<code><span style="color: orange;">options</span>         ALTQ_RIO        <span style="color: red;"># RED In/Out</span>
<span style="color: orange;">options</span>         ALTQ_HFSC       <span style="color: red;"># Hierarchical Packet Scheduler (HFSC)</span>
<span style="color: orange;">options</span>         ALTQ_PRIQ       </code><span style="color: red;"># Priority Queuing (PRIQ) PRIQ всегда первым пропускает трафик из очереди </span>
		<span style="color: red;">c более высоким приоритетом.</span>
<code><span style="color: orange;">options</span>         ALTQ_NOPCC      </code><span style="color: red;"># Required for SMP build Эта опция необходима для SMP систем.</span></pre>
<br style="color: #000000;" /><br style="color: #000000;" /><br style="color: #000000;" /><big style="font-weight: bold;"><big>Руссифицирцем консоль:</big></big>

Добавляем
<p style="color: #000000;">mcedit  /etc/profile</p>
<p style="color: #000000;">следующее:</p>

<div style="color: #000000;">
<div class="smallfont">Код:</div>
<pre class="alt2" dir="ltr">LANG=ru_RU.KOI8-R; export LANG
MM_CHARSET=KOI8-R; export MM_CHARSET</pre>
</div>
а в
<p style="color: #000000;">mcedit  /etc/csh.login</p>
<p style="color: #000000;">следующее:</p>
Код:
<div style="color: #000000;">
<pre class="alt2" dir="ltr">setenv LANG ru_RU.KOI8-R
setenv MM_CHARSET KOI8-R.</pre>
</div>
<p style="color: #000000;"><big style="font-weight: bold;"><big>Cобираем наше новое ядро:</big></big></p>

<div style="color: #000000;">
<pre class="alt2" dir="ltr">cd /usr/src
make buildkernel KERNCONF=IPSECKERNEL && make installkernel KERNCONF=IPSECKERNEL</pre>
</div>
Когда наше ядро собралось, необходимо перезагрузиться
<div style="color: #000000;">
<div class="smallfont">Код:</div>
<pre class="alt2" dir="ltr">reboot или <code>shutdown -r now

3. Установка пакета ipsec-tools

Код:
cd /usr/ports/security/ipsec-tools
make install clean

в начале установки будет предложено выбрать опции для установки. Я убрал поддержку IPv6, NATT, HYBRID.
Демон racoon, необходимый для шифрования данных, уже включён в пакет ipsec-tools и установится автоматически.

4. Настраеваем фаервол pf с трансляцией nat'а

Внимание! Для того, чтобы наш сервер выпускал соединения из локальной сети, в /etc/rc.conf должен обязательно присутствовать параметр gateway_enable="YES".

echo  gateway_enable="YES" >> /etc/rc.conf

Создаем файл /etc/pf.conf:

Код:
# vr0 - имя сетевой карточки, смотрящей в офисную сеть
int_if="vr0"
# rl0 - имя сетевой карточки, смотрящей в интернет
ext_if="rl0"
localnet="192.168.1.0/24"

#определяем через переменные ip-адреса офисов

Код:
office1_ip="111.111.111.111"
office2_ip="222.222.222.222"

#опять таки, через переменную перечисляем какие порты выпускать из офиса во внешний мир

Код:
tcp_ports="{22,80,443,25,110,465,995,5190}"
udp_ports="{53}"

#не фильтруем трафик, проходящий по интерфейсу lo0 (интерфейс внутренней петли), gif0 (виртуальный туннель между офисами) и $int_if (интерфейс внутренней офисной сети)

Код:
set skip on lo0
set skip on gif0
set skip on $int_if

#отбрасываем входящие пакеты, с нестандартными опциями

Код:
scrub in all

#создаем правило трансляции адресов из офисной сети во внешний мир

Код:
nat on $ext_if from $localnet to any -> ($ext_if)

#включаем антиспуфинг для внешнего интерфейса

Код:
antispoof quick for $ext_if

#блокируем все по умолчанию

Код:
block all

#разрешаем доступ из офисной сети во внешний мир портам, перечисленным в переменных tcp_ports и udp_ports:

Код:
pass out on $ext_if proto tcp to any port $tcp_ports keep state
pass out on $ext_if proto udp to any port $udp_ports keep state

#разрешаем доступ к нашей машине по ssh из внешнего мира

Код:
pass in inet proto tcp from any to $ext_if port 22 keep state

#разрешаем пинг

Код:
pass inet proto icmp all

#разрешаем исходящий трафик IPSec с офиса 1 на офис 2

Код:
pass out quick on $ext_if proto udp from $office1_ip port = isakmp to $office2_ip port = isakmp
pass out quick on $ext_if proto esp from $office1_ip to $office2_ip
pass out quick on $ext_if proto ipencap from $office1_ip to $office2_ip

#разрешаем входящий трафик IPSec, пришедший с офиса 2 на офис 1

Код:
pass in quick on $ext_if proto udp from $office2_ip port = isakmp to $office1_ip port = isakmp
pass in quick on $ext_if proto esp from $office2_ip to $office1_ip
pass in quick on $ext_if proto ipencap from $office2_ip to $office1_ip

Это были приведены настройки сервера офиса 1, для второй машины необходимо поменять IP-адреса зеркально.
Для проверки правил (на случай если вы допустили где-то синтаксическую ошибку) можно воспользоваться командой pfctl -n -f

Код:
/etc/pf.conf

Добавляем в /etc/rc.conf:

#включем наш фаервол на этапе загрузки системы

Код:
echo #FIREWALL PF >> /etc/rc.conf
echo pf_enable="YES">> /etc/rc.conf
#указываем откуда загружать правила
echo pf_rules="/etc/pf.conf">> /etc/rc.conf
#указываем где находится программа для управления pf
echo pf_program="/sbin/pfctl">> /etc/rc.conf
echo pf_flags="" >> /etc/rc.conf
#включаем логирования для pf
Код:
echo #FIREWALL PF LOG >> /etc/rc.conf
echo pflog_enable="YES">> /etc/rc.conf
echo pflog_logfile="/var/log/pf.log">> /etc/rc.conf
echo pflog_program="/sbin/pflogd">> /etc/rc.conf
echo pflog_flags="">> /etc/rc.conf
echo pfsync_enable="NO">> /etc/rc.conf
echo pfsync_syncdev="">> /etc/rc.conf
echo pfsync_ifconfig="">> /etc/rc.conf

После перезагрузки мы получим рабочий шлюз на FreeBSD с NAT.

5. Настройка VPN

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

mcedit /etc/ipsec.conf

Код:
#!/usr/local/sbin/setkey -f
flush;
spdflush;
Код:
spdadd 192.168.1.0/24 192.168.2.0/24 any -P out ipsec
esp/tunnel/111.111.111.111-222.222.222.222/require;
Код:
spdadd 192.168.2.0/24 192.168.1.0/24 any -P in ipsec
esp/tunnel/222.222.222.222-111.111.111.111/require;

Это я привел пример настройки для сервера первого офиса. Для второй машины надо просто поменять IP местами.

Переходим в директорию /usr/local/etc, где создадим каталог racoon  (если его нет)

Код:
cd /usr/local/etc
mkdir racoon
cd racoon

создаем файл racoon.conf следующего содержания:

#указываем где будет лежать файл, с фразой авторизации

Код:
path pre_shared_key "/usr/local/etc/racoon/psk.txt";

#указываем на каком интерфейсе слушать соединения

Код:
listen
{
isakmp 111.111.111.111;
}

#указываем, что любой аутентифицированный хост будет приниматься как anonymous. Вместо anonymous можно указать ip-адрес удаленного сервера.

Код:
remote anonymous
{
exchange_mode aggressive;

my_identifier address;

lifetime time 24 hour;

proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
sainfo anonymous
{
pfs_group 2;
lifetime time 12 hour;
encryption_algorithm 3des, blowfish, des, rijndael;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}

Соездаем файлик psk.txt, в котором будет храниться фраза аутентификации удаленного хоста.
Синтаксис psk.txt такой:

ip_удаленного_хоста фраза

Например, для первой машины это будет:

222.222.222.222 sometext

А для второй:

111.111.111.111 sometext

Устанавливаем соответствующие права на psk.txt (обязательно!)

chmod 600 psk.txt

Теперь переходим в /usr/local/etc/rc.d

Код:
cd /usr/local/etc/rc.d

После установки пакета ipsec-tools там появится скрипт для запуска демона шифрования racoon. Мы его удалим и создадим на его месте новый, более простой скрипт. (Лично у меня возникали непонятные глюки при использовании стандартного скрипта).

rm racoon

Затем создаем файл racoon.sh со следующим содержанием:

Код:
#!/bin/sh

case "$1" in

start)
if [ -x /usr/local/sbin/racoon ]; then
/usr/local/sbin/racoon -f /usr/local/etc/racoon/racoon.conf
&& echo -n ' racoon'
fi
;;

stop)
/usr/bin/killall racoon && echo -n ' racoon'
;;
*)
echo "Usage: `basename $0` { start | stop }"
exit 64
;;
esac

Устанавливаем для racoon.sh флаг +x (для того, чтобы этот скрипт был исполняемым).

Код:
chmod +x racoon.sh

racoon.sh лежит в каталоге /usr/local/etc/rc.d, и будет сам автоматически запускаться вместе с загрузкой системы.

Добавляем в /etc/rc.conf:

# включем racoon

Код:
echo #IPSEC >> /etc/rc.conf
echo racoon_enable="YES" >>/etc/rc.conf
echo racoon_flags="-F -f /usr/local/etc/racoon/racoon.conf" >>/etc/rc.conf

#включем ipsec

Код:
echo ipsec_enable="YES" >> /etc/rc.conf
echo ipsec_file="/etc/ipsec.conf" >> /etc/rc.conf

#создаем вирутуальный gif-интерефейс

Код:
gif_interfaces="gif0"
gifconfig_gif0="111.111.111.111 222.222.222.222"
ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff"

#прописываем статический рутинг для удаленной сети

Код:
static_routes="vpn"
route_vpn="192.168.2.0/24 -interface gif0"
если необходим доступ из одной сети в другую то 
route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00"

После перезагрузки должен появиться виртуальный интерфейс gif0.
Внимание! Соединение VPN устанавливается не моментально! Обычно в течении 10 секунд, после того как прийдет пакет, необходимый для отправки по VPN.

6. Защита сервера

После настройки VPN хорошо бы позаботиться о безопасности наших серверов.

Добавляем в /etc/sysctl.conf:

#устанавливаем так называемую «черную дыру» для пакетов, приходящих на закрытый порт, что усложняет процесс сканирования злоумышленником портов.

Код:
echo net.inet.tcp.blackhole=2  >>/etc/sysctl.conf
echo net.inet.udp.blackhole=1 >> /etc/sysctl.conf
Генерируем произвольный ID для IP пакета для того чтобы исключить возможность fingerprint и затруднить возможность злоумышленника систематизировать пакеты.

# echo net.inet.ip.random_id=1 >> /etc/sysctl.conf
# echo net.inet.icmp.maskrepl=0 >> /etc/sysctl.conf

#указываем размер очереди сокета

Код:
echo kern.ipc.somaxconn=1024 >> /etc/sysctl.conf

# отрубаем ip-редиректы

Код:
echo net.inet.icmp.drop_redirect=1 >> /etc/sysctl.conf
echo net.inet.icmp.log_redirect=1 >> /etc/sysctl.conf
echo net.inet.ip.redirect=0 >> /etc/sysctl.conf
echo net.inet6.ip6.redirect=0 >> /etc/sysctl.conf

# определяем размеры буфера для TCP-подключений

Код:
echo net.inet.tcp.sendspace=32768 >>  /etc/sysctl.conf
echo net.inet.tcp.recvspace=32768 >> /etc/sysctl.conf

# обновляем ARP-таблицу каждые 20 минут

Код:
echo net.link.ether.inet.max_age=1200 >> /etc/sysctl.conf

# запрещаем отвечать на все лишние запросы

Код:
echo net.inet.ip.sourceroute=0 >> /etc/sysctl.conf
echo net.inet.ip.accept_sourceroute=0 >> /etc/sysctl.conf
echo net.inet.icmp.bmcastecho=0 >> /etc/sysctl.conf
echo net.inet.icmp.maskrepl=0 >> /etc/sysctl.conf

Добавляем в /etc/rc.conf:

# включаем удаленный доступ по ssh

Код:
sshd_enable="YES"

# отключаем sendmail

Код:
sendmail_enable="NONE"

# очищаем каталог /tmp при каждой загрузке системы

Код:
clear_tmp_enable="YES"

Если не планируется на сервере использовать систему NFS, то отключаем его и демона portmap:

# echo 'nfs_server_enable="NO"' >> /etc/rc.conf
# echo 'nfs_client_enable="NO"' >> /etc/rc.conf
# echo 'portmap_enable="NO"' >> /etc/rc.conf

icmp_bmcastecho="NO"
fsck_y_enable="YES"
log_in_vain="YES"

По умолчанию уровень безопасности системы (kernel level) равен -1, т.е. мало защищенный. Если предполагается использовать защищенный уровень, то рекомендуется использовать 2, или даже 3 – как наиболее защищенный.

# echo 'kern_securelevel_enable='YES"' >> /etc/rc.conf
# echo 'kern_securelevel="2"' >> /etc/rc.conf

Cообщения ICMP redirect могут быть использованы для атаки, поэтому игнорируем и логируем их

# echo 'icmp_drop_redirect="YES"' >> /etc/rc.conf
# echo 'icmp_log_redirect="YES"' >> /etc/rc.conf

Чтобы при входе в консоль не выводилась версия OS и координаты ядар, запрещаем обновление файла с сообщением дня (Message of Day)

# echo 'update_motd="NO"' >> /etc/rc.conf

Задаем несколько параметров ядра путем редактирования файла /etc/sysctl.conf . Для начала запрещаем обычным пользователям просмотр процессов запущенных с иным UID

# echo «security.bsd.see_other_uids=0» >> /etc/sysctl.conf

 

Следующая опция ядра подойдет для рутеров, фаерволов и шлюзов: конфигурируем систему отбрасывать SYN/FIN пакеты, при желании её можно включать и на обычных срверах, но это чревато падением производительности.

# echo 'tcp_drop_synfin="YES"' >> /etc/rc.conf

Мы открыли доступ из вне для подключения на наш ssh сервер. Рано или поздно в логах можно будет увидеть, что кто-то пытался подключиться и переберал пару логин/пароль. При использовании сложного пароля атака с перебором пароля практически не грозит. Но все же немного не спокойно.
Для автоматического блокирования «переборщиков паролей» существует отличная утилита sshit, причем очень простая в настройке и использовании.
Устанавливаем sshit:

Код:
cd /usr/ports/security/sshit/
make install clean

затем добавляем в /etc/syslog.conf

после строчки:

Код:
auth.info;authpriv.info /var/log/auth.log

строчку:

Код:
auth.info;authpriv.info |exec /usr/local/sbin/sshit

в файл конфигурации фаервола /etc/pf.conf добавляем после правила block all:

Код:
table <badhosts> persist
block quick on $ext_if from <badhosts> to any

Далее, чтобы сохранить созданную таблицу блокировки между перезагрузками, необходимо добавить

Код:
touch /etc/pf.badhosts.block.list
# echo '/sbin/pfctl -t ftp-attacks -T show > /etc/pf.ftp.block.list' >> /etc/rc.shutdown
table <badhosts> persist file "/etc/pf.badhosts.block.list"
block quick on $ext_if from <badhosts> to any


в файл настройки /usr/local/etc/sshit.conf увеличиваем параметр RESET_IP (время в секундах, на сколько блокировать нежелательный хост)

mcedit /usr/local/etc/sshit.conf

Код:
RESET_IP = 86400

Теперь при трех неудачных попытках авторизоваться, удаленный хост будет заблокирован на сутки.
Перезагружаемся.

У меня уже через час появился один заблокированный адрес.
Просмотреть список заблокированных адресов можно так:

Код:
pfctl -t badhosts -T show

Добавить/Удалить в ручную можно набрав команду:

Код:
pfctl -t badhosts -T add 192.168.1.1
pfctl -t badhosts -T add 192.168.1.0/24
pfctl -t badhosts -T delete 192.168.1.1



Для мониторинга сетевых соединений в режиме реального времени есть очень удобная и простая утилита — pftop, которая находится в портах и работает по принципу стандартной unix-овой команды top.

Код:
cd /usr/ports/sysutils/pftop/
make install clean

 

# tcpdump -n -e -ttt -r /var/log/pflog
Note that using tcpdump(8) to watch the pflog file does not give a real-time display. A real-time display of logged packets is achieved by using the pflog0 interface:
# tcpdump -n -e -ttt -i pflog0




Для мониторинга сетевых соединений в режиме реального времени есть очень удобная и простая утилита — pftop, которая находится в портах и работает по принципу стандартной unix-овой команды top.

Код:
cd /usr/ports/sysutils/pftop/
make install clean

Синхронизация времени на FreeBSD сервере 

1) Первым делом, проверим наличие ntpd в системе:

Код:
whereis ntpd
ntpd: /usr/sbin/ntpd /usr/local/man/man1/ntpd.1.gz /usr/src/contrib/ntp/ntpd

Подредактируем конфиг /etc/ntp.conf

Код:
mcedit /etc/ntp.conf

Пример конфига

Код:
#добавляем сервера, с которыми будет проводиться синхронизация
# prefer - предпочтительный сервер
# iburst позволяет ntpd ускорить начальный процесс синхронизации

server nut.rsuitb.ru iburst maxpoll 9 prefer
server time.nist.gov iburst maxpoll 9
server kent.naviteh.ru iburst maxpoll 9
server ntp.manov.su iburst maxpoll 9
server 0.ru.pool.ntp.org iburst maxpoll 9
server 1.ru.pool.ntp.org iburst maxpoll 9
server 2.ru.pool.ntp.org iburst maxpoll 9

#путь к дрифт файлу
# Для хранения смещения частоты системных часов
driftfile /etc/ntp/drift
# Основной лог logfile
/var/log/ntp.log
#разрешаем обновляться только localhost и своей подсети
restrict default ignore  # Запрещаем всем сверяться с нашим сервером
restrict 172.16.174.0 mask 255.255.255.0 nomodify notrap
restrict localhost
#разрешаем синхронизироваться с удаленными серверами
restrict nut.rsuitb.ru  noquery notrap  # Разрешаем изменять наше время
restrict time.nist.gov nomodify noquery notrap
restrict kent.naviteh.ru nomodify noquery notrap
restrict ntp.manov.su nomodify noquery notrap
restrict 0.ru.pool.ntp.org nomodify noquery notrap
restrict 1.ru.pool.ntp.org nomodify noquery notrap
restrict 2.ru.pool.ntp.org nomodify noquery notrap

3) На всякий случай создадим все упомянутые файлы:

Код:
mkdir /etc/ntp & touch /etc/ntp/drift & touch /var/log/ntp.log

По умолчанию лог ntpd имеет имя ntp.log и находится в папке /var/log. Для того, чтобы newsyslog (8) выполнял его ротацию, необходимо добавить в файл/etc/newsyslog.conf строку:

Код:
/var/log/ntp.log 644 3 100 * J /var/run/ntpd.pid

4) Добавим ntpd в автозагрузку: /etc/rc.conf

Код:
ntpd_sync_on_start="YES" # Синхронизация часов при запуске
ntpdate_program="/usr/sbin/ntpdate" # Программа для синхронизации
ntpdate_flags="-u 172.16.174.2" # Сервер для синхронизации
ntpd_enable="YES" # Демон синхронизации
ntpd_program="/usr/sbin/ntpd" # Полный путь к нему
ntpd_flags="-p /var/run/ntpd.pid" # .pid процесса


5) Запустим: /etc/rc.d/ntpd start 
      проверим /etc/rc.d/ntpd status — должен показать pid процесса


ps -ax |grep ntpd

Код:
27476  ??  Ss       0:00.80 /usr/sbin/ntpd -g -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
27650   0  RV       0:00.00 grep ntpd (csh)

sockstat |grep ntp

Код:
root     ntpd       27476 3  dgram  -> /var/run/logpriv
root     ntpd       27476 20 udp4   *:123                 *:*
root     ntpd       27476 21 udp6   *:123                 *:*
root     ntpd       27476 22 udp4   172.16.174.2:123      *:*
root     ntpd       27476 23 udp6   fe80:1::a00:27ff:feb9:dde4:123 *:*
root     ntpd       27476 24 udp6   fe80:4::1:123         *:*
root     ntpd       27476 25 udp6   ::1:123               *:*
root     ntpd       27476 26 udp4   127.0.0.1:123         *:*


Запустить на клиенте опрос сервера

Код:
ntpq -c rv 172.16.174.2
Код:
assID=0 status=46f4 leap_add_sec, sync_ntp, 15 events, event_peer/strat_chg,
version="ntpd 4.2.4p5-a (1)", processor="i386",
system="FreeBSD/9.0-RELEASE-p1", leap=01, stratum=5, precision=-18,
rootdelay=653.543, rootdispersion=177.318, peer=11434,
refid=193.41.86.177,
reftime=d3a15cf5.0befd834  Fri, Jul  6 2012 16:47:49.046, poll=6,
clock=d3a15eb7.7b0cfaa8  Fri, Jul  6 2012 16:55:19.480, state=2,
offset=113.594, frequency=500.000, jitter=283.771, noise=27.248,
stability=0.039, tai=0


      проверим удаленные серверы ntpdc -p

Код:
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*nut.rsuitb.ru   3.92.124.211     3 u   58   64  177   31.752   36.608 158.566
+131.107.13.100  .ACTS.           1 u   27   64  377  232.343  237.962 154.421
+kent.naviteh.ru 192.36.144.22    2 u   29   64  377   59.988  111.880 105.970
+ntp.manov.su    192.36.133.25    2 u   20   64  377   46.745  -24.952 199.900
 195.5.136.3     .STEP.          16 u    -  512    0    0.000    0.000   0.000
 jane.telecom.mi .STEP.          16 u    -  512    0    0.000    0.000   0.000
 81.95.131.130   .STEP.          16 u    -  512    0    0.000    0.000   0.000
Тут остановимся по-подробнее.

remote - имена удаленных ntp серверов (в нашем случае полученные из пулов 0/1/2/3.ua.pool.ntp.org)
refid - сервер, с которым производит синхронизацию удаленный сервер ntp
st - стратум (уровень) удаленного сервера. 1 - самый высокий, эти
 сервера для вычисления точного времени используют специальное
дорогостоящее оборудование; 16 - рядовая машина/клиент.
t - тип пира (u = unicast, m = multicast)
when - указывает на то, как давно была произведена синхронизация с сервером
poll - частота в секундах, с которой NTP демон синхронизируется с пиром
reach - состояние доступности сервера, это значение
стабилизируется на уровне 377 если последних 8 попыток синхронизации с
удаленным сервером были успешны
delay - он и в Африке delay - задержка (в миллисекундах) ответа от сервера
offset - разница в миллисекундах между системным временем и
временем удаленного сервера; значение с минусом - отставание, с плюсом -
 наши часики спешат
jitter - смещение времени на удаленном сервере

Теперь немного о значках, следа от имени пира:

"*" - пир, с которым последний раз у нас была выполнена синхронизация

"+" - "хороший" (пригодный для обновления) сервер

"-" - "плохой" (непригодный для обновления) сервер
"х" - сервер не отвечает

Узнать, пригоден ли наш сервер для синхронизации, а также узнать некоторые его данные можно следующей командой: 

 

Код:
ntpdate -q localhost

В ответ должны получить что-то подобное:

 

Код:
server 127.0.0.1, stratum 4, offset -0.000008, delay 0.02588
server ::1, stratum 4, offset -0.000010, delay 0.02589
 4 Jul 13:44:28 ntpdate[21536]: adjust time server 127.0.0.1 offset -0.000008 sec

Этот ответ означает, что наш сервер пригоден для синхронизации, его страта равна трем, смещение — 0.000010 а задержка при ответе равна 0.02589.

Аналогичной командой можно узнать эти параметры на удаленном сервере:

 

Код:
ntpdate -q nut.rsuitb.ru
server 193.41.86.177, stratum 3, offset 0.156204, delay 0.06969
 4 Jul 13:48:29 ntpdate[21543]: adjust time server 193.41.86.177 offset 0.156204 sec

Ниже приведен пример ответа сервера, непригодного для синхронизации:

 

Код:
server 132.123.123.123, stratum 16, offset 6.188638, delay 0.03827
17 Nov 16:17:36 ntpdate[1027]: no server suitable for synchronization found

В /var/log/ntp.log должны быть сообщения аналогичные нижеприведенным:

 

Код:
16 Nov 22:23:23 ntpd[27414]: synchronized to 193.34.155.4, stratum=2
17 Nov 01:51:11 ntpd[27414]: synchronized to 82.207.89.35, stratum=3
17 Nov 01:51:13 ntpd[27414]: synchronized to 193.34.155.4, stratum=2

Каждая запись соответствует успешной синхронизации с удаленным сервером. Если они отсутствуют, значит синхронизация не производиться. В случае, если после запуска ntpd он только 1 раз синхронизируется с удаленным сервером и дальнейшая синхронизация не наблюдается, лог выглядит так:

 

Код:
17 Nov 15:47:17 ntpd[5059]: synchronized to 91.198.10.4, stratum=2
17 Nov 15:47:17 ntpd[5059]: kernel time sync disabled 0041
17 Nov 15:47:21 ntpd[5059]: kernel time sync enabled 0001

Все, теперь настраиваем клиентов на синхронизацию с нашим сервером (172.16.174.2). В случае с клиентом под FreeBSD (под Linux тоже должно работать) рисуем следующий конфиг:

 

Код:
# ee /etc/ntp.conf
server 172.16.174.2 iburst
driftfile /etc/ntp/drift
logfile /var/log/ntp.log
restrict default ignore
restrict 172.16.174.2

Второй вариант заключается в выполнении команды ntpdate -b <ip-адрес fqdn="« внутреннего=»" ntp-сервера="«>при запуске операционной системы и последующем выполнении команды ntpdate -s<ip-адрес fqdn=»" внутреннего="« ntp-сервера=»">каждый час. Ключ -b заставляет ntpdate принудительно использовать системный вызов settimeofday (2), предназначенный для грубой корректировки системного времени (по умолчанию, если локальное время время отличается от времени, полученного с NTP-сервера, менее чем на 0,5 секунд, ntpdate использует системный вызов adjtime (2), предназначенный для плавной корректировки системного времени), ключ -s включает перенаправление вывода в syslog (3). Таким образом эмулируется поведение NTP-сервера. Грубая корректировка времени при запуске операционной системы является очень важной операцией. Она позволяет избежать значительный скачок системного времени (и возможные проблемы в работе систем биллинга, статистики, СУБД и т.п.), который может произойти в том случае, если первая операция синхронизации времени будет выполнена позже, чем запустится операционная система, и локальное время будет отличаться от времени на NTP-сервере более чем на 0,5 секунд. Для того, чтобы команда грубой корректировки времени автоматически выполнялась при запуске операционной системы, следует добавить в файл /etc/rc.conf строки:

 

Код:
ntpdate_enable="YES"
ntpdate_hosts="172.16.174.2<ip-адрес fqdn="" внутреннего="" ntp-сервера="">"
ntpd_enable="YES"
<ip-адрес fqdn="" внутреннего="" ntp-сервера="">

Для того, чтобы команда точной корректировки времени каждый час выполнялась с помощью cron (8), необходимо войти в систему под root'том, выполнить команду crontab -e, позволяющую внести изменения в crontab текущего пользователя (т.е. root'a), и добавить строку:

 

Код:
0 * * * * /usr/sbin/ntpdate -s 172.16.174.2

Настройка почты только для отправки

Код:
# cd /usr/ports/mail/ssmtp
# make install replace clean

Создадим и настроим конфигурационные файлы:

Код:
# cd /usr/local/etc/ssmtp/
# ll
total 4
-rw-r-----  1 root  ssmtp   200 Apr 22 11:53 revaliases.sample
-rw-r-----  1 root  ssmtp  1286 Apr 22 11:53 ssmtp.conf.sample
# cp ssmtp.conf.sample ssmtp.conf
# cp revaliases.sample revaliases

Настроим ssmtp.conf

Код:
grep -v '^#' ssmtp.conf |grep -v ^$
  root=it@rmntk-ts.ru
mailhub=ms2.rmntk-ts.ru:25
rewriteDomain=rmntk-ts.ru
hostname=ts174-02

Настроим revaliases

Revaliases нужен для создания псевдонимов (например как файл /etc/mail/aliases для sendmail). Переведем конфигурационный файл:

Код:
 # cat revaliases
# sSMTP псевдонимы
#
# Формат: local_account:outgoing_address:mailhub
#
# Пример: root:your_login@your.domain:mailhub.your.domain[:port]
# где [:port] – это дополнительный номер порта, который по умолчанию 25.

Настроим соответствующим образом:

Код:
# grep -v '^#' revaliases |grep -v ^$
root:root@ts174-02.rmntk-ts.ru:it.rmntk-ts.ru

Система Остановите Sendmail и приведите конфигурационные файлы к этому виду:

Код:
# cat /etc/rc.conf |grep sendmail
sendmail_enable="NONE"
Код:
# grep -v ^# /etc/mail/mailer.conf |grep -v ^$
sendmail /usr/local/sbin/ssmtp
send-mail /usr/local/sbin/ssmtp
mailq /usr/local/sbin/ssmtp
newaliases /usr/local/sbin/ssmtp
hoststat /usr/local/sbin/ssmtp
purgestat /usr/local/sbin/ssmtp

 

Тестируем Отправим письмо руту:

Код:
# mail root
Subject: test ssmtp
test ssmtp
.
EOT
1

отправить письмо командой в консоли FreeBSD:

Код:
# echo "hello" | mail it@rmntk-ts.ru

Готово. Если письмо пришло то вас можно поздравить.

Проблемы

А если не пришло то это проблема =). Для начала нам нужно обнаружить проблемное место. Для этого в конфигурационном файле ssmtp.conf Добавляем в самое начало конфига строчку:

Код:
Debug=YES

СДалее необходимо смотреть как и куда отправляются письма. Для этого необходимо видеть логи почтового сервера в реальном времени (для удобства). И пробуем отправить письмо заодно смотря логи.

Код:
# # tail -f /var/log/maillog
Apr 23 11:38:43 bsd sSMTP[72138]: Sent mail for root@raven.local (221 Bye) uid=0
username=root outbytes=296
Apr 23 11:38:51 bsd sSMTP[72143]: Set Root="Raven2000@lissyara.su"
Apr 23 11:38:51 bsd sSMTP[72143]: Set MailHub="mail.ignix.ru"
Apr 23 11:38:51 bsd sSMTP[72143]: Set RemotePort="25"
Apr 23 11:38:51 bsd sSMTP[72143]: Set HostName="raven.local"
Apr 23 11:38:51 bsd sSMTP[72143]: Set MailHub="mail.ignix.ru"
Apr 23 11:38:51 bsd sSMTP[72143]: via SMTP Port Number="25"
Apr 23 11:38:51 bsd sSMTP[72143]: 220 MailServer 2005
Apr 23 11:38:51 bsd sSMTP[72143]: HELO raven.local
Apr 23 11:38:52 bsd sSMTP[72143]: 250 ignix.ru
Apr 23 11:38:52 bsd sSMTP[72143]: MAIL FROM:<root@raven.local>
Apr 23 11:38:52 bsd sSMTP[72143]: 250 Ok
Apr 23 11:38:52 bsd sSMTP[72143]: RCPT TO:<raven2000@lissyara.su>
Apr 23 11:38:52 bsd sSMTP[72143]: 250 Ok
Apr 23 11:38:52 bsd sSMTP[72143]: DATA
Apr 23 11:38:52 bsd sSMTP[72143]: 354 End data with .
Apr 23 11:38:52 bsd sSMTP[72143]: Received: by raven.local (sSMTP sendmail emulation);
Fri, 23 Apr 2010 11:38:51 +0400
Apr 23 11:38:52 bsd sSMTP[72143]: From: "Charlie &" <root@raven.local>
Apr 23 11:38:52 bsd sSMTP[72143]: Date: Fri, 23 Apr 2010 11:38:51 +0400
Apr 23 11:38:52 bsd sSMTP[72143]: To: Raven2000@lissyara.su
Apr 23 11:38:52 bsd sSMTP[72143]: Subject: test ssmtp2
Apr 23 11:38:52 bsd sSMTP[72143]:
Apr 23 11:38:52 bsd sSMTP[72143]: test ssmtp2
Apr 23 11:38:53 bsd sSMTP[72143]: .
Apr 23 11:38:53 bsd sSMTP[72143]: 250 Ok: queued as 50A392BC12D
Apr 23 11:38:53 bsd sSMTP[72143]: QUIT
Apr 23 11:38:53 bsd sSMTP[72143]: 221 Bye
Apr 23 11:38:53 bsd sSMTP[72143]: Sent mail for root@raven.local (221 Bye) uid=0
username=root outbytes=331

Вот собственно и все. Мы соединили два офиса в одну сеть. Аналогичным образом можно подключить несколько сетей.

 

http://www.lissyara.su/?id=1000 —> главная <code>—> Архив —> IPsec

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

Автор: lissyara.

<b>Эта статья в архиве. Новая версия доступна по адресу:</b> 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/><span style="color: #ff00ff;">cd</span> /usr/src/sys/i386/conf/
/usr/src/sys/i386/conf/><span style="color: #ff00ff;">ls</span>
GENERIC         LINT
/usr/src/sys/i386/conf/><span style="color: #ff00ff;">cp</span> GENERIC IPSec
/usr/src/sys/i386/conf/><span style="color: #ff00ff;">ls</span>
GENERIC         LINT            IPSec
/usr/src/sys/i386/conf/><span style="color: #ff00ff;">ee</span> IPSec

 

И вносим туда строки:

<span style="color: red;"># firewall</span>
<span style="color: orange;">options</span>         IPFIREWALL
<span style="color: orange;">options</span>         IPFIREWALL_VERBOSE
<span style="color: orange;">options</span>         IPFIREWALL_VERBOSE_LIMIT=<b><span style="color: #00008b;">1000</span></b>
<span style="color: orange;">options</span>         TCP_DROP_SYNFIN
<span style="color: red;"># IPSEC</span>
<span style="color: orange;">options</span>         IPSEC
<span style="color: orange;">options</span>         IPSEC_ESP
<span style="color: orange;">options</span>         IPSEC_DEBUG

 

Также проверяем наличие этого самого gif`a, должна быть строка
<span style="color: green;">pseudo-device   gif             # IPv6 and IPv4 tunneling</span>
учтите, если у Вас фря до версии 4.2 то надо указать число интерфейсов, т.е она будет такой:
<span style="color: green;">pseudo-device   gif       2      # IPv6 and IPv4 tunneling</span>
После чего пересобираем ядро и перезагружаемся:

/usr/src/sys/i386/conf/><span style="color: #ff00ff;">cd</span> ../../../
/usr/src/><span style="color: #ff00ff;">make</span> buildkernel KERNCONF=IPSec && <span style="color: #ff00ff;">make</span> 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/