Разворачивание syslog-сервера с веб-интерфейсом

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

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

И так как в целом задача развертывания сислог-сервера с веб-мордой не решается автоматически установкой какого-нибудь пакета в этом нашем дебиане, я решил во-первых написать скрипт, который сделает все за вас, ну а попутно еще расписать как в целом все это инсталлируется и настраивается руками.

Итак, скрипт писался и проверялся на Debian 10 «Buster», его актуальная версия находится на гитхабе, а текущую я оставлю здесь:

loganalyzer_install.sh
 
#!/bin/bash
# Syslog server with web interface for Debian 10
# LAMP + phpmyadmin + rsyslog + Log Analyzer
PHPMYADMINUSER="pma"
PHPMYADMINPASS="321"
SYSLOGDBPASSWORD="Qwerty"
PMAVER="4.9.2"
LAVERSION="4.1.7"
export LANG="en_US.UTF-8"
function check_packages {
    notinstalled=""
    if [ $# -eq 0 ]; then echo "Package name(s) required"; fi
    if [ $# -gt 0 ]; then
        for packagename in $@; do
            if [[ "" == $(dpkg-query  -W --showformat='${Status}\n' ${packagename}  2>&1 | grep "install ok") ]]; then
                notinstalled=${notinstalled}${packagename}" "
            fi
        done
    fi
    if [[ "" == ${notinstalled} ]]; then
        echo "true"
    else
        echo "${notinstalled}"
    fi
}
######## MARIA DB
function check_sql {
    if [[ "true" != $( check_packages  mariadb-server ) && "true" != $( check_packages  mysql-server) ]]; then
        echo "false"
    fi
    if  [[ "true" == $( check_packages  mariadb-server ) ]]; then echo "mariadb"; fi
    if  [[ "true" == $( check_packages  mysql-server ) ]]; then echo "mysql"; fi
}
function install_sql {
    apt -y install mariadb-server
#    mysql -uroot -e "UPDATE mysql.user SET Password=PASSWORD('${MYSQLROOTPASS}') WHERE User='root';\
#    DELETE FROM mysql.user WHERE User='';\
#    DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');\
#    DROP DATABASE test;\
#    DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%';\
#    FLUSH PRIVILEGES;"
}
######### PHP
function check_php {
    phpnotinstalled=$( check_packages php libapache2-mod-php php-mysql php-common php-cli  php-json php-opcache php-readline php-mbstring )
    if [[ "true" != ${phpnotinstalled} ]]; then
        echo "${phpnotinstalled}"
    else
        echo "true"
    fi
}
######### PHPMYADMIN
function check_phpmyadmin {
    if [[ ! -d /usr/share/phpmyadmin/ ]]; then
        echo "false"
    fi
}
function install_phpmyadmin {
IFS='' read -r -d '' SITECONFIG  <<"EOF"
Alias /phpmyadmin /usr/share/phpmyadmin
<Directory /usr/share/phpmyadmin>
    Options SymLinksIfOwnerMatch
    DirectoryIndex index.php
    <IfModule mod_php5.c>
        <IfModule mod_mime.c>
            AddType application/x-httpd-php .php
        </IfModule>
        <FilesMatch ".+\.php$">
            SetHandler application/x-httpd-php
        </FilesMatch>
        php_value include_path .
        php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
        php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
        php_admin_value mbstring.func_overload 0
    </IfModule>
    <IfModule mod_php.c>
        <IfModule mod_mime.c>
            AddType application/x-httpd-php .php
        </IfModule>
        <FilesMatch ".+\.php$">
            SetHandler application/x-httpd-php
        </FilesMatch>
        php_value include_path .
        php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
        php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
        php_admin_value mbstring.func_overload 0
    </IfModule>
</Directory>
# Authorize for setup
<Directory /usr/share/phpmyadmin/setup>
    <IfModule mod_authz_core.c>
        <IfModule mod_authn_file.c>
            AuthType Basic
            AuthName "phpMyAdmin Setup"
            AuthUserFile /etc/phpmyadmin/htpasswd.setup
        </IfModule>
        Require valid-user
    </IfModule>
</Directory>
# Disallow web access to directories that don't need it
<Directory /usr/share/phpmyadmin/templates>
    Require all denied
</Directory>
<Directory /usr/share/phpmyadmin/libraries>
    Require all denied
</Directory>
<Directory /usr/share/phpmyadmin/setup/lib>
    Require all denied
</Directory>
EOF
if [ ! -f phpMyAdmin-${PMAVER}-all-languages.tar.gz ]; then wget https://files.phpmyadmin.net/phpMyAdmin/${PMAVER}/phpMyAdmin-${PMAVER}-all-languages.tar.gz; fi
tar -xf phpMyAdmin-${PMAVER}-all-languages.tar.gz
mkdir /usr/share/phpmyadmin
cp -r phpMyAdmin-${PMAVER}-all-languages/* /usr/share/phpmyadmin
mkdir -p /var/lib/phpmyadmin/tmp
chown -R www-data:www-data /var/lib/phpmyadmin
mkdir /etc/phpmyadmin/
cp /usr/share/phpmyadmin/config.sample.inc.php  /usr/share/phpmyadmin/config.inc.php
ln -s /usr/share/phpmyadmin/config.inc.php /etc/phpmyadmin/
echo "\$cfg['TempDir'] ='/var/lib/phpmyadmin/tmp';" >> /usr/share/phpmyadmin/config.inc.php
r="\$cfg\['blowfish_secret'\] = '"
sed -i  "s/${r}/${r}$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)/g" /usr/share/phpmyadmin/config.inc.php
echo "$SITECONFIG" >  /etc/apache2/sites-available/phpmyadmin.conf
ln -s /etc/apache2/sites-available/phpmyadmin.conf /etc/apache2/sites-enabled/
service  apache2 restart
mysql -uroot -e "use mysql; CREATE USER ${PHPMYADMINUSER}@localhost IDENTIFIED BY '${PHPMYADMINPASS}'; GRANT ALL ON *.* TO ${PHPMYADMINUSER}@localhost WITH GRANT OPTION;"
service mysql restart
}
######### SYSLOG
function install_rsyslog_mysql {
debconf-set-selections << END
rsyslog-mysql      rsyslog-mysql/mysql/admin-pass      password
# MySQL application password for rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/mysql/app-pass      password ${SYSLOGDBPASSWORD}
rsyslog-mysql      rsyslog-mysql/password-confirm      password ${SYSLOGDBPASSWORD}
rsyslog-mysql      rsyslog-mysql/app-password-confirm      password ${SYSLOGDBPASSWORD}
# MySQL username for rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/db/app-user      string      rsyslog@localhost
# Back up the database for rsyslog-mysql before upgrading?
rsyslog-mysql      rsyslog-mysql/upgrade-backup      boolean      true
# Host running the MySQL server for rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/remote/newhost      string
# MySQL database name for rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/db/dbname      string      Syslog
# Reinstall database for rsyslog-mysql?
rsyslog-mysql      rsyslog-mysql/dbconfig-reinstall      boolean      false
rsyslog-mysql      rsyslog-mysql/missing-db-package-error      select      abort
rsyslog-mysql      rsyslog-mysql/remote/port      string
# Perform upgrade on database for rsyslog-mysql with dbconfig-common?
rsyslog-mysql      rsyslog-mysql/dbconfig-upgrade      boolean      true
# Host name of the MySQL database server for rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/remote/host      select      localhost
# Deconfigure database for rsyslog-mysql with dbconfig-common?
rsyslog-mysql      rsyslog-mysql/dbconfig-remove      boolean      true
# Database type to be used by rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/database-type      select      mysql
rsyslog-mysql      rsyslog-mysql/upgrade-error      select      abort
rsyslog-mysql      rsyslog-mysql/remove-error      select      abort
rsyslog-mysql      rsyslog-mysql/install-error      select      abort
rsyslog-mysql      rsyslog-mysql/passwords-do-not-match      error
rsyslog-mysql      rsyslog-mysql/internal/skip-preseed      boolean      false
# Delete the database for rsyslog-mysql?
rsyslog-mysql      rsyslog-mysql/purge      boolean      false
# Connection method for MySQL database of rsyslog-mysql:
rsyslog-mysql      rsyslog-mysql/mysql/method      select      Unix socket
rsyslog-mysql      rsyslog-mysql/mysql/admin-user      string      root
rsyslog-mysql      rsyslog-mysql/internal/reconfiguring      boolean      false
# Configure database for rsyslog-mysql with dbconfig-common?
rsyslog-mysql      rsyslog-mysql/dbconfig-install      boolean      true
END
DEBIAN_FRONTEND=noninteractive apt-get install -y rsyslog-mysql
echo "Creating /etc/rsyslog.d/enable-remote.conf"
echo "module(load=\"imudp\")" > /etc/rsyslog.d/enable-remote.conf
echo "input(type=\"imudp\" port=\"514\")" >> /etc/rsyslog.d/enable-remote.conf
echo "module(load=\"imtcp\")" >> /etc/rsyslog.d/enable-remote.conf
echo "input(type=\"imtcp\" port=\"514\")" >> /etc/rsyslog.d/enable-remote.conf
service rsyslog restart
echo "17 2     * * *     root mysql -uroot -e 'use Syslog; DELETE FROM SystemEvents WHERE ReceivedAt < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 365 DAY);'" > /etc/cron.d/rsyslog_mysql
#mysql -uroot -e "CREATE DATABASE Syslog_template;"
#mysqldump -uroot Syslog > /tmp/sql.sql
#mysql -uroot Syslog_template < /tmp/sql.sql
#mysql -uroot -e "TRUNCATE TABLE Syslog_template.SystemEvents"
}
######### LOG ANALYZER
function install_loganalyzer {
if [ ! -f loganalyzer-${LAVERSION}.tar.gz ]; then wget http://download.adiscon.com/loganalyzer/loganalyzer-${LAVERSION}.tar.gz; fi
tar -xf loganalyzer-${LAVERSION}.tar.gz
cp -r loganalyzer-${LAVERSION}/src/* /var/www/html/
rm -rf ./loganalyzer-${LAVERSION}/
rm /var/www/html/index.html
chown www-data:www-data -R /var/www/html/
#create new db for loganalyzer user and settings with rsyslog user as admin
mysql -uroot -e "create database loganalyzer; grant all privileges on loganalyzer.* to rsyslog@localhost"
#disable new version check during logon into admin panel
r="\$content\['UPDATEURL'\] = \"http://loganalyzer.adiscon.com/files/version.txt\";"
sed -i  "s|${r}|\$content\['UPDATEURL'\] = \"\";|g"  /var/www/html/include/functions_common.php
}
####
## MAIN
####
instaldebconf="false"
installmariadb="false"
installapache="false"
installphp="false"
instalphpmyadmin="false"
installrsyslog="false"
printf "Checking debconf-utils..."
check=$( check_packages debconf-utils )
if [[ $check != "true" ]]; then
    echo "......will be installed"
    instaldebconf="true"
else
    echo "......found!"
fi
printf "Checking sql..."
check=$( check_sql )
case ${check} in 
    false)
        echo "................will be installed: MariaDB"
        installmariadb="true"
        ;;
    mysql)
        echo "................MySQL found, it will be used during installation"
        ;;
    mariadb)
        echo "................MariaDB found, it will be used during installation"
        ;;
esac
printf "Checking apache..."
check=$( check_packages apache2 )
if [[ $check != "true" ]]; then
    echo ".............will be installed"
    installapache="true"
else
    echo ".............found!"
fi
printf "Checking php..."
check=$( check_php )
if [[ $check != "true" ]]; then
    echo "................will be installed: ${check}"
    installphp="true"
    phptoinstall=${check}
else
    echo "................found!"
fi
printf "Checking rsyslog-mysql..."
check=$( check_packages rsyslog-mysql )
if [[ $check != "true" ]]; then
    echo "......will be installed"
    installrsyslog="true"
else
    echo "......found!"
fi
printf "Checking phpmyadmin..."
check=$( check_phpmyadmin )
if [[ $check == "false" ]]; then
    echo ".........not found in /usr/share/phpmyadmin/"
    echo
    while true; do
        read -p "Do you wish to install phpmyadmin? (y/n): " yn
        case $yn in
            [Yy] ) instalphpmyadmin="true"; break;;
            [Nn] ) break;;
            * ) echo "Please answer [y]es or [n]o.";;
        esac
    done
else
    echo ".........found!"
fi
echo
echo "This file(s) should be downloaded:"
if [[ ${instalphpmyadmin} != "false" ]]; then echo "https://files.phpmyadmin.net/phpMyAdmin/${PMAVER}/phpMyAdmin-${PMAVER}-all-languages.tar.gz" ; fi
echo "http://download.adiscon.com/loganalyzer/loganalyzer-${LAVERSION}.tar.gz"
echo "You can place this file(s) into current directory manually if you have not an Internet connection."
echo "Debian repository must be accessible!"
echo
read -p "Ok, let's do it. Press ENTER to install, CTRL-C - to abort."
# INSTALL
apt update
if [[ ${instaldebconf} != "false" ]]; then apt -y install debconf-utils ; fi
if [[ ${installmariadb} != "false" ]]; then install_sql ; fi
if [[ ${installapache} != "false" ]]; then apt -y install apache2 ; fi
if [[ ${installphp} != "false" ]]; then  apt -y install ${phptoinstall} ; fi
if [[ ${installrsyslog} != "false" ]]; then  install_rsyslog_mysql  ; fi
installrsyslog
if [[ ${instalphpmyadmin} != "false" ]]; then install_phpmyadmin ; fi
install_loganalyzer
serverip=$(ip addr show | grep -o "inet [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | grep -v "^127.0.0.1" | head -n 1)
echo
echo
echo Installation complete
echo
if [[ ${instalphpmyadmin} != "false" ]]; then 
    echo "phpmyadmin address: http://${serverip}/phpmyadmin"
    echo "             login:${PHPMYADMINUSER}"
    echo "          password:${PHPMYADMINPASS}"
    echo
fi
echo "Open IP address of this server in web-browser (http://${serverip}/)"
echo and use next settings for wizard:
echo
echo "User Database Options (optional)"
echo "Enable User Database: Yes"
echo "       Database User: rsyslog"
echo "   Database Password: ${SYSLOGDBPASSWORD}"
echo
echo "First Syslog Source"
echo "                        Source Type: MYSQL Native"
echo "     Database Name (case-sensitive): Syslog"
echo "Database Tablename (case-sensitive): SystemEvents"
echo "                      Database User: rsyslog"
echo "                  Database Password: ${SYSLOGDBPASSWORD}"
echo "                Enable Row Counting: Yes"

 

Лучше всего использовать его на свежеустановленном дебиане в минимальной конфигурации. Перед запуском нужно его отредактировать, изменив пароль для создаваемого в процессе пользователя (базы данных) rsyslog, а также логин и пароль дополнительного администратора БД, который будет создан в случае установки (опциональной) PhpMyAdmin.  Всего скрипт установит:

  1. mariadb в качестве сервера баз данных,
  2. rsyslog с коннектором rsyslog-mysql в качестве сислог сервера, и создаст конфиг для приема логов по сети
  3. веб-сервер apache
  4. опционально phpmyadmin для управления базой данных
  5. LogAnalyzer.

После завершения работы скрипта останется пройти мастера настройки LogAnalyzer, перейдя в браузере по адресу вашего сервера. Так что если вы решите его использовать, то можете листать к разделу «Настройка LogAnalyzer», а также посмотреть наглядное видео:

Настройка сервера syslog с веб-интерфейсом и хранением логов в базе данных (на Debian 10 «buster»)

Установка debian

Для наших целей подойдет установленный в минимальной конфигурации дебиан. Идеально сразу при установке поставить LAMP-набор, отметив опцию web server

Но можно обойтись пунктом standard system utilities, а все остальное установить самостоятельно. Я буду исходить из этого варианта.

Установка базы данных MariaDB

 
 
apt update && apt -y install mariadb-server

Установка веб-сервера apache

 
 
apt -y install apache2

Установка необходимых модулей PHP

 
 
apt -y install php libapache2-mod-php php-mysql php-common php-cli php-json php-opcache php-readline php-mbstring

Установка rsyslog

 
 
apt -y rsyslog-mysql

В процессе установки соглашаемся сконфигурировать базу данных

Придумываем и подтверждаем пароль для пользователя «rsyslog» БД

После того как сислог будет установлен, его нужно сконфигурировать так, чтобы он мог принимать события с сетевого оборудования. Создаем файл /etc/rsyslog.d/enable-remote.conf с таким содержанием:

/etc/rsyslog.d/enable-remote.conf
 
  1. module(load="imudp")
  2. input(type="imudp" port="514")
  3. module(load="imtcp")
  4. input(type="imtcp" port="514")

И перезагружаем сервис

 
 
service rsyslog restart

Установка веб-интерфейса (LogAnalyzer)

Скачиваем и распаковываем файлы в директорию веб-сервера:

 
 
wget http://download.adiscon.com/loganalyzer/loganalyzer-4.1.7.tar.gz
tar -xvf loganalyzer-4.1.7.tar.gz
rm loganalyzer-4.1.7.tar.gz
cp -r loganalyzer-4.1.7/src/* /var/www/html/
rm /var/www/html/index.html
chown www-data:www-data -R /var/www/html/

Перед тем как перейти мастеру настройки, создадим еще одну одну базу, в которой лог аналайзер будет хранить свои настройки, и дадим пользователю rsyslog полные права на нее

 
 
mysql -uroot -e "create database loganalyzer; grant all privileges on loganalyzer.* to rsyslog@localhost"

Настройка LogAnalyzer

Теперь к мастеру. Перейдя в браузере по адресу сервера мы должны увидеть его приглашение создать конфиг

Первые два шага пропускаем, интересное  начинается с третьего. Здесь нужно выбрать Enable User Database и ввести имя пользователя (rsyslog)  и пароль с которыми будет производиться подключение к созданной нами базе «loganalyzer». Остальные настройки можно оставить по умолчанию.

На шестом шаге создаем внутреннего администратора лог аналайзера

На следующем шаге выбираем источник данных — базу rsyslog\’а. Важные пункты, которые будет нужно здесь изменить:

  1. Source Type — MYSQL Native
  2. Database Name — Syslog (была создана при установке rsyslog-mysql)
  3. Database Tablename — SystemEvents (именно так — с большими буквами, а не как по дефолту)
  4. Database User — rsyslog
  5. Database Password — пароль юзера rsyslog
  6. Enable Row Counting — Yes

Next, Finish и перед нами интерфейс лог аналайзера

Тюнинг

Теперь остается сделать две довольно важные вещи.

Во-первых, при попытке логина в админку, лог аналайзер пытается проверить свое собственное обновление, и это приводит к длительному ожиданию, если сервер не имеет выхода в интернет. Чтобы этого не происходило — нужно отредактировать файл /var/www/html/include/functions_common.php, изменив строку

 
 
$content['UPDATEURL'] = "http://loganalyzer.adiscon.com/files/version.txt";

на

 
 
$content['UPDATEURL'] = "";

Второе, и не менее важное. Со временем база сислога будет опухать, поэтому ее стоит периодически очищать от старых записей. Для этого нужно создать файлик /etc/cron.d/rsyslog_mysql с содержимым

 
 
23 2     * * *     root mysql -uroot -e 'use Syslog; DELETE FROM SystemEvents WHERE ReceivedAt < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 365 DAY);'

С ним каждый день из базы будут удаляться записи старше 365 дней (разумеется это количество можно поправить на необходимое)

Написал поисковик для файлопомоек — pyFileSearcher

По работе нужно было внести ясность в постоянно убывающее место на файловых серверах, на которые пользователи любят сгружать всякий мусор, не относящийся к работе. Столкнувшись с такой необходимостью, полез искать софт и выяснил, что хотя индексаторов в целом довольно много, но они или перегружены функционалом и нацелены на домашнего пользователя — такие просто не справляются с большим объемом файлов; или являются какими-то безумными корпоративными системами, которые выглядят страшно шописец, ставятся как отдельный сервер с разворачиваемыми агентами и настраиваются так, что без поллитры не разобраться.

В общем, я решил что было бы прикольно написать что-то свое. Эту мысль я вынашивал наверное больше года, так как яжнепрограммист ну абсолютно, но вот прошел курс по гуям в питоне и подумал что надо бы попробовать че получится.

Получилось портабельное приложение, которое не обладает горой функционала, но во-первых умеет сожрать в себя 20 миллионов файлов, во-вторых — умеет искать по нужным в быту параметрам, таким как размер файла, тип, и — это важно — дате добавления в индекс. Строго говоря я не видел тулзов, которые бы сами запоминали время, когда файл был обнаружен. Да, у файла есть время создания и время модификации — и казалось бы их должно хватать для отфильтровывания новых файлов, когда мы хотим их найти. Но хрен там был, эти атрибуты ведут себя черт знает как — например файл притащенный с плеера может показать какой-нить 1700й год до нашей эры.

В общем ладно, это все лирика, вот что вышло:

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

При скролле результатов отсутствующие файлы подсвечиваются красным, список можно сохранить в csv чтобы предъявить владельцу каталога на сервере или его начальнику =) Фильтры поиска можно сохранять (обычно мне нужны медиафайлы размером не менее, список расширений прилагается, в индексе появились за неделю)

Вся эта балалайка разумеется умеет работать под виндой, но и линукс не забыл (была бы макось под рукой, тестил бы код еще и под маком). В качестве базы данных можно использовать или sqlite, базы которого можно рожать прямо из проги, или подключиться к MySQL — мой случай, 20 лямов записей sqlite тупо не вывозит (собственно это проблема большинства несложных индексаторов, какие можно найти в инете)

В общем получилось такое промежуточное решение — простенькое и на скорую руку, не требующее воскуривания мануалов перед использованием, но и не умирающее от большого файлсервера. Да, поиск внутри файлов не умеет, как и кучу других плюшек, так что для домашнего использования скорее всего не пригодится, но мою задачу решает лучше чем что-то похожее, что я использовал (Locate32 — от его интерфейса и возможностей я отталкивался, но он с некоторой периодичностью терял конфиг, жрал под гиг оперативки из-за использования локальных баз, и был виндуз-онли. Хотя в целом прога более чем годная). Так что вот он, первый релиз: https://github.com/qiwichupa/pyFileSearcher/releases также залил на сурсфордж.

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