*nix
11 November 2011

Автоматический сбор и архивация фото/видеонаблюдения

ЗАДАЧА


Однажды, начальство потребовало круглосуточно вести запись происходящего в офисах. А также, в рабочее время — периодически публиковать фото из офисов на сайте.

От моего предшественника мне досталось:
  • Несколько офисов с умными видеокамерами D-Link, которые фотографируют происходящее
  • Сервер на FreeBSD
  • Сайт организации, куда должен попадать снимок с каждой камеры
  • Сетевая папка в локальной сети, где должны храниться архивы записей

Известно:

— Сервер FreeBSD не доступен извне
— Хостер не любит, когда к его FTP подключаются чаще, чем раз в минуту
— Учитывая качество и толщину каналов связи, камеры не пишут видео, а делают периодические фото

На момент постановки задачи, видеокамеры самостоятельно вразнобой подключались к FTP хостера и выкладывали снимки по расписанию каждую минуту. В результате чего, хостер периодически блокировал доступ по FTP к сайту.



РЕШЕНИЕ

Решение — теория

Решением этой задачки стал один из уроков по информационной безопасности, данный мне однажды в СПбГУ ИТМО. В уроке говорилось о зонах безопасности, об их уровнях, и о правилах чтения/записи между уровнями.

В двух словах: приложение с высшим уровнем безопасности, например — 1, может читать и писать в приложение уровня 2 или 3. Но приложение 2, не может ни читать, ни писать в приложение 1, хотя может читать и писать в приложение 3.

На самом деле правила несколько сложнее, но я упростил для облегчения восприятия.

Who is who

Схема взаимодействия всех вышеуказанных элементов выстроилась простая:
Камеры складывают фотографии на мой сервер по FTP, сервер их копирует в сетевую папку, а также публикует на хостинге.



Сервер здесь выступает уровнем 1, имеющим доступ ко всем остальным уровням. Нетрудно заметить, что здесь есть как-бы нарушение правила: камерам, имеющим более низкий 2й уровень, дано право писать на 1й уровень. По-хорошему, следовало сервер научить читать картинку с камер, а не открывать им доступ, но в данном случае, общая безопасность системы не пострадала. Объясняю: хитрость в том, что камеры пишут в FTP-папку, имеющую тот же уровень безопасности, что и у камер, т.е. 2й. Папка находится отдельно от всех остальных и содержит только текущие изображения с камер. Любой кто подключится к FTP используя логин и пароль с камеры, получит только несколько фотографий офисов, но не сможет увидеть всех архивов.

Пока расписывал это все, подумал, что злоумышленник может выгрузить таким образом свою фотографию, содержащую какую-нибудь непристойность, и она автоматически попадет на сайт. Надо подумать, как этого избежать. Можно, например, ограничить доступ к FTP по статическим IP-адресам камер и усложнить пароли для доступа к камерам и FTP. Но лучше, чем научить сервер считывать изображение с камер самостоятельно, боюсь, ничего не придумать. Что поделать — технические ограничения камер.

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

Вернемся к нашим баранам

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

Решение — практика

  1. Устанавливаем и настраиваем на FreeBSD-сервере ProFTP (о вкусах не спорят, я просто предлагаю понятный вариант) и ffmpeg.
  2. Создаем папку для видеокамер и папку для архива (например, где-нибудь в папке /usr/)
  3. Создаем в ProFTP учетную запись для видеокамер и отдаем ей созданную папку
  4. Настраиваем камеры, используя их веб-интерфейс, таким образом, чтобы они круглосуточно и, к примеру, ежеминутно (кому какой период подойдет), подключались к нашему серверу по FTP и сохраняли фотографию.
  5. Очень важно также, настроить камерам правильную дату, время и автоматическую синхронизацию с местным NTP-сервером точного времени.
  6. Вспоминаем параметры подключения к FTP нашего хостинга.
  7. Пишем хитроумный SH-скрипт и заносим его в cron с частотой выполнения, аналогичной частоте выкладывания фотографий камерами, т.е. раз в минуту.
  8. Наслаждаемся и идем докладывать начальству.


И наконец сердце решения — скрипт, собственной наработки:
#!/bin/sh

## Запоминаем дату. Требуется, чтобы делать
## архив отправленных файлов, на будущее
day="`date +%Y-%m-%d`"
archive="/store/STORE/cam_archive"
## Данные для подключения по FTP

