Дано:
Задачи:
Необходимое отступление. Я не буду обсуждать моральные аспекты подобной слежки за сотрудниками. Есть корпоративные стандарты и требования корпоративной службы безопасности с которыми ознакомлены сотрудники.
Для выполнения данной задачи я использовал свойство udev, которое позволяет выполнять скрипт при наступлении какого-либо события. Создадим правило, которое будет отвечать за подключение и отключение usb устройств:
Содержимое файла usb.rules:
Где:
Скриптам usb_on.sh и usb_off.sh udev передает следующие данные:
Скрипт usb_on.sh:
Скрипт usb_off.sh:
Данные скрипты выполняют единственное действие – посылают http POST запрос по адресу 10.0.40.16/usb/input.php (директива noproxy 10.0.40.16 нужна для того, что бы запрос отсылался минуя прокси-сервер). В данном POST запросе передаются следующие переменные:
Как видно из запускаемых скриптов usb_on.sh и usb_off.sh – вся информация передается на php скрипт, который состоит из простой веб-формы и обработчика запроса.
Обработчик делает одно – складывает принятые данные в таблицу usb БД MySQL
Структура таблицы:
Для выполнения функции отслеживания операций, которые выполнялись на файлами на подключенном носителе был написан следующий скрипт:
Данный скрипт добавляется в автозапуск и работает в фоновом режиме.
Для получения выборки сохраненной информации написан php скрипт, выбирающий из БД записи за указанный период и по выбранным ПК. Пример вывод информации:

Т.к. ПК с сети расположено достаточно много, было решено сделать это в полу-автоматическом режиме. А именно: написан скрипт, который считывает из файла список ПК для распространения и передает на них необходимые файлы. Выполняется это с помощью утилит sshpass (для автоматического ввода пароля) и scp (копирование).
Для начала в /etc/ssh/ssh_config меняем директиву StrictHostKeyChecking:
Делается это для того, что бы ssh ключи автоматически добавлялись в список доверенных.
Непосредственно сам скрипт распространения:
Т.к. некоторые ПК могут быть выключенными, запуск скрипта выполняется с выводом всей информации в лог и последующим анализом:
Что нужно доработать:
- Пользовательские ПК, под управлением 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 скрипт, выбирающий из БД записи за указанный период и по выбранным ПК. Пример вывод информации:

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