Skip to main content
  1. Concetti/

How Web Works

·7 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa è
#

Architettura completa di una richiesta web end-to-end: DNS, WAF, load balancer, web server, virtual host, database, contenuto statico vs dinamico, backend languages.


Flusso completo — dalla URL al browser
#

  Browser: "tryhackme.com"
  ┌─────────────────────────────┐
  │  1. Cache locale            │  /etc/hosts → cache OS
  └──────────────┬──────────────┘
                 │ miss
  ┌─────────────────────────────┐
  │  2. Recursive DNS           │  ISP / 1.1.1.1 / 8.8.8.8
  └──────────────┬──────────────┘
                 │ miss
  ┌─────────────────────────────┐
  │  3. Root DNS → TLD → Auth   │  risposta: IP = 104.26.10.229
  └──────────────┬──────────────┘
                 │ IP ottenuto
  ┌─────────────────────────────┐
  │  4. WAF                     │  analizza la richiesta HTTP
  │  Web Application Firewall   │  è un attacco? → DROP
  │                             │  è un bot? → DROP / captcha
  │                             │  rate limit superato? → DROP
  └──────────────┬──────────────┘
                 │ richiesta pulita
  ┌─────────────────────────────┐
  │  5. Load Balancer           │  quale server è meno carico?
  │                             │  algoritmo: round-robin o weighted
  │                             │  health check: server vivo?
  └──────┬──────────┬───────────┘
         │          │          │
         ▼          ▼          ▼
      [web-1]    [web-2]    [web-3]     ← uno viene scelto
  ┌─────────────────────────────┐
  │  6. Web Server              │  porta 80 (HTTP) o 443 (HTTPS)
  │  Apache / Nginx / IIS       │  riceve GET /page HTTP/1.1
  │  Node.js                    │
  └──────────────┬──────────────┘
  ┌─────────────────────────────┐
  │  7. Virtual Host matching   │  legge header Host:
  │                             │  trova la root directory giusta
  └──────────────┬──────────────┘
         ┌───────┴────────┐
         ▼                ▼
   [statico]          [dinamico]
   serve file         chiama backend
   direttamente       (PHP, Python...)
         │                │
         │                ▼
         │         ┌─────────────┐
         │         │  Database   │  MySQL, Postgres, MongoDB...
         │         └──────┬──────┘
         │                │ dati
         └───────┬─────────┘
  ┌─────────────────────────────┐
  │  8. Risposta HTTP           │  HTML + CSS + JS + immagini
  └──────────────┬──────────────┘
         Browser renderizza ✓

Location fisica dei componenti nel flusso
#

  LOCALE (tua macchina)              RETE (server di qualcun altro)
  ──────────────────────────         ──────────────────────────────────
  /etc/hosts                         Recursive DNS  (ISP / Google / CF)
  Cache OS RAM                       Root DNS       (distribuito Anycast)
  /etc/resolv.conf                   TLD server     (Verisign, Registro.it)
                                     Authoritative  (Cloudflare, AWS, etc.)

  I primi tre non escono mai dalla tua macchina.
  Dal Recursive DNS in poi sei in rete.

Dettaglio per ogni step del flusso:

  Step 1 — Cache locale
  ├── /etc/hosts       → file su disco, tua macchina, priorità assoluta
  ├── Cache OS DNS     → RAM, tua macchina, svuotata al reboot
  └── /etc/resolv.conf → file su disco, tua macchina,
                         contiene l'IP del recursive server da usare

  Step 2 — Recursive DNS
  └── server fisico nel datacenter dell'ISP
      oppure macchine Google    (8.8.8.8)
      oppure macchine Cloudflare (1.1.1.1)

  Step 3 — Root DNS
  └── macchine fisiche distribuite globalmente via Anycast
      stesso IP → risponde la macchina più vicina a te

  Step 4 — TLD server
  └── macchine fisiche di Verisign (.com), Registro.it (.it), etc.

  Step 5 — Authoritative NS
  └── macchine fisiche di Cloudflare, AWS Route53, etc.
      dove hai configurato i record del tuo dominio

