понедельник, 23 мая 2016 г.

Ротация логов сервера OpenVPN под FreeBSD


Задача эта, как ни странно, весьма нетривиальная.
Во-первых, если расположение log-файлов задать в конфиге OpenVPN через дерективу:

log /var/log/openvpn/openvpn.log

то никакой ротации настроить не получится. Дело тут в том, что демон OpenVPN держит этот файл до своего перезапуска и пытается писать именно в него не по имени, а по дескриптору. Т.е., когда программа newsyslog осуществляет ротацию логов, она старый файл копирует, удаляет и создаёт вместо него новый, а OpenVPN продолжает пытаться писать логи в файл со старым дескриптором, которого уже не существует. В результате, после ротации лога таким способом, запись в него прекращается.
В сети описаны способы, как настроить это через утилиту logrotate с использованием параметра copytruncate, но, во-первых, logrotate штатно во FreeBSD не входит, а во-вторых, у меня это тоже не заработало. Идея тут в том, что параметр copytruncate позволяет не удалять старый log-файл, копируя его в другой, а старый просто обнулять. После этого, по идее, OpenVPN должен продолжить писать в старый файл нулевого размера с тем же дескриптором, а предыдущий лог уже подвергается упаковке и ротации. Однако у меня ротация лога таким способом, конечно, произошла, но OpenVPN продолжил писать в старый файл с той же позиции, на которой он остановился. Т.е. размер текущего log-файла не уменьшился.

Второй способ более правильный, и описан в документации OpenVPN, хотя и не совсем явно. Состоит он в том, что дерективу "log" из файла конфигурации OpenVPN нужно убрать. После этого все логи OpenVPN начнут попадать в общий файл /var/log/messages, а уже оттуда их нужно перенаправить в другой файл через настройки syslogd и ротировать посредством newsyslog. Во многих руководствах, найденных мной в сети, написано, что для этого нужно всего-лишь добавить в конец стандартного файла /etc/syslog.conf следующие строки:

!openvpn
*.*                                             /var/log/openvpn/openvpn.log

Добавил, логи OpenVPN действительно начали писаться куда надо, НО они продолжали попадать и в /var/log/messages, т.е. дублировались.
После долгих экспериментов и консультаций с умными людьми выяснилось, что вышеуказанные строки нужно добавлять не в конец файла syslog.conf, а в его начало, добавив туда ещё одну строку, в результате чего выглядеть это должно так:

!openvpn
*.*                                             /var/log/openvpn/openvpn.log
!-openvpn

Первые две строки указывают демону syslogd перенаправлять все сообщения от программы openvpn в файл /var/log/openvpn/openvpn.log, а третья сточка отключает какое-либо другое сохранение сообщений от программы openvpn.
Далее добавляем в newsyslog.conf то, что нам нужно, например такую строку:

/var/log/openvpn/openvpn.log    644     7       *       @T04    ZC


и процесс пошёл. Всё работает.

В заключении ещё один момент. Мне нужно было сделать всё описанное для трёх демонов OpenVPN, запущенных на одном сервере. В результате экспериментов выяснилось, что выглядеть это должно так:

В начале /etc/syslog.conf:
!openvpn1
*.*                                             /var/log/openvpn/openvpn1.log
!openvpn2
*.*                                             /var/log/openvpn/openvpn2.log
!openvpn3
*.*                                             /var/log/openvpn/openvpn3.log
!-openvpn1,openvpn2,openvpn3
...

В конце /etc/newsyslog.conf:
...
/var/log/openvpn/openvpn1.log    644     7       *       @T04    ZC
/var/log/openvpn/openvpn2.log    644     7       *       @T04    ZC
/var/log/openvpn/openvpn3.log    644     7       *       @T04    ZC

Теперь всё.