RDS Server 2016: tracciare e bloccare gli accessi falliti (Event 4625) su RD Web con Duo

Su un server Windows Server 2016 con ruolo Remote Desktop Services (RD Web) e 2FA Duo, la Security log può riempirsi di eventi 4625 – An account failed to log on senza indirizzo IP. Qui trovi la guida completa per tracciare l’origine degli attacchi e bloccarli, senza perdere tempo.

Indice

Scenario reale: eventi 4625 su RD Web senza IP

Un amministratore nota ripetuti 4625 con queste caratteristiche:

  • Source Network Address: “-” (vuoto).
  • Processo: w3wp.exe (IIS).
  • Identità: IIS APPPOOL\RDWebAccess.
  • Username inesistenti (esempio: recepsto), tipici del credential stuffing o del brute‑force automatico.

Obiettivo: capire da dove arrivano i tentativi e mitigarli in modo duraturo.

Perché l’indirizzo IP spesso non compare

RD Web vive in IIS. Quando l’autenticazione fallisce prima che Windows completi la transizione a un contesto utente, il provider di sicurezza non valorizza il campo “Source Network Address”. In più:

  • Se RD Web è dietro un reverse proxy / load balancer, c-ip nei log IIS e nei 4625 può essere l’IP del proxy. L’IP vero è spesso nell’header X-Forwarded-For (XFF).
  • L’identità IIS APPPOOL\RDWebAccess è l’application pool che processa la richiesta: è normale vederla in Process Information.
  • Con autenticazione 2FA (Duo), una parte della verifica può avvenire prima o in parallelo rispetto al logon Windows: i log Duo sono spesso la fonte più immediata dell’IP.

Roadmap rapida (TL;DR)

  1. Forza il logging dettagliato dei Logon (Success e Failure) con GPO o auditpol.
  2. Analizza i 4625/4624 e cerca pattern (user, orari, codici di errore).
  3. Accendi i log IIS, aggiungi c-ip e X-Forwarded-For, e collega richieste HTTP ⇄ eventi 4625.
  4. Se serve, cattura rete su 443 (solo metadati: IP/port) per attribuire l’origine.
  5. Blocca gli IP o, meglio, limita perimetrale/whitelist su RD Web. Valuta Dynamic IP Restrictions in IIS.
  6. Indurimento: RD Gateway o VPN, policy di lockout, password robuste, aggiornamenti regolari.

Abilitare il logging di sicurezza dettagliato

Via Group Policy (dominio)

  1. Apri Group Policy Management (GPMC).
  2. Modifica la GPO applicata ai server RDS o creane una nuova dedicata.
  3. Vai a:
    Computer Configuration ▸ Windows Settings ▸ Security Settings ▸ Advanced Audit Policy Configuration ▸ Audit Policies ▸ Logon/Logoff ▸ Audit Logon
  4. Seleziona Success e Failure.
  5. Forza l’aggiornamento: gpupdate /force.

Via Local Security Policy (standalone)

  1. Apri secpol.mscAdvanced Audit Policy Configuration.
  2. Stesso percorso: abilita Success e Failure su Audit Logon.

Via riga di comando

auditpol /set /subcategory:"Logon" /success:enable /failure:enable
gpupdate /force

Questo aumenta le probabilità che il campo IpAddress venga popolato negli eventi 4624/4625 (quando tecnicamente disponibile).

Analizzare i log di sicurezza: cosa cercare

  1. Apri Event ViewerWindows Logs ▸ Security.
  2. Crea filtri per Event ID 4625 (falliti) e 4624 (riusciti).
  3. Ordina per TimeCreated e osserva Logon Type, Status, SubStatus, IpAddress.

Interpretare un 4625 tipico di RD Web

Log Name: Security
Event ID: 4625
Account For Which Logon Failed:   TargetUserName: recepsto
Process Information:              ProcessName: C:\Windows\System32\inetsrv\w3wp.exe
Network Information:              Source Network Address: -
Failure Information:              Status: 0xC0000064   SubStatus: 0x0
Logon Type:                       3
CampoCosa indicaCome leggerlo
TargetUserNameAccount richiestoUtenti inesistenti → spray automatizzato; se esiste, controlla i tentativi ripetuti.
ProcessNameChi ha invocato il logonw3wp.exe (IIS) → evento originato da RD Web.
LogonTypeContesto del logonSpesso 3 (Network) su RD Web.
StatusCodice errore NTSTATUS0xC0000064 = utente inesistente; 0xC000006A = password errata; 0xC000006D = credenziali non valide.
IpAddressIP sorgentePuò essere vuoto (-) se fallisce prima del binding utente o se c’è un proxy non trasparente.

Estrarre pattern e IP con PowerShell

