Создание файла Casper-RW

Довольно часто в мой блог попадают с вопросом о создании файла casper-rw. Что это за файл такой? Это файл в котором хранятся изменения на загрузочной флешке с Ubuntu. Создание самой флешки уже я описывал на странице «Живая» флешка с Linux-ом (в разделе Persistent mode). Там же есть несколько ссылок на готовые файлы casper-rw. Но, всегда найдется тот, кому имеющиеся варианты не подходят, и нужно создать свой собственный. Вот для таких и написана данная заметка.

Должен сразу сказать, что данная инструкция предполагает ее выполнение на компьютере, работающем под управлением операционной системы Linux.  Как это сделать из под Windows, я увы не знаю (ниже я скажу — почему).

Итак приступим. Первым делом нужно запустить консоль и авторизоваться в ней root-ом (ввести команду su, а потом в ответ на запрос — пароль администратора системы). После этого запускаем команду:

dd if=/dev/zero of=casper-rw bs=1M count=280

По этой команде:

  • запускается программа dd;
  • которая в выходной файл casper-rw (of=casper-rw);
  • записывает нули (if=/dev/zero);
  • в количестве 280 блоков (count=280);
  • каждый блок размером в 1 Мегабайт (bs=1M)

По окончании работы программа выдает вот такой отчет о выполнении:

280+0 записей считано 280+0 записей написано скопировано 293601280 байт (294 MB), 5,72013 c, 51,3 MB/c

Таким образом мы получили тот самый файл с размером …. правильно — 280х1024х1024=293601280 байт. Чтож, задача выполнена? Почти! Файл действительно создан, размер выдержан (и при необходимости, я думаю, вы уже поняли, как сможете задать свой собственный любой требуемый размер). Единственный нюанс — пока что это по прежнему просто файл, забитый нулями. А casper-rw — это не «просто так файл», а файл … внутри которого создана файловая система ext3 (по крайней мере именно такая ФС требуется, если делать файл для использования с загрузочными флешками, создание которых описано в упоминавшейся выше заметке).

И вот теперь пару слов собственно, о том, почему я не знаю, как создать файл casper-rw из под Windows. Бог с ней, с командой dd — уже есть ее аналог для Windows. И устройство «zero», думаю, при необходимости найдется. Но вот как отформатировать файл и создать внутри него файловую систему, работая в ОС Windows, я увы не знаю…

Но вернемся к инструкции, тем более, что мы выполняем ее в Linux-е, и в нем «создать файловую систему внутри файла» я знаю как :)…

Для этого вводим команду:

mkfs.ext3 casper-rw

Первое сообщение, которое программа выведет, это будет запрос подтверждения указанного действия, так как мы пытаемся отформатировать не блочное устройство (читай — не диск). (В принципе, программа очень правильно утверждает — мы ведь действительно форматируем не диск, а файл 😉 ).

mke2fs 1.41.9 (22-Aug-2009) casper-rw is not a block special device. Proceed anyway? (y,n) 

Естественно, соглашаемся и вводим на клавиатуре «y». Процесс займет некоторое время, после чего будет выведен отчет о его выполнении:

Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 71680 inodes, 286720 blocks 14336 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67633152 35 block groups 8192 blocks per group, 8192 fragments per group 2048 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185 Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 29 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.

Текста много, не спорю… Но весь он «о хорошем». Иными словами — «done» — это «выполнено». Таким образом форматирование завершено, и мы получили файл casper-rw, внутри которого сформирована файловая система ext3. (Кстати, если нужна другая ФС, просто используйте соответствующую команду, например, mkfs.ext2 для файловой системы ext2). Как нам проверить, что все хорошо? Есть простой способ — смонтируем для этого наш «файл-диск» в какую-нибудь папку:

mount casper-rw /mnt/temp -o loop

Обращаю внимание, что папка /mnt/temp, у меня уже была создана ранее. Вы можете использовать другую, а можете создать и такую же (команду mkdir никто не отменял)… Вернемся к монтированию — если ответом на команду «будет молчание», а не сообщения о каких бы то ни было ошибках, значит, монтирование прошло успешно. Перейдем в папку, куда смонтирован наш «диск»:

cd /mnt/temp

И введем команду:

ls

В ответ мы должны получить следующее:

lost+found/

То есть, на данном этапе единственным содержимым нашего диска является папка lost+found, которую полагается иметь каждому … диску (или разделу диска). Значит, все у нас хорошо! Проверка завершена. Отмонтируем наш «диск»:

umount /mnt/temp

Результатом выполнения описанной выше процедуры стал файл casper-rw, размером 280 Мб. Кстати, те, кому нужен именно такой файл, или те, у кого нет возможности выполнить это все в Linux-е, могут скачать готовый файл по вот этой ссылке. (Естественно, качать 280 Мб нулей не придется — файл сжат zip-ом, и его размер равен ~300 кб).

