OpenVPN TCP+UDP

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

После продолжительных мучений со связкой Racoon+IPSec, решено было перейти на OpenVPN. Дело в том, что предыдущий вариант организации VPN не обеспечивал адекватного и надежного варианта переключения каналов при падении интернета. Всяческие сбросы ключей и т.п. все равно время от времени приводили к необходимости ручками лезть на роутеры и что-то перезагружать/дописывать. OpenVPN отлично себя показал в этом плане, однако возникла другая проблема — в него не заложено возможности одновременно работать по протоколам TCP и UDP, а UDP и multihome вообще не предусмотрен в версии под FreeBSD.

Итак, имеем 2 офиса по 2 интернет-канала в каждом (основной+резервный). На обоих сторонах FreeBSD, один назовем «Центральный офис» второй «Филиал». Установка и настройка делалась по статье [urlspan]Cancer[/urlspan] . Далее возникли первые проблемы. Оказалось, что при некоторых комбинациях этих каналов, VPN лучше работает по TCP, а при других — только UDP. Соответственно требуется такая настройка, чтобы без вмешательства админа, каналы могли сами переключаться. Решается все путем запуска трех серверов OpenVPN — один на TCP протокол и два на UDP-по одному на канал (см. проблему с multihome во FreeBSD).

Центральный офис

убираем из /etc/rc.conf упоминания openvpn
добавляем в /etc/rc.conf:

openvpntcp_enable="YES"
 openvpntcp_if="tun"
 openvpntcp_configfile="/usr/local/etc/openvpn/routertcp.conf"
 openvpntcp_dir="/usr/local/etc/openvpn"
openvpnudpop1_enable="YES"
 openvpnudpop1_if="tun"
 openvpnudpop1_configfile="/usr/local/etc/openvpn/routerudpop1.conf"
 openvpnudpop1_dir="/usr/local/etc/openvpn"
openvpnudpop2_enable="YES"
 openvpnudpop2_if="tun"
 openvpnudpop2_configfile="/usr/local/etc/openvpn/routerudpop2.conf"
 openvpnudpop2_dir="/usr/local/etc/openvpn"

 

копируем базовый /usr/local/etc/rc.d/openvpn в /usr/local/etc/rc.d/openvpntcp и т.д. и допиливаем:

...
 pidfile="/var/run/openvpntcp.pid"
 ...
 load_rc_config openvpntcp
 ...
 eval ": ${openvpntcp_enable:="NO"}"
 eval ": ${openvpntcp_flags:=""}"
 eval ": ${openvpntcp_if:=""}"
 eval ": ${openvpntcp_configfile:="/usr/local/etc/openvpn/openvpntcp.conf"}"
 eval ": ${openvpntcp_dir:="/usr/local/etc/openvpn"}"
 ...
 configfile="$(eval echo ${openvpntcp_configfile})"
 dir="$(eval echo ${openvpntcp_dir})"
 interfaces="$(eval echo ${openvpntcp_if})"
 ...
 command_args="--cd ${dir} --daemon openvpn --config ${configfile} --writepid ${pidfile}"

Аналогично поступаем с двумя остальными, меняя openvpntcp на openvpnop1 и openvpnop2
Далее ставим права:

chmod 755 /usr/local/etc/rc.d/openvpntcp
 chmod 755 /usr/local/etc/rc.d/openvpnudpop1
 chmod 755 /usr/local/etc/rc.d/openvpnudpop2

Далее конфиги:

/usr/local/etc/openvpn/routerudpop1.conf:

local 85.95.105.115 #IP адрес канала 1
 port 1194
 proto udp
 dev tun0
 management localhost 8321
 ca /usr/local/etc/openvpn/keys/ca.crt
 cert /usr/local/etc/openvpn/keys/router.crt
 key /usr/local/etc/openvpn/keys/router.key
 dh /usr/local/etc/openvpn/keys/dh1024.pem
 server 10.10.100.0 255.255.255.0
 push "dhcp-option DNS 10.1.1.1"
 push "dhcp-option DNS 10.1.1.2"
 push "dhcp-option WINS 10.1.1.3"
 push "route 10.1.1.0 255.255.255.0"  #подсеть центрального офиса
 push "route 10.1.2.0 255.255.255.0"  #подсеть филиала
 push "route 10.10.100.0 255.255.255.0"
 push "route 10.10.101.0 255.255.255.0"
 push "route 10.10.102.0 255.255.255.0"
 client-config-dir ccdudpop1
 route 10.10.100.0 255.255.255.0
 client-to-client
 tls-server
 tls-auth keys/ta.key 0
 tls-timeout 120
 auth SHA1
 cipher BF-CBC
 keepalive 10 30
 comp-lzo
 max-clients 100
 user nobody
 group nobody
 persist-key
 persist-tun
 status /var/log/openvpn/openvpn-status-udpop1.log
 log /var/log/openvpn/openvpn-udpop1.log
 verb 3
 push "ping 10"
 push "ping-restart 20"
 client-connect /usr/local/etc/openvpn/route.sh
 script-security 3 system

 

/usr/local/etc/openvpn/routerudpop2.conf:

local 185.195.205.215 #IP адрес канала 1
 port 1194
 proto udp
 dev tun1
 management localhost 8322
 ca /usr/local/etc/openvpn/keys/ca.crt
 cert /usr/local/etc/openvpn/keys/router.crt
 key /usr/local/etc/openvpn/keys/router.key
 dh /usr/local/etc/openvpn/keys/dh1024.pem
 server 10.10.101.0 255.255.255.0
 push "dhcp-option DNS 10.1.1.1"
 push "dhcp-option DNS 10.1.1.2"
 push "dhcp-option WINS 10.1.1.3"
 push "route 10.1.1.0 255.255.255.0"  #подсеть центрального офиса
 push "route 10.1.2.0 255.255.255.0"  #подсеть филиала
 push "route 10.10.100.0 255.255.255.0"
 push "route 10.10.101.0 255.255.255.0"
 push "route 10.10.102.0 255.255.255.0"
 client-config-dir ccdudpop2
 route 10.10.101.0 255.255.255.0
 client-to-client
 tls-server
 tls-auth keys/ta.key 0
 tls-timeout 120
 auth SHA1
 cipher BF-CBC
 keepalive 10 30
 comp-lzo
 max-clients 100
 user nobody
 group nobody
 persist-key
 persist-tun
 status /var/log/openvpn/openvpn-status-udpop2.log
 log /var/log/openvpn/openvpn-udpop2.log
 verb 3
 push "ping 10"
 push "ping-restart 20"
 client-connect /usr/local/etc/openvpn/route.sh
 script-security 3 system

/usr/local/etc/openvpn/routertcp.conf:

port 1195
 proto tcp
 dev tun2
 management localhost 8323
 ca /usr/local/etc/openvpn/keys/ca.crt
 cert /usr/local/etc/openvpn/keys/router.crt
 key /usr/local/etc/openvpn/keys/router.key
 dh /usr/local/etc/openvpn/keys/dh1024.pem
 server 10.10.102.0 255.255.255.0
 push "dhcp-option DNS 10.1.1.1"
 push "dhcp-option DNS 10.1.1.2"
 push "dhcp-option WINS 10.1.1.3"
 push "route 10.1.1.0 255.255.255.0"  #подсеть центрального офиса
 push "route 10.1.2.0 255.255.255.0"  #подсеть филиала
 push "route 10.10.100.0 255.255.255.0"
 push "route 10.10.101.0 255.255.255.0"
 push "route 10.10.102.0 255.255.255.0"
 client-config-dir ccdtcp
 route 10.10.102.0 255.255.255.0
 client-to-client
 tls-server
 tls-auth keys/ta.key 0
 tls-timeout 120
 auth SHA1
 cipher BF-CBC
 keepalive 10 30
 comp-lzo
 max-clients 100
 user nobody
 group nobody
 persist-key
 persist-tun
 status /var/log/openvpn/openvpn-status-tcp.log
 log /var/log/openvpn/openvpn-tcp.log
 verb 3
 push "ping 10"
 push "ping-restart 20"
 client-connect /usr/local/etc/openvpn/route.sh
 script-security 3 system