Il seguente script estrae Username, IP, codici e li raggruppa (è utile anche post‑mortem dopo aver attivato l’audit):

$events = Get-WinEvent -FilterHashtable @{
  LogName = 'Security'
  Id      = 4625
  StartTime = (Get-Date).AddDays(-7)
}

$rows = foreach ($e in $events) {
$xml = [xml]$e.ToXml()
$kv  = @{}
foreach ($d in $xml.Event.EventData.Data) { $kv[$d.Name] = $d.'#text' }
[pscustomobject]@{
TimeCreated = $e.TimeCreated
User       = $kv['TargetUserName']
Ip         = $kv['IpAddress']
Status     = $kv['Status']
SubStatus  = $kv['SubStatus']
LogonType  = $kv['LogonType']
Process    = $kv['ProcessName']
}
}

$rows | Group-Object Ip, User |
Sort-Object Count -Descending |
Select-Object Count, Name |
Format-Table -AutoSize 

Quando l’IP continua a mancare: dove guardare

Log di IIS su RD Web

Per il sito di RD Web (tipicamente Default Web Site ▸ /RDWeb):

  1. Apri IIS Manager → seleziona il sito di RD Web → Logging.
  2. Formato W3C e cartella predefinita: %SystemDrive%\inetpub\logs\LogFiles\W3SVC….
  3. Clicca Fields… e verifica che Client IP Address (c-ip) sia attivo.
  4. Aggiungi X-Forwarded-For:
    • Fields… ▸ Add Field…
    • Source: Request Header
    • Field name: X-Forwarded-For

Così potrai incrociare: c‑ip (spesso il proxy) e X‑Forwarded‑For (IP reale del client), oltre a cs-username se la richiesta ha inviato un nome utente.

Duo Admin Panel

Nella sezione Authentication/Telephony Logs puoi spesso leggere IP del client e dettagli del fattore. È prezioso quando l’evento Windows non espone l’IP, perché Duo registra la pre‑autenticazione.

Network capture sul server

Se devi attribuire l’origine in tempo reale, una cattura leggera rivela gli IP dei peer TLS (non i contenuti):

netsh trace start capture=yes persistent=no tracefile=c:\temp\rdweb_trace.etl scenario=InternetClient
rem …lascia girare 2–5 minuti durante i tentativi…
netsh trace stop

Apri il trace con Microsoft Message Analyzer/Wireshark: filtra su tcp.port == 443 e lista i remote address.

Bloccare gli IP malevoli

Windows Firewall (regole host‑based)

Per tagliare subito il rumore:

  1. Apri Windows Firewall with Advanced SecurityInbound Rules.
  2. Crea una regola di blocco per HTTPS (TCP/443) con Remote IP impostati agli indirizzi ostili.

Oppure via riga di comando:

netsh advfirewall firewall add rule name="Block RDWeb IP 203.0.113.45" ^
    dir=in action=block protocol=TCP localport=443 remoteip=203.0.113.45

Se gli IP sono numerosi e in continua rotazione, considera blocchi per paese o per ASN a livello di firewall perimetrale, o applica una whitelist se l’utenza è nota (uffici/partner/VPN).

IIS Dynamic IP Restrictions

Su Server 2016 puoi installare la funzionalità IP and Domain Restrictions (e l’estensione Dynamic IP Restrictions) per limitare i tentativi troppo frequenti verso RD Web:

  1. Server Manager → Add Roles and FeaturesWeb Server (IIS)Web Server ▸ Security → spunta IP and Domain Restrictions.
  2. In IIS Manager, sul sito RD Web:
    • Apri IP Address and Domain Restrictions.
    • Edit Dynamic IP Restrictions…: imposta p.es. Max N requests nel Time period di pochi secondi.
    • In Edit Feature Settings…: abilita Proxy Mode se usi un reverse proxy (così si usa X-Forwarded-For).

Risultato: gli indirizzi che martellano la pagina di login vengono automaticamente negati per un intervallo configurabile.

Migliorare la postura di sicurezza (oltre il blocco reattivo)

Metti un cancello davanti a RD Web

  • RD Gateway o VPN come primo fattore di esposizione: RD Web e RDP restano raggiungibili solo dopo autenticazione perimetrale.
  • Whitelist IP (IIS o firewall): consenti solo subnet conosciute (uffici, sedi, IP statici, pool VPN).

Policy di lockout e password

  • Account Lockout Policy: soglie moderate (es. 10 tentativi, reset 15–30 minuti) per evitare sia brute force sia lockout DoS.
  • Complessità password & scadenze ragionevoli; privilegia MFA ovunque.