Ну и теперь вкратце об изменении в процедуре создания флешки с persistent mode, которые нужно нести в процедуру описанную на упоминавшейся уже странице. Перед запуском файла U810.bat (пункт 3-й инструкции) нужно новый (созданный или скачанный) файл casper-rw поместить в папку U810p, заменив им уже имеющийся там такой-же файл размером 1 Гб.

Ну и о размере, использованном в данном примере — он был выбран равным 280 Мб для того, чтобы загрузочную флешку Ubuntu с сохранением изменений можно было создать на драйве размером 1 Гб.

И снова fail2ban — на этот раз охраняем ProFTP и Dovecot

Собственно, это уже совсем … скучно. И тем не менее…

Просмотр логов показывает, что и в ftp-сервер мой постоянно кто-то пытается попасть «мимо кассы»:

Янв 19 07:54:36 dmitrykhn.homedns.org proftpd[27832] dmitrykhn.homedns.org (82.213.28.12[82.213.28.12]): USER service: no such user found from 82.213.28.12 [82.213.28.12] to 192.168.1.115:21
Янв 19 07:54:37 dmitrykhn.homedns.org proftpd[27832] dmitrykhn.homedns.org (82.213.28.12[82.213.28.12]): USER service: no such user found from 82.213.28.12 [82.213.28.12] to 192.168.1.115:21

…и в почтовый сервер тоже:

Feb  1 00:10:12 dmitrykhn dovecot: pop3-login: Disconnected (auth failed, 1 attempts): user=, method=PLAIN, rip=59.124.32.168, lip=192.168.1.115
Feb  1 00:10:19 dmitrykhn dovecot: pop3-login: Disconnected (auth failed, 1 attempts): user=, method=PLAIN, rip=210.202.39.205, lip=192.168.1.115

Что же тогда, сидеть и ждать? Решил я воспользоваться все тем же fail2ban — он и так уже трудится, вот пусть теперь и тут еще постарается…

С ProFTP, как мне казалось, все будет просто — соответствующий фильтр в наборе fail2ban имелся. Взял я программу fail2ban-regex и скормил ей файл протокола /var/log/proftpd/proftpd.log в паре с данным фильтром (как пользоваться fail2ban-regex я уже писал тут). Совпадения нашлись, и почти все было бы хорошо, если бы не одно «но». Программа fail2ban-regex сказала, что моя дата не подходит ни под один из известных ей шаблонов. Как я понял, единственное, что могло смутить fail2ban-regex в моей дате, так это тот язык, на котором она была выведена. То есть, «пришла беда, откуда не ждали». То ли авторы дистрибутива Mandriva, используемого мной, то ли авторы ProFTP, решили сделать мне «хорошо» — раз уж выбрал я русский язык, то пусть и протокол будет на русском. В принципе, оно конечно хорошо — понятнее. Даже не смотря на то, что русского того там в протоколе  — аж целых три буквы в имени месяца!..

В принципе, программа ProFTP (как я понял) использует тот язык, который в момент ее запуска указан в системе в качестве системного. Что ж, подумал я, если в момент запуска ProFTP указать, что системный язык английский, то есть шанс, что и сообщения в лог пойдут тоже на нем. Сказано — сделано. Пошел я в папку /etc/init.d и нашел в ней скрипт запуска сервера ProFTP (файл proftpd). Открыл его в редакторе и нашел в нем следующую строку:

         daemon "proftpd >/dev/null 2>&1"

и НАД ней добавил (чтоб долго не угадывать) следующие три:

        export LC_MESSAGES="en_US.UTF-8"
        export LC_ALL="en_US.UTF-8"
        export LANG="en_US.UTF-8"

Должен заметить, что строка daemon «proftpd >/dev/null 2>&1» присутствует в скрипте два раза. Как следствие и свои строки с назначением переменным LC_MESSAGES, LC_ALL и LANG значения en_US.UTF-8 я тоже добавил два раза (в обоих местах). Перезапустил ProFTP, заглянул в лог — красота, сообщения в нем снова на «родном английском»! Что ж, пол дела сделано.

Вторая половина — включить в fail2ban соответствующий фильтр (proftpd). Для этого я открыл в редакторе файл /etc/fail2ban/jail.conf и сделал в нем следующее — нашел в нем секцию про указанный фильтр и изменил ее, после чего она стала выглядеть следующим образом:

[proftpd-iptables]

enabled  = true
filter   = proftpd
action   = iptables[name=ProFTPD, port=ftp, protocol=tcp]
#           sendmail-whois[name=ProFTPD, dest=you@mail.com]
logpath  = /var/log/proftpd/proftpd.log
maxretry = 4

