Скрипт для автоблокировки новых пользователей

Материал из Неолурк, народный Lurkmore
Перейти к навигации Перейти к поиску

Скрипт для автоблокировки новых пользователей — мощный скрипт, который был реализован в MediaWiki в апреле 2026 года.

Описание[править]

Сильные дятлы стали буйствовать и долбить, что не наносило особого вреда, однако отвлекало людей от работы, так как требовалось подчищать вандализм. При этом птица использовала много разных IP-адресов и на то, чтобы бан диапазонов и автономных систем заработал и накопился, требовалось время.

И вот во времена особой атаки дятла был реализован сильный скрипт, который потужно жужжит на сервере и время от времени проверяет журналычи новых регистраций, чтобы затем восраться в оныя, проверить нет ли вандальных именований, и яко таковые имеются, то и пристрелить нах такого злодеянича.

В случае если дятле долбил упорно, был режим бана вообще всех новых пользователей. Проверка делалась раз в 8-15 секунд, так что при условии наличия каптчи у вандалыча не было никакой возможности успеть навандалить, он моментально получал сильный бан от робота.

В связи с полным выжиганием гнёзд дятла скрипт вряд ли нужен, а оттого публикуется.

Запускался сей мощный борец с пернатыми как сервис, то бишь мог произвольно подрубаться да отрубаться: systemctl start mediawiki-banbot.service.

Исходный код[править]

anti-kluv.pl[править]

В @FORBIDDEN_PATTERNS первая строчка содержит вандальные паттерны, вторая же значит что будут баниться вообще все новые аккаунты (режим ЧЕРЕПАХА при натиске дятла).

#!/usr/bin/perl

use strict;
use warnings;
use MediaWiki::API;
use POSIX qw(strftime);
use Data::Dumper;          # core module – always available
use utf8;

# ================== CONFIGURATION ==================
my $API_URL          = 'https://lurkmore.org/w/api.php';
my $BOT_USERNAME     = 'Balledur';
my $BOT_PASSWORD     = 'tyzhepojedshproveyatpetyhtyebanij9000';

my @FORBIDDEN_PATTERNS = (
    qr/(пидо|педик|говно|некроф|админ|сперм|дебил|дально|трак|драйв|driv|truck|антисем|евре|жид|14|88)/iu,   # example words
#    qr/[а-я0-9a-z]/iu
    # add your patterns here
);

my $BLOCK_REASON     = 'дятел';
my $BLOCK_EXPIRY     = 'never';   # "never" or "infinite" = permanent block
my $LOG_FILE         = '/var/log/mediawiki-banbot.log';
# ===================================================

my $mw = MediaWiki::API->new({ api_url => $API_URL });

# Login once
print "Logging in as $BOT_USERNAME...\n";
unless ($mw->login({ lgname => $BOT_USERNAME, lgpassword => $BOT_PASSWORD })) {
    die "LOGIN FAILED: " . Dumper($mw->{error});
}
print "Logged in successfully.\n";

my $max_seen_logid = mw_timestamp_to_num(get_current_timestamp());
my $csrf_token;

sub get_csrf_token {
    my $resp = $mw->api({ action => 'query', meta => 'tokens', type => 'csrf' });
    if (!$resp) {
        die "CSRF TOKEN FAILED: " . Dumper($mw->{error});
    }
    return $resp->{query}->{tokens}->{csrftoken};
}

sub get_current_timestamp {
    my $resp = $mw->api({
        action       => 'query',
        meta         => 'info',
        curtimestamp => 1,
    }) or die "Failed to get current timestamp: " . Dumper($mw->{error});

    return $resp->{curtimestamp};   # e.g. '2026-04-02T12:39:52Z'
}

sub mw_timestamp_to_num {
    my $ts = shift || '';
    $ts =~ s/[-T:Z]//g;      # remove -, T, :, Z
    return 0 + $ts;          # convert to real number for easy > / <= comparison
}

