Aktívny firewall pre vaše webové aplikácie

Aktívny firewall pre vaše webové aplikácie 
Elektrolab Autor  Elektrolab
  239 zobrazení
1
 0
Počítače a...
 Fórum

V dnešnej dobe je ochrana webovej aplikácie pred podozrivými IP adresami, útokmi typu bruteforce, pokusmi o skenovanie zraniteľností alebo prístupmi z rizikových krajín absolútnou nevyhnutnosťou. Každá požiadavka od neznámeho návštevníka môže v sebe skrývať pokus o útok, či už ide o botnet, skript či VPN adresu zo známej útočnej siete.

Tento článok vás prevedie krok za krokom vytvorením jednoduchého, ale veľmi účinného aktívneho firewallu v PHP, ktorý funguje bez nutnosti používať Composer, databázu či akýkoľvek framework. Výhodou je jeho autonómnosť a rýchlosť nasadenia – vložíte jeden skript, zavoláte ho z úvodného PHP súboru a máte aktívnu prvú líniu ochrany. Nevýhodou môže byť, že firewall neposkytuje vizuálne rozhranie ani štatistiky či grafy – všetko je čistý kód, ideálny pre vývojárov, ktorí chcú mať veci pod kontrolou.

Čo je aktívny firewall?

Na rozdiel od pasívneho riešenia, ako je napríklad jednoduché logovanie IP adries alebo blokovanie pomocou statického súboru .htaccess, aktívny firewall vykonáva dynamické kontroly nad každou požiadavkou v reálnom čase. Znamená to, že ihneď po tom, ako návštevník vstúpi na stránku, sa jeho IP adresa vyhodnotí prostredníctvom série kontroných mechanizmovl:

  • overí sa, či sa IP nachádza vo vnútornom blacklist súbore,
  • zisťuje sa krajina pôvodu IP adresy cez GeoIP API,
  • následne sa IP adresa skontroluje cez AbuseIPDB, aby sa zistila jej reputácia (napr. či ide o známu útočiacu adresu, VPN, TOR výstupný uzol atď.),
  • a podľa výsledkov týchto kontrol sa rozhodne, či bude prístup povolený alebo zablokovaný.

Tieto kontroly prebiehajú okamžite počas spracovania každej požiadavky, ešte predtým, než sa načíta samotný obsah stránky alebo framework. To znamená, že ak IP adresa návštevníka nevyhovuje bezpečnostným kritériám (je na blackliste, pochádza z blokovanej krajiny alebo má vysoké skóre na AbuseIPDB), firewall okamžite ukončí spracovanie požiadavky a zobrazí chybovú hlášku 403. Vďaka tomu sa kódy aplikácie vôbec nespustia, čím sa šetria systémové zdroje a znižuje riziko útoku. Tento prístup zabezpečuje, že aplikácia reaguje flexibilne a aktuálne – akonáhle sa IP dostane na blacklist, firewall ju pri ďalšom pokuse zablokuje bez meškania.

Štruktúra firewallu

Skript sa skladá z nasledujúcich krokov:

  1. Načítanie IP adresy
  2. Kontrola vo vlastnom zozname blokovaných IP
  3. Overenie krajiny pôvodu cez GeoIP API (napr. ipapi.co)
  4. Overenie reputácie IP cez AbuseIPDB API
  5. Cacheovanie odpovedí pre šetrenie dotazov
  6. Automatické čistenie starej cache

Kód firewallu

Firewall je napísaný ako autonómny PHP skript s názvom firewall.php, ktorý funguje nezávisle od frameworku. Najčastejšie sa umiestni do priečinka public/ alebo priamo do rootu webovej aplikácie (napr. v Laravel projektoch, alebo iných PHP projektoch). Na to, aby bol firewall aktívny, je potrebné ho načítať čo najskôr v procese spracovania požiadavky. To znamená, že do všetkých hlavných vstupných bodov aplikácie (napr. index.php, alebo iný súbor, ktorý sa vykonáva ako prvý pri každom načítaní stránky) je potrebné pridať nasledujúci riadok hneď na začiatok súboru:

require __DIR__ . '/firewall.php'; // Volanie ma firewall.php je v subore index.php v roote