WAF — Web Application Firewall
#

  Internet
     │  GET /login?user=admin'OR'1'='1   ← SQL injection attempt
  ┌──────────────────────────────────────┐
  │  WAF                                 │
  │                                      │
  │  checks:                             │
  │  ├── pattern matching (SQLi, XSS...)  │  ├── è un browser reale o un bot?    │
  │  ├── rate limit: >100 req/sec?       │
  │  └── IP in blacklist?                │
  │                                      │
  │  CLEAN  ──────────────────────────── │──► web server
  │  ATTACK → DROP (mai arriva al server)  └──────────────────────────────────────┘

  Blue team: i log del WAF sono la prima fonte di alert.
  Un flood di DROP sullo stesso IP = attacco in corso.
  Un 403 improvviso su /admin = qualcuno sta cercando pannelli.

Dove sta fisicamente il WAF — 3 architetture:

  1. Appliance dedicata (hardware o VM separata):
     Internet → [WAF fisico] → Load Balancer → Web Server
     Esempi: F5 BIG-IP, Fortiweb

  2. Software integrato nel load balancer:
     Internet → [Load Balancer + WAF] → Web Server
     Esempi: nginx + ModSecurity, AWS ALB + WAF

  3. Cloud WAF (livello CDN):
     Internet → [Cloudflare WAF] → il tuo server
     La richiesta non arriva mai al tuo datacenter se bloccata
     Esempio: Cloudflare, Akamai

  Nel flusso TryHackMe è mostrato come componente separato
  ma nella realtà è spesso integrato nel load balancer o CDN.

Load Balancer
#

  Client
  ┌─────────────────────────────────────────┐
  │  Load Balancer                          │
  │                                         │
  │  algoritmi di distribuzione:            │
  │  ├── round-robin: server 1→2→3→1→2→3   │
  │  └── weighted: manda al meno occupato   │
  │                                         │
  │  health check (heartbeat):              │
  │  ├── ogni N secondi pinga ogni server   │
  │  ├── server risponde? → attivo ✓        │
  │  └── server non risponde? → escluso ✗  │
  └──────┬──────────────┬───────────────────┘
         │              │              │
         ▼              ▼              ▼
    ┌─────────┐    ┌─────────┐    ┌─────────┐
    │ web-1   │    │ web-2   │    │ web-3   │
    │ attivo  │    │ attivo  │    │  DOWN ✗ │
    └─────────┘    └─────────┘    └─────────┘
                          load balancer smette
                          di mandargli traffico

CDN — Content Delivery Network
#

  Senza CDN:
  Utente UK ──────────────────────────────► Server USA
                   ~100ms latenza

  Con CDN:
  Utente UK ──► Edge server Londra ✓        Server USA
                   ~5ms latenza          (solo per contenuto dinamico)

  File statici copiati su edge server globali:
  ├── JavaScript
  ├── CSS
  ├── Immagini
  └── Video

  Esempi: Amazon CloudFront, Cloudflare CDN, Netflix edge nodes

Edge server — cos'è fisicamente:

  CDN = rete globale di edge server fisici

       ┌──────────────────────────────────┐
       │  Origin server (il tuo server)       │  /var/www/html/logo.png          │
       └──────────────┬───────────────────┘
                      │ copia i file statici
            ┌─────────┼─────────┐
            ▼         ▼         ▼
       [Milano]   [Londra]   [Tokyo]   ← edge server fisici
                                         nei datacenter locali

  Utente UK richiede logo.png:
  CDN calcola → edge server Londra è più vicino
  risponde da Londra (~5ms) invece che dal tuo server (~100ms)

  Il tuo server origin viene contattato solo per
  contenuto dinamico o quando la cache dell'edge è scaduta.

Virtual Host — matching Host header → directory
#

  Richiesta in arrivo al web server:

  GET /page HTTP/1.1
  Host: one.com              ← questo header decide tutto
  User-Agent: Firefox/87.0


  Web server legge Host: one.com
  ┌─────────────────────────────────────────────────┐
  │  Virtual Host config (file testuali su disco)  │                                                 │
  │  one.com  → /var/www/website_one                │
  │  two.com  → /var/www/website_two                │
  │  default  → /var/www/html                       │
  └──────────────────┬──────────────────────────────┘
                     │ match trovato: one.com
  ┌─────────────────────────────────────────────────┐
  │  Document root: /var/www/website_one            │
  │                                                 │
  │  GET /page  →  /var/www/website_one/page.html   │
  └─────────────────────────────────────────────────┘

  Nessun match → serve /var/www/html (sito di default)

  Default document root per OS:
  ├── Linux (Apache/Nginx): /var/www/html
  └── Windows (IIS):        C:\inetpub\wwwroot

  Blue team: virtual host misconfiguration → un dominio interno
  potrebbe servire il sito di default invece del sito corretto,
  oppure esporre directory non previste.