Hardening di sistema

  • Aggiorna regolarmente Windows, IIS, Duo e i certificati TLS.
  • Riduci la superficie: disabilita funzionalità inutili su IIS, limita metodi HTTP, imposta HSTS.
  • Separa i ruoli: RD Gateway su host dedicato; RD Web con Application Pool a identità dedicata e ACL minimi.

Correlare eventi: come risalire all’origine in modo deterministico

Per attribuire un tentativo:

  1. Timeline: annota data/ora del 4625.
  2. IIS Log: cerca richieste a /RDWeb nello stesso minuto; confronta cs-username, sc-status (401/403) e c-ip/X‑Forwarded‑For.
  3. Duo: verifica un log di pre‑auth nello stesso istante per lo stesso username; prendi l’IP (spesso quello reale).
  4. Firewall/Proxy: se hai un reverse proxy, i suoi log sono gold per l’IP client e l’header XFF preservato.

Esempio di query sui log IIS con PowerShell

IIS scrive in formato W3C (spazi come delimitatore). Un esempio minimale per contare hit su /RDWeb per IP:

$path = "$env:SystemDrive\inetpub\logs\LogFiles\W3SVC1\*.log"
Select-String -Path $path -Pattern "/RDWeb" |
  ForEach-Object {
    $line = $_.Line
    # i campi variano a seconda della configurazione; cerchiamo c-ip e XFF
    $ip  = ($line -split ' ' | Select-Object -Index 8) # spesso c-ip
    [pscustomobject]@{ Ip=$ip; Raw=$line }
  } | Group-Object Ip | Sort-Object Count -Desc | Select-Object Count, Name

Nota: adatta l’indice del campo in base all’ordine #Fields: presente in ogni file log. Se hai aggiunto X-Forwarded-For, estrailo e preferiscilo a c-ip.

Prevenzione proattiva: limitare l’accesso sin dall’origine

Whitelisting a livello IIS

  1. In IP Address and Domain RestrictionsAdd Allow Entry…: aggiungi subnet autorizzate (es. 203.0.113.0/24, 198.51.100.10).
  2. Imposta Access for unspecified clients su Deny.

È drastico, ma estremamente efficace in ambienti controllati (es. solo accesso via VPN).

Rate‑limiting e tarpitting

Oltre alle restrizioni dinamiche, puoi impostare tarpit (risposte lente) per richieste ripetute: rallenta il bot senza impattare gli utenti legittimi. In IIS si ottiene combinando Dynamic IP Restrictions con tempi di deny progressivi.

Domande ricorrenti

Vedo username assurdi (es. recepsto): sono compromesso?

In genere no: è rumore di Internet. La presenza di 2FA e password robuste riduce drasticamente il rischio. Va però limitata l’esposizione per non sprecare risorse e non inquinare i log.

Perché Source Network Address è “-” anche dopo l’audit?

Perché il fallimento avviene prima che il token di rete sia disponibile, oppure perché c’è di mezzo un reverse proxy che maschera l’IP. In tali casi i log IIS e/o del proxy restano la fonte principale; registra X‑Forwarded‑For.

Meglio bloccare gli IP o mettere una whitelist?

Gli IP blocklist funzionano solo contro una manciata di sorgenti persistenti. Se l’attaccante ruota molte origini, scegli whitelist o RD Gateway/VPN.

RD Gateway risolve il problema?

Non “magicamente”, ma sposta l’esposizione su un punto più controllabile, dove puoi imporre pre‑auth, policy TLS e controlli più granulosi. Spesso abbatte il volume di spray su RD Web.

Checklist operativa

  • ✔ Abilita Audit Logon (Success/Failure) via GPO o auditpol.
  • ✔ Verifica i log 4624/4625, annota codici Status/SubStatus.
  • ✔ Attiva IIS Logging con c-ip + X‑Forwarded‑For.
  • ✔ Incrocia Security log ↔ IIS ↔ Duo.
  • ✔ Implementa Dynamic IP Restrictions (proxy mode se serve).
  • ✔ Applica blocchi firewall mirati o whitelist.
  • ✔ Valuta RD Gateway/VPN perimetrali.
  • ✔ Imposta Account Lockout e mantieni aggiornamenti regolari.

Esempi di automazione utili

Bloccare in automatico gli IP più aggressivi dai 4625

Script concettuale (usare con cautela per evitare falsi positivi):

$threshold = 50 # tentativi in 10 minuti
$since = (Get-Date).AddMinutes(-10)

$bad = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$since} |
ForEach-Object {
$xml = [xml]$*.ToXml()
($xml.Event.EventData.Data | ? { $*.Name -eq 'IpAddress' }).'#text'
} | ? { $ -and $ -ne '-' } |
Group-Object | ? { $_.Count -ge $threshold } | Select -Expand Name

