Försvara din webbserver mot distribuerade Denial of Services (DDos) Attacks

I datasäkerhet blir det snabbt uppenbart att förhindrande av datorattacker är mycket mer utmanande än attackerande datorer. Ett bra exempel på en enkel teknik för att förhindra en webbplats från att fungera är en distribuerad nekad tjänst eller DDoS, ett angrepp där ett antal kompromissade datorer runt internet gör webbförfrågningar (eller andra protokoll) på någon dålig server. Om den begärda webbsidan är en som kräver mycket serverhantering, förhindrar den resulterande belastningen från de kombinerade förfrågningarna att webbservern svarar på legitima förfrågningar och därigenom nekar tjänsten. Som Tech-Recipes.com utsattes för en sådan attack nyligen, kände vi oss att det skulle vara till nytta för andra om vi beskrev de steg vi tog i vårt svar.


Obs! Följande information är relevant för UNIX-baserade servrar som kör Apache (även om andra plattformar och programvara kan vara tillämpliga). En förutsättning för detta tillvägagångssätt kräver användning av iptables som sannolikt innebär att du behöver root access till servern, så det här kommer nog inte hjälpa dig om du använder delad hosting. Förlåt! Din bästa satsning är att kontakta din Internetleverantör för deras hjälp (lycka till) eftersom det är i deras bästa intresse att förhindra höga belastningar på sina delade servrar, även om det är troligt att de tillfälligt kommer att inaktivera dina domän tjänster, vilket definitivt är inte den bästa lösningen ur ditt perspektiv.

För att minimera effekterna av en attack av denial of service, bör du göra dig medveten om problem med din webbserver i nära realtid. Flera serverövervakningstjänster finns tillgängliga. Vi använder både Pingdom och SiteUptime. Med hjälp av dessa tjänster har vi överflödiga meddelanden om eventuella serviceavbrott som skickas till våra mobiltelefoner via SMS och till flera e-postadresser (ingen av dem hanteras av våra övervakade servrar, förstås). Med hjälp av dessa tjänster meddelas vi inom en minut av en misslyckad begäran till våra produktionsservrar.

Innan du implementerar specifika anti-DDoS-tekniker eller söker hjälp från en DDos Protection-tjänst, är det klokt att se till att problemet är en DDoS-attack. Tjänsterna kan misslyckas med att svara på en förfrågan av ett antal skäl bland dem som körningen körs, och tjänsten dör oväntat, Internetleverantören värd servern som upplever ett nätverks- eller serveravbrott eller någon annan självkorrigeringsfel i matrisen. För att avgöra om tjänsten fel beror på en DDoS och att samla in information som krävs för att vidta åtgärder mot attacken måste du gräva runt först.

Du behöver tillgång till din access_log, loggfilen som innehåller en textinmatning för varje begäran som gjorts till din webbserver. Det finns många platser där den här filen kan gömma sig och det är beroende av din serverinställning. När du är i tvivel kan du kontrollera ISP: s dokumentation (sök efter åtkomstlogg) - loggdata kan vara tillgängliga via en webbkonsol, men det är optimalt om du har åtkomst till din server. Om din Internet-leverantörs onlinehjälp inte är så användbar för att hitta åtkomstloggen, kan du använda UNIX-find-kommandot.

När du har hittat din åtkomstlogg, cd in i katalogen som innehåller loggen och kör svanskommandot på den med -f-alternativet:

svans -f access_log

