Incidència #5565
tancatAtac xinès, possiblement CVE-2019-9517, gener del 2020
Descripció
El DDD ha estat víctima d'un atac DDoS a partir del dia 2 de gener d'enguany. L'atac sembla continuar, però de moment hem pogut restablir l'accés públic al DDD. En aquest correu us explico què hem provat, què ha funcionat i què no, amb l'objectiu que en pugueu aprendre alguna cosa.
Des de fa anys (juny del 2012) tenim un sistema molt senzill de prevenció d'atacs, que fins ara ens havia servit prou bé. Es tracta d'un shell script que, cada 5 minuts, compta quants processos d'Apache hi ha executant-se. Si n'hi ha més d'un màxim n (nosaltres ho teniem a 300), reinicia el servidor, i ens envia un correu als administradors. Aquesta tècnica la vam posar en marxa a l'època de l'atac del Slow Loris:
https://en.wikipedia.org/wiki/Slowloris_(computer_security)
A partir del 2 de gener, però, aquest reinci d'Apache va ser constant. Cada 5 minuts es reiniciava l'Apache, durant tot el dia i tota la nit. Fer ús del DDD, i dels altres serveis que utilitzen el mateix Apache (4 en total) era pràcticament impossible.
A partir de mirar l'origen de les adreces via GeoIP i comprovant que moltíssimes venien de la Xina, i veient que moltes anaven a la pàgina de login del DDD (https://ddd.uab.cat/youraccount/login), inicialment vaig restringir l'accés a aquesta pàgina per GeoIP si venien de la Xina. No havent-n'hi prou, després ho vaig restringir a la cerca, i com que no funcionava, vaig restringir l'ús de l'aplicació Invenio a tota la Xina (els pdfs i altres documents estàtics sí, perquè en el nostre cas els serveix directament Apache). Però no va ser suficient.
Va ser molt il·lustratiu graficar els accessos i veure que, per exemple, just el desembre l'any passat, amb les mateixes versions de software de tot el sistma, vam rebre un allau molt més gran d'uns atacs procedents d'Alemanya, amb més de 8 milions d'accesos a la pàgina https://ddd.uab.cat/youraccount/login, i només en quatre dies, i no haviem rebut pas alertes del sistema avisant que es reinciés Apache:
https://ddd.uab.cat/accessos/2019/access_a2019m12_geoip.svg
L'abast del que ens està arribant de la Xina aquest mes de gener és molt menor. Aquest gràfic s'actualitza cada hora:
https://ddd.uab.cat/accessos/2020/access_a2020m1_geoip.svg
Però en canvi, el sistema no aguantava. Afortunadament, semblava que la solució podria consistir (només) amb actualitzar la versió d'Apache a la 2.4.41, que ja n'hi ha una de preparada per a Debian 10 (Buster):
https://packages.debian.org/apache2
Perquè, pel que sembla, aquesta 2.4.41 té un missatge que podria correspondre's al que ens està passant: relativament poques peticions, però que ens col·lapsen:
http://www.apache.org/dist/httpd/CHANGES_2.4.41
*) SECURITY: CVE-2019-9517 (cve.mitre.org)
mod_http2: a malicious client could perform a DoS attack by flooding
a connection with requests and basically never reading responses
on the TCP connection. Depending on h2 worker dimensioning, it was
possible to block those with relatively few connections. [Stefan Eissing]
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9517
És a dir, una variació del Slow Loris, però per http2 i ip6.
Inicialment semblava que aquesta actualització, a més de pujar el valor de MaxKeepAliveRequests del 100 que venia per defecte a 200, era suficient: el nombre de processos d'Apache ha baixava dels 300 habituals a 150-250, però amb canvis molt dinàmics; per tant, semblava ser un paràmetre molt rellevant.
Després d'unes hores que semblava amainar, ahir al migdia la situació tornava al començament: reinicis molt sovintejats d'Apache, menys que abans de l'actualització, però clarament la solució no va ser suficient.
Per continuar el diagòstic, vaig crear una llista de les adreces IP que van les darreres 1000 peticions al DDD, ordenades per països i número IP. S'actualitza cada minut:
https://ddd.uab.cat/accessos/2020/access_a2020_actual.txt
Estudiant l'origen d'aquests accessos i les peticions que fan, hem pogut confirmar que, efectivament, es tracta d'un atac de denegació de servei distribuit, i amb origen la Xina. Distribuit perquè són més de 100.000 adreces IP (a hores d'ara, 123.881) que accedeixen al DDD des de tota la Xina, i cadascuna d'aquestes adreces només fa una única petició.
FJ Actualitzat per Ferran Jorba fa aproximadament 6 anys
- S'ha actualitzat Descripció (diferències)
FJ Actualitzat per Ferran Jorba fa aproximadament 6 anys
Entenent millor la naturalesa de l'atac, que consisteix en fer peticions de recursos però no alliberar-los (és a dir, com no penjar el telèfon i mantenir la línia ocupada), el dia 4 de gener vaig canviar el valor de timeout, dels 300 segons per defecte a 30, de manera que la línia quedi alliberada abans, en mig minut en comptes de 5 minuts. Sembla ser raonablement efectiu. No he detectat que perjudiqui el funcionament del DDD, perquè pràcticament sempre (quan funciona bé) respon molt abans d'aquests 30 segons.
FJ Actualitzat per Ferran Jorba fa aproximadament 6 anys
L'equip de producció va suggerir-nos un altre solució: el mòdul reqtimeout, estàndard d'Apache.
https://httpd.apache.org/docs/2.4/mod/mod_reqtimeout.html
Aquest mòdul el teníem ja activat a Mompou, perquè Debian l'activa per defecte, però després de fer diferents proves, van arribar a la conclusió que millor canviar-los:
# the time a browser may need to fetch the CRL for the certificate. If
# the CRL server is not reachable, it may take more than 10 seconds
# until the browser gives up.
- RequestReadTimeout header=20-40,minrate=500
+ RequestReadTimeout header=10-30,minrate=1000
# Wait max 10 seconds for the first byte of the request body (if any)
# From then, require a minimum data rate of 500 bytes/s
- RequestReadTimeout body=10,minrate=500
+ RequestReadTimeout body=10-30,minrate=1000
El tenim activat amb aquests canvis des de dissabte 11 de gener, i sembla que funciona. És massa aviat per saber si els atacs xinesos han acabat perquè ja ho tenien previst, o que aquesta defensa és efectiva.
Sigui com sigui, incialment em el timeout genèric i ara amb aquest mod_reqtimeout, com a mínim el DDD respon i s'hi pot treballar.
FJ Actualitzat per Ferran Jorba fa aproximadament 6 anys
- Estat ha canviat de Creada a Tancada
Com que les solucions semblen funcionar, crec que podem tancar aquesta incidència.
FJ Actualitzat per Ferran Jorba fa més d'un any
- S'ha afegit relacionat amb Incidència #8740: DDD - Allau de peticions des d'una adreça IP