Рекурсивное множественное добавление IP для блокировки в файл .htaccess

Задача. На 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


Далее нам нужно выполнить некоторые манипуляции над файлом, а именно:
  1. Найти строчку «Allow from all»
  2. Вставить после неё строчку «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  "
    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 для добавления?


Насколько много? Тут отдельная тема для анализа вопроса и дальнейшей автоматизации.

Комментарии (0)

© Habrahabr.ru