Svansen kommandot på egen hand visar de sista 10 raderna i den angivna filen och avslutar sedan. Alternativet -f kommer att berätta att svansen fortsätter att gå efter att de senaste 10 raderna visas och fortsätter att visa efterföljande rader som läggs till i filen. Du kommer sannolikt att se en flurry av poster. Om du inte ser några loggmeddelanden efter standard 10 tittar du antingen på fel fil eller webbservern är död eller annars inte ser någon trafik. Det är möjligt att en server kan vara värd för många webbplatser och var och en kan ha en separat access_log-fil, så var säker på att du misshandlar den rätta. Om tjänsten är död, återuppliva den genom vilken mekanism som helst. Vi kommer att anta härifrån att du ser ett ton av åtkomstloggmeddelanden som ser väldigt liknande ut (troligen slår samma webbadress) som inte har en giltig eller någon hänvisning (om hänvisningen är slashdot.org eller digg.com, ja då kan du vara både glad och ledsen att trafiken, trots att serveren är förkrossad, är legitim) och har en massa olika IP-adresser. Under vår senaste belejring fanns det så många falska begär att mycket få legitima förfrågningar gjorde det till access_log-filen. Här är några rader från vår access_log under attacken:

220.255.7.204 - - [07 / jul / 2008: 19: 28: 18 -0700] "GET /modules.php?name=Forums&file=index HTTP / 1.1" 200 0 "-" "Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

220.255.7.209 - - [07 / Jul / 2008: 19: 28: 18 -0700] "GET /modules.php?name=Forums&file=index HTTP / 1.1" 200 0 "-" "Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

220.255.7.208 - - [07 / Jul / 2008: 19: 28: 18 -0700] "GET /modules.php?name=Forums&file=index HTTP / 1.1" 200 0 "-" "Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

71.232.78.53 - - [07 / jul / 2008: 19: 28: 19 -0700] "GET /modules.php?name=Forums&file=index HTTP / 1.1" 200 14313 "-" "Mozilla / 4.0 (kompatibel; MSIE 7.0 ; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727) "

Om du inte är bekant med standardstrukturen för Apache's access_log är det första värdet källans IP-adress för begäran, då är datum och tid för begäran i kvadratparentes och den första strängen i dubbla citat är HTTP-förfrågan tillverkad. I vårt exempel var förfrågan alltid densamma: "GET / modules.php?name=Forums&file=index HTTP / 1.1" - en GET-begäran från webbadressen (/modules.php?....) Och det HTTP-protokoll som används (1.1 ).Den del av webbadressen som används är viktig eftersom det är den enda vi kan använda för att identifiera de förekommande IP-adresserna. Den andra strängen i citat är referensadressen, i vårt fall finns det inte en så visas det som "-" vilket ger credence till misstanken att det är en DDoS-attack. Den återstående strängen beskriver plattformen och mjukvaran som har gjort förfrågan och är inte så meningsfull eller hjälpsam för oss som det lätt kan smides.

Nu när vi vet att det finns en DDoS-attack pågår, behöver vi en lista över de IP-adresser som är involverade i attacken för att blockera deras efterföljande förfrågningar med iptables. I exemplet access_log ovan vet jag att den begärda URL-komponenten "/modules.php?name=Forums&file=index" kan användas för att söka igenom access_log. Eftersom det innehåller specialtecken som & och? som de flesta UNIX-skal tolkar som något helt annat, är det en bra idé att sätta söksträngen i dubbla citat i alla kommandon som använder den. Följande kommando tar bara de raderna i access_log som matchar URL-komponenten ovan och kommer att returnera en lista över IP-adresser som begärde det och en räkning av hur många gånger varje IP-adress gjorde begäran, sorterad efter räkningen.

fgrep "/modules.php?name=Forums&file=index" access_log | cut -d \ -f1 | sortera -n | uniq -c | sortera -rn

Fgrep-kommandot är ett snabbt grep som inte letar efter reguljära uttryck och kan riva genom stora loggfiler mycket mer effektivt. Om ditt system inte har det för någon ofattbar anledning, ersätter planen gammal grep för fgrep. Byt namn på din åtkomstlogg om det är annorlunda än access_log. Observera att det finns två mellanslag efter backslashen i cut -d \ -alternativet. Denna sträng kommandon kommer att dra ut matchande rader i access_log (fgrep), extrahera det första fältet separerat med mellanslag (klipp), sortera dem numeriskt (sort -n), gruppera dem för att göra en lista med unika IP-adresser och räkna händelserna (uniq) och sortera dem numeriskt i omvänd ordning så att IP-adresserna med högsta antal kommer först. Här är ett exempel på utgången:

21889 71.232.78.53
17181 220.255.7.208
16162 220.255.7.209
16142 220.255.7.204

Du kommer sannolikt att se två grupper, vissa IP-adresser med ett stort antal (hundratals, tusentals) begäranden och några med bara några, kanske tiotals begäranden. När du väljer antalet förfrågningar som skiljer de två grupperna, var försiktig eftersom du inte vill blockera legitima förfrågningar. Chanserna är när du börjar blockera IP-adresser från toppen av listan, du vet när siffrorna ändras och blir legitima, uppenbara värden, som ett hopp från många hundra träffar till några tiotals träffar. Om du kan kan du kopiera utmatningen från kommandot ovan till någon form av textredigerare för att hålla dig till hands. En anteckning, om din access_log inte roteras ofta (dess innehåll kopieras till en annan plats och eventuellt komprimerad) kan det bli enormt. Du kan använda kommandot svans på ett annat sätt så att den här kommandot körs snabbare, vilket din trojdade server sannolikt kommer att uppskatta - kommandot "svans -10000 access_log" tar de sista 10 000 raderna från access_log och fortsätter bearbeta dem (du kan ändra 10000 till ett antal av dina önskemål):

svans -10000 access_log | fgrep "/modules.php?name=Forums&file=index" | cut -d \ -f1 | sortera -n | uniq -c | sortera -rn

Nu när du är beväpnad med kunskapen om vilken IP-adress du behöver blockera är det dags att lägga ner den iptable lagen. Iptables-systemet kan hantera många olika operationer och lyckligtvis för oss är blockering av en enda IP-adress en av de enklare konfigurationerna. För att blockera alla förfrågningar från en IP-adress som 71.232.78.53, använd kommandot:

iptables -A INPUT -s 71.232.78.53 -j DROP

Om du inte är inloggad på servern som root, lägg bara till en "sudo" framför det här kommandot och ge ditt lösenord när du blir ombedd. Detta kommando lägger till en tillfällig regel i iptables-systemet för att släppa alla paket som kommer från den angivna IP-adressen. Denna effekt är tillfällig eftersom den inte kommer att fortsätta efter en omstart. Om du vill göra dessa ändringar permanenta (förmodligen inte en bra idé, men inte så illa heller, om du planerar att starta om omedelbart för att befria ett läckt minne) kan du försöka springa

/etc/init.d/iptables spara

Detta kommando kommer antingen att fungera och låta dig veta att det fungerade eller kommer att fel. I det senare fallet kan du upprepa kommandona iptables, en per IP-adress, för att återupplösa dem.

Om du har förfrågningar som kommer från ett antal IP-adresser inom samma delnät kan du blockera delnätet i ett iptables-kommando. I vårt fall hade vi en massa IP-adresser från de 220.255.7.0 begärda subnätverken. I stället för att upprepa kommandot iptables ett par hundra gånger, gör subnet-shorthand för kommandot iptables den här uppgiften mycket enklare:

iptables -A INPUT -s 220.255.7.0/24 -j DROP

Jag skulle inte blockera mer än ett klass C-undernät i taget, som visas ovan. I huvudsak om du ser en massa begäranden från IP-adresser där de tre första siffrorna i IP-adressen är desamma, är de alla i samma C-delnät och du kan blockera dem alla med de tre första separata numren följt av en .0 / 24 som ovan.

Eftersom en DDoS-attack kan vara igång och fler maskiner kan delta i attacken över tid, kan det vara värt din ansträngning att göra ett snabbt manus för att bara blockera en IP-adress. Jag skrev följande skript och placerade det i / usr / sbin / block

#! / Bin / bash

iptables -A INPUT -s $ 1 -j DROP

När filen är på plats, gör den körbar med chmod + x / usr / sbin / block och använd sedan den som:

block 71.232.78.53

Varje system är unikt, har olika applikationer och versioner av program installerade på olika platser, så körsträckan kan variera med instruktionerna ovan.