Bezpieczeństwo WP: zabezpieczenie wp-admin | zmiana adresu logowania, limit logowań, XML-RPC

Informacja o linkach partnerskich v3.1
Informacja o linkach partnerskich v3.2 (wersja mobilna)

Zabezpieczenie wp-admin to ustawienia, które blokują ataki brute force na panel administracyjny i ekran logowania WordPressa. Analiza logów dostępu serwera Nginx + Apache, na którym działa kilka witryn na WordPressie, pokazała, że automatyczne żądania do xmlrpc.php napływały dalej także po zmianie adresu logowania, dlatego wprowadzono również limit żądań na poziomie serwera.

1️⃣ Dlaczego wp-admin i wp-login.php są celem ataków

To, że adres panelu WordPressa jest powszechnie znany, jest słabym punktem, ale możesz to zrównoważyć, wzmacniając zabezpieczenia. Każda witryna na WordPressie używa tego samego /wp-admin/ i [wp-login.php], a po otwarciu /wp-admin/ bez zalogowania trafiasz na ekran logowania [wp-login.php].

Ataki przychodzą jako brute force – na tym ekranie logowania raz za razem wpisuje się nazwy użytkownika i hasła. Dlatego w zabezpieczeniu wp-admin blokowanie prób logowania jest ważniejsze niż ukrywanie adresu.

Dwa wejścia do logowania WordPressa
Wejście przez przeglądarkę
/wp-admin/
Bez zalogowania przekierowanie na ekran logowania (302)
wp-login.php
Ekran logowania · wpisanie nazwy użytkownika i hasła
Aplikacje · automatyczne żądania
xmlrpc.php
Nazwa użytkownika i hasło trafiają w żądaniu POST, bez ekranu logowania
Omija ekran logowania
system.multicall: wiele haseł w jednym żądaniu · adres się nie zmienia, nawet gdy zmienisz adres logowania
Ta sama weryfikacja nazwy użytkownika i hasła
Oba wejścia sprawdzają konto tą samą funkcją uwierzytelniania WordPressa
Ataki brute force wchodzą tym wejściem, które jest otwarte. Zmiana adresu logowania dotyczy tylko górnego wejścia, dlatego xmlrpc.php trzeba zamknąć osobno albo ograniczyć liczbę żądań.

2️⃣ Zmiana adresu logowania: co daje, a czego nie

Gdy zmienisz adres logowania wtyczką bezpieczeństwa, domyślny [wp-login.php] zaczyna zwracać błąd 404, więc automatyczne ataki uderzające w domyślny adres nie docierają nawet do ekranu logowania. Nowy adres trzeba osobno przekazać każdemu, kto ma konto administratora.

🧭 Wejścia do logowania WordPressa
Diagram objaśniający
⬜ Bez wtyczki
🛡️ Hide My WP
🚪 Wejście logowania
/wp-login.php · /wp-admin/Ten sam adres w każdym WordPressie
Ekran logowania404
/newloginZmieniony adres · znają go tylko administratorzy
Ekran logowania
POST /xmlrpc.phpSprawdza hasło bez ekranu logowania
Odpowiada na sprawdzenie hasłaWyłączone 405
Pomiar na witrynie testowej · żądania bez zalogowania
→
🤖 Ataki automatyczne
Wejścia, w których można próbować haseł pod znanym adresem
2
1
Brak
Bez wtyczki hasła można próbować w dwóch miejscach: w [wp-login.php], takim samym w każdej witrynie na WordPressie, i w [xmlrpc.php], który sprawdza hasło bez ekranu logowania.
Po zmianie adresu logowania [wp-login.php] i /wp-admin/ zwracają 404, ale [xmlrpc.php] nadal odpowiada, czy nazwa użytkownika i hasło są poprawne.
Gdy wyłączysz też XML-RPC, żądania logowania do [xmlrpc.php] kończą się odpowiedzią, że usługa XML-RPC jest wyłączona, i pod znanym adresem nie da się już próbować haseł.

Ta metoda wymaga niewiele pracy, ale jeśli zapomnisz nowy adres, nie wejdziesz do panelu administracyjnego i trzeba będzie wyłączyć wtyczkę, zmieniając nazwę jej folderu przez FTP albo w menedżerze plików. Jeśli witryną zarządza kilka osób, warto zapisać adres w jednym miejscu.

3️⃣ Limit prób logowania i uwierzytelnianie dwuskładnikowe

Nawet po zmianie adresu logowania, gdy nowy adres wycieknie, próby odgadnięcia hasła trwają dalej. Rdzeń WordPressa nie ogranicza nieudanych logowań – niezależnie od tego, ile razy wpiszesz złe hasło, ten sam ekran logowania otwiera się ponownie.

🧭 Limit prób logowania i uwierzytelnianie dwuskładnikowe
Diagram objaśniający
⬜ Bez wtyczki
🛡️ Wtyczka bezpieczeństwa
🔑 Logowania z tego samego IP
1.Błędne hasło
Znów ekran logowaniaZostały 3
2.Błędne hasło
Znów ekran logowaniaZostały 2
3.Błędne hasło
Znów ekran logowaniaZostała 1
4.Błędne hasło
Znów ekran logowaniaBlokada na 20 min
5.ZablokowaneBłędne hasłoLogowanie · żądania XML-RPC
Znów ekran logowaniaxmlrpc.php też 403
Wpisanie hasłaPoprawne hasło
Ekran wpisania kodu
Authentication Code6 cyfr z aplikacji uwierzytelniającej · zmienia się co 30 s
Panel administracyjny
Atakujący, który zna tylko hasłoNie zna kodu
Zatrzymuje się na ekranie kodu
Pomiar na witrynie testowej · kolejne żądania z tego samego IP
→
🤖 Ataki automatyczne
Czy można dalej próbować haseł?
Bez limitu
Blokada przy 4. próbie
Zatrzymuje się na kodzie
Bez wtyczki nawet po sześciu błędnych hasłach z tego samego IP za każdym razem otwiera się ten sam ekran logowania.
Po włączeniu limitu prób logowania przy każdym błędzie widać, ile prób zostało, a po 4. błędzie to IP nie może się logować przez 20 minut. W czasie blokady żądania do xmlrpc.php też kończą się kodem 403.
Po włączeniu uwierzytelniania dwuskładnikowego panel administracyjny otwiera się nawet przy poprawnym haśle dopiero po wpisaniu 6-cyfrowego [Authentication Code], który aplikacja uwierzytelniająca tworzy co 30 sekund.

