Consigli essenziali per la sicurezza di Docker in self‑hosting
Proteggi ituoi servizi auto‑ospitati, dalla difesa al monitoraggio!
Indice
- 🧗♀️ Per i coraggiosi
- 🔄 Il ballo del
:latest - 🔐 Gestione dei segreti: il modo giusto
- 🌐 Pericolo di rete
- 🛡️ Controlli di accesso
- 🔍 Monitoraggio e verifica
- ⏰ Suggerimenti spesso trascurati
- 🚀 Checklist di produzione
- 📚 Letture aggiuntive
🧗♀️ Per i coraggiosi
Se stai auto‑ospitando servizi Docker, la sicurezza è tutta tua, dall’alto verso il basso—non c’è un provider cloud che ti protegga da scansioni di porte o configurazioni approssimative. Che tu stia lanciando applicazioni sulla tua rete domestica o noleggiando VPS da provider come Vultr, DigitalOcean, Linode, AWS, Azure o Google Cloud, dovrai chiudere le porte—e verificare di averlo fatto correttamente.
In questa guida percorreremo la sicurezza di Docker—da tecniche meno conosciute a quelle difficili da eseguire correttamente; esploreremo token canary, volumi in sola lettura, regole firewall, segmentazione e rinforzo della rete, aggiunta di proxy autenticati e molto altro.
Confronteremo anche le reti domestiche con le configurazioni cloud pubbliche e ti mostreremo come impostare un proxy con autenticazione di base usando Nginx. Alla fine avrai diverse opzioni per tenere fuori i fastidi (amici, famiglia e talvolta anche te stesso…)
È un sacco di roba! Ma gran parte è correlata, e puoi scegliere ciò che è più pertinente al tuo ambiente. 🍀
🔄 Il ballo del :latest
Mantenere le immagini aggiornate è fondamentale per la sicurezza. Tuttavia, fare affidamento su :latest può introdurre cambiamenti incompatibili o build vulnerabili senza una fase di revisione.
Il modo sicuro per aggiornare
Combina i comandi di aggiornamento con pull o build in modo da rinfrescare deliberatamente le immagini, poi riavvia durante una finestra in cui puoi notare eventuali rotture.
#!/bin/bashdocker compose pull && \ docker compose up -dPinning della versione vs Latest
Scegliere la versione giusta da fissare è un equilibrio tra stabilità e sicurezza. Ecco alcune strategie comuni:
# ... # Pinning della versione esatta, ideale per servizi critici image: postgres:17.2
# Pinning della patch, buono per servizi non critici image: postgres:17.2
# Pinning della major version, perfetto per progetti hobby image: postgres:17
# Yolo, da evitare se possibile image: postgres:latestUsa Dependabot o Renovate per aprire PR di aggiornamento revisionabili. Per tutto ciò che ti dispiacerebbe ricostruire alle 2 del mattino, fissa a una versione specifica o a un digest e lascia che l’automazione ti avvisi quando è il momento di passare.
Fammi sapere quali sono i tuoi strumenti preferiti per tenere aggiornate le immagini Docker!
🔐 Gestione dei segreti
Ci sono molti modi per gestire i segreti, ma una delle regole più importanti da rispettare è: non inserire mai segreti direttamente nelle tue immagini Docker né commetterli su git. È uno degli errori di sicurezza più comuni, comporta un rischio a lungo termine e richiede molto sforzo per essere corretto.
Conservare i segreti in modo sicuro è un argomento ampio con molte opzioni, dai file .env, Docker secrets, 1Password/Bitwarden, o un gestore di segreti come HashiCorp Vault o AWS Secrets Manager.
Dovrai scegliere il livello “giusto” di sforzo e sicurezza per il tuo caso d’uso.
Genera Segreti Forti
Ecco un piccolo script per generare nuovi segreti da inserire in un file .env:
#!/bin/bashgenerate_secret() { local length=${1:-30} local generate_length=$((length + 4)) openssl rand -base64 "$generate_length" | tr -d '+=/\n' | cut -c1-"$length"}
[ -f .env ] && { echo ".env file already exists!"; exit 1; }
cat > .env << EOLPOSTGRES_PASSWORD=$(generate_secret)JWT_SECRET=$(generate_secret 64)SESSION_KEY=$(generate_secret 24)REDIS_PASSWORD=$(generate_secret 20)UNSAFE_PLACEHOLDER=__WARNING_REPLACE_RANDOM_TEXT__EOL
echo "New .env file generated with secure random values!"Token Canary
Canary Tokens sono un ottimo metodo per rilevare se i tuoi segreti sono stati compromessi (e utilizzati). Funzionano come una trappola che puoi aggiungere a qualsiasi file sensibile, URL o token.
Considera di posizionarli accanto ai segreti che ti preoccupano davvero: file .env, variabili CI, gestori di password, cartelle di backup e credenziali cloud. Non trasformare tutto in uno spettacolo; metti le trappole dove un vero aggressore o un futuro te stesso potrebbero toccarle.
Esistono molti tipi di “token” canary tra cui scegliere, da token AWS, numeri di carta di credito falsi, file Excel e Word, file Kubeconfig, credenziali VPN, fino a dump SQL che possono contenere una trappola!
Buone Pratiche per i Token Canary
- Posiziona Ovunque: In ogni file
.env, pipeline CI/CD e “secrets manager” che ti viene in mente.- Metti un file
passwords.xlsxopasswords.docxnella tua home directory. - Aggiungi un profilo AWS
billing_prodcon un token canary come segreto. - Genera un file
private.keyper la tua directory~/.ssh. - Crea un dump SQL Canary
all_credit_cards.sqlnella tua directory~/backups.
- Metti un file
- Monitora: Configura regole/avvisi email per intercettare quando un token canary viene attivato.
Aggiornamento da .env a Keychain macOS
Per gli utenti Mac, una delle soluzioni più semplici è usare Keychain.
Ecco un modo rapido per automatizzare il caricamento dei segreti dal portachiavi di macOS, con supporto a TouchID e una sicurezza leggermente superiore rispetto ai file .env.
Original credit: Brian Hetfield and Jan Schaumann.
### Funzioni per impostare e recuperare variabili d'ambiente dal portachiavi OSX ###### Adattato da: https://www.netmeister.org/blog/keychain-passwords.html eOriginal credit: [Brian Hetfield](https://gist.github.com/bmhatfield/f613c10e360b4f27033761bbee4404fd) and [Jan Schaumann](https://www.netmeister.org/).
# Uso: get-keychain-secret VAR_ENV_SEGRETOfunction get-keychain-secret () { security find-generic-password -w -a ${USER} -D "environment variable" -s "${1}"}
# Uso: set-keychain-secret VAR_ENV_SEGRETO# Ti verrà chiesto di inserire il valore segreto!function set-keychain-secret () { [ -n "$1" ] || print "Manca il nome della variabile d'ambiente"
# richiedi all'utente il segreto echo -n "Inserisci il segreto per ${1}" read secret [ -n "$secret" ] || return 1
( [ -n "$1" ] || [ -n "$secret" ] ) || return 1 security add-generic-password -U -a ${USER} -D "environment variable" -s "${1}" -w "${secret}"}source ~/keychain-secrets.sh
# Carica le variabili d'ambiente nella shell correnteexport AWS_ACCESS_KEY_ID=$(get-keychain-secret AWS_ACCESS_KEY_ID);export AWS_SECRET_ACCESS_KEY=$(get-keychain-secret AWS_SECRET_ACCESS_KEY);# Nota: se un attaccante può eseguire `env` nella tua shell, questi segreti potrebbero essere esposti!#!/usr/bin/env bashsource ~/keychain-secrets.sh
# Specifica tutti i segreti per questo progettoAWS_ACCESS_KEY_ID=$(get-keychain-secret AWS_ACCESS_KEY_ID) \AWS_SECRET_ACCESS_KEY=$(get-keychain-secret AWS_SECRET_ACCESS_KEY) \ "$@"
# Nota: usare un wrapper shell aiuta a impedire che i segreti rimangano# nell'ambiente. Ed è sicuro da includere nel repository.
# Uso:# ./scripts/env-run.sh docker compose up -d# ./scripts/env-run.sh docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY ...🌐 Pericolo di rete
Reti personalizzate e porte interne
Isolare correttamente i servizi con le reti Docker è un modo importante per ridurre la superficie di attacco.
Fai attenzione a non aprire buchi nella tua rete! Un singolo port forwarding configurato male può avere conseguenze molto gravi.
Per impostazione predefinita, i servizi su una LAN privata non saranno esposti a Internet – devi esplicitamente inoltrare le porte dal tuo router.
Docker su LAN
Che tu sia uno sviluppatore che esegue server di sviluppo in locale, o che stia auto‑ospitando servizi dalla tua rete domestica, le supposizioni sul modello di rete di Docker possono causare problemi.
Gli sviluppatori spesso rimangono sorpresi nel constatare che i metodi “tradizionali” per mettere in sicurezza i server Linux (iptables, restrizioni sulle opzioni sysctl tcp/ip) possono fallire silenziosamente sugli host Docker! Questo è particolarmente vero quando si auto‑ospita o si opera su una tipica rete domestica. (Per chi è in fondo: questo può consentire l’accesso ai container di sviluppo sul tuo MacBook!!!)
⚠️ Avviso #1: Le porte pubblicate da Docker possono aggirare le regole del firewall che pensavi stessero proteggendo l’host, soprattutto con UFW su Ubuntu/Debian. Questo non rende inutili tutte le regole del firewall, ma significa che “UFW dice deny” non è una prova. Vedi issue #690: Docker bypasses ufw firewall rules.
⚠️ Avviso #2: Il binding delle porte a indirizzi IP locali (es.,
-p 127.0.0.1:8080:80) è il valore predefinito corretto, ma le versioni del Docker Engine precedenti alla 28.0.0 presentavano casi in cui host sulla stessa rete L2 potevano ancora raggiungere le porte pubblicate su localhost. Docker documenta la limitazione nella sua guida al port publishing, e l’abitudine di verificare con nmap mostrata sotto resta importante.
Se sei sorpreso di scoprirlo, lo stesso!
Il binding a IP locali è ancora una buona pratica e ha un impatto significativo negli ambienti cloud gestiti e in reti appositamente configurate.
Esempio Docker Compose
Ecco un file docker-compose.yml di esempio che associa il servizio app a 127.0.0.1:8080 e collega entrambi i container alla rete personalizzata backend.
networks: backend:
services: app: networks: - backend ports: # Bind to localhost if possible - "127.0.0.1:8080:8080" # ... other settings database: image: postgres:17.1 # No ports needed; accessible inside backend network. networks: - backendBest Practice di Rete
- 🏆 Non pubblicare ALCUNE porte Recentemente ho scoperto che questo è più utile di quanto si pensi! Quando usi una rete nominata (bridge), i container hanno accesso non filtrato l’uno all’altro. Si comportano come se fossero dietro una rete locale (gateway NAT).
- Anche se non è possibile in tutti i casi d’uso, può risultare utile per container che eseguono job batch, o che sono principalmente accessibili via
attachoexec.
- Anche se non è possibile in tutti i casi d’uso, può risultare utile per container che eseguono job batch, o che sono principalmente accessibili via
- 🥇 Usa Docker Networks per isolare e controllare quali container possono comunicare tra loro.
- 🥉 Usa il binding a localhost: Sebbene imperfetto, è generalmente più sicuro associare le porte a un indirizzo di loopback (es.,
127.0.0.1:8080:80). Basta assicurarsi di verificare la configurazione.
🛡️ Controlli di Accesso
I controlli di accesso sono una parte cruciale per mettere in sicurezza i tuoi servizi Docker. Questo include limitare le capacità e i permessi dei container, restringere l’accesso al socket Docker, e altro ancora.
- Limitare le Capacità del Container
- Accesso al Socket Docker
- Bloccare Paesi!
- Rinforzare l’Host Proxy CloudFlare
Limitare le Capacità del Container
Un’altra pratica solida di controllo di accesso è limitare le capacità dei tuoi container. Questo riduce il raggio d’azione di diverse minacce, dall’escalation di privilegi al dirottamento del traffico. Non è un campo di forza, ma elimina permessi che la maggior parte dei container non ha mai bisogno.
Cosa sono le capacità? Permessi o abilità nominati definiti dal kernel Linux. (La pagina man capabilities contiene l’elenco completo.) Includono cose come CAP_CHOWN (cambia il proprietario di un file), CAP_NET_ADMIN (configura interfacce di rete), CAP_KILL (termina qualsiasi processo) e molte altre.
I due modi per determinare le capacità necessarie sono:
- Prova ed errore: Questo metodo più lento ma efficace ti fa partire senza capacità, poi aggiungerle una alla volta finché l’app funziona.
- Cerca lavoro preesistente: Cerca “
project-namecap_dropDockerfile” o “project-namecap_dropdocker-compose.yml” per vedere se altri hanno già fatto il lavoro per te. Un LLM può suggerire un punto di partenza, ma trattalo come un’ipotesi finché non testi il container e leggi la documentazione dell’immagine.
Best Practice sulle Capacità
- Rimuovi tutte le capacità: Usa
cap_drop: [ ALL ]per eliminare tutte le capacità Linux dal container. - Nessun nuovo privilegio: Usa
security_opt: [ no-new-privileges=true ]per impedire al container di acquisire nuovi privilegi.
services: database: image: postgres:17.1 networks: [ db-network ] security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - DAC_READ_SEARCH - FOWNER - SETGID - SETUID db-admin: image: dpage/pgadmin4:4.1 networks: [ db-network ] ports: - "8081:80" # ... other settingsnetworks: db-network:Ora i tuoi servizi possono comunicare tra loro tramite la rete db-network. Docker Compose creerà automaticamente quella rete.
Usa l’opzione --external/external: per unirti a una rete preesistente. Omettela per creare una nuova rete.
Accesso al Socket Docker
⚠️ Attenzione: docker.sock è praticamente l’accesso amministrativo dell’host
⚠️ L’opzione :ro non influisce sull’I/O inviato attraverso il socket!
Assicura solo che il percorso del socket sia montato in sola lettura. Le chiamate API inviate tramite quel socket possono comunque creare container, montare percorsi dell’host e fare altre cose molto interessanti che probabilmente non intendevi delegare.
Buona Pratica per il Socket
- 🥇 Evita di montare il socket Docker, c’è quasi sempre un’alternativa migliore.
- 🫣 Se è indispensabile, metti un proxy ristretto davanti e consenti solo gli endpoint API di cui l’app ha realmente bisogno. Dai un’occhiata al progetto
docker-socket-proxyoriginariamente di Tecnativa, docker-socket-proxy. Poi verifica che le chiamate negate siano effettivamente bloccate. - 🤢 Ok, forse condividere il socket è accettabile in un ambiente di test ad alta fiducia e a basso rischio.
Blocco per Paese!
A volte utile, ma non costituisce una vera barriera di sicurezza.
Parliamo dell’entità geopolitica, non della musica…
Se ospiti applicazioni principalmente per la tua famiglia e i tuoi amici locali, puoi bloccare il traffico proveniente da paesi da cui non ti aspetti visite. Oppure consentire solo il traffico dai paesi che ti aspetti. Riduce il rumore; non ferma VPN, proxy, botnet o chiunque sia sufficientemente paziente.
Dai un’occhiata a questo script per bloccare tutto il traffico dalla Cina:
curl -fsSL https://www.ipdeny.com/ipblocks/data/countries/cn.zone | \ while read line; do ufw deny from $line to any; doneAllo stesso modo, puoi consentire solo il traffico dagli Stati Uniti:
curl -fsSL https://www.ipdeny.com/ipblocks/data/countries/us.zone | \ while read line; do ufw allow from $line to any; doneHardening CloudFlare Proxy Host
Se il tuo server domestico è protetto dietro un IP di CloudFlare (proxy), puoi limitare l’accesso solo agli IP di CloudFlare e alla tua rete locale.
È un po’ simile al blocco per Paese sopra, ma con un controllo molto più restrittivo.
ufw default deny incoming # Blocca tutto il traffico in ingresso!!!ufw default allow outgoing # Consenti tutto il traffico in uscitaufw allow ssh # Consenti SSH
# Consenti l’accesso per la subnet locale (idealmente una DMZ/VLAN dedicata per i servizi ospitati)ufw allow from 10.0.0.0/8 to any port 443
# Consenti gli IP di CloudFlarecurl -fsSL https://www.cloudflare.com/ips-v4 | \ while read line; do ufw allow from $line to any port 443; done# Aggiungi supporto IPv6# curl -fsSL https://www.cloudflare.com/ips-v6 | \# while read line; do ufw allow from $line to any port 443; donePer testare modifiche basate sulla geolocalizzazione può tornare utile una VPN con endpoint nel paese desiderato. Vedi più dettagli nella sezione Monitoring & Verification.
Sicurezza a livello di applicazione
Una volta che la tua rete e host sono stati rinforzati, potresti scoprire che c’è ancora altro da fare.
Ora dobbiamo considerare il livello “applicazione” dei nostri servizi stessi.
Il database ha una password valida? Il container automatizza HTTPS/certificati? L’app include un’autenticazione integrata? Ci sono limiti su quali email possono registrarsi? Esistono credenziali predefinite o variabili d’ambiente da modificare?
L’unico modo per sapere è controllare. In questo caso, parti dal README e da altri file chiave come docker-compose.yml, Dockerfile e .env.*. Fai lo stesso sia per il progetto sia, idealmente, per i servizi di supporto (ad esempio Postgres, Redis, ecc.).
Reverse Proxy
Un altro livello di difesa è l’autenticazione di base. Non usarla senza HTTPS. Per i servizi legacy, mettere l’autenticazione di base davanti a una rotta amministrativa è spesso sufficiente a bloccare richieste casuali e crawler non autenticati che tentano di accedere direttamente.
location /admin { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://internal_admin:80; proxy_set_header X-Real-IP $remote_addr;}Genera le credenziali:
htpasswd -c /etc/nginx/.htpasswd adminCon un proxy che usa l’autenticazione di base, gli aggressori devono superare un ostacolo aggiuntivo—username e password—prima di raggiungere il tuo servizio interno.
Un’alternativa è utilizzare un servizio come Traefik o Caddy che può automatizzare HTTPS e l’autenticazione di base per te.
Se vuoi gestire molti domini e servizi tramite un’interfaccia grafica, ti consiglio Nginx Proxy Manager.
🔍 Monitoraggio e Verifica
Questo è il passo più importante e più trascurato. Puoi avere il firewall migliore, la rete migliore e le migliori pratiche, ma se non verifichi, non hai alcuna certezza che funzionino.
In più, conoscere solo qualche comando – o sapere dove trovarli – può fare la differenza nel prevenire una violazione. Sentirsi come un hacker è solo un bonus. (Per dettagli ed esempi, vai direttamente alla sezione Monitoraggio e Verifica.)
Non fidarti, verifica due volte
Controlla le tue porte
⚠️ IMPORTANTE: non scansionare host che non possiedi.
Che tu sia su una rete domestica o su un VPS, vorrai sapere quali porte sono aperte verso il mondo.
Ci sono 2 modi per farlo:
- Controllare la rete (
nmap,masscan) - Interrogare il sistema operativo (
lsof,netstat,ss)
Testare al di fuori della tua rete
Ti servirà il tuo attuale IP pubblico, facilmente ottenibile con servizi come ifconfig.me: curl https://ifconfig.me. Oppure controllalo nella dashboard del tuo provider.
curl -fsSL https://ifconfig.me# --> CURRENT PUBLIC IPUna volta ottenuto l’IP pubblico, devi connetterti a una rete esterna. Puoi usare il computer di un amico, un hotspot telefonico/5G, o un server dedicato.
target_host="$(curl -fsSL https://ifconfig.me)"
#Nota: Assicurati che `target_host` sia l'IP desiderato
# Scansiona porte specifiche:nmap -A -p 80,443,8080 --open --reason $target_host# Le 100 porte più comuni:nmap -A --top-ports 100 --open --reason $target_host# Tutte le portenmap -A -p1-65535 --open --reason $target_hostTest nella tua rete
Esercitati con nmap, scansiona la tua rete locale o uno dei tuoi server, controlla il router, la stampante, il frigorifero intelligente.
Esempi di comandi di scansione
# Scansiona il tuo localhost per tutte le porte apertenmap -sT localhost
# Scansiona l'IP privato della tua macchina per i servizinmap -sV 192.168.1.10
# Trova i dettagli dei servizi nella tua retenmap -sn 192.168.0.0/24nmap -sn 10.0.0.0/24# O su un Docker 172.18.0.1/16nmap -sn 172.18.0.1/16% nmap -A --open --reason 192.168.0.87
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-06 13:51 MSTNmap scan report for dev02.local (192.168.0.87)Host is up, received syn-ack (0.0067s latency).Not shown: 995 closed tcp ports (conn-refused)PORT STATE SERVICE REASON VERSION22/tcp open ssh syn-ack OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)| ssh-hostkey:|_ 256 {FINGERPRINT} (ED25519)80/tcp open http syn-ack Caddy httpd|_http-server-header: Caddy|_http-title: Dev02.DanLevy.net443/tcp open ssl/https syn-ack|_http-title: Dev02.DanLevy.net1234/tcp open http syn-ack Node.js Express framework|_http-cors: GET POST PUT DELETE PATCH|_http-title: Dev02.DanLevy.net (application/json; charset=utf-8).Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .Nmap done: 1 IP address (1 host up) scanned in 13.36 secondsVisualizza le porte aperte
Familiarizzati con lsof – è disponibile su macOS e Linux. Mostra lo stato della rete a livello granulare e l’attività del disco.
# Monitora una porta specificasudo lsof -i:80 -Pn
# Monitora le connessioni ESTABLISHEDsudo lsof -i -Pn | grep ESTABLISHED# Visualizza le porte LISTENsudo lsof -i -Pn | grep LISTEN
# per vedere i nomi di rete invece degli indirizzi IP (può essere molto lento a causa delle risoluzioni DNS inverse)sudo lsof -i -P | grep LISTEN
# Monitorare tutte le connessioni di retesudo watch -n1 "lsof -i -Pn"Output di esempio