Virtual host = file di configurazione testuale su disco:

  Nginx — file: /etc/nginx/sites-enabled/one.com.conf
  ┌──────────────────────────────────────┐
  │ server {  │     server_name one.com;  │     root /var/www/website_one;}  └──────────────────────────────────────┘

  Apache — file: /etc/apache2/sites-enabled/one.com.conf
  ┌──────────────────────────────────────┐
  │ <VirtualHost *:80>                   │
  │     ServerName one.com               │
  │     DocumentRoot /var/www/website_one│
  │ </VirtualHost>                       │
  └──────────────────────────────────────┘

  Il software legge questi file all'avvio → mappa in RAM →
  quando arriva Host: one.com sa subito dove guardare
  senza rileggere il file a ogni richiesta.

Web server = software, non hardware:

  Macchina fisica o VM
       └── OS (Linux / Windows)
             └── Web server software  ← Apache / Nginx / IIS / Node.js
                   └── ascolta porta 80/443
                         └── gestisce richieste HTTP

  Apache  → open source, Linux/Windows, molto diffuso
  Nginx   → open source, più leggero e veloce di Apache
  IIS     → Microsoft, solo Windows
  Node.js → runtime JavaScript — non è un web server classico,
            ma può fungere da server HTTP tramite librerie

Statico vs Dinamico
#

  STATICO                          DINAMICO
  ────────────────────             ────────────────────────────
  File serviti così com'è          Generato al momento della richiesta
  CSS, JS, immagini, HTML fisso    Blog, risultati di ricerca, dashboard

  Flusso statico:                  Flusso dinamico:
  Browser → web server             Browser → web server
              │                                │
              ▼                                ▼
        /var/www/html              Backend (PHP, Python, Node...)
        /img/logo.png                          │
              │                               ▼
              ▼                          Database query
        risposta diretta                       │
                                        HTML generato
                                        risposta al browser

Backend Languages — esempio PHP
#

  Richiesta:
  GET /index.php?name=adam HTTP/1.1

  Codice PHP sul server (il client NON lo vede mai):
  <html><body>Hello <?php echo $_GET["name"]; ?></body></html>
                                    │ legge ?name=adam dalla query string
  HTML restituito al client:
  <html><body>Hello adam</body></html>

  ⚠️  Input utente → codice backend → output HTML
      Se il backend non sanitizza → SQL injection, XSS, RCE
      Questo è il motivo per cui "non vedi il codice""è sicuro"

Database comuni
#

DBTipoUso tipico
MySQLRelazionaleWeb app classiche, WordPress
PostgreSQLRelazionaleApp complesse, dati strutturati
MSSQLRelazionaleStack Microsoft/Windows
MongoDBNon relazionale (documenti)App JSON, dati flessibili

Scenario Reale
#

Un analista SOC vede questo nei log del WAF:

  192.168.1.45  GET /index.php?id=1'     → DROP  (SQLi attempt)
  192.168.1.45  GET /index.php?id=1 OR  → DROP  (SQLi attempt)
  192.168.1.45  GET /../../../etc/passwd → DROP  (path traversal)
  192.168.1.45  GET /admin               → 403   (arrivato al server)
  192.168.1.45  GET /wp-admin            → 404   (arrivato al server)

Le prime tre sono state bloccate dal WAF. Le ultime due sono arrivate al web server — il WAF non le ha riconosciute come attacco ma sono comunque tentativi di enumerazione. Un attaccante che cerca /admin e /wp-admin sta fingerprinting il target.

Collegato a
#

  • http-in-detail — protocollo HTTP usato in tutto questo flusso
  • dns-resolution — passo 1-3 del flusso
  • network — categoria
  • ctf — categoria

Related