Опыт внедрения OpenVPN во FreeBSD

Почему OpenVPN?

---------------

На ключевое слово vpn Google откликнулся 17 000 000 ссылок.

Это приятно удивило. Немного сузив поиск наткнулся на сайт

openvpn.sourceforge.net. Вводная статья обещала простоту

инсталяции и конфигурирования,а главное,- возможность создания

тунеля для большинства наиболее распрастранённых операционных

систем, включая Linux,SUN Solaris,*BSD, Mac OS X, w2k, w2k3.

Это то что мне нужно...

Внешний интерфейс Внешний интерфейс

100.100.100.1 101.101.101.1

+--------------+ +-------------+

| SuSE 8.2 | Internet | FreeBSD 5.3 |

| |<->-----------<->| |

| NAT,FireWall | | NAT, ipfw |

| | | |

+-----+--------+ +-------+-----+

^ ^ ^ ^

| | VPN | |

| +---------------------+ |

| 10.1.1.0 |

+-----+---+ +--+------+

|Локальная| |Локальная|

| сеть | | сеть |

+---------+ +---------+

10.0.0.0 192.168.1.0

Рис.1. Схема моей виртуальной частной сети.

Так как работать с VPN планируется "навсегда", пересобрал ядро SuSE

с поддержкой tun/tap драйвера. В современные дистрибутивы FreeBSD

поддержка tun/tap уже встроена в ядро.

Далее установил пакет. Для SuSE:

#cp openvpn-1.6.0.tar.gz /usr/src

#tar -xzvf openvpn-1.6.0.tar.gz.

#./configure

#./make

#./make install

Закапризничавшая во время конфигурированя SuSE потребовала

установить предварительно библиотеку lzo.

Под FreeBSD всё прошло гладко:

#cd /usr/ports/security/openvpn

#./make

#./make install

OpenVPN имеет два режима защиты.Первый базируется на SSL/TLS защите

с использованием сертификатов и ключей. Второй,- на использовании

статических ключей.

Для создания сертификатов пришлось подредактировать в файле

/etc/ssl/openssl.cnf несколько строк:

#

...

dir = /usr/local/etc/openvpn

certificate = $dir/my-ca.crt

private_key = $dir/private/my-ca.key

И для того чтобы не заниматься этой процедурой(созданием ключей и

сертификатов) каждый год (наверняка забуду).

default_days = 3650 #(10 лет) до пенсии хватит...

...

Далее генерирую ключи и сертификаты:

openvpn reg -nodes -new -x509 -keyout my-ca.key -out my-ca.crt -day 3650

Данная команда создаст пару сертификат/ключ действующими 10 лет.

Затем создаю пару сертифика/частный ключ для каждого офиса:

openvpn reg -nodes -new -x509 -keyout office1.key -out office1.csr

openvpn reg -nodes -new -x509 -keyout office2.key -out office2.csr

openvpn ca -out office1.crt -in office1.csr

openvpn ca -out office2.crt -in office2.csr

Я особенно не силён в защите,но раз требуют создать Диффи Хельман

параметры для office2,создаём:

openvpn dhparam -out dh1024.pem 1024

Не забываю перенести ключи и сертификаты на машину office2.

С ключами всё.Перехожу к конфигурированию vpn.

Собственно конфигурирование сводится к созданию конфигурационных файлов

для офиса1 и офиса2. У меня офис1 выступает в качестве сервера и содержит:

#office1

dev tun

port 5000

ifconfig 10.1.1.1 10.1.1.2

#Здесь маршрутизацию поднимаем

up /etc/openvpn/office1.up

#Здесь маршрутизацию удаляем

down /etc/openvpn/office1.down

tls-server

dh dh1024.pem

ca my-ca.crt

cert office1.crt

key office1.key

verb3

#end office1

А это клиент:

#office2

dev tun

port 5000

remote 100.100.100.1

ifconfig 10.1.1.2 10.1.1.1

#Здесь маршрутизацию поднимаем

up /etc/openvpn/office2.up

#Здесь маршрутизацию удаляем

down /etc/openvpn/office2.down

tls-client

dh dh1024.pem

ca my-ca.crt

cert office2.crt

key office2.key

verb3

#end office2

Чтобы сети могли видеть друг друга файл office1.up содержит:

#up routing

route add -net 192.168.10.0/24 10.1.1.2

Сценарий down должен удалить маршрут

office1.down

#down

route del -net 192.168.10.0/24

office2.up содержит:

#up routing FreeBSD

route add -net 10.0.0.0/24 10.1.1.1 netmask 255.255.255.0

office2.down:

#down FreeBSD

route delete -net 10.0.0.0/24

Запускаем:

openvpn --config office1 на серврере;

openvpn --config office2 на машине-клиенте.

И проверяем.

SuSE:

$ ifconfig

tun0 Link encap:Point-to-Point Protocol

inet addr:10.1.1.1 P-t-P:10.1.1.2 Mask:255.255.255.255

UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1259 Metric:1

RX packets:79017 errors:0 dropped:0 overruns:0 frame:0

TX packets:85421 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:10

RX bytes:11237151 (10.7 Mb) TX bytes:34079868 (32.5 Mb)

$ ping 10.1.1.2

PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.

64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=271 ms

64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=419 ms

64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=277 ms

64 bytes from 10.1.1.2: icmp_seq=4 ttl=64 time=184 ms

64 bytes from 10.1.1.2: icmp_seq=5 ttl=64 time=137 ms

--- 10.1.1.2 ping statistics ---

6 packets transmitted, 5 received, 16% packet loss, time 5039ms

rtt min/avg/max/mdev = 137.763/258.168/419.546/96.461 ms

FreeBSD:

$ ifconfig

tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1259

inet6 fe80::202:44ff:fe92:7ac6%tun0 prefixlen 64 scopeid 0x5

inet 10.1.1.2 --> 10.1.1.1 netmask 0xffffffff

Opened by PID 429

$ ping 10.1.1.1

PING 10.1.1.1 (10.1.1.1): 56 data bytes

64 bytes from 10.1.1.1: icmp_seq=0 ttl=64 time=159.315 ms

64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=426.403 ms

64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=352.940 ms

64 bytes from 10.1.1.1: icmp_seq=3 ttl=64 time=394.593 ms

64 bytes from 10.1.1.1: icmp_seq=4 ttl=64 time=249.855 ms

64 bytes from 10.1.1.1: icmp_seq=5 ttl=64 time=203.441 ms

^C

--- 10.1.1.1 ping statistics ---

6 packets transmitted, 6 packets received, 0% packet loss

round-trip min/avg/max/stddev = 159.315/297.758/426.403/99.439 ms

$

Разработчики OpenVPN любезно предоставили настройку файервола

для Linux,которая подключается в сценарии автозапуска OpenVPN.

#!/bin/sh

dir=/etc/openvpn

$dir/firewall.sh

openvpn --cd $dir --daemon --config office1

Для FreeBSD,как всегда всё гораздо проще:

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

#!/bin/sh

dir=/etc/openvpn

case $1 in

start) openvpn --cd $dir --daemon --config office1;;

stop) killall -TERM openvpn;;

*) echo "Use: {start|stop}"

esac

rc.firewall

#

vpn="tun0"

#vpn

${fwcmd} add allow ip from any to any via ${vpn}

#nat

${fwcmd} add divert natd all from any to any via ${oif}

#

Всё.

Огромное спасибо разработчикам OpenVPN!

Обновлено: 12.03.2015