[Из песочницы] Мониторинг подключения USB накопителей и логирование операций с файлами
Дано: Пользовательские ПК, под управлением linux (suse 11, mint 16); Пользователи работают удаленно с терминалами, куда пробрасываются USB накопители; Пользователи не имеют на персональных компьютерах никаких прав, кроме запуска rdesktop/freerdp. Задачи: отслеживать факты подключения USB накопителей; отслеживать факты записи и изменения файлов на USB накопителях. Необходимое отступление. Я не буду обсуждать моральные аспекты подобной слежки за сотрудниками. Есть корпоративные стандарты и требования корпоративной службы безопасности с которыми ознакомлены сотрудники. 1. Отслеживаем факт подключения USB устройстваДля выполнения данной задачи я использовал свойство udev, которое позволяет выполнять скрипт при наступлении какого-либо события. Создадим правило, которое будет отвечать за подключение и отключение usb устройств:
touch /etc/udev/rules.d/usb.rules Содержимое файла usb.rules: ACTION==«add», SUBSYSTEM==«block», ENV{ID_BUS}==«usb|mmc|memstick|ieee1394», RUN+=»/bin/bash /etc/udev/usb_on.sh %E{ID_SERIAL_SHORT} %E{ID_MODEL} %E{ID_VENDOR}» ACTION==«remove», SUBSYSTEM==«block», ENV{ID_BUS}==«usb|mmc|memstick|ieee1394», RUN+=»/bin/bash /etc/udev/usb_off.sh %E{ID_SERIAL_SHORT} %E{ID_MODEL} %E{ID_VENDOR}» Где: ACTION — отслеживаемое действие, add — подключение устройств, remove — отключение; ENV — перечень отслеживаемых устройств по типу; RUN — исполняемое действие. В данном случае, в зависимости от события, запускаются скрипты usb_on.sh и usb_off.sh. Скриптам usb_on.sh и usb_off.sh udev передает следующие данные:%E{ID_SERIAL_SHORT} — серийный номер USB устройства; %E{ID_MODEL} — модель USB устройства; %E{ID_VENDOR} — производитель USB устройства. Скрипт usb_on.sh:
/usr/bin/curl -d «host=$(hostname)&serial=$1&name=$2&vendor=$3&file=on&sub=true» --noproxy 10.0.40.16 http://10.0.40.16/usb/input.php Скрипт usb_off.sh: /usr/bin/curl -d «host=$(hostname)&serial=$1&name=$2&vendor=$3&file=off&sub=true» --noproxy 10.0.40.16 http://10.0.40.16/usb/input.php Данные скрипты выполняют единственное действие — посылают http POST запрос по адресу 10.0.40.16/usb/input.php (директива noproxy 10.0.40.16 нужна для того, что бы запрос отсылался минуя прокси-сервер). В данном POST запросе передаются следующие переменные: host — имя компьютера результат выполнения команды hostname; serial — серийный номер USB устройства (%E{ID_SERIAL_SHORT}) name — модель USB устройства (%E{ID_MODEL}) vendor — производитель USB устройства (%E{ID_VENDOR}) file — действие. on — подключение, off — отключение (file — название поля выбрано по той причине, что сюда же будет вноситься и информация о файлах, над которыми производились какие-либо действия) sub=true — имитация нажатия кнопки на веб-форме. 2.Сервер сбора информации Как видно из запускаемых скриптов usb_on.sh и usb_off.sh — вся информация передается на php скрипт, который состоит из простой веб-формы и обработчика запроса.
Обработчик делает одно — складывает принятые данные в таблицу usb БД MySQLmysql_query («INSERT INTO `usb` (`id`, `date`, `host`, `ip`, `serial`, `name`, `vendor`, `file`) VALUES (NULL, '$time', '$_POST[host]', '$_SERVER[REMOTE_ADDR]', '$_POST[serial]', '$_POST[name]', '$_POST[vendor]', '$_POST[file]')»); Структура таблицы:
CREATE TABLE IF NOT EXISTS `usb` ( `id` int (11) NOT NULL AUTO_INCREMENT, `date` bigint (20) NOT NULL, `ip` varchar (15) COLLATE utf8_bin NOT NULL, `host` varchar (50) COLLATE utf8_bin NOT NULL, `serial` varchar (100) COLLATE utf8_bin NOT NULL, `name` varchar (100) COLLATE utf8_bin NOT NULL, `vendor` varchar (100) COLLATE utf8_bin NOT NULL, `file` text COLLATE utf8_bin, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1; 3. Мониторинг операций с файлами Для выполнения функции отслеживания операций, которые выполнялись на файлами на подключенном носителе был написан следующий скрипт: touch /var/tmp/usb.check # обновляем время модификации файла check=1 while [ $check ] # бесконечный цикл do if [ -f /var/tmp/usb.check ] # если существует файл then ACCESS='' # обнуляем переменные CREATE='' MODIFY='' # Далее, ищем в папке /media файлы, значения времен создания, изменения, доступа которых больше, чем только что созданным файлом /var/tmp/usb.check ACCESS=`find /media -anewer /var/tmp/usb.check -type f` CREATE=`find /media -cnewer /var/tmp/usb.check -type f` MODIFY=`find /media -newer /var/tmp/usb.check -type f` if [ ! -z »$ACCESS» ] then ACCESS=«access »$ACCESS # Передача информации на сервер /usr/bin/curl -d «host=$(hostname)&serial=$2&name=$3&vendor=$4&action=$ACCESS&sub=true» --noproxy 10.0.40.16 http://10.0.40.16/usb/input.php fi if [ ! -z »$CREATE» ] then CREATE=«create »$CREATE /usr/bin/curl -d «host=$(hostname)&serial=$2&name=$3&vendor=$4&action=$CREATE&sub=true» --noproxy 10.0.40.16 http://10.0.40.16/usb/input.php fi if [ ! -z »$MODIFY» ] then MODIFY=«modify »$MODIFY /usr/bin/curl -d «host=$(hostname)&serial=$2&name=$3&vendor=$4&file=$MODIFY&sub=true» --noproxy 10.0.40.16 http://10.0.40.16/usb/input.php fi fi touch /var/tmp/usb.check # обновляем время sleep 5 # пауза done Данный скрипт добавляется в автозапуск и работает в фоновом режиме.Для получения выборки сохраненной информации написан php скрипт, выбирающий из БД записи за указанный период и по выбранным ПК. Пример вывод информации:
4. Распростренение по ПК Т.к. ПК с сети расположено достаточно много, было решено сделать это в полу-автоматическом режиме. А именно: написан скрипт, который считывает из файла список ПК для распространения и передает на них необходимые файлы. Выполняется это с помощью утилит sshpass (для автоматического ввода пароля) и scp (копирование).Для начала в /etc/ssh/ssh_config меняем директиву StrictHostKeyChecking: StrictHostKeyChecking no Делается это для того, что бы ssh ключи автоматически добавлялись в список доверенных.Непосредственно сам скрипт распространения:
#!/bin/bash while read line; do array[$index]=»$line» index=$(($index+1)) done < hosts.conf for ((a=0; a < ${#array[*]}; a++)) do remote=`echo ${array[$a]} | awk '{ print $1 }'` echo "$remote begin"; /usr/bin/sshpass -p "root_password" /usr/bin/scp /home/user/usb_mon/usb.rules admin@$remote:/etc/udev/rules.d/usb.rules /usr/bin/sshpass -p "root_password" /usr/bin/scp /home/user/usb_mon/*.sh admin@$remote:/etc/udev/ /usr/bin/sshpass -p "root_password" /usr/bin/scp /home/user/usb_mon/boot.local admin@$remote:/etc/rc.d/boot.local echo "$remote end"; done Т.к. некоторые ПК могут быть выключенными, запуск скрипта выполняется с выводом всей информации в лог и последующим анализом:
./deploy.sh &> deploy.log & PS. Планы на будущее Что нужно доработать: безопасность передачи информации при POST запросе убрать логирование служебных файлов (например Thumbs.db) теневое копирование файлов, над которыми были произведены какие-либо действия.