foreach ($ip in $bad) {
Write-Host "Blocco $ip"
netsh advfirewall firewall add rule name="AutoBlock RDWeb $ip" dir=in action=block protocol=TCP localport=443 remoteip=$ip | Out-Null
} 

Tip: tieni una allowlist interna (sedi, ISP aziendale) per evitare di bloccarti da solo.

Hardening extra per RD Web

  • Cookie e sessione: riduci timeout della sessione RD Web, abilita flag Secure e HttpOnly.
  • TLS: disabilita protocolli/cipher deboli; prediligi TLS 1.2/1.3 (se compatibile con il tuo stack).
  • Header di sicurezza: Strict-Transport-Security, X-Content-Type-Options, Content-Security-Policy.
  • Log retention: conserva abbastanza giorni di Security + IIS per indagini (dipende dal volume).
  • WEF/SIEM: inoltra eventi 4624/4625 e log IIS a un collettore; crea regole di correlazione per username inesistenti e rate > soglia.

Tabella di riferimento: codici Status/SubStatus comuni

StatusSubStatusSignificatoAzione consigliata
0xC00000640x0Account inesistenteBlocco IP/rate‑limit; verifica se la lista utenti è stata esposta altrove.
0xC000006A0x0Password errataControlla se l’utente è legittimo; valuta lockout progressivo.
0xC000006D0xC0000064 o 0xC000006ACredenziali non valideCome sopra; incrocia con 4624 successivi per vedere se qualcuno indovina.
0xC00002340x0Account bloccatoRivedi le soglie lockout; verifica tentativi anomali per eventuale spray.

Best practice di pubblicazione

  • DNS dedicato per RD Web/RD Gateway, con certificati validi e OCSP stapling.
  • Separazione tra RD Web, RD Gateway e Session Host per isolare i rischi.
  • Monitoring: alert su picchi di 4625, su 401/403 in IIS e su errori duo bypass.

Conclusioni

Gli eventi 4625 senza IP su Windows Server 2016 RD Web non sono un vicolo cieco. Con audit esteso, log IIS ben configurati (c-ip + X-Forwarded-For), controlli Duo e – quando serve – una semplice cattura di rete, riuscirai a identificare l’origine dei tentativi e a tagliarli in modo mirato. La mitigazione più efficace resta però ridurre l’esposizione: RD Gateway/VPN, whitelist e rate‑limiting spengono il rumore di fondo e proteggono davvero le tue risorse RDS.


Procedura prescrittiva (passo‑passo) pronta all’uso

  1. Abilita audit Logon (Success/Failure) via GPO o auditpol.
  2. Abilita e arricchisci logging IIS (aggiungi X‑Forwarded‑For).
  3. Raccogli campioni per 15–30 minuti durante l’attacco.
  4. Estrai IP da 4625 (se presenti) e dai log IIS (c‑ip/XFF); incrocia con Duo.
  5. Blocca o whitelista su firewall/IIS; abilita Dynamic IP Restrictions.
  6. Indurisci: RD Gateway o VPN, lockout e aggiornamenti.

Riepilogo visivo: dove cercare l’IP

FonteChe IP troviQuando usarlaNote
Event 4624/4625IpAddress (se disponibile)Primo controlloSpesso vuoto su RD Web con proxy o fallimenti “early”.
IIS W3Cc-ip, X-Forwarded-ForSempreAbilita e conserva; incrocia con cs-username, sc-status.
DuoIP del clientCon 2FASpesso il più affidabile per la pre‑auth.
Capture di retePeer TCP/443In live incidentMostra l’IP reale indipendentemente dai log.

Template di comunicazione interna

Quando hai identificato la sorgente, usa un messaggio standard verso il team:

Oggetto: Tentativi falliti RD Web (Event 4625) — attribuzione e blocco
Periodo: 09:15–09:45 UTC
Username bersaglio: “recepsto”, vari
Origine: 198.51.100.23 (X‑Forwarded‑For), 10.0.0.5 (LB)
Azione: Blocco su FW perimetrale + Dynamic IP Restrictions abilitate; nessun 4624 correlato.
Follow‑up: Whitelist utenti, attivazione alert su >100 4625/5min.

Takeaway finali

  • Non fidarti di un’unica fonte log: Security + IIS + Duo + rete raccontano l’intera storia.
  • Blocca in fretta (host o perimetro), poi ottimizza (whitelist, rate‑limiting).
  • Prevenzione batte reazione: RD Gateway/VPN riducono drasticamente i 4625.

Con questi passaggi, trasformi un flusso confuso di 4625 senza IP in un flusso di lavoro ripetibile di individuazione e mitigazione degli attacchi a RD Web su Windows Server 2016.

Indice