sub log_message {
    my $msg = shift;
    my $timestamp = strftime("%Y-%m-%d %H:%M:%S", localtime);
    my $full_msg  = "[$timestamp] $msg";
    print "$full_msg\n";
    if ($LOG_FILE) {
        open my $fh, '>>', $LOG_FILE or warn "Cannot write log: $!";
        print $fh "$full_msg\n";
        close $fh;
    }
}

log_message("=== MediaWiki username auto-ban service STARTED (debug mode) ===");

while (1) {
    eval {
        log_message("--- Starting new check cycle ---");

        # Refresh CSRF token
        $csrf_token = get_csrf_token() unless $csrf_token;
        log_message("CSRF token obtained successfully");

        # Get new user registrations
        my $result = $mw->api({
            action  => 'query',
            list    => 'logevents',
            letype  => 'newusers',
            lelimit => 30,
            leprop  => 'id|title|timestamp|user|comment',
            ledir   => 'older',
        });

        if (!$result) {
            die "LOG EVENTS QUERY FAILED: " . Dumper($mw->{error});
        }

        my $logs = $result->{query}->{logevents} || [];
        my $new_max_id = $max_seen_logid;

        log_message("Fetched " . scalar(@$logs) . " log entries");

        for my $log (@$logs) {
            my $logid = mw_timestamp_to_num($log->{timestamp}) or next;
            next if $logid <= $max_seen_logid;

            my $username = $log->{title} || $log->{user} || next;
            $username =~ s/^Участник://iu;
            log_message("Processing $username");

            my $is_forbidden = 0;
            for my $pat (@FORBIDDEN_PATTERNS) {
                if ($username =~ $pat) {
                    $is_forbidden = 1;
                    last;
                }
            }

            if ($is_forbidden) {
                log_message("FORBIDDEN USERNAME DETECTED → '$username' (log id: $logid) — banning now");

                my $block_params = {
                    action    => 'block',
                    user      => $username,
                    expiry    => $BLOCK_EXPIRY,
                    reason    => $BLOCK_REASON,
                    token     => $csrf_token,
                    autoblock => 1,
                    nocreate  => 1,
                    noemail   => 1,
                };

                my $block_result = $mw->api($block_params);
                if ($block_result) {
                    log_message("✓ SUCCESSFULLY BLOCKED '$username'");
                } else {
                    die "BLOCK FAILED for '$username': " . Dumper($mw->{error});
                }
            }

            $new_max_id = $logid if $logid > $new_max_id;
        }

        $max_seen_logid = $new_max_id;
        log_message("Cycle completed successfully. Next check in 20 seconds.");
    } or do {
        my $err = $@ || 'Unknown error (no $@)';
        log_message("ERROR in main loop: $err");
        # also dump the raw error object if it exists
        log_message("Raw MediaWiki error object: " . Dumper($mw->{error})) if $mw->{error};
    };

    sleep 15;
}

/etc/systemd/system/mediawiki-banbot.service[править]

[Unit]
Description=MediaWiki New User Auto-Ban Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=clown
ExecStart=/usr/bin/perl /home/clown/anti-dyatel/anti-kluv.pl
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=yes