Monitoraggio dei file
Per identificare quali processi stanno consumando più larghezza di banda del disco, puoi usare iotop:
sudo iotopPer osservare le modifiche a singoli file, usa inotifywait su Linux o fswatch su macOS:
Questo può risultare utile per rilevare comportamenti non autorizzati o anomali a livello di cartella o dell’intero sistema.
# Monitorare tutte le modifiche ai file in una directorysudo inotifywait -m /path/to/directorySu macOS puoi usare fswatch:
Installa con brew install fswatch
fswatch -r /path/to/directory⏰ Suggerimenti spesso trascurati
-
Rate Limiting per i tentativi di autenticazione e per qualsiasi altro endpoint critico. Che sia tramite il modulo
limit_reqdi Nginx ofail2banper l’accesso SSH, limitare i brute‑force è probabilmente una buona idea. Dico probabilmente perché, nell’era di IPv6 e botnet a basso costo, le cose non sono più come una volta. -
Usa volumi in sola lettura dove possibile:
services:webapp:volumes:- ./config:/config:roIn combinazione con altre best practice (utenti non root, permessi di cartella minimi), l’opzione di mount
:roaggiunge una salvaguardia contro modifiche accidentali e alcuni tentativi di scrittura dall’interno del container. Non protegge l’host da un processo che già possiede privilegi più ampi. -
Esegui audit regolari sull’accesso ai container.
Se un container non ha bisogno di un secret, di una porta o di un mount, rimuovili! -
Fai attenzione al Wi‑Fi
Sono sicuro che non darai mai la password del tuo Wi‑Fi a sconosciuti, vero? Beh, tranne qualche amico… Ok, forse anche alla famiglia. Non sai mai quali app usano e quali potrebbero condividere SSID e password con il mondo.
Rete domestica vs. Provider pubblico vs. Tunneling
-
Isolamento virtuale/DMZ: per i server domestici, posizionali su una VLAN o DMZ separata, se possibile. Questo mantiene i tuoi dispositivi interni fuori dalla portata di eventuali compromissioni provenienti dal server.
- Usa un router o una VLAN dedicata per il tuo server domestico.
- Usa una rete Wi‑Fi separata per il tuo server domestico.
- Usa una subnet separata per il tuo server domestico.
-
Provider Cloud: Hetzner, Vultr, DigitalOcean, Linode, AWS, Azure e Google Cloud offrono funzionalità firewall differenti.
- Alcuni provider e servizi bloccano le porte per impostazione predefinita. Alcuni offrono opt‑in o componenti aggiuntivi. Controlla la documentazione del tuo provider.
- Molti provider mettono a disposizione servizi avanzati di monitoraggio e rilevamento delle minacce.
-
VPN e Tunneling: Valuta l’uso di un’opzione tipo VPN o di un servizio di tunneling per collegare in modo sicuro i servizi attraverso Internet senza esporli al pubblico.
- TailScale, ngrok, ZeroTier.
- WireGuard, OpenVPN.
🚀 Checklist di Produzione
- Segreti: Tutti i segreti generati casualmente e archiviati in modo sicuro
- Aggiornamenti: Strategia di aggiornamento dei container documentata e automatizzata. (Va bene anche se è solo qualche comando in un file di testo.)
- Rete: Solo le porte necessarie esposte, reti interne configurate.
- Regole Firewall: Default deny, allow espliciti, blocchi per paese se necessario.
- Reverse Proxy: Nginx, Caddy o Traefik possono aggiungere un livello di autenticazione di base.
- Canary Tokens: Posizionali vicino ai file sensibili e alle credenziali che effettivamente indagheresti se toccati.
- Monitoraggio Conosci i tuoi sistemi con
nmap,lsof,inotifywait,glances, ecc. - Strategia di Backup: Testata, preferibilmente automatizzata e off‑site.
- Principio del Minimo Privilegio: Utenti non root nei container, volumi read‑only.
📚 Ulteriori Letture
- Docker Security Best Practices
- OWASP Docker Security Cheat Sheet
- CIS Docker Benchmark
- Canarytokens.org for Canary Tokens
Grazie
Un ringraziamento a qualche Redditor attento:
Grazie per aver letto! Spero che questa guida ti sia stata utile. Se hai domande o suggerimenti, contattami sui miei social qui sotto, oppure clicca sul collegamento Edit on GitHub per aprire una PR! ❤️