Создание ключей и т.п. делаем по статье [urlspan]Cancer[/urlspan].
Далее делаем каталоги ccd — для каждого сервера свой:

mkdir /usr/local/etc/openvpn/ccdtcp
mkdir /usr/local/etc/openvpn/ccdudpop1
mkdir /usr/local/etc/openvpn/ccdudpop2

В каждом из них делаем ccd файл для филиала:
/usr/local/etc/openvpn/ccdudpop1/filial1:

ifconfig-push 10.10.100.2 10.10.102.1
 iroute 10.1.2.0 255.255.255.0

/usr/local/etc/openvpn/ccdudpop2/filial1:

ifconfig-push 10.10.101.2 10.10.102.1
 iroute 10.1.2.0 255.255.255.0

/usr/local/etc/openvpn/ccdtcp/filial1:

ifconfig-push 10.10.102.2 10.10.102.1
 iroute 10.1.2.0 255.255.255.0

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

Далее самое интересное. Сервер OpenVPN оказывется не может динамически, во время подключения клиента, прописывать маршруты — он умеет это делать только в момент запуска сервера. Поскольку серверов у нас несколько и какому именно будет принадлежать этот маршрут — неясно, приходится обходить это внешним скриптом, который будет запускаться при установлении любого соединения:

/usr/local/etc/openvpn/route.sh:

#!/usr/local/bin/bash
 if [ $common_name == "filial1" ]; then    #filial1 - имя сертификата филиала
 sudo /sbin/route delete 10.1.2.0/24
 sudo /sbin/route add 10.1.2.0/24 $ifconfig_pool_local_ip
 fi

Не забываем про права:

chmod 755 /usr/local/etc/openvpn/route.sh

Однако просто так sudo не даст добавить роут — он естественно спросит пароль. Тут мы ломаем все понятия о безопасности и добавляем в /usr/local/etc/sudoers :

nobody ALL=(ALL) NOPASSWD:/sbin/route
 После этого sudo route будут выполняться без запроса пароля. Как руки дойдут — обязательно пересажу сервера на другого пользователя. Далее, запускаем сервера:
 /usr/local/etc/rc.d/openvpntcp start
 /usr/local/etc/rc.d/openvpnudpop1 start
 /usr/local/etc/rc.d/openvpnudpop2 start

Вывод ifconfig, касаемо интерфейсов tun:

tun0: flags=8051<up ,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 inet 10.10.100.1 --> 10.10.100.2 netmask 0xffffffff
 Opened by PID 44907
 tun1: flags=8051</up><up ,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 inet 10.10.101.1 --> 10.10.101.2 netmask 0xffffffff
 Opened by PID 43764
 tun2: flags=8051</up><up ,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
 inet 10.10.102.1 --> 10.10.102.2 netmask 0xffffffff
 Opened by PID 52890</up>

Видим как поднялись три tun-интерфейса — по одному на каждый openvpn сервер.

Филиал
Все настроено по статье [urlspan]Cancer[/urlspan], ключи размещены. Меняем конфиги.

/usr/local/etc/openvpn/filial1.conf :

dev tun
 remote 185.195.205.215 1195 tcp
 #remote 85.95.105.115 1195 tcp
 #remote 185.195.205.215 1194 udp
 remote 85.95.105.115 1194 udp
 client
 resolv-retry infinite
 pkcs12 keys/filial1.p12
 tls-client
 tls-auth keys/ta.key 1
 auth SHA1
 cipher BF-CBC
 ns-cert-type server
 comp-lzo
 persist-key
 persist-tun
 status /var/log/openvpn/openvpn-status.log
 log /var/log/openvpn/openvpn.log
 verb 3
 ping-restart 20
 #connect-timeout 15

Вот и все. Комбинации каналов и портов в remote меняем по собственной необходимости...

 

 

http://www.mahno.su/freebsd/network/openvpn-tcp-udp

Понравилась статья, расскажи о ней друзьям, нажми кнопку!