---
title: "MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening"
description: "Hardening MySQL su VPS con Laravel: root senza password, bind su 0.0.0.0, niente TLS. Il protocollo CIS benchmark che applico in due ore su ogni server che prendo in carico."
canonical: "https://www.mauriziofonte.it/blog/post/hardening-urgente-mysql-laravel-vps.html"
author: "Maurizio Fonte"
date: "2025-07-04T07:47:49+02:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Sicurezza Informatica"
tags: ["Sicurezza Informatica", "Database"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Sicurezza Informatica](https://www.mauriziofonte.it/blog/cat/sicurezza_informatica.html) [Database](https://www.mauriziofonte.it/blog/cat/database.html)

# [MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening](https://www.mauriziofonte.it/blog/post/hardening-urgente-mysql-laravel-vps.html)

Venerdì 4 Luglio 2025, alle 07:47 ![MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening](https://www.mauriziofonte.it/image/001970200-hardening-urgente-mysql-laravel-vps.jpg)

A luglio 2025 ho eseguito un audit di sicurezza su un VPS Hetzner AX41 (Ryzen 5 3600, 64 GB RAM, 2×512 GB NVMe) che ospitava un e-commerce B2B Laravel 10 nel settore dell'elettronica industriale - circa 1.200 clienti attivi e un fatturato e-commerce di 800.000 euro. Il titolare mi aveva chiamato per un problema di performance, ma quando ho aperto il terminale la prima cosa che ho verificato è stata la sicurezza del database. Quello che ho trovato era lo scenario che incontro in almeno il 60% dei VPS che prendo in carico per PMI italiane: MySQL era raggiungibile da internet sulla porta 3306, l'utente root non aveva password, `local_infile` era abilitato, e l'applicazione Laravel si connetteva al database come root per ogni operazione - dal checkout del cliente alla migrazione dello schema.

Il [CIS Benchmark per MySQL](https://www.cisecurity.org/benchmark/oracle_mysql) - lo standard di riferimento per la configurazione sicura dei database pubblicato dal Center for Internet Security - definisce circa 80 controlli organizzati in categorie. Sull'installazione del cliente, 14 di questi controlli fallivano. Questo articolo descrive i 14 fix nell'ordine in cui li applico, e il perché di ciascuno.

## Perché un MySQL non hardenizzato è il bersaglio più pericoloso su un VPS?

Un MySQL esposto su internet senza autenticazione è peggio di un SSH con password debole. SSH almeno richiede un'autenticazione; MySQL con root senza password e bind su `0.0.0.0` dà accesso completo a tutti i dati dell'applicazione a chiunque conosca l'IP del server. E gli IP dei VPS Hetzner, OVH, Contabo e Digital Ocean sono in range noti - i bot di scansione li testano sistematicamente, porta per porta. La [guida al secure deployment di MySQL 8.0 pubblicata da Oracle](https://downloads.mysql.com/docs/mysql-secure-deployment-guide-8.0-en.pdf) è esplicita: un'installazione di default non è pensata per la produzione.

Il primo comando diagnostico:

```bash
# MySQL è raggiungibile dall'esterno?
ss -tlnp | grep 3306
# Se mostra 0.0.0.0:3306 o :::3306 → è esposto

# Root ha password?
mysql -u root -e "SELECT User, Host, authentication_string FROM mysql.user WHERE User='root';"
# Se authentication_string è vuoto → nessuna password

# Quali utenti esistono?
mysql -e "SELECT User, Host, plugin FROM mysql.user ORDER BY User;"
```

Sul VPS del cliente, `ss` mostrava `0.0.0.0:3306` - MySQL ascoltava su tutte le interfacce di rete, inclusa quella pubblica. Root non aveva password. Esistevano 4 utenti: `root@localhost`, `root@%` (accesso da qualunque host), `mysql.sys@localhost` e un utente generico `debian-sys-maint`. L'applicazione Laravel si connetteva come `root@localhost` con password vuota.

Stai cercando un **Consulente Informatico** esperto per un hardening MySQL sulla tua infrastruttura Laravel? Nel mio [profilo professionale](https://www.mauriziofonte.it/pages/about) trovi l'esperienza concreta su sicurezza database, segregazione utenti e conformità CIS Benchmark per PMI.

## Il protocollo di hardening: 14 fix in due ore

### Fase 1: accesso e autenticazione (30 minuti)

Il primo passo è `mysql_secure_installation` - uno script incluso in ogni installazione MySQL che automatizza i fix più basilari. Ma sulla maggior parte dei VPS che prendo in carico, non è mai stato eseguito:

```bash
mysql_secure_installation
# Cosa fa:
# - Imposta password per root
# - Rimuove utenti anonimi
# - Disabilita login remoto per root
# - Rimuove il database 'test'
# - Ricarica i privilegi
```

Dopo `mysql_secure_installation`, creo gli utenti segregati - uno per l'applicazione (solo DML), uno per le migration (DDL completo), e rimuovo `root@%`:

```sql
-- Rimuovere root remoto
DROP USER IF EXISTS 'root'@'%';

-- Utente applicativo: solo lettura/scrittura dati
CREATE USER 'app_ecommerce'@'127.0.0.1'
    IDENTIFIED WITH caching_sha2_password BY 'password_generata_con_openssl_rand'
    REQUIRE SSL;
GRANT SELECT, INSERT, UPDATE, DELETE ON ecommerce_db.* TO 'app_ecommerce'@'127.0.0.1';

-- Utente migration: DDL per artisan migrate (usato solo da CLI, mai dal web)
CREATE USER 'deploy_ecommerce'@'127.0.0.1'
    IDENTIFIED WITH caching_sha2_password BY 'altra_password_generata'
    REQUIRE SSL;
GRANT ALL PRIVILEGES ON ecommerce_db.* TO 'deploy_ecommerce'@'127.0.0.1';

FLUSH PRIVILEGES;
```

La separazione tra utente applicativo e utente deploy è il singolo cambiamento con il maggiore impatto sulla sicurezza. Se un attaccante ottiene accesso all'applicazione (tramite SQL injection, compromissione dell'APP_KEY, o qualunque altro vettore), può leggere e scrivere dati - ma non può `DROP TABLE`, non può `ALTER TABLE`, non può creare utenti, non può esportare il database intero con `mysqldump`. Il danno è contenuto al livello DML. Ho descritto in dettaglio come un APP_KEY compromessa può dare accesso completo al server nel mio articolo sulla [compromissione di un'applicazione Laravel via APP_KEY su GitHub](https://www.mauriziofonte.it/blog/post/ripristino-laravel-attacco-informatico-emergenza.html) - in quel caso, l'utente MySQL era root e l'attaccante ha fatto un `mysqldump` completo.

### Fase 2: rete e cifratura (30 minuti)

Il binding su localhost impedisce connessioni dall'esterno. Il TLS obbligatorio cifra il traffico anche su localhost - ridondante? No, perché protegge contro sniffing da processi locali compromessi:

```ini
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
bind-address = 127.0.0.1
require_secure_transport = ON

# Disabilitare local_infile (previene lettura di file del server via SQL)
local_infile = OFF

# Disabilitare symbolic-links (previene escape dalla data directory)
symbolic-links = 0
```

`local_infile = OFF` è un controllo CIS specifico che [la guida di hardening MySQL 2025](https://www.onlinehashcrack.com/guides/tutorials/harden-mysql-2025-secure-database-guide.php) segnala come prioritario: quando è abilitato, una query SQL può leggere qualunque file sul filesystem a cui l'utente `mysql` ha accesso - incluso `/etc/passwd`, i file di configurazione dell'applicazione, e potenzialmente l'`.env` di Laravel con tutte le credenziali.

### Fase 3: hardening dei permessi e logging (30 minuti)

```ini
# /etc/mysql/mysql.conf.d/mysqld.cnf (continuazione)
[mysqld]
# Log di tutte le connessioni e le query DDL per audit
general_log = OFF              # troppo verboso per produzione continua
log_error = /var/log/mysql/error.log
log_error_verbosity = 3        # include warning, non solo errori

# Permessi filesystem
# (da eseguire dopo ogni modifica a my.cnf)
```

```bash
# Permessi sulla data directory (controllo CIS 1.1)
chmod 700 /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql

# Permessi sulla configurazione (controllo CIS 1.2)
chmod 640 /etc/mysql/mysql.conf.d/mysqld.cnf
chown root:mysql /etc/mysql/mysql.conf.d/mysqld.cnf
```

### Fase 4: verifica e restart (30 minuti)

```bash
# Restart MySQL con la nuova configurazione
systemctl restart mysql

# Verificare che il bind sia solo su localhost
ss -tlnp | grep 3306
# Deve mostrare solo 127.0.0.1:3306

# Verificare che root remoto non esista più
mysql -u root -p -e "SELECT User, Host FROM mysql.user WHERE Host='%';"
# Deve restituire empty set

# Verificare che local_infile sia OFF
mysql -u root -p -e "SHOW VARIABLES LIKE 'local_infile';"

# Verificare che require_secure_transport sia ON
mysql -u root -p -e "SHOW VARIABLES LIKE 'require_secure_transport';"

# Test connessione applicativa con nuovo utente
mysql -u app_ecommerce -p --ssl-mode=REQUIRED -e "SELECT 1;"
```

Sul VPS del cliente, dopo il restart, il test di connessione dall'esterno ha confermato che MySQL non rispondeva più sulla porta 3306 da IP remoti. Il test di SQL injection simulato - una query con `LOAD DATA LOCAL INFILE '/etc/passwd'` - ha fallito con l'errore `The used command is not allowed with this MySQL version` perché `local_infile` era disabilitato. Il test di escalation - tentare un `DROP TABLE` con l'utente applicativo - ha restituito `Access denied for user 'app_ecommerce'`. Tre scenari di attacco chiusi in due ore.

Un punto che i titolari di PMI non capiscono fino a quando non glielo mostri con un esempio concreto: la segregazione degli utenti MySQL non protegge solo contro attaccanti esterni. Protegge anche contro errori interni. Se un operatore di backoffice con accesso phpMyAdmin cancella per errore una tabella - cosa che ho visto succedere tre volte in carriera - con l'utente segregato non può farlo. Il `DELETE` funziona (è DML), il `DROP TABLE` no (è DDL). La differenza tra un errore recuperabile (record cancellati, ripristinabili da backup) e un errore catastrofico (tabella eliminata, schema perso) è tutta nella configurazione dei permessi.

Un altro scenario che vale la pena menzionare: la [guida CIS Benchmark Configuration del 2026 pubblicata da OneUpTime](https://oneuptime.com/blog/post/2026-03-31-mysql-configure-cis-benchmarks/view) raccomanda di verificare anche che il plugin `validate_password` sia attivo con policy MEDIUM o STRONG. Su MySQL 8, l'attivazione è semplice:

```sql
INSTALL COMPONENT 'file://component_validate_password';
SET GLOBAL validate_password.policy = MEDIUM;
SET GLOBAL validate_password.length = 12;
```

Questo impedisce la creazione di utenti con password deboli - un controllo che sembra superfluo finché non scopri che il precedente sviluppatore aveva creato un utente `test` con password `test` per il debugging e non l'aveva mai rimosso.

Dopo la verifica, aggiornare il `.env` di Laravel con le nuove credenziali:

```env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_USERNAME=app_ecommerce
DB_PASSWORD=password_generata
```

E testare che l'applicazione funzioni: `php artisan migrate:status` (con l'utente deploy nel `.env` temporaneo o via parametro) e una navigazione completa del sito (con l'utente applicativo nel `.env` di produzione).

Un errore che trovo frequentemente dopo la segregazione utenti: Laravel lancia un `PDOException: SQLSTATE[42000]: Access denied` la prima volta che esegui `php artisan migrate` perché il `.env` usa l'utente applicativo (che non ha permessi DDL). La soluzione è avere due configurazioni database in `config/database.php` - una per il runtime web (`mysql` con l'utente applicativo), una per le migration (`mysql_deploy` con l'utente deploy) - e specificare la connessione nei comandi Artisan:

```bash
# Migration con utente deploy (ha privilegi DDL)
DB_USERNAME=deploy_ecommerce DB_PASSWORD=... php artisan migrate --force
```

Questo pattern evita di tenere credenziali DDL nel `.env` di runtime - le credenziali dell'utente deploy vivono solo nell'ambiente CI/CD o nella sessione SSH dell'operatore che esegue il deploy.

## Backup cifrati e monitoring: i due pezzi che completano l'hardening

L'hardening della configurazione MySQL è il primo livello. Ma un database protetto da password forte, TLS e permessi segregati resta vulnerabile se i backup non sono cifrati e se nessuno monitora gli accessi anomali.

Sul VPS del cliente, il backup girava con `mysqldump -u root -pPASSWORD` in un cron job - password in chiaro nella crontab, dump non cifrato scritto in una directory senza permessi restrittivi. Chiunque con accesso al filesystem poteva leggere il dump e ottenere tutti i dati del database, bypassando completamente i permessi MySQL. Il fix è su tre livelli:

```bash
# 1. Backup con credential file (password non in chiaro nella crontab)
# Creare /root/.my.cnf con permessi 600:
cat > /root/.my.cnf << 'EOF'
[mysqldump]
user=deploy_ecommerce
password=la_password_generata
EOF
chmod 600 /root/.my.cnf

# 2. Dump cifrato con openssl (chiave simmetrica, AES-256)
mysqldump --single-transaction ecommerce_db \
    | gzip \
    | openssl enc -aes-256-cbc -salt -pbkdf2 -pass file:/root/.backup-key \
    > /backup/ecommerce-$(date +%F).sql.gz.enc

# 3. Permessi sulla directory di backup
chmod 700 /backup
chown root:root /backup
```

Per il monitoring degli accessi, il log delle connessioni fallite è il segnale più utile. Su MySQL 8, il `log_error_verbosity = 3` cattura i tentativi di connessione con credenziali errate. Un alert Prometheus che conta gli `Access denied` nel log errori e scatta dopo 10 tentativi in 5 minuti è sufficiente per rilevare un brute force sull'autenticazione MySQL - e si integra con lo stack di monitoring che ho descritto nel mio articolo sul [monitoring proattivo per Laravel su VPS unmanaged](https://www.mauriziofonte.it/blog/post/vps-monitoring-laravel-prevenzione-downtime.html).

Un ultimo controllo che raccomando: verificare periodicamente (ogni trimestre) che non siano stati creati utenti MySQL non autorizzati. Su un VPS con più sviluppatori che si alternano nel tempo, è comune trovare utenti "temporanei" creati per debugging e mai rimossi - ognuno dei quali è un potenziale punto di ingresso.

```sql
-- Audit trimestrale: utenti esistenti e loro privilegi
SELECT User, Host, plugin, account_locked
FROM mysql.user
ORDER BY User;

-- Privilegi globali per utente
SELECT * FROM mysql.global_priv WHERE User NOT IN ('mysql.sys', 'mysql.infoschema', 'mysql.session', 'debian-sys-maint');
```

Per il quadro completo dell'hardening a livello di server - non solo MySQL ma anche SSH, PHP-FPM, Nginx e firewall - ho scritto una guida dedicata all'[hardening di server Debian e Ubuntu per applicativi PHP delle PMI](https://www.mauriziofonte.it/blog/post/hardening-server-debian-ubuntu-applicativi-php-sicurezza-pmi.html). E per la gestione specifica delle credenziali Laravel, inclusa la rotazione dell'APP_KEY e il rehashing delle password, c'è il mio articolo sulla [sicurezza credenziali Laravel da L9/L10 a L12](https://www.mauriziofonte.it/blog/post/laravel-sicurezza-credenziali-rotazione-chiavi-rehashing-password-l12.html).

Se il tuo MySQL è in produzione da più di un anno e nessuno ha mai eseguito `mysql_secure_installation`, il tuo database è quasi certamente esposto. La verifica richiede 5 minuti: `ss -tlnp | grep 3306` per il bind, `mysql -u root -e "SELECT 1"` per la password root. Se il bind è su `0.0.0.0` o root entra senza password, hai un problema che va risolto oggi - non la prossima settimana, oggi. Il rischio non è teorico: i bot che scansionano la porta 3306 sono attivi 24 ore su 24 sugli IP di Hetzner, OVH, Contabo e Digital Ocean. Un MySQL esposto senza password viene trovato in media entro 48 ore dalla messa online - e il danno non è un cryptominer come per Redis, è l'esfiltrazione completa di tutti i dati del tuo database, clienti inclusi. Con le implicazioni GDPR che ne derivano: notifica al Garante entro 72 ore, potenziale sanzione fino al 4% del fatturato annuo, e un danno reputazionale che nessun hardening retroattivo può riparare. [Contattami](https://www.mauriziofonte.it/pages/contattami) se hai bisogno di un hardening MySQL: in due ore applico il protocollo CIS completo, segrego gli utenti, abilito TLS, configuro i backup cifrati e ti consegno un server con 14 controlli di sicurezza in meno da preoccuparti.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedentePHP-FPM che crasha sotto carico su VPS: come ho diagnosticato un OOM killer silenzioso su un portale Laravel con 200 utenti concorrenti3 Luglio 2025](https://www.mauriziofonte.it/blog/post/ripristino-crash-php-fpm-laravel-vps.html)[Articolo successivo »Certificato HTTPS scaduto o mal configurato su VPS con Laravel: diagnosi, fix e hardening TLS nel 20254 Luglio 2025](https://www.mauriziofonte.it/blog/post/https-compromesso-vps-laravel-protezione-urgente.html)

### Articoli correlati a MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening

- [Refactoring database MySQL su Laravel: report da 47 minuti a 11 secondi senza upgrade hardware](https://www.mauriziofonte.it/blog/post/rifacimento-strategico-database-mysql-laravel.html)

  Un database MySQL da 12 GB su un VPS Contabo, un report mensile che impiegava 47 minuti, 38 indici su una tabella di cui 12 mai utilizzati, e · 26 Giugno 2025

  ![Refactoring database MySQL su Laravel: report da 47 minuti a 11 secondi senza upgrade hardware](https://www.mauriziofonte.it/image/001870070-rifacimento-strategico-database-mysql-laravel.jpg)
- [Diagnosi e risoluzione di connessioni lente al database MySQL su VPS senza supporto tecnico: guida operativa per Debian e Ubuntu](https://www.mauriziofonte.it/blog/post/diagnosi-risoluzione-connessioni-lente-mysql-vps.html)

  Un gestionale Laravel su Hetzner con MySQL che impiegava 3 4 secondi per ogni query di ricerca prodotti. La causa: InnoDB buffer pool a 128MB · 11 Luglio 2025

  ![Diagnosi e risoluzione di connessioni lente al database MySQL su VPS senza supporto tecnico: guida operativa per Debian e Ubuntu](https://www.mauriziofonte.it/image/002080070-diagnosi-risoluzione-connessioni-lente-mysql-vps.jpg)
- [LLM per la generazione di migration SQL: gestire l'evoluzione dello schema senza errori](https://www.mauriziofonte.it/blog/post/llm-generazione-migration-sql-evoluzione-schema-database.html)

  Ho iniziato a usare Claude per generare migration SQL complesse su schemi di database con 200 tabelle e vincoli FK intricati. Il risultato non · 26 Febbraio 2026

  ![LLM per la generazione di migration SQL: gestire l'evoluzione dello schema senza errori](https://www.mauriziofonte.it/image/002470070-llm-generazione-migration-sql-evoluzione-schema-database.jpg)
- [Applicazione Laravel compromessa via APP_KEY su GitHub: forensics, contenimento e ripristino in cinque giorni](https://www.mauriziofonte.it/blog/post/ripristino-laravel-attacco-informatico-emergenza.html)

  Un CRM Laravel 9 per una PMI logistica veneta è stato compromesso perché un file .env con l'APP KEY era stato committato su un repository GitHub · 30 Giugno 2025

  ![Applicazione Laravel compromessa via APP_KEY su GitHub: forensics, contenimento e ripristino in cinque giorni](https://www.mauriziofonte.it/image/001900070-ripristino-laravel-attacco-informatico-emergenza.jpg)
- [Migrare MySQL 5.7 EOL su Hetzner senza fermare il business: la strategia di replicazione che ho usato per spostare 78GB con quattro minuti di downtime](https://www.mauriziofonte.it/blog/post/migrazione-database-mysql-guida-strategica-server-hetzner-ovh.html)

  Migrare un database MySQL 5.7 fuori supporto fa paura ai clienti, e quasi sempre per il motivo sbagliato: pensano al rischio di perdita dati · 12 Giugno 2025

  ![Migrare MySQL 5.7 EOL su Hetzner senza fermare il business: la strategia di replicazione che ho usato per spostare 78GB con quattro minuti di downtime](https://www.mauriziofonte.it/image/001760070-migrazione-database-mysql-guida-strategica-server-hetzner-ovh.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "MySQL esposto su un VPS Hetzner con root senza password: il CIS benchmark che applico nelle prime due ore di hardening", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/hardening-urgente-mysql-laravel-vps.html

Pubblicato: 2025-07-04 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
