Scelta architetturale su Debian 12
Nginx Proxy Manager (NPM) conviene installarlo come stack Docker su Debian 12: separi bene i componenti, semplifichi aggiornamenti e rollback, e tieni sotto controllo i file di configurazione. L’approccio più pulito è usare Docker Engine e Docker Compose, con volumi persistenti per configurazione, certificati e database.
Lo scenario tipico è questo: Debian 12 come host, NPM esposto su porte 80/443 per i reverse proxy pubblici, e la web UI amministrativa limitata a rete fidata o almeno protetta da accesso ristretto. Se hai già un web server sulla macchina, devi decidere prima chi prende 80/443: NPM oppure il servizio esistente. Non vanno condivise alla cieca.
Obiettivo di sicurezza minimo: ridurre la superficie esposta, proteggere l’accesso admin, mantenere i dati persistenti separati dal container, aggiornare senza rompere il servizio e avere un rollback semplice.
Prerequisiti minimi
- Debian 12 aggiornato.
- Accesso root o sudo.
- Una macchina con IP pubblico o raggiungibile dal reverse proxy che userai.
- DNS già pronto per i domini che passeranno da NPM.
- Porte 80 e 443 libere se NPM deve gestire il traffico HTTPS pubblico.
Se la macchina ospita già Apache, Nginx, Caddy o un altro servizio su 80/443, fermalo o spostalo prima di procedere. Verifica con:
sudo ss -ltnp | egrep ':(80|443)'Atteso: nessun altro processo deve occupare le porte che assegnerai a NPM. Se trovi un listener, identifica il servizio prima di modificare nulla.
Installazione base di Docker su Debian 12
Usa i pacchetti ufficiali di Docker per evitare versioni vecchie o incoerenti nei repository Debian. La sequenza sotto installa prerequisiti, repository e motore Docker.
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginVerifica subito che il servizio sia attivo:
sudo systemctl status docker --no-pagerAtteso: active (running). Se non lo è, controlla i log con journalctl -u docker -n 50 --no-pager prima di andare avanti.
Creazione directory persistenti
Metti i dati di NPM in una directory dedicata, ad esempio /opt/npm. Questo ti aiuta con backup e rollback.
sudo mkdir -p /opt/npm/{data,letsencrypt}
sudo chown -R root:root /opt/npm
sudo chmod 0755 /opt/npm /opt/npm/data /opt/npm/letsencryptSe vuoi tenere il file di Compose separato, crea anche una cartella di lavoro:
sudo mkdir -p /opt/npm-stackCon questa struttura puoi fare snapshot o backup del contenuto in modo semplice, senza toccare l’immagine container.
Docker Compose per Nginx Proxy Manager
Per installare NPM in modo ripetibile, crea un file docker-compose.yml dedicato. Usa una password iniziale robusta e non lasciare valori deboli nei file condivisi.
cd /opt/npm-stack
sudo nano docker-compose.ymlContenuto consigliato:
services:
app:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81"
environment:
DB_SQLITE_FILE: "/data/database.sqlite"
volumes:
- /opt/npm/data:/data
- /opt/npm/letsencrypt:/etc/letsencryptQuesta configurazione usa SQLite, che è la scelta più semplice per installazioni singole o piccole. Se prevedi alta disponibilità o più istanze, valuta MySQL/MariaDB esterno, ma per la maggior parte dei casi su Debian 12 SQLite basta e riduce complessità.
Nota importante: la porta admin 81 è legata a 127.0.0.1, quindi non è esposta su tutte le interfacce. È una misura di hardening minima e pratica.
Avvio del servizio
Avvia lo stack e verifica che il container sia su:
cd /opt/npm-stack
sudo docker compose up -d
sudo docker ps --filter name=npmAtteso: il container npm deve risultare Up. Se si ferma subito, guarda i log:
sudo docker logs --tail 100 npmPer il primo accesso apri la UI da localhost o tramite tunnel SSH se sei remoto:
ssh -L 8181:127.0.0.1:81 user@serverPoi visita http://127.0.0.1:8181. In alternativa, se hai deciso di esporre la porta admin su rete, fallo solo dietro firewall e rete fidata.
Credenziali iniziali e primo hardening
Al primo login, cambia immediatamente l’account amministrativo predefinito. La UI iniziale di NPM usa credenziali note e non va lasciata così.
Subito dopo il primo accesso:
- cambia email e password dell’admin;
- abilita l’autenticazione a due fattori se disponibile nella tua versione;
- limita l’accesso alla UI admin a IP di gestione o VPN;
- non pubblicare la porta 81 su Internet.
Se usi un firewall host-based, consenti solo ciò che serve.
Firewall su Debian 12
Se usi nftables o ufw, apri solo le porte necessarie. Esempio con UFW, se è il tuo standard operativo:
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 127.0.0.1 to any port 81 proto tcp
sudo ufw enable
sudo ufw status verboseAtteso: 22, 80 e 443 devono essere aperte; 81 deve restare accessibile solo da loopback se la UI è bindata su 127.0.0.1. Se gestisci la macchina via VPN, puoi restringere ancora di più la porta SSH.
Se preferisci nftables, mantieni la stessa logica: consenti solo gestione, HTTP e HTTPS, e non esporre la dashboard amministrativa.
Primo proxy host e certificato TLS
La funzione principale di NPM è creare reverse proxy verso servizi interni. Dopo il login, crea un Proxy Host puntando a un backend interno, ad esempio un’app su 127.0.0.1:3000 o su IP privato.
Configurazione tipica:
- Domain Names: il dominio pubblico.
- Scheme:
httpohttpsa seconda del backend. - Forward Hostname / IP: indirizzo del servizio origin.
- Forward Port: porta dell’app.
- Websockets Support: attiva se il backend lo richiede.
- Block Common Exploits: attiva.
Per il TLS, usa Let’s Encrypt solo dopo aver verificato che il DNS punti correttamente alla macchina e che le porte 80/443 siano raggiungibili dall’esterno. Se la validazione fallisce, controlla prima:
curl -I http://tuodominio.tldAtteso: risposta HTTP raggiungibile dalla rete pubblica. Se ottieni timeout o NXDOMAIN, il problema non è NPM ma DNS o routing.
Hardening della superficie esposta
Qui si fa la differenza tra “funziona” e “è esposto male”. Le misure minime sono poche e concrete.
- Non esporre la porta 81 su WAN.
- Usa password forte e 2FA sull’account admin.
- Limita SSH a chi serve davvero.
- Tieni aggiornato Docker e l’immagine NPM.
- Evita volumi con permessi troppo larghi.
Controlla i permessi dei volumi:
sudo ls -ld /opt/npm /opt/npm/data /opt/npm/letsencryptAtteso: ownership chiara e permessi non world-writable. Se trovi permessi anomali, correggili prima di procedere con l’esposizione pubblica.
Se usi SELinux o AppArmor in modalità restrittiva, verifica che non blocchino Docker o i bind mount. Su Debian 12 il caso più comune resta però il firewall e la gestione dei listener.
Aggiornamento controllato e rollback
Con Docker, l’aggiornamento è semplice ma va fatto con disciplina. Prima di aggiornare, salva lo stato e verifica lo spazio disco.
df -h
sudo docker compose pull
sudo docker compose up -dPrima di cambiare versione, fai una copia dei dati persistenti:
sudo tar -czf /root/npm-backup-$(date +%F).tar.gz -C /opt npmSe qualcosa va storto, il rollback tipico è rimettere il tag immagine precedente nel file di Compose e rilanciare docker compose up -d. Se usi latest, il rollback è meno preciso: meglio fissare una versione nota quando passi in produzione.
Rollback operativo:
- ferma lo stack:
sudo docker compose down; - ripristina il file
docker-compose.ymldalla copia di backup; - riavvia:
sudo docker compose up -d; - verifica log e accesso UI.
Controlli finali di sicurezza e funzionamento
Dopo l’installazione, fai questi controlli minimi:
- Servizio attivo:
sudo docker ps --filter name=npmdeve mostrare il container in esecuzione. - Listener corretti:
sudo ss -ltnp | egrep ':(80|443|81)'deve mostrare 81 solo su loopback se hai applicato il binding locale. - UI raggiungibile: accesso su
http://127.0.0.1:8181via tunnel o sulla rete di gestione autorizzata. - Certificato valido: dal browser o con
curl -I https://tuodominio.tldverifica che il certificato sia emesso correttamente. - Log puliti:
sudo docker logs --tail 50 npmnon deve mostrare errori ripetuti su database, bind o permessi.
Se vuoi un controllo più sintetico della reachability pubblica, usa:
curl -sI https://tuodominio.tld | headAtteso: risposta 200, 301 o 302 coerente con la tua configurazione. Errori 502 o 504 indicano che NPM è su ma il backend proxyato non risponde.
Problemi comuni da evitare
- Lasciare la porta 81 esposta su Internet.
- Usare credenziali predefinite oltre il primo accesso.
- Mettere NPM su 80/443 senza verificare conflitti con altri servizi.
- Ignorare il backup dei volumi prima degli upgrade.
- Confondere problemi DNS con problemi di NPM.
Se il certificato Let’s Encrypt non viene emesso, la causa più frequente è una combinazione di DNS errato, porta 80 non raggiungibile o proxy/CDN davanti che blocca la challenge. In quel caso, prima di cambiare configurazioni a caso, verifica il layer di rete e la raggiungibilità esterna.
Conclusione operativa
Su Debian 12, Nginx Proxy Manager si installa bene in Docker se tieni separati i dati persistenti, limiti la dashboard admin, apri solo le porte necessarie e fai controlli dopo ogni modifica. La regola pratica è semplice: prima osservi, poi cambi una cosa sola, poi verifichi. Così eviti di trasformare un proxy utile in un punto unico di fallimento.
Assunzione: macchina Debian 12 singola, uso standard di Docker Compose, UI admin non esposta pubblicamente, e dominio già delegato correttamente verso l’host.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.