UMGUM.COM (лучше) 

OpenVPN + check validity ( Следим за истечением срока действия сертификатов OpenVPN. )

15 марта 2011  (обновлено 2 ноября 2014)

OS: Debian GNU/Linux Lenny.

Помните, когда общество наше перешло от собирательства к взращиванию, появилось такое понятие, как разделение труда. Идея в том, что кузнец куёт, косец косит, пекарь выпекает, а кто-то съедает результат. Многим это пришлась по душе. Потребители радостно устремились к состоянию чистого потребительства, не желая давать себе труда пошевелить чем бы то ни-было, кроме как челюстями.

Доходит до смешного, выдаёшь человеку сертификат доступа к VPN, в котором вписан срок его действия, и выясняется, оказывается - ты же ещё и обязан напомнить вовремя потребителю о том, что срок вот-вот закончится. Интересно, кто таким деятелям напоминает о сроке хранения продуктов или о необходимости вовремя налоги заплатить?

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


Для начала оборудуем местечко для сохранения журнала отправленных уведомлений:

# mkdir -p /var/log/openvpn
# touch /var/log/openvpn/check-expare.log
# chown openvpn:openvpn /var/log/openvpn/check-expare.log
# chmod o-rwx /var/log/openvpn/check-expare.log

Размещаем где-нибудь наш скрипт:

# mkdir -p /etc/custom/openvpn
# touch /etc/custom/openvpn/check-expare.sh
# chmod ugo+x /etc/custom/openvpn/check-expare.sh

Содержимое следует:

# cat /etc/custom/openvpn/check-expare.sh

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
MAILADM=support@vpn.example.local

# Указываем месторасположение файлов сертификатов
KEYS=/etc/openvpn/easy-rsa/keys/
# Указываем имя и местораположение индекса используемых сервером сертификатов
INDEX=/etc/openvpn/easy-rsa/keys/index.txt

# Указываем имя и месторасположение индекса рассылки
LOG=/var/log/openvpn/check-expare.log

# Задаём временные метки для инициирования высылки уведомления
AMONTH=2678400
AWEEK=604800
ATREEDAY=259200

# Запускаем перебор строк файла индекса (отрабатываем только задействованные, не отозванные)
cat $INDEX | grep '^V' | while read LINE
do

  # Получаем имя сертификата
  CN=`echo $LINE | awk 'match($0,/\/CN=.+\//) {print substr($0, RSTART, RLENGTH)}' | cut -c 5- | rev | cut -c 5- | rev`
  # Получаем адрес электронного почтового ящики, на который будем слать уведомления
  emailAddress=`echo $LINE | awk 'match($0,/\/emailAddress=.+/) {print substr($0, RSTART, RLENGTH)}' | cut -c 15- | rev | cut -c 1- | rev`
  
  # Получаем дату начала действия сертификата
  DFROM=`cat ${KEYS}/${CN}.crt | grep -i "Not Before" | awk 'match($0,/: .+/) {print substr($0, RSTART, RLENGTH)}' | cut -c 3- | rev | cut -c 1- | rev`
  # Получаем дату окончания действия сертификата
  DTO=`cat ${KEYS}/${CN}.crt | grep -i "Not After" | awk 'match($0,/: .+/) {print substr($0, RSTART, RLENGTH)}' | cut -c 3- | rev | cut -c 1- | rev`

  # Приводим значения полученных дат к единому образцу - времени, прошедшему от начала "эпохи" UNIX (seconds since 1970-01-01 00:00:00 UTC)
  DCURR=`date +%s`
  DFROM=`date --date="${DFROM}" +%s`
  DTO=`date --date="${DTO}" +%s`

  # Вычисляем, сколько секунд осталось до окончания действия сертификата
  DEXP=`expr ${DTO} - ${DCURR}`

  # Проверяем, не настало-ли время
  if [ ${DEXP} -lt ${ATREEDAY} ]
  then
    # Если событие по сроку информирования для проверяемого сертификата не зафиксировано, то делаем это
    if [ "`cat ${LOG} | grep -i ${CN} | grep -i ATREEDAY`" == "" ] || [ `cat ${LOG} | sort --reverse | grep -i ${CN} | grep -i --max-count=1 ATREEDAY | awk '{print $1}'` -lt ${DFROM} ]
    then
      # Высылаем уведомление на адрес электронной почты, указанный при создании сертификата
      echo -e "Content-Type: text/plain; charset="utf-8"\nSubject: Warning from ITS VPN server to ${CN}\nДо окончания срока действия сертификата (VPN) удалённого доступа осталось три дня." | sendmail -F${HOSTNAME} ${emailAddress} ${MAILADM}
      # Записываем в журнал событие
      echo "${DCURR}  ${CN}  ATREEDAY" >> ${LOG}
    fi
  else
    if [ ${DEXP} -lt ${AWEEK} ]
    then
      if [ "`cat ${LOG} | grep -i ${CN} | grep -i AWEEK`" == "" ] || [ `cat ${LOG} | sort --reverse | grep -i ${CN} | grep -i --max-count=1 AWEEK | awk '{print $1}'` -lt ${DFROM} ]
      then
        echo -e "Content-Type: text/plain; charset="utf-8"\nSubject: Warning from ITS VPN server to ${CN}\nДо окончания срока действия сертификата (VPN) удалённого доступа осталась одна неделя." | sendmail -F${HOSTNAME} ${emailAddress} ${MAILADM}
        echo "${DCURR}  ${CN}  AWEEK" >> ${LOG}
      fi
    else
      if [ ${DEXP} -lt ${AMONTH} ]
      then
        if [ "`cat ${LOG} | grep -i ${CN} | grep -i AMONTH`" == "" ] || [ `cat ${LOG} | sort --reverse | grep -i ${CN} | grep -i --max-count=1 AMONTH | awk '{print $1}'` -lt ${DFROM} ]
        then
          echo -e "Content-Type: text/plain; charset="utf-8"\nSubject: Warning from ITS VPN server to ${CN}\nДо окончания срока действия сертификата (VPN) удалённого доступа остался один месяц." | sendmail -F${HOSTNAME} ${emailAddress} ${MAILADM}
          echo "${DCURR}  ${CN}  AMONTH" >> ${LOG}
        fi
      fi
    fi
  fi

done

exit 0

Вот и всё, в общем-то. Созданный нами скрипт должен запускаться периодически. Думаю, что одного раза в сутки, с утра, будет достаточно. Размещаем команду запуска скрипта в таблице /etc/crontab:

# cat /etc/crontab

....
30  6 * * *   openvpn    /etc/custom/openvpn/check-expare.sh &
....


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )