OpenVPN сервер для офисного шлюза на FreeBSD

()

Недавно мы развернули шлюз для небольшого офиса и организовали на нём учёт трафика. Следующей задачей, которую полезно решить, является удалённый доступ сотрудников в офисную сеть. Для этого можно использовать одну из реализаций VPN. Мы будем использовать OpenVPN, как наиболее гибкий и удобный в использовании вариант.

Первым делом установим OpenVPN:

cd /usr/ports/security/openvpn && make install clean

Приступаем к настройке. Сначала создадим необходимые директории:

mkdir -p /usr/local/etc/openvpn/{ccd,easy-rsa/keys}

Скопируем скрипты для генерации ключей в более удобное для нас место:

cp -av /usr/local/share/doc/openvpn/easy-rsa/2.0/* /usr/local/etc/openvpn/easy-rsa/

Ключи будут сгенерированы в директории /usr/local/etc/openvpn/easy-rsa/keys. Однако удобнее будет использовать в файлах конфигурации путь /usr/local/etc/openvpn/keys, поэтому создадим симлинк:

ln -sf /usr/local/etc/openvpn/easy-rsa/keys /usr/local/etc/openvpn/

Следующим шагом редактируем по своему вкусу файл /usr/local/etc/openvpn/easy-rsa/vars, который описывает большую часть настроек для новых ключей, после чего переходим в директорию со скриптами:

cd /usr/local/etc/openvpn/easy-rsa

FreeBSD использует в качестве оболочку по умолчанию /bin/csh, а скрипты генерации ключей написаны в расчёте на /bin/sh и при использовании их в csh наблюдаются проблемы с использованием переменных окружения. Чтобы решить эту проблему запустим классически шелл:

sh

По умолчанию со скриптов снят атрибут "исполняемый". Установим его:

chmod +x *

Считаем настройки для генерации скриптов:

. ./vars

Генерируем ключ для сервера:

./clean-all && ./build-ca && ./build-dh && ./build-key-server server

Теперь создадим файл /usr/local/etc/openvpn/server.conf, описывающий конфигурацию сервера. Здесь и далее мы исходим из того, что для клиентов нашего OpenVPN-сервера мы выделяем сеть 172.31.254.0/24:

# OpenVPN запускается в режиме сервера
mode server

# Используем TLS-шифрование
tls-server

# Работаем в режиме демона
daemon

# Настройки виртуального интерфейса на стороне сервера
ifconfig 172.31.254.1 255.255.255.0

# Порт, на котором будет слушать
port 1194

# Используем протокол tcp
proto tcp-server

# Имя интерфейса, который будет использовать сервер
dev tap0

# Сертификаты
ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/keys/server.crt
key /usr/local/etc/openvpn/keys/server.key
dh /usr/local/etc/openvpn/keys/dh1024.pem

# Отдаём клиентам маршрут на офисную сеть
push "route 172.31.255.0 255.255.255.0 172.31.254.1"

# Директория, в которой будут описаны настройки для всех клиентов
client-config-dir /usr/local/etc/openvpn/ccd

# Настройки поддержания соединения
keepalive 10 120

# Разрешаем трафик между клиентами
client-to-client

# Используем сжатие
comp-lzo

# Не перечитывать ключевые файлы при переподключении клиентов
persist-key

# Не пересоздавать виртуальный интерфейс
persist-tun

# Уровень детализации в логе
verb 3

# Файл лога
log-append /var/log/openvpn.log

Для автоматического запуска openvpn при старте системы нужно добавить в файл /etc/rc.conf строки:

openvpn_enable="YES"
openvpn_configfile="/usr/local/etc/openvpn/server.conf"

Далее нужно подгрузить модуль для работы с tap-интерфейсами:

kldload if_tap

Чтобы модуль автоматически подгружался при загрузке нужно добавить в /boot/loader.conf строку:

if_tap_load="YES"

Наконец запускаем сервер:

/usr/local/etc/rc.d/openvpn start

Теперь нам нужно внести изменения в настройки пакетного фильтра, который мы настроили в предыдущей статье. Сразу приведём обновлённый вариант файла /etc/pf.rules:

# Основные настройки
if_ext = "le0"
if_int = "em0"
if_vpn = "tap0"
net_int = "172.31.255.0/24"
net_vpn = "172.31.254.0/24"

set block-policy drop
set state-policy if-bound

scrub all reassemble tcp fragment reassemble

# NAT для локальной сети
nat pass on $if_ext from $net_int -> ($if_ext) static-port

# Разрешаем всё на loopback-интерфейсе
pass quick on lo0 all

# Разрешаем исходящий трафик
pass out quick on $if_ext inet proto tcp from ($if_ext) to any flags S/SA keep state
pass out quick on $if_ext inet proto { udp, icmp } from ($if_ext) to any keep state


# Разрешаем исходщящий трафик в сторону локальной сети
pass out quick on $if_int from ($if_int) to $net_int
pass out quick on $if_int from $net_vpn to $net_int

# Разрешаем входящий трафикк со стороны локальной сети
pass in quick on $if_int from $net_int to any keep state

# Разрешаем исходящий трафик в сторону VPN-сети
pass out quick on $if_vpn from ($if_vpn) to $net_vpn
pass out quick on $if_vpn from $net_int to $net_vpn

# Разрешаем входящий трафик со стороны VPN-сети
pass in quick on $if_vpn from $net_vpn to any keep state

# Разрешаем обращение к нашему VPN-серверу снаружи
pass in quick on $if_ext inet proto tcp from any to ($if_ext) port 1194 flags S/SA keep state

# Запрещаем весь остальной трафик
block drop all

Применяем правила:

pfctl -f /etc/pf.rules

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

cd /usr/local/etc/openvpn/easy-rsa

Запустим оболочку, в контексте которой будут работать скрипты:

sh

Установим необходимые переменные окружения:

. ./vars

Сгенерируем ключ для пользователя "username":

./build-key username

Затем создадим файл /usr/local/etc/openvpn/ccd/username примерно вот такого содержания:

ifconfig-push 172.31.254.101 255.255.255.0

Здесь мы указываем IP-адрес и маску сети, которые будут на виртуальном интерфейсе у клиента. Разумеется что адреса разных клиентов не должны совпадать.

Файл конфигурации клиента будет иметь вид:

client
dev tap
proto tcp

# Внешний адрес офисного сервера
remote office.example.com 1194

resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo
ns-cert-type server

# Файлы ключей
ca ca.crt
cert username.crt
key username.key

Настройки OpenVPN-клиента в разных ОС уже описывалась ранее и потому подробно рассматривать этот вопрос мы не будем.

На этом всё. Приятной работы!

Ключевые слова: openvpn, freebsd.

Подписаться на обновления: RSS-лента Канал в TamTam Telegram канал Канал в ICQ

Комментарии:

Новый комментарий

Жирный текстКурсивный текстПодчёркнутый текстЗачёркнутый текстПрограммный кодСсылкаИзображение




© 2006-2024 Вадим Калинников aka MooSE
Политика конфиденциальности

этот на сайте eurostela.ru