Pull to refresh

Мониторинг подключения USB накопителей и логирование операций с файлами

Reading time5 min
Views45K
Дано:
  • Пользовательские ПК, под управлением 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 скрипт, который состоит из простой веб-формы и обработчика запроса.

<form action="" method="post" enctype="multipart/form-data">
<input type="submit" name="sub" value="Сохранить">
<input type="text" name="host" maxlength=255 size=100>
<input type="text" name="serial" maxlength=255 size=100>
<input type="text" name="name" maxlength=255 size=100>
<input type="text" name="vendor" maxlength=255 size=100>
<textarea id="file" name="file"></textarea>
</form>


Обработчик делает одно – складывает принятые данные в таблицу usb БД MySQL
mysql_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&file=$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&file=$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 скрипт, выбирающий из БД записи за указанный период и по выбранным ПК. Пример вывод информации:
image

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)
  • теневое копирование файлов, над которыми были произведены какие-либо действия.
Tags:
Hubs:
+20
Comments18

Articles