Kód firewallu po častiach:

Nižšie si rozoberieme celý firewall krok za krokom, aby ste presne vedeli, čo ktorá časť robí a ako funguje.

1. Získanie IP adresy

$ip = $_SERVER['REMOTE_ADDR'];

Táto premenná uloží IP adresu aktuálneho návštevníka. Bude sa používať pri všetkých ďalších kontrolách.

2. Zoznam blokovaných krajín a nastavenie API

$blocked_countries = ['RU'];
$abuse_api_key = 'TVOJ_KLUC';
$abuse_cache_file = __DIR__ . '/abuse_cache.json';

Tu definujeme, ktoré krajiny sú automaticky blokované (napr. Rusko), zadáme náš API kľúč pre AbuseIPDB a cestu k súboru, kde sa budú ukladať cacheované výsledky. Skratky štátov sa zadávajú pomocou štandardu ISO 3166-1 alpha-2 codes, ktorý je uvedený v tejto tabuľke - klikni. Pokiaľ chcete zadať viac štátov, reťazec vyzerá takto: $blocked_countries = ['RU', 'CN', 'IR', 'KP']; // Rusko, Čína, Irán, Severná Kórea . Reťazec $abuse_cache_file = __DIR__ . '/abuse_cache.json';  má na starosti určenie cesty k súboru, kde sa ukladá cache z API služby AbuseIPDB. 

3. GeoIP kontrola

$geo = json_decode(file_get_contents("https://ipapi.co/{$ip}/json/"), true);
if (in_array($geo['country'] ?? '', $blocked_countries)) {
    deny("Blokovaná krajina");
}

Tu sa IP adresa posiela na bezplatné GeoIP API ipapi.co, ktoré vráti krajinu pôvodu IP. Ak sa krajina nachádza v zozname zakázaných krajín, prístup sa okamžite zamietne a zobrazí sa Blokovaná krajina

4. Načítanie a čistenie cache

$cache = file_exists($abuse_cache_file) ? json_decode(file_get_contents($abuse_cache_file), true) : [];
$now = time();
foreach ($cache as $cached_ip => $entry) {
    if (($now - $entry['timestamp']) > 172800) unset($cache[$cached_ip]);
}

Ak už súbor abuse_cache.json existuje, načítame ho do poľa $cache. Pre každú IP v cache overíme, či jej záznam nie je starší ako 2 dni (172800 sekúnd). Ak je, záznam vymažeme. To pomáha udržiavať cache čistú a relevantnú, čím sa zbytočne súbor nezväčšuje.

5. Dotaz na AbuseIPDB, ak IP nie je v cache

if (!isset($cache[$ip])) {
    $response = file_get_contents("https://api.abuseipdb.com/api/v2/check?ipAddress=$ip", false, stream_context_create([
        'http' => [
            'header' => [
                "Key: $abuse_api_key",
                "Accept: application/json"
            ]
        ]
    ]));
    $data = json_decode($response, true);
    $score = $data['data']['abuseConfidenceScore'] ?? 0;
    $cache[$ip] = ['score' => $score, 'timestamp' => $now];
    file_put_contents($abuse_cache_file, json_encode($cache));
}

Ak IP adresa nie je v cache, odošle sa dotaz na AbuseIPDB API a z odpovede sa získa tzv. „abuse confidence score“ (dôveryhodnosť IP). Tento údaj sa uloží do cache spolu s aktuálnym časom.

Príklad zápisu IP adresa 139.59.234.203 (Singapore), skóre score": 54 čo je síce pomerne vysoké, ale nie až tak, aby to spustilo mechanizmus blokovania prístupu, nakoľko ten je nastavený na hodnotu 75. Hodnota timestamp (časová pečiatka) "timestamp": 1744878967 zodpovedá dátumu a času 17. máj 2025 o 12:36:07 UTC, ktorý je uvedený v systéme UNIX timestamp čo je jednoducho celé číslo, ktoré predstavuje počet sekúnd, ktoré uplynuli od 1. januára 1970 o 00:00:00 UTC – tzv. „epoch“.

    "139.59.234.203": {
        "score": 54,
        "timestamp": 1744878967
    },

6. Posledná kontrola skóre a zablokovanie

