Zabezpieczenie RDP: ochrona Windows Server przed atakami
Świeżo postawiony serwer Windows zbiera w ciągu kilku godzin tysiące nieudanych logowań RDP. Ten poradnik pokazuje, które środki naprawdę działają, ile każdy z nich kosztuje i jak nie odciąć samego siebie od serwera.
Serwer Windows, który wychodzi do sieci z otwartym portem 3389, nie zostaje zaatakowany kiedyś tam, tylko w ciągu kilku minut. Skanery pracują bez przerwy, znają każdy zakres adresów IPv4 i tępo przemielają nazwy użytkowników oraz hasła. Prawie każdy incydent z ransomware na małym serwerze zaczyna się dokładnie w tym miejscu: konto o nazwie Administrator, hasło, które ktoś uznał za wystarczające, i brak blokady po tysięcznej nieudanej próbie.
Ten poradnik omawia poszczególne środki w kolejności ich rzeczywistej skuteczności, a nie w tej, w jakiej stoją w większości artykułów. Wszystkie polecenia uruchamiasz w sesji PowerShell z uprawnieniami administratora, na Windows Server od 2016 do 2025.
Dlaczego RDP jest najczęściej atakowaną furtką
RDP nie jest złym protokołem. Problem polega na tym, że wystawia pełnoprawny formularz logowania do otwartego internetu, a Windows domyślnie pozwala wypełniać ten formularz nieograniczoną liczbę razy. Atakujący nie potrzebuje żadnej luki, wystarczą mu cierpliwość i lista haseł.
Jak mocno obrywa twój serwer, sprawdzisz w jednej linijce. Policz nieudane logowania z ostatnich 24 godzin:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} -ErrorAction SilentlyContinue | Measure-Object | Select-Object -ExpandProperty Count
Serwer wewnętrzny, nieosiągalny z internetu, mieści się zwykle w kilkudziesięciu próbach dziennie, w większości to zapomniane hasła i stare konta usług. Serwer z otwartym portem 3389 szybko dochodzi do liczb czterocyfrowych, a nawet pięciocyfrowych. Ta liczba jest twoją miarą: po zastosowaniu poniższych środków powinna spaść o rzędy wielkości. Jeśli Get-WinEvent odpowiada komunikatem „Nie znaleziono zdarzeń zgodnych z określonymi kryteriami wyboru”, twój serwer w ogóle nie zapisuje nieudanych logowań. Naprawiamy to niżej.
Zanim zmienisz cokolwiek: zabezpiecz sobie drogę powrotną
Każdy z poniższych kroków może cię odciąć od serwera. Przy maszynie, do której dostajesz się wyłącznie przez RDP, oznacza to koniec sesji i początek długiego wieczoru. Trzy zabezpieczenia kosztują pięć minut i dokładnie temu zapobiegają.
Po pierwsze: sprawdź, czy masz konsolę działającą niezależnie od RDP. Przy serwerach root KVM od KernelHosta znajdziesz w panelu klienta konsolę VNC, która patrzy prosto na ekran maszyny wirtualnej. Działa nawet wtedy, gdy firewall, sieć i usługa RDP popsuły się jednocześnie. Otwórz ją raz na próbę, zanim cokolwiek zmienisz, a nie po fakcie.
Po drugie: załóż drugie konto administratora, żeby zablokowany login nie oznaczał od razu utraconego serwera. Nazwy grup zależą od języka systemu, dlatego pracujemy na stałych identyfikatorach SID (S-1-5-32-544 to lokalna grupa administratorów, S-1-5-32-555 to użytkownicy pulpitu zdalnego):
New-LocalUser -Name 'kh-adm' -Password (Read-Host -AsSecureString -Prompt 'Hasło') -FullName 'Konto serwisowe' -PasswordNeverExpires
Add-LocalGroupMember -SID 'S-1-5-32-544' -Member 'kh-adm'
Add-LocalGroupMember -SID 'S-1-5-32-555' -Member 'kh-adm'
Trzecia linijka jest ściśle rzecz biorąc zbędna, bo członkowie lokalnej grupy administratorów i tak wchodzą przez RDP. Nie szkodzi jednak, a przy okazji pokazuje zamiar, gdybyś później wyjął to konto z grupy administratorów.
Po trzecie: zostaw sesję RDP, w której pracujesz, otwartą przez całą przebudowę i testuj każdą zmianę drugim, nowym połączeniem. Istniejąca sesja nie zostaje zerwana przez nowe reguły firewalla od razu, natomiast nowe połączenie nie uda się natychmiast. Dzięki temu zauważysz błąd, dopóki możesz go jeszcze cofnąć.
Wymuszenie uwierzytelniania na poziomie sieci
Bez uwierzytelniania na poziomie sieci (po angielsku Network Level Authentication, w skrócie NLA) serwer najpierw buduje sesję, rysuje ekran logowania, a dopiero potem pyta o dane logowania. Każda anonimowa próba połączenia kosztuje więc pamięć RAM i czas procesora, a cały kod stojący za ekranem logowania jest osiągalny przed jakimkolwiek uwierzytelnieniem. Właśnie tam siedziały poważne luki RDP z przeszłości.
Z włączonym NLA serwer sprawdza dane logowania przez CredSSP, zanim w ogóle powstanie sesja. Bot bez poprawnych danych dostaje tylko odrzucone połączenie TLS.
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name 'UserAuthentication' -Value 1
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name 'SecurityLayer' -Value 2
SecurityLayer ustawiony na 2 wymusza TLS przy negocjacji. Wartość 1 (negocjowanie) pozwala klientowi w razie potrzeby zejść z powrotem do starej warstwy zabezpieczeń RDP, 0 to ta stara warstwa bez TLS. Sprawdzenie:
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' | Select-Object UserAuthentication, SecurityLayer
Restart nie jest potrzebny, wartości obowiązują dla każdego nowo zestawianego połączenia. Istniejące sesje działają dalej bez zmian, co bywa praktyczne, gdy właśnie odcinasz sobie jakiegoś klienta.
Gdy potem nikt już się nie dostaje do środka
Po włączeniu NLA regularnie pojawiają się dwa obrazy błędu.
„Komputer zdalny wymaga uwierzytelniania na poziomie sieci, którego ten komputer nie obsługuje. Aby uzyskać pomoc, skontaktuj się z administratorem systemu lub z pomocą techniczną.” Klient jest za stary albo nie mówi w CredSSP. Aktualne klienty Windows radzą sobie z tym od lat. W Linuksie FreeRDP wymaga przełącznika /sec:nla, Remmina ustawienia protokołu zabezpieczeń na NLA, a bardzo stare klienty macOS zawodzą z zasady. Rozwiązaniem jest zawsze nowszy klient, nigdy wyłączanie NLA.
Logowanie zawodzi mimo poprawnego hasła. To jest pułapka, o której większość poradników milczy: jeśli przy koncie zaznaczona jest opcja „Użytkownik musi zmienić hasło przy następnym logowaniu” albo hasło wygasło, takie konto przy aktywnym NLA w ogóle się nie zaloguje. CredSSP nie potrafi przeprowadzić zmiany hasła, tak to zaprojektowano. Zależnie od wersji serwer zgłasza błąd uwierzytelniania albo po prostu nieprawidłowe dane logowania. Wyjście prowadzi przez konsolę w panelu klienta, albo wyłączasz konta serwisowe z terminu wygasania:
Set-LocalUser -Name 'kh-adm' -PasswordNeverExpires $true
Blokada konta: pojedynczy przełącznik o największej skuteczności
Silne hasło chroni przed zgadywaniem, blokada konta chroni przed zgadywaniem bez ograniczeń. Bez niej atakujący ma do dyspozycji miliony prób tygodniowo, z nią zostaje mu dziesięć na kwadrans. Ustaw próg, czas blokady i okno obserwacji w jednym wywołaniu, inaczej Windows odrzuci czas blokady, dopóki próg stoi jeszcze na 0:
net accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15
Czas blokady musi być zawsze większy lub równy oknu obserwacji. Sprawdzenie wyniku:
net accounts
Nowsze wersje Windows przynoszą już domyślne ustawienie tego rzędu, starsze instalacje i wiele obrazów systemu od dostawców nie. Sprawdzenie nic nie kosztuje.
Objęcie blokadą wbudowanego konta Administrator
Historycznie akurat to konto, które każdy atakujący próbuje jako pierwsze, było z blokady wyłączone. Służy do tego zasada „Zezwalaj na blokadę konta Administrator”. Wymaga ona jednak nowszej wersji systemu, czyli Windows 11 22H2 albo Windows Server 2025. Na Windows Server 2022 (kompilacja 20348) eksport zasad zabezpieczeń w ogóle nie zawiera wiersza AllowAdministratorLockout, w sekcji [System Access] stoją tam tylko wartości w rodzaju LockoutBadCount czy MinimumPasswordLength. Sprawdź więc najpierw, co twój system faktycznie eksportuje:
secedit /export /cfg C:\secpol.inf
Select-String -Path C:\secpol.inf -Pattern 'AllowAdministratorLockout'
Jeśli nic tu nie wyjdzie, twoja kompilacja nie zna tej zasady i ten podrozdział masz z głowy. Właśnie tu leży pułapka, którą zastawia większość poradników: typowy jednolinijkowiec z -replace podmienia ciąg znaków, którego w pliku w ogóle nie ma, nie zgłasza przy tym żadnego błędu, a następujące po nim secedit /configure kwituje wszystko sukcesem. Potem wierzysz, że blokada konta Administrator działa, choć nic się nie zmieniło.
Na kompilacji, która tę zasadę zna, zmieniasz wiersz, jeśli istnieje, a w przeciwnym razie go dopisujesz. Ta wersja obsługuje oba przypadki:
$c = Get-Content C:\secpol.inf
if ($c -notmatch 'AllowAdministratorLockout') { $c = $c -replace '(LockoutBadCount = \d+)', "`$1`r`nAllowAdministratorLockout = 1" } else { $c = $c -replace 'AllowAdministratorLockout = 0','AllowAdministratorLockout = 1' }
$c | Set-Content C:\secpol.inf -Encoding Unicode
-Encoding Unicode jest obowiązkowe i nie jest to detal: plik INF musi być w UTF-16 LE ze znacznikiem kolejności bajtów. Set-Content zapisuje w Windows PowerShell 5.1 w przeciwnym razie w ANSI, a secedit odmawia wtedy przyjęcia pliku. Przed zapisaniem z powrotem plik sprawdza secedit /validate C:\secpol.inf, a potem:
secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.inf /areas SECURITYPOLICY
I koniecznie przeczytaj potem wynik jeszcze raz, bo udany przebieg secedit niczego w tym miejscu nie dowodzi. Wyeksportuj zasady ponownie do drugiego pliku i zobacz, czy wartość naprawdę stoi tam z 1.
Na kontrolerze domeny te ustawienia lokalne nie działają. Tam zasada blokady należy do Default Domain Policy, w gałęzi Konfiguracja komputera, Ustawienia systemu Windows, Ustawienia zabezpieczeń, Zasady kont.
Druga strona medalu i droga z powrotem do środka
Blokada konta jest bronią również przeciwko tobie: kto zna twoją nazwę użytkownika, może trzymać ją zablokowaną na stałe, wysyłając co 15 minut dziesięć błędnych haseł. Właśnie dlatego blokada jest dopiero drugą linią obrony, a pierwszą jest ograniczenie po adresie IP z następnego rozdziału.
Gdy konto lokalne jest zablokowane, klient zgłasza z grubsza „Konto, do którego istnieje odwołanie, jest obecnie zablokowane i nie można się do niego zalogować”. Najprostszą drogą powrotną jest przeczekanie, bo po upływie czasu blokady Windows odblokowuje konto sam. Kto nie chce czekać, odblokowuje z konsoli:
$u = [ADSI]"WinNT://./kh-adm,user"; $u.IsAccountLocked = $false; $u.SetInfo()
W Active Directory idzie krócej, przez Unlock-ADAccount -Identity kh-adm.
Hasła, które dopiero nadają blokadzie sens
Dziesięć prób na kwadrans jest przeszkodą tylko wtedy, gdy hasło nie stoi na trzecim miejscu każdej listy. Minimalną długość i złożoność ustawiasz tak:
net accounts /minpwlen:14
Reguła złożoności leży znowu w zasadach zabezpieczeń, sekcja [System Access], klucz PasswordComplexity = 1. Droga jest ta sama co wyżej, przez secedit.
Dwie uwagi z praktyki. Po pierwsze, wymuszona zmiana hasła co 30 dni daje dowodnie niewiele, a w połączeniu z NLA generuje dokładnie ten problem z logowaniem, który opisaliśmy w poprzednim rozdziale. Lepsze są hasła długie, ustawione raz i odłożone w menedżerze haseł. Po drugie, zasada obowiązuje tylko dla haseł ustawianych na nowo. Istniejące hasło sześcioznakowe pozostaje ważne, dopóki go nie zmienisz.
Ograniczenie dostępu do znanych adresów IP
To jest ten środek, który naprawdę kończy ruch atakujący, i to całkowicie. Wszystkie reguły z grupy Pulpit zdalny da się ograniczyć do listy adresów. Używaj neutralnego językowo identyfikatora grupy, żeby skrypt działał także na instalacjach angielskich:
Get-NetFirewallRule -Group '@FirewallAPI.dll,-28752' | Select-Object Name, DisplayName, Enabled, Profile
Set-NetFirewallRule -Group '@FirewallAPI.dll,-28752' -RemoteAddress @('203.0.113.10','198.51.100.0/24')
Spodziewaj się przy tym większej liczby trafień, niż spodziewasz się reguł. -Group rusza wszystkie reguły z grupy, na systemie testowym było ich sześć, razem z regułami cieniami i dodatkowymi kopiami nazwanymi identyfikatorem GUID w profilu Public. Tak ma być i tak jest dobrze, bo inaczej jedna z kopii zostałaby otwarta. Wcześniejsze wypisanie przez Get-NetFirewallRule pokazuje ci z góry, czego zmiana dotknie.
Kontrola, jakie adresy faktycznie zostały zapisane:
Get-NetFirewallRule -Group '@FirewallAPI.dll,-28752' | Get-NetFirewallAddressFilter
Jeśli zmieniłeś port, wbudowane reguły przestają działać, bo są na sztywno przypięte do 3389. Wtedy potrzebujesz własnej reguły:
New-NetFirewallRule -DisplayName 'RDP ograniczony' -Direction Inbound -Protocol TCP -LocalPort 34567 -RemoteAddress '203.0.113.10' -Action Allow -Profile Any
Koło ratunkowe na wypadek własnej reguły firewalla
Kto przepisze swój adres IP z błędem albo wpisze adres dynamiczny, odetnie się od serwera z całą pewnością. Załóż więc wcześniej zadanie, które po dziesięciu minutach samo cofnie to ograniczenie:
Set-Content -Path C:\rdp-ratunek.ps1 -Value "Set-NetFirewallRule -Group '@FirewallAPI.dll,-28752' -RemoteAddress Any"
Register-ScheduledTask -TaskName 'RDP-Ratunek' -Action (New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-ExecutionPolicy Bypass -File C:\rdp-ratunek.ps1') -Trigger (New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(10)) -User 'SYSTEM' -RunLevel Highest
Jeśli nowe połączenie działa, usuwasz zadanie z powrotem:
Unregister-ScheduledTask -TaskName 'RDP-Ratunek' -Confirm:$false
Jeśli nie masz stałego adresu IP, czystym rozwiązaniem jest w ogóle nie wystawiać RDP do internetu, tylko dostawać się do niego przez VPN. Jak to postawić, opisaliśmy w poradniku o serwerze VPN WireGuard. Serwer nasłuchuje wtedy już tylko na adresie VPN, a port 3389 znika z internetu całkowicie.
Zmiana portu i to, co ona naprawdę daje
Inny port nie jest środkiem bezpieczeństwa, tylko środkiem wyciszającym hałas. Wielka masa botów skanuje wyłącznie 3389 i potem już cię nie znajduje, co z reguły drastycznie obniża twoją liczbę zdarzeń 4625 i przywraca czytelność logom zdarzeń. Kto szuka celowo, i tak usługę znajdzie: wyszukiwarki otwartych usług rozpoznają RDP po odcisku palca protokołu, niezależnie od portu, a pełne skanowanie 65535 portów trwa sekundy.
Zmiana portu ma więc sens jako uzupełnienie, ale nigdy jako zamiennik NLA, blokady konta i ograniczenia adresowego. Praktyczne wykonanie, razem z tą częścią, którą prawie wszystkie poradniki robią źle, czyli bez restartu, opisaliśmy osobno: zmiana portu RDP bez restartu. W każdym razie pamiętaj, żeby założyć regułę firewalla dla nowego portu, zanim przestawisz usługę.
Analiza logów logowań
Najpierw rejestrowanie w ogóle musi być włączone. Nazwy podkategorii w auditpol są przetłumaczone, więc polecenie po angielsku zawodzi na systemie polskim z komunikatem „Wystąpił błąd 0x00000057: Parametr jest niepoprawny.” Identyfikator GUID działa natomiast w każdej wersji językowej:
auditpol /set '/subcategory:{0CCE9215-69AE-11D9-BED3-505054503030}' /success:enable /failure:enable
auditpol /get '/subcategory:{0CCE9215-69AE-11D9-BED3-505054503030}'
Pojedyncze apostrofy wokół całego parametru to nie kwestia estetyki, tylko konieczność. PowerShell odczyta inaczej nawiasy klamrowe jako blok skryptu i je usunie, z jednego argumentu zrobią się trzy, a auditpol przerwie pracę komunikatem Wystąpił błąd 0x00000057: Parametr jest niepoprawny. i kodem wyjścia 87, a za nim wypisze tekst pomocy. W cmd.exe zapis bez apostrofów działa, w PowerShellu nie. Z apostrofami oba przechodzą z kodem wyjścia 0, a zapytanie kontrolne odpowiada wtedy Logowanie Powodzenie i niepowodzenie.
Pod ostrzałem log zabezpieczeń przewija się w kilka godzin i nadpisuje dokładnie te wpisy, których potrzebujesz. Daj mu więcej miejsca:
wevtutil sl Security /ms:1073741824
Potem najczęstsze adresy źródłowe z ostatniego tygodnia, posortowane według liczby. Wariant idący przez strukturę XML jest tym odpornym, bo nie zależy od kolejności pól:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-7)} -ErrorAction SilentlyContinue | ForEach-Object { ([xml]$_.ToXml()).Event.EventData.Data | Where-Object { $_.Name -eq 'IpAddress' } | Select-Object -ExpandProperty '#text' } | Group-Object | Sort-Object Count -Descending | Select-Object -First 15 Count, Name
-ErrorAction SilentlyContinue należy dopisać do każdego z tych wywołań. Get-WinEvent przerywa pracę czerwonym błędem, gdy tylko w badanym okresie nie ma ani jednego pasującego zdarzenia: „Nie znaleziono zdarzeń zgodnych z określonymi kryteriami wyboru.” Na świeżo zabezpieczonym serwerze to właśnie jest przypadek normalny, polecenie zawodzi więc akurat przy tym sukcesie, do którego zmierza ten poradnik.
Decydujące pytanie brzmi jednak nie kto próbował, tylko czy komuś się udało. Udane logowania pulpitu zdalnego niosą identyfikator zdarzenia 4624 z typem logowania 10 (RemoteInteractive):
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624; StartTime=(Get-Date).AddDays(-7)} -ErrorAction SilentlyContinue | Where-Object { $_.Properties[8].Value -eq 10 } | Select-Object TimeCreated, @{n='Użytkownik';e={$_.Properties[5].Value}}, @{n='Źródło';e={$_.Properties[18].Value}} | Format-Table -AutoSize
Jeśli stoi tam nazwa użytkownika albo adres źródłowy, którego nie potrafisz przypisać, ktoś znalazł poprawne hasło. Wtedy zaostrzanie zasad już nie pomoże, wtedy serwer nadaje się do postawienia od nowa.
Dodatkowo opłaca się zajrzeć do własnego logu RDP. Zdarzenie 1149 podaje użytkownika, domenę i adres źródłowy każdego autoryzowanego połączenia w jednym wierszu:
Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' -FilterXPath '*[System[EventID=1149]]' -MaxEvents 25 | Format-List TimeCreated, Message
Zmiana nazwy konta Administrator, a jeszcze lepiej jego wyłączenie
Wbudowane konto Administrator to jedyna nazwa użytkownika, którą każdy atakujący zna na pewno. Zmiana nazwy nic nie kosztuje:
Rename-LocalUser -Name 'Administrator' -NewName 'kh-svc'
Miej jednak świadomość granicy: SID tego konta nadal kończy się na -500, a każdy uwierzytelniony dostęp potrafi po nim rozwiązać nową nazwę. Przeciwko masowym botom zmiana nazwy działa, przeciwko atakującemu wymierzonemu w ciebie, który już postawił stopę w drzwiach, nie. Tak znajdziesz to konto mimo nowej nazwy:
Get-LocalUser | Where-Object { $_.SID.Value -like '*-500' } | Select-Object Name, Enabled
Wyraźnie skuteczniejsze jest całkowite wyłączenie wbudowanego konta, po tym jak twoje własne konto administratora z rozdziału „zabezpiecz sobie drogę powrotną” dowodnie działa. Przetestuj logowanie nowym kontem w drugiej sesji, i dopiero wtedy:
Disable-LocalUser -Name 'kh-svc'
Ogranicz dodatkowo dostęp RDP do osób, które go potrzebują. Domyślnie przez RDP wchodzi każdy członek lokalnej grupy administratorów, także konta usług, które nigdy nie powinny tego robić. Kto ma prawo teraz, pokaże:
Get-LocalGroupMember -SID 'S-1-5-32-555'
Po czym poznasz, że naprawdę zadziałało
Odhaczanie zamiast nadziei. Te pięć sprawdzeń powie ci, czy przebudowa dotarła do celu:
- NLA:
Get-ItemPropertynaRDP-TcpzwracaUserAuthentication : 1orazSecurityLayer : 2. Nowe połączenie pyta teraz o dane logowania przed zestawieniem połączenia, a nie dopiero na ekranie logowania w oknie. - Blokada:
net accountspokazuje próg blokady inny niż „Nigdy”. Kontrpróba na koncie jednorazowym: po jedenastym błędnym haśle klient musi pokazać komunikat o blokadzie, a już nie komunikat o nieprawidłowych danych logowania. - Firewall:
Get-NetFirewallAddressFilterpokazuje twoje adresy zamiastAny. Test połączenia z obcego adresu musi skończyć się timeoutem, a nie prośbą o zalogowanie. Sprawdź to z zewnątrz przezTest-NetConnection -ComputerName twojserwer -Port 3389, wynik musi brzmiećTcpTestSucceeded : False. - Logi:
auditpol /getzgłasza dla podkategorii powodzenie i niepowodzenie. - Ta liczba: policz zdarzenia 4625 ponownie 24 godziny po przebudowie. Musi być wyraźnie niższa. Jeśli zostaje wysoka, jedna z twoich reguł nie działa, najczęściej dlatego, że istnieje druga, bardziej otwarta reguła firewalla dla portu 3389, założona przez obraz systemu od dostawcy albo przez instalację jakiegoś oprogramowania. Ta linijka ją znajdzie:
Get-NetFirewallPortFilter | Where-Object { $_.LocalPort -eq 3389 } | Get-NetFirewallRule | Select-Object DisplayName, Enabled, Profile, Action. Kolejność w potoku jest zamierzona. Jeśli ją odwrócić i przepuścić najpierw wszystkie reguły firewalla przezGet-NetFirewallPortFilter, wywołanie trwa zmierzone około 12 sekund zamiast jednej, a przede wszystkim w wyniku brakuje nazwy reguły: widzisz wtedy cztery trafienia, nie dowiadując się, o jakie reguły chodzi.
Jeśli i tak właśnie stawiasz serwer od zera, przerób te punkty od razu na początku, zamiast doposażać go później. Dla systemów Linux obowiązuje ten sam wzorzec, tylko z SSH zamiast RDP, opisany w tekście zabezpieczanie SSH i logowanie kluczem, a kolejność pierwszych kroków znajdziesz w naszej liście kontrolnej dla nowych serwerów root.
Czego hardening RDP nie obejmuje
Powyższe środki chronią przed próbami logowania. Nie chronią przed atakami wolumetrycznymi, które mają uczynić serwer nieosiągalnym po stronie łącza. Na to pomaga wyłącznie filtrowanie w sieci przed nim. Jak takie ataki działają, wyjaśniamy w tekście czym jest atak DDoS, a które zabezpieczenia po stronie serwera pozostają sensowne, w tekście ochrona serwera przed atakami DDoS. Wszystkie serwery KernelHost stoją w centrum danych maincubes we Frankfurcie nad Menem za filtrowaniem, które wyłapuje ruch atakujący jeszcze przed serwerem.
I nie zastąpią kopii zapasowej. Serwer, na którym ktoś skutecznie się zalogował, nie jest już godny zaufania, niezależnie od tego, jak szybko zmienisz potem hasło. Jedyną pewną drogą powrotną jest kopia zapasowa sprzed incydentu.
Najczęstsze pytania
Czy wystarczy zmienić port RDP z 3389 na inny?
Odciąłem się od serwera po ustawieniu reguły firewalla. Co teraz?
Dlaczego użytkownik nie może się zalogować mimo poprawnego hasła, odkąd NLA jest aktywne?
Czy blokada konta obejmuje wbudowane konto Administrator?
Czy atakujący może przez blokadę konta odciąć mnie od serwera na stałe?
Po czym poznam, że atak się powiódł?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

