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
/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