if ($cache[$ip]['score'] >= 75) {
    deny("Vysoké AbuseIPDB skóre");
}

Ak skóre IP adresy je vyššie alebo rovné 75 (hodnota si môžete upraviť podľa potreby), prístup sa zablokuje.

7. Funkcia deny()

Táto funkcia by mala byť definovaná v skripte a jej cieľom je okamžite prerušiť načítavanie stránky a zobraziť chybovú správu:

function deny($reason = '403 – Prístup zamietnutý.') {
    header('HTTP/1.1 403 Forbidden');
    echo "<h1>403 Forbidden</h1><p style='font-family: sans-serif;'>$reason</p>";
    exit;
}

Registrácia AbuseIPDB

Tento účet potrebujeme pre napojenie na databátu IP adries, s ktorou bude pracovať náš firewall. Registrácia je jednoduchá, takže poďme na to.

  • Registrácia: https://www.abuseipdb.com/register
  • Po registrácii získate Basic API key (1000 req/deň)
  • Navýšenie limitu na 5000 req/deň je možné po potvrdení vlastníctva domény pomocou pridania meta tagu (najrýchlejšie) alebo TXT záznamu DNS

ElektroLab

API kľúč si vygeberujete v záložke "API" kliknutím na "Create Key". Najskúr si kľúč pomenujte.

ElektroLab

Vygenerovaný kľúč sa vám zobrazí v karte "Keys"

Overenie domény

Teraz si overíme vašu doménu, čo je dôležuté z toho dôvodu, že sa vám po úspešnom overení navýši denný limi na počet requestov. Urobíme tak v štyroch krokoch.

  1. Overenie pomocou META značky
  2. Overenie pomocou HTML súboru
  3. Pridanie domény
  4. Pridanie bannera zo spätným odkazom na vaše stránky

1. Meta značka

Prvý je pridanie META značky do vášho zdrojového kódu. Meta značku nájdete na karte "Webmasters". Značku si vykopírujete a vložíte. V mojom prípade, keďže mám Laravel je to súbor šablóny blade, konkrétne /web/resources/views/layouts/master.blade.php. Až pridáte Meta značku, kliknite na tlačidlo pre overenie jej vloženia. Ak prebehla kontrola úspešne, stránka o tom podá informáciu. Príklad meta tagu pre overenie:

<meta name="abuseipdb-verification" content="TVOJ_KOD">

2. HTML súbor

Ďalšim overením, je overenie domény, čo je jednoduché, pokiaľ budete overovať pomocou HTML súboru. Ten si stiahnete a jednoducho ho vložíte do rootu vašej stránky (tam, kde máte súbor index.php). Následne kliknete opäť na overenie. Stránka tak isto podá o tom informáciu. Hotovo a denný limit sa vám automaticky navýši z 1000 requestov pri registrácii na 3000.

ElektroLab

Overenie vlastníctva domény

3. Pridanie domény

Pridajte si vašu doménu, ktorú budete používať s firewallom. Doménu môžete pridať v karte "Webmasters". Pokiaľ si pridáte doménu, záskate zdarma ďalších 2000 requestov.

ElektroLab

Pridajte si doménu, ktorá bude použitá pre váš Firewall.

4. Pridanie bannera zo spätným odkazom na vaše stránky

Ďalšou možnosťou ako získať 2000 requestou zdarma je pridať spätný odkaz na stránku abuseipdb vo forme HTML bannera s trackimgom. Banner / spätný odkaz je na karte "Contributor Badge", kde si môžete prispôsobiť jeho veľkosť, vzhľad a čiastočne aj farbu. Pozor! V kóde bannera nič nemeňte! Až si pridáte banner na stránku - je jedno kde. Pozor! 2000 requestov záskate k spätnému odkazu iba vtedy, ak si k projektu priradíte aj doménu!

Integrácia firewallu

Ako na to? Jednoducho.

Ako integrovať firewall do Laravelu alebo inej PHP aplikácie

Umiestni súbor firewall.php do adresára public/ alebo root adresára aplikácie. Otvor súbor index.php a na jeho  začiatok pridaj:

require __DIR__ . '/firewall.php';