## Имя пользователя
FTPUSER='*********'

## IP-адрес или доменное имя хоста
FTPHOST='***.***.***.***'

## Пароль FTP
FTPPASS='************'

## Удалённый каталог, в который будем пересылать файл
REMOTEDIR="/www/img"

## Локальный каталог откуда будем копировать файлы
LOCALDIR="/store/STORE/cam"

## Входим в локальный каталога, откуда будем копировать файлы
cd $LOCALDIR

# Пишем в лог новую дату
echo .
echo -================================================-
date

## Создаём каталог, куда будем ложить копии отправленных файлов
mkdir $archive/$day >/dev/null 2>&1

## Запоминаем время для имени файла.
time1=`date +%H_%M_%S`

## Копируем файлы в созданную нами директорию, текущего дня.
# Для каждой камеры создается своя папка (по имени файла, который создает камера)
echo Сохраняем снимки в архив.
for file in $(ls -1 *.jpg)
do
 camfolder=`echo ${file} | sed 's/\.jpg//'`
 mkdir $archive/$day/$camfolder >/dev/null 2>&1
 cp $file $archive/$day/$camfolder/$time1\_$file
done

# Топорный метод для определения подходящего времени, чтобы выложить снимки на сайт
# grep дает ответ, есть ли в строке minutes1 текущая минута времени minutes2
minutes1='01 03 05 07 09 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59'
minutes2=`date +%M`
result=`echo ${minutes1} | grep ${minutes2}`

# Публикуем снимки на сайте, только если время в пределах режима работы учреждения (>=10 and <=18 and !result)
if [ `date +%H` -ge 10 ] && [ `date +%H` -le 18 ] && [ -n "$result" ]
then {
echo Публикуем снимки на FTP.
## Здесь начинается подключение к FTP-серверу и выгрузка снимков
ftp -n $FTPHOST <<EOF
quote USER $FTPUSER
quote PASS $FTPPASS
binary
cd $REMOTEDIR
dir
mput *
a
EOF
}
fi

# Если настал новый день (часы=00 and минуты=00), тогда делаем видео из папки вчерашнего дня.
if [ `date +%H` -eq '00' ] && [ `date +%M` -eq '00' ]
then {

# вычислим вчерашний день
LASTDAY=`date -v-1d +"%Y-%m-%d"`

## заходим в эту папку
cd $archive/$LASTDAY/

## проходим по всем подпапкам и чистим их от пустых и недогруженных файлов
## фотографии с моих камер всегда имеют размер более 10k, поэтому все что меньше - однозначно недогружено
find $archive/$LASTDAY/ -size -10k -print | {
while read files
    do
    rm "${files}"
    done
}

## Проходим по всем папкам камер по очереди, выполняя три действия
for camfolders in $(ls -1 -U)
do
## 1. Переименование файлов в ряд с именами в виде порядковых номеров
   y=0
   ls -1 $archive/$LASTDAY/$camfolders/*.jpg | {
   while read files2
       do
       y=`expr ${y} + 1`
       mv ${files2} $archive/$LASTDAY/$camfolders/img`printf %04d ${y}`.jpg
       done
   }

## 2. Конвертируем все в видеоряд
## TODO: требуется настройка высокого качества видео
   ffmpeg -f image2 -i $archive/$LASTDAY/$camfolders/img%04d.jpg -r 6 -s 720x576 $archive/$LASTDAY/$camfolders\_$LASTDAY.avi

## 3. Удаляем все изображения из папки
   rm -rf $camfolders

done

}
fi
exit 0


Работа для напильника:

  • Качество сжатия видеозаписи, мягко говоря, страдает ужасно. Не могу разобраться в хитроумных параметрах ffmpeg. А возможно, что не хватает кодеков. Прошу тех кто сталкивался — подсказать подходящий перечень ключей.
  • Злоумышленник-инсайдер, прикинувшись камерой, может устроить некислый дефейс уважаемому сайту, если конечно узнает пароль от FTP. Нужно либо закрыться как-то, либо научить сервер заходить в веб-интерфейс камер и скачивать с них текущее изображение (у камеры для этого предусмотрен статичный адрес cam1/snapshot.php, а аутентификация производится на базе .htaccess). Посоветуйте, пожалуйста, при помощи каких команд и утилит это можно решить.
    UPD: решение этого момента подсказал Akint. Чуть позже добавлю в код.

+24
6.7k 100
Comments 38
Top of the day