Nginx Proxy Manager (NPM) è un server web progettato per semplificare la gestione di Nginx, con particolare attenzione alla funzionalità di reverse proxy.

Un reverse proxy funge da intermediario tra i client esterni e i servizi interni: riceve le richieste HTTP/HTTPS in entrata e le inoltra al servizio o all’applicazione appropriata in base all’indirizzo richiesto.

reverse-proxy

Uno dei punti di forza di NPM è la gestione semplificata dei certificati SSL. Per abilitare il protocollo HTTPS, l’applicazione si integra nativamente con Let’s Encrypt, un servizio che fornisce certificati SSL gratuiti. È sufficiente specificare il dominio o il sottodominio di riferimento affinché NPM provveda alla generazione, all’installazione e al rinnovo automatico dei certificati, eliminando la necessità di interventi manuali.

Nginx, nella sua forma nativa, richiede la configurazione manuale tramite file di testo e comandi da terminale, mentre NPM offre un’interfaccia grafica intuitiva, che ne semplifica notevolmente la gestione.

Nginx Proxy Manager Plus

npm

NPM Plus è un fork di Nginx Proxy Manager, sviluppato con l’obiettivo di migliorarne la stabilità, la sicurezza e l’integrazione con strumenti moderni, mantenendo una compatibilità totale con il progetto originale.

Le migliorie principali sono:

Creazione della VLAN per NPM Plus

Come descritto nella documentazione relativa alla creazione della VLAN DMZ, la prima fase prevede la configurazione di una VLAN dedicata in OPNsense, seguendo le specifiche tecniche di seguito riportate:

  • Tag VLAN: 70
  • Subnet: 10.0.70.0/24
  • Gateway: 10.0.70.254
  • Range DHCP: 10.0.70.50-10.0.70.249
  • Indirizzo IP assegnato alla VM (NPMP_VM): 10.0.70.1

Sebbene per una singola macchina virtuale non sia strettamente necessaria l’allocazione di un servizio DHCP o l’utilizzo di una subnet con 254 indirizzi, questa configurazione viene adottata per comodità operativa.

Regole di firewall

Successivamente alla creazione e all’abilitazione della VLAN, è fondamentale configurare le regole di firewall. Queste regole devono garantire che la VM di NPM Plus possa accedere alle risorse presenti nella DMZ attraverso le porte web standard (80 per HTTP e 443 per HTTPS), nonché raggiungere i nodi Proxmox VE e Proxmox Backup, rispettivamente sulle porte 8006 e 8007. L’immagine seguente illustra l’applicazione di tali regole:

npm-vlan-rules

Configurazione dello switch

Per il corretto funzionamento della VLAN, è necessario configurare anche lo switch. L’operazione prevede il tagging della VLAN 70 sulla porta configurata in modalità trunk (nello specifico, la porta 1).

create-npm-vlan-switch

Installazione e configurazione di NPM Plus

La procedura di deployment si articola nei seguenti passaggi:

  • Creazione di una VM Debian in Proxmox, utilizzando un template o le immagini qcow2 ufficiali, secondo le modalità descritte nell’articolo dedicato
  • Installazione di Docker sulla macchina virtuale, seguendo la procedura ufficiale
  • Creazione del file docker-compose.yml all’interno della directory /opt/npmp, con il seguente contenuto:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
name: npmplus
services:
  npmplus:
    container_name: npmplus
    image: docker.io/zoeyvid/npmplus:latest # or ghcr.io/zoeyvid/npmplus:latest
    restart: unless-stopped
    ports:
      - 81:81
      - 443:443
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    volumes:
      - "/opt/npmplus:/data"
    environment:
      - "TZ=Europe/Rome"
      - "DISABLE_IPV6=true"
      - "DISABLE_HTTP=true"
      - "LOGROTATE=true"
      - "LOGROTATIONS=7"
  • Avviare il container col comando docker compose up -d

Le direttive cap_drop e security_opt costituiscono importanti misure di hardening volte a ridurre la superficie di attacco di un container, applicando il principio del privilegio minimo. L’obiettivo consiste nel limitare i privilegi disponibili ai processi in esecuzione, consentendo esclusivamente le operazioni strettamente necessarie al corretto funzionamento dell’applicazione.

In un sistema Linux, i processi eseguiti con privilegi di root (UID 0) dispongono, per impostazione predefinita, di un insieme esteso di privilegi sul sistema operativo. Per evitare che tali privilegi siano gestiti come un unico blocco, il kernel implementa il meccanismo delle Linux Capabilities, che suddivide i privilegi amministrativi in un insieme di capacità indipendenti e assegnabili singolarmente.

La direttiva:

1
2
cap_drop:
  - ALL

rimuove tutte le capabilities assegnate ai processi del container. Di conseguenza, anche qualora l’applicazione venisse compromessa, il codice malevolo opererebbe in un ambiente fortemente limitato, privo dei privilegi necessari per eseguire operazioni amministrative o interagire con il kernel attraverso funzionalità privilegiate.

L’opzione:

1
2
security_opt:
  - no-new-privileges:true

impedisce a qualsiasi processo del container di acquisire privilegi superiori rispetto a quelli posseduti al momento della sua creazione. In assenza di questa protezione, un processo potrebbe, in determinate circostanze, ottenere privilegi aggiuntivi eseguendo un file contrassegnato con il bit setuid oppure sfruttando altri meccanismi di elevazione dei privilegi previsti dal sistema operativo.

Certificati SSL

Per garantire la sicurezza delle comunicazioni, è necessario generare un certificato self-signed sulla macchina host, eseguendo i seguenti comandi:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mkdir -p ~/certs

openssl req -x509 -nodes -days 1095 \
  -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
  -keyout home.lan.key -out home.lan.crt \
  -subj "/CN=home.lan" \
  -addext "subjectAltName=DNS:*.home.lan,DNS:home.lan,IP:10.0.99.21,IP:10.0.99.20" \
  -addext "keyUsage=digitalSignature,keyEncipherment" \
  -addext "extendedKeyUsage=serverAuth" \
  -sha256

nello specifico:

  • -days 1095: imposta la validità del certificato a 1095 giorni
  • -newkey ec: crea una nuova coppia di chiavi basata sulla crittografia a curve ellittiche
  • -pkeyopt ec_paramgen_curve:prime256v1: seleziona la curva ellittica prime256v1 per la generazione della chiave
  • -keyout home.lan.key: specifica il file in cui salvare la chiave privata
  • -out home.lan.crt: specifica il file in cui salvare il certificato
  • -subj "/CN=home.lan": imposta automaticamente il Common Name del certificato, evitando l’inserimento interattivo dei dati
  • -addext "subjectAltName=...": aggiunge l’estensione Subject Alternative Name, definendo i nomi DNS e gli indirizzi IP per cui il certificato è valido
  • -sha256: utilizza l’algoritmo di hashing SHA-256 per la firma del certificato

Poiché il certificato è self-signed, la relativa CA non è riconosciuta come attendibile dal sistema operativo o dalle varie applicazioni. Per evitare errori di validazione durante l’instaurazione delle connessioni TLS, è necessario importarlo nel sistema:

1
2
3
cp home.lan.crt /usr/local/share/ca-certificates/

update-ca-certificates

Si consiglia di importare il certificato anche nei vari browser utilizzati, seguendo le guide che si trovano online, come How to Trust a Self-Signed Certificate in Firefox

Primo accesso a NPMP

Per consentirci l’accesso iniziale all’interfaccia di amministrazione, è necessario creare apposite regole di firewall. In questa fase preliminare, antecedente alla configurazione dei Proxy Host, la regola deve includere anche l’apertura della porta 81, oltre alle classiche porte WEB.

allow-access-npm-vm-web-ports

A questo punto è possibile accedere a NPMP tramite l’indirizzo http://10.0.70.1:81, procedendo alla creazione dell’utente amministratore.

Una volta effettuato l’accesso, il certificato precedentemente generato deve essere caricato nella sezione dedicata ai certificati personalizzati (Custom Certificates).

add-custom-certs

Creazione dei Proxy Host

La configurazione del reverse proxy avviene tramite la creazione di nuovi Proxy Host. Per ciascun servizio da esporre, è necessario inserire il nome di dominio, l’indirizzo IP di destinazione e la porta.

create-new-proxy-host

Nel pannello SSL del Proxy Host, è obbligatorio selezionare il certificato personalizzato appena importato per abilitare la crittografia HTTPS.

add-custom-tls-proxy-host

Qualora il servizio di destinazione lo richieda, è possibile inserire direttive personalizzate nel campo Advanced Configuration. Ad esempio, per le istanze di Proxmox VE e Proxmox Backup, la documentazione ufficiale raccomanda l’inserimento delle seguenti direttive:

1
2
3
4
5
6
7
8
9
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
client_max_body_size 0;
proxy_connect_timeout  3600s;
proxy_read_timeout  3600s;
proxy_send_timeout  3600s;
send_timeout  3600s;

Si consiglia di configurare un reverse proxy per NPM stesso, in modo da eliminare la necessità di accedere tramite la porta 81 e utilizzare esclusivamente HTTPS con il certificato personalizzato.

npm-behind-npm

Configurazione DNS locale

Creare le seguenti entry DNS in OPNsense Services > Unbound DNS > Overrides, in modo che tutti i record puntino al server NPM:

dns-overrides

Per Home Assistant, è necessario seguire la procedura specifica descritta nella documentazione di riferimento, aggiungendo l’indirizzo IP di NPMP ai trusted_proxies e importando il certificato sui dispositivi mobili, come spiegato in precedenza.

Riferimenti