Vytvor prázdny súbor na FTP a pomenuj ho abuse_cache.json. Otvor ho a vlož doň {} Do neho sa budú ukladať všetky IP adresy, ktoré navštívili tvojú webovú aplikáciu. Ďalej vytvor TXT súbor a pomenuj ho blocked_ips.txt. Sem môžeš ručne pridávať známe IP adresy ručne (každú na jeden riadok), ktoré chceš permanentne blokovať.

{
    "XXX.XXX.113.77": {
        "score": 0,
        "timestamp": 1744807155
    },
    "XXX.XXX.0.2": {
        "score": 0,
        "timestamp": 1744807155
    },
    "XXX.XXX.102.176": {
        "score": 0,
        "timestamp": 1744807157
    },
    "XXX.XXX.0.17": {
        "score": 0,
        "timestamp": 1744807159
    },
    "XXX.XXX.137.79": {
        "score": 3,
        "timestamp": 1744807161
}

Detail uložených IP adries v abuse_cache.json

Uisti sa, že sa skript spúšťa čo najskôr, ešte pred načítaním hlavného kódu aplikácie alebo frameworku. To platí nielen pre Laravel, ale pre akýkoľvek PHP systém alebo CMS (napr. WordPress, Joomla, vlastné CMS). Hlavným cieľom je zabezpečiť, aby sa firewall spustil pred spracovaním akejkoľvek požiadavky alebo načítaním šablón, čím sa maximalizuje jeho ochranná funkcia.

Kompletný kód firewallu

Vytvor si PHP súbor, napríklad cez pspad, alebo iný editor kódiu a vlož doň nasledujúci kód. Jediný údaj, ktorý sa v ňom bude dopĺňať je API key, ktorý získaš podľa návodu vyššie. Až bude vložený, súbor ulož a pomenuj ho firewall.php. Súbor ulož a nakopíruj ho do rootu svojho FTP. No a to je všetko. Ak si správne vložil require __DIR__ . '/firewall.php'; do index.php firewal sa automaticky spustí, čo zistíš na stránke abuseipdb.com v karte API, že je zaznamenaná aktivita  a zároveň v súbore abuse_cache.json že sa doň zaznamenávajú IP adresy.

<?php
// ============ FIREWALL ============
// Volanie ma firewall.php je v subore index.php v roote
// === NASTAVENIE ===
$blocked_countries = ['RU']; // Pridaj dalšie podla potreby a oddeľ ich čiarkou
$blocked_ips_file = __DIR__ . '/blocked_ips.txt';
$abuse_cache_file = __DIR__ . '/abuse_cache.json';
$abuse_api_key = 'API KEY'; // vlož svoj AbuseIPDB API key
$abuse_score_threshold =75;  // skóre, od ktorého zablokovat. 100 je max. pre dobrý výsledok je vhodné použit 75
$cache_lifetime = 86400; // 24 hodín v sekundách

// === ZÍSKAJ IP ===
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';

// === BLOKOVANIE PODLA IP ZO ZOZNAMU ===
$blocked_ips = file_exists($blocked_ips_file)
    ? file($blocked_ips_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
    : [];

if (in_array($ip, $blocked_ips)) {
    deny("Prístup zablokovaný – IP je na blacklist-e.");
}

// === GEOLOKÁCIA – ipapi.co ===
$geo = @json_decode(file_get_contents("https://ipapi.co/{$ip}/json/"), true);
$country_code = $geo['country'] ?? null;

if (in_array($country_code, $blocked_countries)) {
    deny("Prístup z krajiny $country_code je zablokovaný.");
}

// === ABUSEIPDB S CACHE ===
$abuse_cache = file_exists($abuse_cache_file)
    ? json_decode(file_get_contents($abuse_cache_file), true)
    : [];
// === Vycistenie cache od záznamov starších ako 2 dni ===
$now = time();
$cleaned = false;

foreach ($abuse_cache as $cached_ip => $entry) {
    if (!isset($entry['timestamp']) || ($now - $entry['timestamp']) > 172800) {
        unset($abuse_cache[$cached_ip]);
        $cleaned = true;
    }
}

if ($cleaned) {
    file_put_contents($abuse_cache_file, json_encode($abuse_cache, JSON_PRETTY_PRINT));
}


// Ak je IP v cache a neexpirovala:
if (isset($abuse_cache[$ip]) && (time() - $abuse_cache[$ip]['timestamp']) < $cache_lifetime) {
    $score = $abuse_cache[$ip]['score'];
} else {
// Over IP cez AbuseIPDB API
    $opts = [
        'http' => [
            'method' => 'GET',
            'header' => [
                "Key: $abuse_api_key",
                "Accept: application/json"
            ]
        ]
    ];
    $context = stream_context_create($opts);
    $abuse_url = "https://api.abuseipdb.com/api/v2/check?ipAddress={$ip}&maxAgeInDays=30&verbose=true";
    $response = @file_get_contents($abuse_url, false, $context);
    $data = json_decode($response, true);
    $score = $data['data']['abuseConfidenceScore'] ?? 0;

// Uložit do cache
    $abuse_cache[$ip] = [
        'score' => $score,
        'timestamp' => time()
    ];
    file_put_contents($abuse_cache_file, json_encode($abuse_cache, JSON_PRETTY_PRINT));
}

// Blokuj ak je skóre vysoké
if ($score >= $abuse_score_threshold) {
    deny("Zablokované: IP má skóre $score v AbuseIPDB.");
}

// === BLOKOVACIA FUNKCIA ===
function deny($reason = '403 – Prístup zamietnutý.') {
    header('HTTP/1.1 403 Forbidden');
    echo "<h1>403 Forbidden</h1><p style='font-family: sans-serif;'>$reason</p>";
    exit;
}

// === Ak je skóre vyššie ako povolené, zablokuj ===
if ($score >= $abuse_score_threshold) {
    deny("Zablokované: IP má vysoké skóre (" . $score . ") v AbuseIPDB.");
}

Testujeme funkčnosť

1. Blokovanie podľa krajiny (GeoIP test)

Dočasne v kóde firewall.php nastav:

$blocked_countries = ['SK']; // alebo CZ, podľa tvojej IP

Otvor si stránku normálne z prehliadača → Výsledok: 403 Forbidden = firewall funguje správne. Potom vráť späť pôvodnú hodnotu napr. ['RU']

2. Simulácia falošnej IP a krajiny (test v kóde)

Dočasne nahraď reálne hodnoty vlastnými, napríklad:

$ip = '1.2.3.4';
$geo = ['country' => 'RU'];

Vypni API volanie file_get_contents(...) a nechaj len túto hodnotu a uvidíš, či skript spracuje blokovanie podľa tejto „simulovanej“ IP/krajiny.

3. Testovanie AbuseIPDB blokovania

Vlož IP adresu 218.92.0.218. Táto adresa má aktuálne skŕe 100% Info o nej nájdeš na  AbuseIPDB - klikni:

$ip = 'vloz_tu_skodlivu_IP';
$cache[$ip] = ['score' => 85, 'timestamp' => time()];

Načítaj stránku – mala by ťa zablokovať.

4. Vlastná IP ako blacklist (manuálna simulácia)

Ak si chceš overiť, že firewall správne blokuje IP adresy podľa reputačného skóre, môžeš svoju vlastnú IP adresu manuálne pridať do súboru abuse_cache.json s vysokým skóre. Napríklad:

{
  "MOJA.IP.ADRESA": {
    "score": 90,
    "timestamp": 1744878967
  }
}

Následne si načítaj stránku z tejto IP (tvoja) → Ak dostaneš 403, funguje to.

Po úspešnom otestovaní, vráť samozrejme hodnoty na pôvodné nastavenia.

Zhrnutie

Vytvorený firewall je jednoduchý, šikovný a dokáže reálne chrániť tvoju aplikáciu pred podozrivými prístupmi, ktoré sú zaznamenané v databázach:

  • žiadny Composer ani zložitá inštalácia
  • žiadna databáza
  • funguje ako autonómny PHP skript
  • šetrí API dotazy cez caching

Napriek svojej funkčnosti má tento firewall extrémne malú veľkosť – len približne 3,2 kB. To znamená, že ho môžete bez obáv integrovať do akejkoľvek stránky bez toho, aby to malo akýkoľvek negatívny dopad na jej rýchlosť či výkon. Skript sa načíta okamžite, nezdržuje server a nezvyšuje veľkosť prenášaných dát. Jeho výhodou je skritá prevádzaka a prakticky neviditeľnosť. Pokiaľ sa Vám post páčil a plánujete nasadenie firewallu aj na svojej stránke a nie je vánn niečo jasné - pýtajte sa

Celý kód pre firewallu vrátane súborov abuse_cache.json a  blocked_ips.txt si môžete stiahnúť kliknutím na tlačidlo Firewall.zip v.1.0.0

Aktualizácia

Na základe spätnej väzby a ďalšieho vývoja firewallu som pridal nové funkcie, ktoré zvyšujú jeho bezpečnostný potenciál a automatizáciu:

1. Automatické nahlasovanie škodlivých IP adries do AbuseIPDB

Firewall teraz pri detekcii IP adresy s vysokým skóre automaticky nahlási túto IP do databázy AbuseIPDB, čím prispieva ku kolektívnej ochrane pred útokmi.

Pridaný kód:

Volanie reportovacej funkcie pri detekcii nebezpečnej IP:

if ($score >= $abuse_score_threshold) {
    report_to_abuseipdb($ip, '5,11,14,18,21,22', 'Automaticky detekovaná škodlivá IP firewallom');
    deny("Zablokované: IP má skóre $score v AbuseIPDB.");
}

Funkcia na odoslanie IP adresy do AbuseIPDB:

function report_to_abuseipdb($ip, $categories, $comment) {
    global $abuse_api_key;

    $data = http_build_query([
        'ip' => $ip,
        'categories' => $categories,
        'comment' => $comment
    ]);

    $opts = [
        'http' => [
            'method'  => 'POST',
            'header'  => [
                "Key: $abuse_api_key",
                "Content-Type: application/x-www-form-urlencoded",
                "Accept: application/json"
            ],
            'content' => $data
        ]
    ];

    $context  = stream_context_create($opts);
    @file_get_contents("https://api.abuseipdb.com/api/v2/report", false, $context);
}

Kategórie nahlasovaných útokov zahŕňajú:

  • Brute-force
  • DDoS
  • Hacking
  • Web App útoky
  • Port scanning
  • SSH útoky

Tieto hodnoty sú odosielané ako kódované čísla v parametroch API. Kompletný prehľad kategórií nájdete tu - klikni

Celý kód pre firewallu aj s úpravou reportovania vrátane súborov abuse_cache.json a  blocked_ips.txt si môžete stiahnúť kliknutím na tlačidlo Firewall.zip v.1.0.1

Máte aj vy zaujímavú konštrukciu, alebo článok?

Máte aj vy zaujímavú konštrukciu, alebo článok a chceli by ste sa o to podeliť s viac ako 360.000 čitateľmi? Tak neváhajte a dajte nám vedieť, radi ju uverejníme a to vrátane obrazových a video príloh. Rovnako uvítame aj autorov teoretických článkov, či autorov zaujímavých videí z oblasti elektroniky / elektrotechniky.

Kontaktujte nás!

ElektroLab potrebuje aj vašu pomoc / ElektroLab also needs your help
Podpor nás!   Support us!

Tagy : Firewall

Páčil sa Vám článok? Pridajte k nemu hodnotenie, alebo podporte jeho autora.
 

       

Komentáre k článku



Komentár môžete adresovať buď diskutujúcemu priamo pomocou tlačidla „Odpovedať“, alebo ho môžete adresovať všeobecne do poľa nižšie.

Zatiaľ nebol pridaný žiadny komentár k článku. Pridáte prvý? Berte prosím na vedomie, že za obsah komentára je zodpovedný užívateľ, nie prevádzkovateľ týchto stránok.
Pre komentovanie sa musíte prihlásiť.

Vaša reklama na tomto mieste



Vyhľadajte niečo na našom blogu

Máte záujem o reklamu?

PCBWay Promo

Máte záujem o reklamu?

PCBWay Promo

Máte záujem o reklamu?

PCBWay Promo

🎨 Rezistor
Pásiky: 4
Výsledok: 0.00 Ω ±1%
🔗 Zdieľať widget

💡 Vedeli ste, že…


Webwiki Button