Задача. На web-сервере в домашней папке ~/public_html привычным образом располагаются каталоги различных сайтов. Таким же привычным образом в каждом каталоге сайта располагается файл .htaccess. Известно, что с помощью этого файла, в том числе, ограничивается доступ по IP. В моём случае этот файл выглядит так:
Order Allow,Deny
Allow from all
Deny from 194.87.147.196
Эта запись (блок) встречается в каждом файле .htaccess каждого сайта в папке public_html всего один раз. И если требуется заблокировать доступ ко всем сайтам по IP, например 194.165.16.76 – в каждый файл, после строки «Allow from all» добавляется новая строка:
Deny from 194.165.16.76
Вопрос: что же делать, когда на сервере не 2 и не 3 сайта, а намного больше?
Вот как я попытался решить эту задачу.
Команда find
Команда find поможет нам найти все файлы .htaccess рекурсивно, начиная с указанной папки, если мы из любого места выполним следующее:
find ~/public_html -type f -name .htaccess
Параметр –exec
Далее нам нужно выполнить некоторые манипуляции над файлом, а именно:
- Найти строчку «Allow from all»
- Вставить после неё строчку «Deny from 194.165.16.76»
В этом нам поможет параметр –exec для команды find. В частности я использовал потоковый редактор sed. То есть, для частного случая, для конкретного файла .htaccess мне помогает команда:
sed -i "/Allow from all/a Deny from 194.165.16.76" .htaccess
Теперь, соединяем вместе find и sed:
find ~/public_html -type f -name .htaccess –exec sed -i "/Allow from all/a Deny from 194.165.16.76" {} ;
Выполнив эту команду, bash найдет все файлы .haccess и вставить в них Deny from 194.165.16.76 сразу после Allow from all.
Скрипт bash
Сократили одну часть рутины, Идем дальше, стремясь к тому, чтобы не набирать каждый раз одни и те же длинные команды. Создаём в домашней папке файл ~/addblacklistip со следующим содержимым:
#!/bin/bash
me=`basename $0`
if [[ $# -lt 2 ]]; then
echo "Usage $me <start_path> <IP_address>"
exit
fi
find $1 -type f -name .htaccess -exec sed -i "/Allow from all/a Deny from $2" {} ;
Далее выполняем команду:
chmod +x ~/addblacklistip
Наш скрипт готов к использованию. Например, для внесения во все файлы .htaccess блокировки по IP 7.7.7.7 просто выполняем команду:
~/addblacklistip ~/public_html 7.7.7.7
Замечания и дополнения
ТО, ЧТО ВЫ ДЕЛАЕТЕ – ВЫ ДЕЛАЕТЕ НА СВОЙ СТРАХ И РИСК!
Во-первых, много раз проверяйте все команды и скрипты, что вы запускаете. Тем более, когда речь идет о файлах .htaccess. Во-вторых, не поленитесь создать тестовую папочку с вложенными папками и файлами .htaccess, чтобы всё проверить.
Если раздел блокировки у вас выглядит по другому…
Добавьте в то место, куда бы вы хотели вносить новые записи о блокировке, ключевое слово, например #Add next IP here. Это могло бы выглядеть так:
Order Allow,Deny
Allow from all
Deny from 194.87.147.196
#Add next IP here
Deny from 194.87.147.196
А в скрипте строку:
find $1 -type f -name .htaccess -exec sed -i "/Allow from all/a Deny from $2" {} ;
замените на строку:
find $1 -type f -name .htaccess -exec sed -i "/#Add next IP here/a Deny from $2" {} ;
Теперь новые записи о блокировке будут появляться после ключевой записи #Add next IP here.
Если все сайты находятся не в папке ~/public_html, а в ~/www?
Просто выполняйте скрипт с такими параметрами:
~/addblacklistip ~/www 7.7.7.7
где 7.7.7.7 – блокируемый IP.
Если у меня много IP для добавления?
Насколько много? Тут отдельная тема для анализа вопроса и дальнейшей автоматизации.
Автор: mokhin-denis