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

в 12:11, , рубрики: bash scripting, find, sed, автоматизация рутины, Серверное администрирование, хостинг, метки:

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

Источник

Поделиться

* - обязательные к заполнению поля