[Install]
WantedBy=multi-user.target
Movax1010h.png Глубокий смысл скрыт в этих неестественных языках
Языки программированияПромышленные: BATC#CC++JavaJavaScript (AJAX) • PascalPerlPHPPythonRubyABAPАссемблерВасикFortran (Профессор)
Эзотерические: BrainFuckHQ9++ErlangForthHaskellLISP (My other car) • PrologTclΤΕΧOracleMySQLGolangВ++ScalaH и Ё+Программист-бетонщик
ПрофессииБыдлокодерПрограммистТестировщикХакерХеллоуворлдщикIT-звёздыПрограммист (существо)Тернарный операторUnreal MCPИсходный кодSingle-Page ApplicationGiteaForgejoCephIDEДжуниорРепозиторийPostgreSQLSQLiteJQueryБуферWebGLПереполнение буфераХардкодInvoke-WebRequestСкрипт для автоблокировки новых пользователейРазделение диапазоновПроверка диапазоновGeoLite2-Country.mmdbObjective-C
Методы и стилиReverse EngineeringАнти-паттернВыстрелить себе в ногуГрязный хакКод (индусский) • КостыльМетод научного тыкаПомолясьСвистелки и перделкиОчередьСпортивное программированиеОбфускацияБета-тестАльфа-тестШаблоныRegReplaceФреймворкБыдлокодIndex.phpОхота за жукамиКуМирКлеточный автоматПроцедурное программированиеПоиск файлов в Unix по содержимомуPetoohФункция активации нейронаПерегрузка операторов в PythonЗерокодинг
Средства разработкиSublime TextПодсветка синтаксиса кодаUnstable DiffusionAPIPythonTutorCodeWarsDataCampUnity3DКнижный PythonMallocСвязный списокSOLIDООПУказательNULLWeLang++XenonRecompFuse.jsОптимизацияТестированиеAmbreon866Реверс-инжинирингКроссплатформенностьJSON
ЛюдиИлья КанторЮрий КлючевскийЭдуард ЛаасЭдвард СноуденСеймур ПейпертПроблемаK!ockyTypeScriptОтладчикБитЭффективный менеджер (IT)TauriReact NativeWindows APIТипPyTorchTensorFlowПарсерNode.jsFastAPIVue.jsSvelteБэкендElectronBroken Object Level AuthorizationМаппингДжастин ФранкельHex-редакторVisual Basic .NETNext.jsDocker ComposeNode modulesIndexedDBDos2unix
Прочее++i + ++iДедлайн%s640 килобайтCMSDummy modeЕГГОГFoobarGod is real, unless explicitly declared as integerGOTOIfconfigKISSRegExpSICPsql.ruXyzzyДискетаИнжалид дежицеКОИ-8ЛогМанРекурсияСУБДТест ТьюрингаУмение разбираться в чужом кодеФаза ЛуныФатальный недостатокПроблема 2000ТаймстампКэшЗапись в файл без кэша (Perl)Танцы с бубномКодачХукCurl cffiВибе-кодингFlutterАппликативный оператор
Вики подсолнух.png Вики — инновационная технология знаний
ОсновыВикиВикипроектыВикисредаВандализмВикипедияАльтервикипространствоФонд SCPRuwikipedia ruЭнциклонгTV TropesWikiClickАПЭСеребропедияTiddlyWikiWikiUnionFandom (вики-хостинг)MemepediaWikkiumВандальные википроектыНедостабПроекты на ВикииО чём бы написать статью?СмартассизмНейровикиСергей КиршFeetABCBlog del NarcoОхрана границБаозматикРасстрел вкладаКира (Евгений Лисовский)НеолуркоязСкрытый вандализмСтатьяСибирское областничествоКульт гомосексуализма в российской викисредеДизамбигПересечение мыслейКакие-то не такие статьиИскра (мессенджер ФСБ)Евгений Лисовский — внештатный сотрудник органовИИ-гарем ЛисовскогоБлокировка фандомов в РоссииСкрипт для автоблокировки новых пользователей
СайтыРусская Википедия / ПедивикияНеолуркEncyclopedia DramaticaALLЛуркоморьеLukomore.orgВикизнаниеВикиреальностьЦиклопедияГомосообществоАбсурдопедия (ворованнаябесшкрыдневая) • ВикисфераМегапедияТорадицийоНовопедияРукспертПровизории.руУпячкопедияИнтеллектуал ВикиPosmotre.liPosmotreli.suРациоВикиКащепузияВикипедиан.руЗаговор.оргВики-мирЛепропедияНеполжедияРуниверсалисЭнциклопедия РувикиUrbancultureВукипедияEnsiklopedia.ruРапедияWikiLeaksMetapediaSoyjak WikiВикиФокусВикискладInformatorium.infoAnekdot.meConservapediaWikitropesCLG WikiМиграпедияНупедияТехнопедияАнтикопирайтRuxpert.ruЕвгений Пригожин (вики-проект)МракопедияЗнание ВикиНеофициальная Windows ВикиWikiFeetМикроВикиВикиновостиЧеченская ВикипедияPestilenceБудущее викиАльтернативная история викиФекальный слонРелигииВикиCreationWikiWikifurВикистатьяЦифропедияХорватская википедияOurworldoftextБойцовские википроектыСтатья сама не напишется • Псевдообразовательные википроекты (Летописи.руАвачаВикиТолВики) • БубопедияWiki.c2.comМикронации ВикиМногомирье ВикиWikimerdaGrokipediaГриф вцепился в хозяинаЕвгений Генкин
УчастникиЛарри СэнгерДжимбо УэйлсНиколай КолпаковВики-ворГерман ЕфремовArashi110ОрионАндрей РоманенкоЖеня ДуховниковаКуковлевMageredolthЗолотой ПареньВячеслав АфиногеновКот ЯрославГерман Анатольевич ГильАлександр МашинГорный Синий БарабанЕвгений ЛисовскийБолеславDimetrОленьШуклинNatsume-96SmartassМицголЯрослав ЗолотарёвPerdakЛидер АнонимусовАндрей ЗелевРоман БеккерИннокентий МаресинOle FørstenFalongГФ100Lum AntiqueArsenalДыхотаФерворСергей НестеровичWulfson (A dona do gato) • АмшельЛаврентияУчастники сайта posmotre.liДмитрий ХомакЭдуард ЧерненкоMrakiaЛука БатумецВладельцы Викиреальности и ЦиклопедииМопец ЦипельманВики-рыбаВики-легендыСовременный интеллектуалМаша ХвостикСтюардЛуркофагМарк БернштейнKalanA.VajrapaniАмир СарабаданиАлександр КрасоткинПДВПOrsoRussian NatureКирилл КулыгинFinstergeistQ-bit arrayNITronПрофессор абсурдологииДмитрий ПодковыровАлексей Погребной-АлександровСаныч (вандал)Игорь ТемировАлександр Курганов и Норный ГородокСвинофагLvovaOleg YunakovНикита-Родин-20021677venzel gottorpskijКурганов — нейросеть
Платные редакторыРаспилы в ВикипедииВикимедиа РуВикифирмаЗапрет платного редактирования в ВикипедииПиарщики в ВикипедииПлатные итоги в ВикипедииПлатные статьи в ВикипедииКак купить статью в ВикипедииDmitry RozhkovИван СливаПавел КаганерВладимир МедейкоДмитрий ЕрохинБогдан Дубилевский
ВыраженияВсираниеСажание ходячего в анакондуСажание ходячего в пчелуСажание ходячего в бланки ГИА и ЕГЭСажание ходячего в коровуСажание ходячего в микробаСажание ходячего в аквалангСажание ходячего в изоляторПостроились в ряды и машут флажкамиX говно или говно-XБывших википедистов не бываетБашлыки в ей беспереч зверсвуют и подвешывают неповинных людьовСтиль ГСБКакая жалость, какая печальВики-саранчаВики-скарабейПамятник неизвестной статьеУсиленныйКуда бы засунуть ходячего?Сажание ходячего в танкВикипедия «Википедия»Был задан вопросИнвазияВикидолбствоВики-карусельКрасивые приятные деньгиСтарый дедушка-XУютненькоеNyggeliЗмеебарсукКлоунИнститут вики-пчеловодстваБестолупаВсеуничтожающий огоньОператорГомопесниСмрадное жужжание гнилостной пчелыНедавноТипичныйСила и мощьВерхоглядствоЛай ЛисовскогоДопишите статью, а то мне леньГениальноГомоцацуцаГомословаОткат правок ботомДобро викисредыЗло викисредыБагорастКатегория
СказкиИгры википедизма (Глава 1Глава 2Глава 3Глава 4Глава 5Глава 6Глава 7Глава 8Глава 9Глава 10Глава 11Глава 12)
МетаМемы вики