OpenVPN: — PUSH тебе твой собственный ROUTE

К бессонной ночи привёло “молчание логов” OpenVPN сервера при невозможности прочесть файл.

Имеется OpenVPN сервер, к которому подключены VPN клиенты. За некоторыми клиентами находятся сети которые необходимо анонсировать другим клиентам OpenVPN и обеспечить маршрутизацию.

Для этого в OpenVPN предусмотрены четыре параметра находящиеся в двух разных файлах которые позволяют настроить роутинг в сети VPN клиента.

Файл /etc/openvpn/*.conf

push "route 192.168.33.0 255.255.255.0"
route 192.168.33.0 255.255.255.0
client-config-dir ccd-vpn03

client-config-dir определяет каталог в котором будут находиться файлы в которых будут объявлены сети клиентов. Имена файлов должны совпадать с CommonName сертификата клиента за которым находятся сети объявленные в файле. Например если за клиентом с сертификатом у которого CN равен “vpn03.gw01.common-client2” находится сеть 192.168.33.0 255.255.255.0 то файл /etc/openvpn/ccd-vpn03/vpn03.gw01.common-client2

iroute 192.168.33.0 255.255.255.0

При правильном поведении сервер должен посылать VPN клиентам команду PUSH ROUTE но обязан исключать сети самих клиентов которым посылается команда PUSH. Тоесть в нашем случае сервер из всего что отправлял клиенту с сертификатом “vpn03.gw01.common-client2” должен был исключить сеть 192.168.33.0 255.255.255.0 так как она объявлена в файле в директиве iroute. Однако он вёл себя так словно этого файла не существовало и поступал так:

Tue Dec  1 17:25:58 2015 us=889326 vpn03.gw01.common-client2/90.91.92.93:56801 PUSH: Received control message: 'PUSH_REQUEST'
Tue Dec  1 17:25:58 2015 us=889470 vpn03.gw01.common-client2/90.91.92.93:56801 SENT CONTROL [vpn03.gw01.common-client2]: 'PUSH_REPLY,route 10.10.5.0 255.255.255.0,route 192.168.33.0 255.255.255.0,route 192.168.103.0 255.255.255.0,explicit-exit-notify 3,route 10.10.5.1,topology net30,ping 10,ping-restart 60,ifconfig 10.10.5.6 10.10.5.5' (status=1)

На стороне роутера

Tue Dec  1 16:26:00 2015 us=261727 PUSH: Received control message: 'PUSH_REPLY,route 10.10.5.0 255.255.255.0,route 192.168.33.0 255.255.255.0,route 192.168.103.0 255.255.255.0,explicit-exit-notify 3,route 10.10.5.1,topology net30,ping 10,ping-restart 60,ifconfig 10.10.5.6 10.10.5.5'

Видно что и на сервере и на клиенте присутствует маршрут route 192.168.33.0 255.255.255.0 который приводит к вот такой ерунде на стороне клиента:

root@home-anbriz:~# ip route | sort
10.10.5.0/24 via 10.10.5.5 dev tun0 
10.10.5.1 via 10.10.5.5 dev tun0 
10.10.5.5 dev tun0  proto kernel  scope link  src 10.10.5.6 
172.16.88.0/24 dev eth0  proto kernel  scope link  src 172.16.88.226 
192.168.103.0/24 via 10.10.5.5 dev tun0 
192.168.223.0/24 via 10.10.5.5 dev tun0 
192.168.33.0/24 dev br-lan  proto kernel  scope link  src 192.168.33.254 
192.168.33.0/24 via 10.10.5.5 dev tun0 
default via 172.16.88.1 dev eth0  proto static 

Как видно, подствеченные строки указывают один и тот же маршрут через разные интерфейсы. Но то что свой собственный “железный” маршрут прописан через виртуальный интефейс не идёт ни в какие ворота. Вполне логично, что маршрутизация на клиенте “ломается” самым серьёзным образом.

Всё это наводит на мысль что инструкция iroute 192.168.33.0 255.255.255.0 была сервером проигнорирована, либо не связана с CommonName сертификата грубо говоря сервер не признал что у клиента есть свои сети.

Когда файл недоступен первое средство проверить SELinux метки и даже отключить на время SELinux. Но в этом случае мне это не помогло.

Ларчик открылся только утром следующего дня, когда все танцы с бубнами закончились и остались два последних средства strace и отладка исходников.

strace
open("/etc/openvpn/ccd-vpn03/vpn03.gw01.common-client2", O_RDONLY) = -1 EACCES (Permission denied)

И о этом ни единого байта в логах OpenVPN хотя об этом необходимо кричать!

ps ax -o gid,uid,pid,cmd | grep openvpn
   99    99 10883 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/vpn03.gw01.common.com-server-udp-11967.pid --config vpn03.gw01.common.com-server-udp-11967.conf --cd /etc/openvpn

Процесс выполняется от gid=99 и uid=99, а это nobody nogroup. А права на файл?

[root@gw1 ccd-vpn03]# ls -la
total 16
drwxr-xr-x.  2 root root 4096 Nov 30 11:09 .
drwxr-xr-x. 24 root root 4096 Nov 30 10:59 ..
-rw-------.  1 root root   74 Nov 30 11:09 vpn03.gw01.common-client2
-rw-------.  1 root root   35 Nov 30 03:45 vpn03.gw01.common-client3

Только root может читать писать эти файлы.

В отличии от других конфигурационных файлов /etc/openvpn/ccd-vpn03/vpn03.gw01.common-client2 читается во время подсоединения клиента и ошибку стоит ловить в это время. И читается это файл непосредственно сервисом уже после переключения в nobody nogroup.

Вот для сравнения как выглядят логи сервера с заблокированным файлом и с разблокированным:
Вот как выглядит начало иницииации соединия при рестарте со стороны клиента:

файл нормально прочитан

Tue Dec  1 17:25:56 2015 us=817182 MULTI: new connection by client 'vpn03.gw01.common.com-client2' will cause previous active sessions by this client to be dropped.  Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
Tue Dec  1 17:25:56 2015 us=817234 OPTIONS IMPORT: reading client specific options from: /etc/openvpn/ccd-vpn03/vpn03.gw01.common.com-client2
Tue Dec  1 17:25:56 2015 us=817347 MULTI: Learn: 10.10.5.6 -> vpn03.gw01.common.com-client2/90.91.92.93:56801

когда файл не может быть прочитан

Tue Dec  1 17:49:00 2015 us=572601 MULTI: new connection by client 'vpn03.gw01.common.com-client2' will cause previous active sessions by this client to be dropped.  Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
Tue Dec  1 17:49:00 2015 us=572682 MULTI: Learn: 10.10.5.6 -> vpn03.gw01.common.com-client2/90.91.92.93:57091

Как видно ошибки нет. Просто отсутствует строка OPTIONS IMPORT. И из-за этого я потерял несколько часов сна и написал эту статью.

ВЫВОД:
Устанавливая режим работы VPN сервера или клиента под Linux в nobody nogroup проверьте что файлы в каталоге ccd имеют возможность читаться всеми. На остальные файлы логи, статусы и конфиги достаточно что для root установлены права “читать и писать”.

Leave a Reply