В процессе работы с онлайн-редактором статей JCE Editor на CMS Joomla 1.5 пришлось столкнуться с неприятным глюком - иногда статьи не сохраняются из-за включенной защиты компонента sh404SEF (выскакивает сообщение сервера "Forbidden access ..."). Еще один неприятный глюк - иногда срабатывает на сохранение статьи другой компонент защиты - Marco's SQL Injection Plugin (на почту приходит письмо от плагина "Marco's interceptor warning"). После срабатывания защиты доступ к сайту на некоторое время блокируется.
К сожалению, другого способа решить проблему, кроме как временно отключать защиту System - Marco's SQL Injection - LFI Interceptor и sh404SEF, я не нашел. Постоянные заходы в админку для расставления галочек перед и после пользования JCE Editor совсем не радовали - очень неудобно. Нужно было придумать, как легко включать и выключать защиту. Для этого пришлось разобраться, где хранится конфигурация плагина Marco's SQL Injection Plugin и компонента sh404SEF, и как эту защиту можно включать и выключать. В статье описан метод быстрого выключения и включения защит Marco's SQL Injection Plugin и sh404SEF.
[Как управлять конфигурацией Marco's SQL Injection Plugin]
Конфигурация у плагинов хранится в таблице jos_plugins, включен или нет плагин определено в столбце published (если 0, то плагин выключен, если 1, то включен). Нашел это место, просто сравнив два дампа базы MySQL - с одна с выключенным, другая с включенным плагином Marco's SQL Injection Plugin. Название плагина находится в столбце name, и там записано "System - Marco''s SQL Injection - LFI Interceptor".
SQL-запрос, который устанавливает в 0 поле published (выключает Marco's SQL Injection Plugin): UPDATE jos_plugins SET published = 0 WHERE name = 'System - Marco''s SQL Injection - LFI Interceptor'
SQL-запрос, который устанавливает в 1 поле published (включает Marco's SQL Injection Plugin): UPDATE jos_plugins SET published = 1 WHERE name = 'System - Marco''s SQL Injection - LFI Interceptor'
[Как управлять конфигурацией sh404SEF]
Компонент sh404SEF хранит свою конфигурацию в файле administrator\components\com_sh404sef\config\config.sef.php, в переменной shSecEnableSecurity (если она равна "0", то безопасность выключена, если "1" то включена). Поэтому нужно научиться обрабатывать этот файл, и менять в нем значение переменной shSecEnableSecurity.
[Скрипт, который управляет конфигурациями]
Теперь нужно выбрать способ менять конфигурацию Marco's SQL Injection Plugin и sh404SEF. Есть два варианта, как это можно сделать - shell-скриптом (из него можно запускать SQL-запросы и обрабатывать файлы) через соединение ssh, или с помощью кода PHP. Скрипт на shell лучше в плане безопасности (управление защищено паролем пользователя, а также правами на скрипт), а код PHP лучше в плане удобства использования и визуализации - можно просто из браузера запускать ссылку, и будет отображаться страничка с результатами переключения. В результате недолгих раздумий был выбран вариант реализации на shell-скрипте. Он должен запускаться на web-сервере (Debian), и менять конфигурацию безопасности.
Привожу текст скрипта jml-sec-sw.sh, как есть. В самом его начале указаны настройки, которые могут быть изменены при переносе на другой сервер (пароли, пути, название базы данных). Скрипт лучше положить в целях безопасности в какую-нибудь скрытую директорию на www-сервере (использовался Debian), в которую запрещен просмотр со стороны браузеров, посещающих сервер. В простейшем случае можно просто дать папке сложное имя (в этом примере имя папки задано securefolder, поменяйте его на любое другое), и поместить в эту папку пустой файл index.html. В эту же папку нужно положить тексты SQL-запросов m-enable.sql и m-disable.sql, а также perl-скрипт, который будет менять переменную shSecEnableSecurity файла config.sef.php. Итак, сначала список файлов и их назначение (файлы лежат на сервере в папке securefolder).
jml-sec-sw.sh - основной скрипт на языке shell, который принимает параметр on или off. Если указан параметр on, то защита Marco's SQL Injection Plugin и sh404SEF включается, а если off - то защита выключается (напомню, что выключение защиты нужно как временная мера для нормальной работы Joomla JCE Editor).
off-Marco-Plugin.sql - запрос SQL, который выключает Marco's SQL Injection Plugin. Этот файл используется в вызове утилиты mysql (см. скрипт jml-sec-sw.sh).
on-Marco-Plugin.sql - запрос SQL, который выключает Marco's SQL Injection Plugin. Этот файл используется в вызове утилиты mysql (см. скрипт jml-sec-sw.sh).
repl-string-in-file.pl - вспомогательный скрипт на Perl, который включает и выключает компонент sh404SEF. С помощью этого скрипта изменяется значение переменной shSecEnableSecurity в файле конфигурации компонента sh404SEF (см. скрипт jml-sec-sw.sh).
[Начало основного скрипта jml-sec-sw.sh]
#!/bin/sh
mysqluser="тут_вставьте_имя_пользователя_MySQL_базы_данных_Joomla" mysqlpass="тут_вставьте_пароль_пользователя_MySQL_базы_данных_Joomla" mysqlbase="тут_вставьте_имя_MySQL_базы_данных_Joomla" sh404SEFcfgdir="/var/www/username/data/www/mydomain.net/administrator/components/com_sh404sef/config/" sh404SEFcfgfile="config.sef.php" regex="[\$]shSecEnableSecurity = \"[0-1]\";"
############################################################ # ON/OFF Marco's SQL Injection Plugin ############################################################ function onoffMarcoSQLInjectionPlugin () { if [ "$1" == "off" ]; then mysql --batch --user=$mysqluser --host=localhost --password=$mysqlpass $mysqlbase < off-Marco-Plugin.sql echo "Marco's SQL Injection Plugin OFF" else mysql --batch --user=$mysqluser --host=localhost --password=$mysqlpass $mysqlbase < on-Marco-Plugin.sql echo "Marco's SQL Injection Plugin ON" fi }
############################################################ # ON/OFF sh404SEF security ############################################################ function onoffsh404SEFsecurity () { if [ "$1" == "off" ]; then replaceval="\$shSecEnableSecurity = \"0\";" cfgname=$sh404SEFcfgdir$sh404SEFcfgfile perl ./repl-string-in-file.pl "$cfgname" "$regex" "$replaceval" chown username:username "$cfgname" echo "sh404SEF security OFF" else replaceval="\$shSecEnableSecurity = \"1\";" cfgname=$sh404SEFcfgdir$sh404SEFcfgfile perl ./repl-string-in-file.pl "$cfgname" "$regex" "$replaceval" chown username:username "$cfgname" echo "sh404SEF security ON" fi }
############################################################ # [START SCRIPT] ############################################################ if [ "$1" == "off" ]; then onoffMarcoSQLInjectionPlugin "off" onoffsh404SEFsecurity "off" elif [ "$1" == "on" ]; then onoffMarcoSQLInjectionPlugin "on" onoffsh404SEFsecurity "on" else echo "usage . sec.change.sh [on|off]" fi ############################################################ # [END SCRIPT] ############################################################
[Конец основного скрипта jml-sec-sw.sh]
В скрипте jml-sec-sw.sh созданы две функции, которые управляют защитой - onoffMarcoSQLInjectionPlugin и onoffsh404SEFsecurity. По названиям понятно, для чего нужна каждая из них. Функция onoffMarcoSQLInjectionPlugin управляет конфигурацией вызовом запросов SQL, а функция onoffsh404SEFsecurity - с помощью обработки файла скриптом Perl repl-string-in-file.pl. В параметры скрипта repl-string-in-file.pl входят имя обрабатываемого файла (передается через переменную cfgname), регулярное выражение для поиска нужной строки (передается через переменную regex) и строка для замены (передается через переменную replaceval). Так как скрипт jml-sec-sw.sh выполняется с правами админа, и в процессе редактирования файла конфигурации файл sh404SEFcfgfile пересоздается заново, то необходима смена прав на него, чтобы сервер, работающий от имени пользователя username, мог получить доступ к файлу конфигурации. Права на файл конфигурации меняются вызовом утилиты chown.
[Начало файла SQL-запроса off-Marco-Plugin.sql]
UPDATE jos_plugins SET published = 0 WHERE name = 'System - Marco''s SQL Injection - LFI Interceptor'
[Конец файла SQL-запроса off-Marco-Plugin.sql]
[Начало файла SQL-запроса on-Marco-Plugin.sql]
UPDATE jos_plugins SET published = 1 WHERE name = 'System - Marco''s SQL Injection - LFI Interceptor'
[Конец файла SQL-запроса on-Marco-Plugin.sql]
Файлы запросов SQL особенностей не имеют. Запросы нужны, чтобы поменять поле включения published плагина Marco's SQL Injection Plugin. Файлы запросов используются в вызове утилиты mysql.
[Начало вспомогательного Perl-скрипта repl-string-in-file.pl]
#----------------------------------------------------------------------------- # Script replaces in file with . Value # is interpreted as regular expression. # # Usage: # perl repl-string-in-file.pl file pattval repval #-----------------------------------------------------------------------------
sub Usage { die "Usage:\nperl repl-string-in-file.pl file regex_pattern replace_value\n"; }
# просто проверка наличия входных параметров, без затей: if (@ARGV[0] eq "") { Usage(); } if (@ARGV[1] eq "") { Usage(); } if (@ARGV[2] eq "") { Usage(); }
$file=@ARGV[0]; # имя файла, в котором ищем $tempfile=$file.".tmp"; # имя временного файла, который потом заменит исходный $regex=@ARGV[1]; # регулярное выражение для поиска $replval=@ARGV[2]; # текст, который заменит значение, попавшее в регулярное выражение
#Открываем рабочие файлы в двоичном режиме. # Открыть входной файл только на чтение, если не получится, то выход: open SRCFILE, '<', $file or die "Cannot open file ".$file.": $!\n"; # Открыть выходной файл только на запись, если не получится, то выход: open DSTFILE, '>', $tempfile or die "Cannot open file ".$tempfile.": $!\n"; #open only write
# Цикл: читаем построчно входной файл, корректируем, если надо, строку, # и результат пишем в выходной файл. while (!eof(SRCFILE)) { $line = readline SRCFILE; # /g задает менять все "срабатывания" $regex в строке. # Если /g убрать, то произойдет только первая замена. $line =~ s/$regex/$replval/g; print DSTFILE $line; } # закрываем файлы close SRCFILE; close DSTFILE; # старый файл удаляем и заменяем его на новый, скорректированный unlink $file; rename $tempfile, $file;
[Конец вспомогательного Perl-скрипта repl-string-in-file.pl]
Скрипт repl-string-in-file.pl очень удобен для обработки текстовых файлов - я его часто использую для автоматической правки конфигов. Благодаря использованию регулярного выражения для строки поиска можно легко менять в текстовом файле IP-адреса или значения конфигурационных переменных. В нашем случае в файле config.sef.php ищется строка, содержащая переменную shSecEnableSecurity, и меняется значение этой переменной. Таким способом выключается и включается защита компонента sh404SEF.
[Как запускать удаленно скрипт jml-sec-sw.sh]
Для удаленного запуска скрипта применяется соединение по протоколу ssh с помощью утилиты plink.exe (входит в бесплатный пакет putty для операционной системы Windows). Утилита plink предназначена для запуска команд на удаленном сервере (в данном случае WWW-сервер на Debian), и этой утилитой мы будем запускать скрипт jml-sec-sw.sh с параметром on или off. Сама утилита plink в качестве параметров принимает имя пользователя root и его пароль, а также имя файла, который содержит список запускаемых на сервере команд (enable-commands.txt или disable-commands.txt). На скриншоте показано использование утилиты plink для запуска команд на удаленном сервере mydomain.com (утилита plink запускается из командного файла Windows joomla-switch-security.bat).
[Начало файла joomla-switch-security.bat]
@set plink="C:\Program Files\putty\plink.exe"
@if "%1" EQU "on" ( @goto enable_security )
@if "%1" EQU "off" ( @goto disable_security )
@echo "usage: joomla-switch-security.bat [on|off]" @goto exit
:enable_security %plink% -ssh -l root -pw rootpassword mydomain.com -m enable-commands.txt -batch @goto exit
:disable_security %plink% -ssh -l root -pw rootpassword mydomain.com -m disable-commands.txt -batch @goto exit
:exit
[Конец файла joomla-switch-security.bat]
Скрипт joomla-switch-security.bat довольно прост - на его входе применяется текстовый параметр, равный on или off (соответствует включению или выключению защиты), и скрипт запускает на удаленном сервере либо список команд enable-commands.txt, либо список команд disable-commands.txt соответственно.
[Начало файла disable-commands.txt]
cd /var/www/username/data/www/mydomain.com/securefolder . jml-sec-sw.sh off
[Конец файла disable-commands.txt]
[Начало файла enable-commands.txt]
cd /var/www/username/data/www/mydomain.com/securefolder . jml-sec-sw.sh on
[Конец файла enable-commands.txt]
Файлы disable-commands.txt и enable-commands.txt также очень просты - они только запускают скрипт jml-sec-sw.sh с параметром off или on соответственно.
[Ссылки]
1. Скрипты, о которых идет речь в статье, модифицированная утилита plink (убран запрос о занесении ключа ssh в реестр) и документация. |