Автоматическая фильтрация контента через Angie
На подходе новый закон о глобальном запрете мата в сети, поэтому к нему нужно подготовиться. Переебашивать каждый пост в блоге — проблематично, да и лень.
Поэтому, как обычно, будем изобретать велосипед.
ЧИТАТЬ ПЕРВЫМ В ТЕЛЕГРАМСуть идеи — налету в DOM менять маты на синонимы. То есть в момент отдачи контента, контент будет насильно зацензурен.
Хуйня == Фигня, Пезда == 3.14зда ну и в таком духе.
А там уже можно будет добавить регулярки и гибко всё затюнить, мало ли, может можно будет звездочками разбавлять такой контент.
Реализация
За основу я возьму angie (форк nginx) с модулем LUA. Я давно на это решение пересел, так как всё из коробки работает, включая генерацию SSL. Не нужно ебстись с компиляций модулей и страдать.
Как настроить автополучение SSL в angie, писал в этом посте.
Если LUA не установлен, ставим:
apt install angie-module-lua
В /etc/angie/angie.conf
добавляем:
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;
load_module modules/ngx_stream_lua_module.so;
В /etc/angie/sites-available/bashdays.ru.conf
добавляем в корневой локейшен:
location / {
root /var/www/bashdays.ru/htdocs;
index index.html;
gzip off;
body_filter_by_lua_block {
local replacements = dofile("/etc/angie/wordmap.lua")
local chunk = ngx.arg[1]
if chunk then
for _, pair in ipairs(replacements) do
chunk = ngx.re.gsub(chunk, pair[1], pair[2], "ijo")
end
ngx.arg[1] = chunk
end
}
}
Ну и создаем файл /etc/angie/wordmap.lua
который будет содержать шаблоны замены:
return {
{"хуйня", "фигня"},
{"хуй", "писька"},
{"говн%w*", "ерунда"},
{"еба%w*", "плохой"},
}
Проверяем: angie -t
и если всё ок, можно сделать systemctl restart angie
.
Открываем сайт и видим что все маты зацензурились согласно шаблону в файле /etc/angie/wordmap.lua
.
Если всё осталось по-прежнему, скинь кеш, в 99% дело в нем.
Давай разберемся как это работает.
body_filter_by_lua_block
— перед отправкой ответа клиенту, запустится Lua-скрипт, который изменит тело ответа.
dofile("/etc/angie/wordmap.lua")
— загружает Lua-файл со словарём замен.
ngx.arg[1]
— текущий кусок (chunk) ответа (HTML, JSON и т.п.), который angie собирается отправить клиенту. Ответ приходит потоками.
for _, pair in ipairs(replacements)
— перебор всех замен из словаря.
ngx.re.gsub(chunk, pair[1], pair[2], "ijo")
— регулярная замена,[1]
что искать,[2]
на что заменить.
"ijo"
— флаги:i
— без учёта регистра,j
— dotall (точка матчится на\n
),o
— оптимизация.
ngx.arg[1] = chunk
— возвращаем изменённый кусок, который уйдёт клиенту.
И получаем — блок берёт HTML-страницу, проходит по каждому чанку тела ответа, и заменяет в нём «запрещённые» слова из словаря на синонимы.
Ааа, еще в словаре {"говн%w*", "ерунда"}
есть символы %w*
это регулярка.
Любая буква, цифра или подчёркивание ([0-9A-Za-z_]
). В UTF-8 оно обычно ловит только латиницу, а кириллицу нет.
Поэтому лучше сделать как-то так: {"говн[А-Яа-яЁё]*", "ерунда"}
. Короче тут тебе карты в руки, сам натыкай паттерны.
LUA — сила! Рекомендую хоть раз потыкать, проникнешься и уже не сможешь без этого модуля жить. Костыли клепать милое дело.
Есть конечно нюансы, например — Если слово вдруг разорвётся между чанками (например,
ху
в одном чанке ийня
в другом) — фильтр его не заменит. Для надёжности нужно буферизовать весь ответ.Ну и с кириллицей надо вопрос дофиксить, но это я реализую чуть позже. Главное концепт. Всё остальное реализуемо.
Как вариант, позже еще запилю «специальный» заголовок, при передаче которого angie будет отключать цензуру и выводить посты в оригинале.
А можно разработчиков подъебать, пусть ищут в своем коде, почему у них слова странным образом заменяются.
Ну заебись же! Осталось придумать, как зацензурить 1000 постов в телеге.