Собственно, изменений было аж три (выделены красным цветом). Смена в поле enabled значения с false на true включила использование фильтра. Диез (#) превратил строку с командой отправки почтового сообщения в комментарий (ну не надо мне эти письма!). Ну и в поле maxretry я поставил 4 — именно после стольких неудачных попыток нарушитель будет забанен.

А с  dovecot вопрос решился с помощью Google. Нашел я в нем ссылку на вот такую чудную страницу:

http://wiki.dovecot.org/HowTo/Fail2Ban

Просто «тупо» повторил описанное на ней, и все.  Для тех, кому английский так и не стал родным, очень кратко:

Создаем файл /etc/fail2ban/filter.d/dovecot-pop3imap.conf вот такого содержания:

[Definition]
failregex = (?: pop3-login|imap-login): (?:Authentication failure|Aborted login \(auth failed|Disconnected \(auth failed).*rip=(?P\S*),.*
ignoreregex =

После чего в файл /etc/fail2ban/jail.conf добавляем новую секцию вот такого вида:

[dovecot-pop3imap]
enabled = true
filter = dovecot-pop3imap
action = iptables-multiport[name=dovecot-pop3imap, port="pop3,imap", protocol=tcp]
logpath = /var/log/maillog
maxretry = 20
findtime = 1200
bantime = 1200

Пару замечаний про «мой случай» (выделено синим):

  • Лог для анализа в моем случае задействован иной — /var/log/mail/info.log (именно в нем я нашел сообщения об ошибочных авторизациях).
  • Строки про findtime и bantime я в секцию dovecot-pop3imap не писал совсем — меня вполне устраивают и значения «глобальных» настроек».
  • Параметр maxretry я у себя поставил поменьше — нечего тут…

После всех этих описанных выше действий, перезапустил я fail2ban и сижу вот теперь, жду…

Удаление «зависших» сессий из таблицы radacct (в б/д MySQL) сервера RADIUS

Ковыряясь с хотспотом, столкнулся с тем, что иногда в таблице radacct остаются строки, в которых отсутствует время окончания сессии (acctstoptime). То есть, речь идет не о записях текущих сеансов, в которых время окончания естественно отсутствует — по той причине, что сеанс еще не закончен. Речь о записях предыдущих сеансов. В биллинге Easyhotspot, который я использую, наличие таких строк мешает нормальной работе функции принудительного отключения.

Проблема была решена следующим способом:

  1. Был создан набор команд (скрипт) MySQL, удаляющий такие строки.
  2. Был настроен запуск данного скрипта.

Теперь подробнее.

Сам скрипт я создал в папке пользователя root, назвал его clear.sql, и содержимое его выглядит следующим образом:

USE easyhotspot;
DELETE FROM `radacct` WHERE `acctstoptime` IS NULL;

Ничего конгениального в скрипте нет. Первая команда скрипта выбирает базу в сервере MySQL. В используемом мной биллинге Easyhotspot база, с которой работает RADIUS, называется именно easyhotspot. В случае же другого названия базы, нужно всего лишь в первой строке скрипта изменить имя базы, выделенное синим цветом. Вторая команда удаляет из указанной в ней таблицы (radacct), строки, удовлетворяющие условию, а именно те, в которых поле acctstoptime —  пустое (шаблон — ‘ ‘).

Теперь пару слов про запуск. Собственно, чтобы запустить выполнение команд из указанного скрипта, нужно в консоли запустить следующую команду:

mysql -uroot -pпароль_рута < /root/clear.sql

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

И про автоматизацию запуска. Данную команду имеет смысл выполнять в тот момент, когда у RADIUS-а нет подключенных пользователей.  Первый приходящий на ум вариант — при запуске компьютера. То есть, команду нужно добавить в файл rc.local. Но ведь компьютер может и сутками не выключаться (а как следствие — и не включаться). Тогда можно задействовать другой вариант — добавить ее в расписание (cron). При этом нужно указать время, в которое наименьшая вероятность наличия подключенных пользователей.

Ну и еще про один «вредный» файлик. RADIUS в своей работе создает файл ${logdir}/radutmp в котором хранит информацию о текущих сессиях.  Файл этот «мешать» начинает лишь при выполнении ряда условий. А именно; клиенту разрешен лишь один логин на его пару «имя/пароль», клиент был подключен (авторизован), и в этот момент сервер с RADIUS-ом аварийно выключился. В таком случае RADIUS не удаляет из файла radutmp информацию о сессии клиента, и в итоге клиент после того, как работа системы возобновилась, при попытке авторизоваться получает сообщение, что он уже вошел в систему.

Лечение простое — при  загрузке компьютера просто стереть файл  radutmp. Для этого в файл rc.local достаточно добавить команду:

rm -f /var/log/radius/radutmp

В данном случае команда приведена с учетом расположения файла в дистрибутиве Mandriva. Для других дистрибутивов оно может быть иным. Например, в дистрибутиве Ubuntu файл располагается по адресу /var/log/freeradius/radutmp. При необходимости, откорректируйте путь (выделен синим цветом) в соответствии с расположением файла radutmp в вашем дистрибутиве.

Ну и напоследок, для самых ленивых. Я написал скрипт, который в интерактивном режиме (вопрос-ответ) проделывает установку и настройку всего этого на компьютере. Скрипт запрашивает и пароль root для MySQL и имя базы для RADIUS и время, в которое, если что, запускать чистку базы…