Wtyczka ograniczająca próby logowania blokuje na pewien czas IP, które przekroczy ustaloną liczbę prób, a uwierzytelnianie dwuskładnikowe nawet przy poprawnym haśle wymaga jeszcze kodu z aplikacji uwierzytelniającej w telefonie. Włączając uwierzytelnianie dwuskładnikowe, zachowaj też kody zapasowe na wypadek utraty telefonu.

4️⃣ Zamknięcie xmlrpc.php

[xmlrpc.php] to drugie wejście, które przyjmuje nazwę użytkownika i hasło bez ekranu logowania, a metodą [system.multicall] można w jednym żądaniu sprawdzić wiele haseł.

W logach dostępu serwera Nginx + Apache, na którym działa kilka witryn na WordPressie, 13 października między 0:00 a 9:50 do [xmlrpc.php] trafiło 2250 żądań POST. Przyszły z 22 adresów IP, a User-Agent podszywał się pod Jetpack i WordPress.com.

Jeśli nie korzystasz z aplikacji mobilnej WordPressa ani z wtyczki Jetpack, zablokuj żądania do [xmlrpc.php] w konfiguracji Nginx albo użyj opcji wyłączenia XML-RPC we wtyczce bezpieczeństwa.

# W bloku server — odrzucanie żądań do xmlrpc.php
location = /xmlrpc.php {
    deny all;
}

Z tym ustawieniem wszystkie żądania GET i POST do [xmlrpc.php] kończą się kodem 403, zanim dotrą do PHP. Wyłączenie XML-RPC we wtyczce bezpieczeństwa odrzuca tylko żądania wymagające logowania, a plik dalej odpowiada, więc żeby ograniczyć też uruchamianie PHP, lepiej zablokować go w Nginx.

5️⃣ Blokada na serwerze: dostęp administratora tylko z wybranych IP i limit żądań

Jeśli zarządzasz witryną tylko ze stałego IP, najpewniejszą metodą jest dopuszczenie w Nginx do [wp-login.php] i /wp-admin/ wyłącznie tego IP. Nie sprawdza się to tam, gdzie IP w domu lub w biurze często się zmienia.

Może się wydawać, że wystarczy zablokować cały /wp-admin/, ale funkcje po stronie odwiedzających, takie jak wyszukiwarka czy koszyk, często wysyłają żądania do [admin-ajax.php], więc ten plik musi zostać otwarty.

# W bloku server — nad blokiem location obsługującym PHP
location = /wp-login.php {
    allow 203.0.113.10;   # Twoje stałe IP do zarządzania
    deny all;
    # Poniżej skopiuj ustawienia bloku location obsługującego PHP
}

Otwarcie [wp-login.php] z innego IP niż wskazane daje 403, a ze wskazanego IP otwiera się ekran logowania. W bloku location trzeba bez zmian przenieść ustawienia PHP witryny (fastcgi_pass itd.), aby ekran logowania działał prawidłowo.

Jeśli nie możesz ustalić stałego IP, możesz nałożyć limit żądań na żądania PHP od niezalogowanych odwiedzających; proces ustawienia go na 30 na minutę, aby automatyczne żądania nie zajmowały zasobów serwera, opisano w artykule Ostrzeżenie php-fpm max_children poświęconym temu zagadnieniu.

# Blok http — liczenie per IP tylko żądań bez ciasteczka logowania
map $http_cookie $php_anon_key {
    default                 $binary_remote_addr;
    "~*wordpress_logged_in" "";
}
limit_req_zone $php_anon_key zone=php_anon:10m rate=30r/m;

# W bloku location obsługującym PHP
limit_req zone=php_anon burst=60 nodelay;
limit_req_status 429;

Gdy jedno niezalogowane IP wysyła żądania PHP jedno po drugim, przetwarzane są do 61. włącznie, a potem zwracany jest kod 429; żądania z ciasteczkiem logowania nie są liczone. Jeśli pamięć podręczna stron odpowiada bez udziału PHP, zwykli odwiedzający przeglądający strony nie trafiają na ten limit.

ℹ️ Informacja o linkach partnerskich
Treści tej witryny zawierają linki partnerskie. Jeśli odwiedzający kupi produkt lub usługę przez taki link, witryna otrzymuje od sprzedawcy prowizję. Kwota płacona przy tym przez kupującego (podczas promocji spada↓) nie wzrasta. Podane ceny, rabaty i dostępność odnoszą się do chwili pisania i mogą różnić się od stanu faktycznego, dlatego przed zakupem sprawdź je u sprzedawcy. Produkty wybieramy i oceniamy według własnych kryteriów, a prowizja nie wpływa ani na kolejność prezentacji, ani na treść ocen.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

Prove your humanity: 0   +   6   =