Hosting di ASP.NET Core in Linux con Nginx
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Questa guida illustra la configurazione di un ambiente core ASP.NET pronto per la produzione per Ubuntu, Red Hat Enterprise (RHEL) e SUSE Linux Enterprise Server.
Per informazioni su altre distribuzioni Linux supportate da ASP.NET Core, vedere Prerequisiti per .NET Core in Linux.
In questa guida:
- Posizionare un'app ASP.NET Core esistente dietro un server proxy inverso.
- Imposta il server proxy inverso per inoltrare le richieste al Kestrel server Web.
- Verificare che l'app Web venga eseguita all'avvio come daemon.
- Configurare uno strumento di gestione del processo per consentire il riavvio dell'app Web.
Prerequisiti
- Accesso a Ubuntu 20.04 con un account utente standard con privilegi sudo.
- Il runtime .NET stabile più recente installato nel server.
- Un'app ASP.NET Core esistente.
In qualsiasi momento in futuro dopo l'aggiornamento del framework condiviso, riavviare le app ASP.NET Core ospitate dal server.
Pubblicare e copiare l'app
Configurare l'app per una distribuzione dipendente dal framework.
Se l'app viene eseguita localmente nell'ambiente di sviluppo e non è configurata dal server per stabilire connessioni HTTPS sicure, adottare uno degli approcci seguenti:
Configurare l'app per la gestione di connessioni locali sicure. Per altre informazioni, vedere la sezione Configurazione HTTPS.
Configurare l'app per l'esecuzione nell'endpoint non sicuro:
Disattivare il middleware di reindirizzamento HTTPS nell'ambiente di sviluppo (
Program.cs
):if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
Rimuovere
https://localhost:5001
(se presente) dallaapplicationUrl
proprietà nelProperties/launchSettings.json
file.
Per altre informazioni sulla configurazione per ambiente, vedere Usare più ambienti in ASP.NET Core.
Eseguire dotnet publish dall'ambiente di sviluppo per creare un pacchetto di un'app in una directory ( ad esempio , bin/Release/{TARGET FRAMEWORK MONIKER}/publish
dove il {TARGET FRAMEWORK MONIKER}
segnaposto è il moniker framework di destinazione (TFM) che può essere eseguito nel server:
dotnet publish --configuration Release
È anche possibile pubblicare l'app come distribuzione completa se si preferisce non mantenere il runtime .NET Core nel server.
Copiare l'app ASP.NET Core nel server usando uno strumento che si integra nel flusso di lavoro dell'organizzazione ( ad esempio , SCP
). SFTP
È comune individuare le app Web nella var
directory , ad esempio var/www/helloapp
.
Nota
In uno scenario di distribuzione di produzione un flusso di lavoro di integrazione continua esegue le operazioni di pubblicazione dell'app e di copia degli asset nel server.
Eseguire il test dell'app:
- Dalla riga di comando, eseguire l'app:
dotnet <app_assembly>.dll
. - In un browser passare a
http://<serveraddress>:<port>
per verificare se l'app funziona in Linux in locale.
Configurare un server proxy inverso
Un proxy inverso è una configurazione comune per la gestione delle app Web dinamiche. Un proxy inverso termina la richiesta HTTP e la inoltra all'app ASP.NET Core.
Usare un server proxy inverso
Kestrel è ideale per gestire contenuto dinamico da ASP.NET Core. Tuttavia, le funzionalità di gestione Web sono meno avanzate rispetto a quelle offerte da server come IIS, Apache o Nginx. Un server proxy inverso è in grado di eseguire l'offload di attività come la gestione del contenuto statico, la memorizzazione nella cache delle richieste, la compressione delle richieste e la terminazione HTTPS dal server HTTP. Un server proxy inverso può risiedere in un computer dedicato o essere distribuito insieme a un server HTTP.
Ai fini di questa guida viene usata una singola istanza di Nginx. Viene eseguito sullo stesso server, insieme al server HTTP. In base ai requisiti, è possibile scegliere una configurazione diversa.
Poiché le richieste vengono inoltrate tramite proxy inverso, usare il middleware delle intestazioni inoltrate dal Microsoft.AspNetCore.HttpOverrides
pacchetto, incluso automaticamente nelle app core ASP.NET tramite il metapacchetto del Microsoft.AspNetCore.App
framework condiviso. Il middleware aggiorna Request.Scheme
usando l'intestazione X-Forwarded-Proto
, in modo che gli URI di reindirizzamento e altri criteri di sicurezza funzionino correttamente.
Il middleware delle intestazioni inoltrate deve essere eseguito prima di altro middleware. Questo ordine garantisce che il middleware basato sulle intestazioni inoltrate possa usare i valori di intestazione per l'elaborazione. Per eseguire il middleware delle intestazioni inoltrate dopo il middleware di diagnostica e gestione degli errori, vedere Ordine del middleware delle intestazioni inoltrate.
Richiamare il metodo prima di UseForwardedHeaders chiamare un altro middleware. Configurare il middleware per l'inoltro delle intestazioni X-Forwarded-For
e X-Forwarded-Proto
:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication();
var app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
app.MapGet("/", () => "Hello ForwardedHeadersOptions!");
app.Run();
Se non vengono specificate opzioni ForwardedHeadersOptions per il middleware, le intestazioni predefinite per l'inoltro sono None
.
I proxy in esecuzione negli indirizzi di loopback (127.0.0.0/8
, [::1]
), incluso l'indirizzo localhost standard (127.0.0.1
), sono considerati attendibili per impostazione predefinita. Se altri proxy o reti attendibili all'interno dell'organizzazione gestiscono le richieste tra Internet e il server Web, aggiungerli all'elenco di KnownProxies o KnownNetworks con ForwardedHeadersOptions. Nell'esempio seguente viene aggiunto un server proxy attendibile all'indirizzo 10.0.0.100
IP del middleware KnownProxies
delle intestazioni inoltrate:
using Microsoft.AspNetCore.HttpOverrides;
using System.Net;
var builder = WebApplication.CreateBuilder(args);
// Configure forwarded headers
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
builder.Services.AddAuthentication();
var app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
app.MapGet("/", () => "10.0.0.100");
app.Run();
Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.
Installare Nginx
Usare apt-get
per installare Nginx. Il programma di installazione crea uno systemd
script init che esegue Nginx come daemon all'avvio del sistema. Seguire le istruzioni di installazione per Ubuntu riportate nell'articolo Nginx: Official Debian/Ubuntu packages (Nginx: pacchetti Debian/Ubuntu ufficiali).
Nota
Se sono richiesti moduli Nginx facoltativi, potrebbe essere necessario compilare Nginx dall'origine.
Poiché Nginx è stato installato per la prima volta, avviarlo in modo esplicito eseguendo:
sudo service nginx start
Verificare che un browser visualizzi la pagina di destinazione predefinita per Nginx. La pagina di destinazione è raggiungibile all'indirizzo http://<server_IP_address>/index.nginx-debian.html
.
Configurare Nginx
Per configurare Nginx come proxy inverso per inoltrare le richieste HTTP all'app ASP.NET Core, modificare /etc/nginx/sites-available/default
e ricreare il collegamento simbolico. Dopo aver creato il /etc/nginx/sites-available/default
file, usare il comando seguente per creare il collegamento simbolico:
sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
Aprire /etc/nginx/sites-available/default
in un editor di testo e sostituire il contenuto con il frammento di codice seguente:
http {
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://127.0.0.1:5000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Se l'app è un'app SignalR o Blazor Server , vedere ASP.NET Hosting di produzione core SignalR e ridimensionamento e Host e distribuire rispettivamente ASP.NET app sul lato Blazor server Core per altre informazioni.
Se nessun server_name
corrisponde, Nginx usa il server predefinito. Se non è definito alcun server predefinito, il primo server nel file di configurazione è il server predefinito. Come procedura consigliata, aggiungere un server predefinito specifico che restituisce un codice di stato 444 nel file di configurazione. Un esempio di configurazione del server predefinito è il seguente:
server {
listen 80 default_server;
# listen [::]:80 default_server deferred;
return 444;
}
Con il file di configurazione precedente e il server predefinito, Nginx accetta il traffico pubblico sulla porta 80 con l'intestazione host example.com
o *.example.com
. Le richieste che non corrispondono a questi host non verranno inoltrate a Kestrel. Nginx inoltra le richieste corrispondenti a in Kestrel http://127.0.0.1:5000/
. Per altre informazioni, vedere Come nginx elabora una richiesta. Per modificare Kestrell'INDIRIZZO IP/porta, vedere Kestrel: Configurazione dell'endpoint.
Avviso
Se non si specifica una direttiva server_name corretta, l'app può risultare esposta a vulnerabilità di sicurezza. L'associazione con caratteri jolly del sottodominio (ad esempio, *.example.com
) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com
, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Semantica HTTP (sezione 7.2: host e :authority).
Una volta stabilita la configurazione di Nginx, eseguire sudo nginx -t
per verificare la sintassi dei file di configurazione. Se il test dei file di configurazione ha esito positivo, è possibile forzare Nginx ad applicare le modifiche eseguendo sudo nginx -s reload
.
Per eseguire direttamente l'app nel server:
- Passare alla directory dell'app.
- Eseguire l'app:
dotnet <app_assembly.dll>
, doveapp_assembly.dll
è il nome di file di assembly dell'app.
Se l'app viene eseguita sul server ma non risponde su Internet, controllare il firewall del server e verificare che la porta 80 sia aperta. Se si usa una macchina virtuale Ubuntu di Azure, aggiungere una regola del gruppo di sicurezza di rete (NSG) che abiliti il traffico in ingresso della porta 80. Non è necessario abilitare una regola per il traffico in uscita della porta 80, poiché il traffico in uscita viene autorizzato automaticamente quando viene abilitata la regola in ingresso.
Al termine del test dell'app, arrestare l'app con CTRL+C (Windows) o ⌘+C (macOS) al prompt dei comandi.
Aumentare keepalive_requests
keepalive_requests
può essere aumentato per prestazioni più elevate. Per altre informazioni, vedere questo problema di GitHub.
Monitorare l'app
Il server è configurato per inoltrare le richieste effettuate a http://<serveraddress>:80
all'app ASP.NET Core in esecuzione Kestrel in .http://127.0.0.1:5000
Tuttavia, Nginx non è configurato per gestire il Kestrel processo. systemd
può essere usato per creare un file di servizio per avviare e monitorare l'app Web sottostante. systemd
è un sistema init che offre molte potenti funzionalità per l'avvio, l'arresto e la gestione dei processi.
Creare il file del servizio
Creare il file di definizione del servizio:
sudo nano /etc/systemd/system/kestrel-helloapp.service
L'esempio seguente è un .ini
file di servizio per l'app:
[Unit]
Description=Example .NET Web API App running on Linux
[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
[Install]
WantedBy=multi-user.target
Nell'esempio precedente l'utente che gestisce il servizio viene specificato dall'opzione User
. L'utente (www-data
) deve esistere e avere la proprietà appropriata dei file dell'app.
Usare TimeoutStopSec
per configurare il tempo di attesa prima che l'app si arresti dopo aver ricevuto il segnale di interrupt iniziale. Se l'app non si arresta in questo periodo, viene emesso il comando SIGKILL per terminare l'app. Specificare il valore in secondi senza unità di misura (ad esempio, 150
), un valore per l'intervallo di tempo (ad esempio, 2min 30s
) o infinity
per disabilitare il timeout. TimeoutStopSec
per impostazione predefinita il valore di nel file di configurazione di DefaultTimeoutStopSec
gestione (systemd-system.conf
, system.conf.d
, systemd-user.conf
, user.conf.d
). Il timeout predefinito per la maggior parte delle distribuzioni è di 90 secondi.
# The default value is 90 seconds for most distributions.
TimeoutStopSec=90
Linux dispone di un file system con distinzione tra maiuscole e minuscole. Se si imposta ASPNETCORE_ENVIRONMENT
su Production
viene eseguita la ricerca del file appsettings.Production.json
di configurazione , non appsettings.production.json
.
Per alcuni valori (ad esempio, le stringhe di connessione SQL) è necessario usare caratteri di escape, in modo da consentire ai provider di configurazione di leggere le variabili di ambiente. Usare il comando seguente per generare un valore con caratteri di escape corretti per l'uso nel file di configurazione:
systemd-escape "<value-to-escape>"
I due punti (:
) separatori non sono supportati nei nomi delle variabili di ambiente. Usare un doppio carattere di sottolineatura (__
) al posto dei due punti. Il provider di configurazione delle variabili di ambiente converte le doppie sottolineature in due punti quando le variabili di ambiente vengono lette nella configurazione. Nell'esempio seguente la chiave della stringa di connessione ConnectionStrings:DefaultConnection
è impostata nel file di definizione del servizio come ConnectionStrings__DefaultConnection
:
Environment=ConnectionStrings__DefaultConnection={Connection String}
Salvare il file e abilitare il servizio.
sudo systemctl enable kestrel-helloapp.service
Avviare il servizio e verificare che sia in esecuzione.
sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service
◝ kestrel-helloapp.service - Example .NET Web API App running on Linux
Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
CGroup: /system.slice/kestrel-helloapp.service
└─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
Con il proxy inverso configurato e Kestrel gestito tramite systemd
, l'app Web è completamente configurata e accessibile da un browser nel computer locale all'indirizzo http://localhost
. È anche possibile accedervi da un computer remoto, escludendo eventuali firewall che potrebbero impedirlo. Esaminando le intestazioni di risposta, l'intestazione Server
mostra l'app ASP.NET Core gestita da Kestrel.
HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Visualizzare i log
Poiché l'app Web che usa Kestrel viene gestita tramite systemd
, tutti gli eventi e i processi vengono registrati in un journal centralizzato. Tuttavia, questo giornale include tutte le voci per tutti i servizi e i processi gestiti da systemd
. Per visualizzare le voci specifiche di kestrel-helloapp.service
, usare il comando seguente:
sudo journalctl -fu kestrel-helloapp.service
Per filtrare ulteriormente, le opzioni temporali, --since today
ad esempio , --until 1 hour ago
o una combinazione di queste opzioni, possono ridurre il numero di voci restituite.
sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"
Protezione dei dati
Lo stack di protezione dei dati core ASP.NET viene usato da diversi middleware di base ASP.NET, tra cui il middleware di autenticazione (ad esempio, cookie middleware) e le protezioni di richiesta intersito (CSRF). Anche se le DPAPI (Data Protection API) non vengono chiamate dal codice dell'utente, è consigliabile configurare la protezione dati per la creazione di un archivio di chiavi crittografiche permanente. Se non si configura la protezione dei dati, le chiavi vengono mantenute in memoria ed eliminate al riavvio dell'app.
Se il gruppo di chiavi viene archiviato in memoria quando l'app viene riavviata:
- Tutti i token di autenticazione basati su cookie vengono invalidati.
- Gli utenti devono ripetere l'accesso alla richiesta successiva.
- Tutti i dati protetti con il gruppo di chiavi non possono più essere decrittografati. Possono essere inclusi i token CSRF e i cookie TempData di ASP.NET Core MVC.
Per configurare la protezione dei dati in modo da rendere persistente il gruppo di chiavi e crittografarlo, vedere:
- Provider di archiviazione chiavi in ASP.NET Core
- Crittografia delle chiavi rest in Windows e Azure con ASP.NET Core
Campi di intestazione della richiesta di grandi dimensioni
Le impostazioni predefinite del server proxy limitano in genere i campi di intestazione della richiesta a 4 K o 8 K a seconda della piattaforma. Un'app può richiedere campi più lunghi del valore predefinito,ad esempio le app che usano l'ID Microsoft Entra. Se sono necessari campi più lunghi, le impostazioni predefinite del server proxy richiedono la regolazione. I valori da applicare dipendono dallo scenario. Per altre informazioni, vedere la documentazione del server.
Avviso
Aumentare i valori predefiniti dei buffer proxy solo se necessario. Se si aumentano questi valori, si aumenta il rischio di sovraccarico del buffer (overflow) e di attacchi Denial of Service (DoS) da parte di utenti malintenzionati.
Proteggere l'app
Abilitare AppArmor
Linux Security Modules (LSM) è un framework che fa parte del kernel Linux a partire da Linux 2.6. LSM supporta diverse implementazioni di moduli di protezione. AppArmor è un LSM che implementa un sistema di Controllo di accesso obbligatorio, che consente di limitare il programma a un set limitato di risorse. Verificare che AppArmor sia abilitato e configurato correttamente.
Configurare il firewall
Chiudere tutte le porte esterne che non sono in uso. Il firewall non replicato (ufw) fornisce un front-end per iptables
fornendo un'interfaccia della riga di comando per la configurazione del firewall.
Avviso
Un firewall impedisce l'accesso all'intero sistema se non è configurato correttamente. Se si usa SSH per connettersi, non è possibile specificare la porta SSH corretta. Il numero di porta predefinito è 22. Per altre informazioni, vedere l'introduzione a ufw e il manuale.
Installare ufw
e configurarlo per consentire il traffico su tutte le porte necessarie.
sudo apt-get install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Proteggere Nginx
Modificare il nome di risposta Nginx
Modificare src/http/ngx_http_header_filter_module.c
:
static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;
Configurare le opzioni
Configurare il server con moduli aggiuntivi obbligatori. Può essere utile usare un firewall per app Web, ad esempio ModSecurity, per la protezione avanzata dell'app.
Configurazione HTTPS
Configurare l'app per connessioni locali sicure (HTTPS)
Il comando dotnet run usa il file dell'app Properties/launchSettings.json
, che configura l'app per l'ascolto sugli URL forniti dalla applicationUrl
proprietà . Ad esempio: https://localhost:5001;http://localhost:5000
.
Configurare l'app per l'uso di un certificato in fase di sviluppo per il comando o l'ambiente dotnet run
di sviluppo (F5 o CTRL+F5 in Visual Studio Code) usando uno degli approcci seguenti:
- Sostituire il certificato predefinito della configurazione (consigliato)
- KestrelServerOptions.ConfigureHttpsDefaults
Configurare il proxy inverso per connessioni client sicure (HTTPS)
Avviso
La configurazione di sicurezza in questa sezione è una configurazione generale da usare come punto di partenza per un'ulteriore personalizzazione. Non è possibile fornire supporto per strumenti, server e sistemi operativi di terze parti. Usare la configurazione in questa sezione a proprio rischio. Per altre informazioni, accedere alle risorse seguenti:
- Configurazione dei server HTTPS (documentazione di Nginx)
- generatore di configurazione SSL mozilla.org
Configurare il server per l'ascolto del traffico HTTPS sulla porta 443 specificando un certificato valido emesso da un'autorità di certificazione (CA) attendibile.
Rafforzare la protezione adottando alcune delle procedure descritte nel file /etc/nginx/nginx.conf che segue.
L'esempio seguente non configura il server per reindirizzare le richieste non sicure. È consigliabile usare il middleware di reindirizzamento HTTPS. Per altre informazioni, vedere Applicare HTTPS in ASP.NET Core.
Nota
Per gli ambienti di sviluppo in cui la configurazione del server gestisce il reindirizzamento sicuro anziché il middleware di reindirizzamento HTTPS, è consigliabile usare reindirizzamenti temporanei (302) anziché reindirizzamenti permanenti (301). La memorizzazione nella cache dei collegamenti può causare un comportamento instabile negli ambienti di sviluppo.
L'aggiunta di un'intestazione
Strict-Transport-Security
(HSTS) garantisce che tutte le richieste successive effettuate dal client siano tramite HTTPS. Per indicazioni sull'impostazione dell'intestazioneStrict-Transport-Security
, vedere Applicare HTTPS in ASP.NET Core.Se HTTPS verrà disabilitato in futuro, usare uno degli approcci seguenti:
- Non aggiungere l'intestazione HSTS.
- Scegliere un valore breve
max-age
.
Aggiungere il file di configurazione /etc/nginx/proxy.conf:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Sostituire il contenuto del file di configurazione /etc/nginx/nginx.conf con il file seguente. L'esempio contiene entrambe le sezioni http
e server
in un unico file di configurazione.
http {
include /etc/nginx/proxy.conf;
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
server_tokens off;
sendfile on;
# Adjust keepalive_timeout to the lowest possible value that makes sense
# for your use case.
keepalive_timeout 29;
client_body_timeout 10; client_header_timeout 10; send_timeout 10;
upstream helloapp{
server 127.0.0.1:5000;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com *.example.com;
ssl_certificate /etc/ssl/certs/testCert.crt;
ssl_certificate_key /etc/ssl/certs/testCert.key;
ssl_session_timeout 1d;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling off;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
#Redirects all traffic
location / {
proxy_pass http://helloapp;
limit_req zone=one burst=10 nodelay;
}
}
}
Nota
Blazor WebAssembly Le app richiedono un valore di parametro maggiore burst
per supportare il numero maggiore di richieste effettuate da un'app. Per altre informazioni, vedere Ospitare e distribuire ASP.NET Core Blazor WebAssembly.
Nota
L'esempio precedente disabilita l'associazione OCSP (Online Certificate Status Protocol). Se abilitata, verificare che il certificato supporti la funzionalità. Per altre informazioni e indicazioni sull'abilitazione di OCSP, vedere le proprietà seguenti nell'articolo Module ngx_http_ssl_module (documentazione di Nginx):
ssl_stapling
ssl_stapling_file
ssl_stapling_responder
ssl_stapling_verify
Proteggere Nginx dal clickjacking
Il clickjacking, anche noto come attacco UI Redress, è un attacco dannoso in cui un visitatore di un sito Web viene indotto a fare clic su un collegamento o un pulsante in una pagina diversa da quella che sta attualmente visualizzando. Usare X-FRAME-OPTIONS
per proteggere il sito.
Per contrastare gli attacchi di clickjacking:
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
All'interno del blocco di
http{}
codice aggiungere la riga:add_header X-Frame-Options "SAMEORIGIN";
Salvare il file.
Riavviare Nginx.
Analisi del tipo MIME
Questa intestazione impedisce alla maggior parte dei browser di dedurre dall'analisi del tipo MIME un tipo di contenuto diverso da quello dichiarato, poiché l'intestazione indica al browser di non eseguire l'override del tipo di contenuto della risposta. Con l'opzione nosniff
, se il server indica che il contenuto è text/html
, il browser lo esegue come text/html
.
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
All'interno del blocco di
http{}
codice aggiungere la riga:add_header X-Content-Type-Options "nosniff";
Salvare il file.
Riavviare Nginx.
Altri suggerimenti di Nginx
Dopo aver aggiornato il framework condiviso nel server, riavviare le app core ASP.NET ospitate dal server.
Risorse aggiuntive
- Prerequisiti per .NET Core in Linux
- Nginx: Binary Releases: Official Debian/Ubuntu packages (Nginx: Versioni binarie: Pacchetti ufficiali Debian/Ubuntu)
- Risolvere i problemi ed eseguire il debug di progetti ASP.NET Core
- Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico
- NGINX: Using the Forwarded header (NGINX: Uso dell'intestazione Forwarded)
Questa guida descrive come configurare un ambiente ASP.NET Core pronto per la produzione in un server Ubuntu 16.04. Queste istruzioni si applicano probabilmente anche alle versioni più recenti di Ubuntu, sebbene non siano state testate con le versioni più recenti.
Per informazioni su altre distribuzioni Linux supportate da ASP.NET Core, vedere Prerequisiti per .NET Core in Linux.
Nota
Per Ubuntu 14.04, supervisord
è consigliabile come soluzione per il monitoraggio del Kestrel processo. systemd
non è disponibile in Ubuntu 14.04. Per le istruzioni per Ubuntu 14.04, vedere la versione precedente di questo argomento.
In questa guida:
- Posizionare un'app ASP.NET Core esistente dietro un server proxy inverso.
- Imposta il server proxy inverso per inoltrare le richieste al Kestrel server Web.
- Verificare che l'app Web venga eseguita all'avvio come daemon.
- Configurare uno strumento di gestione del processo per consentire il riavvio dell'app Web.
Prerequisiti
- Accedere a un server Ubuntu 16.04 con un account utente standard con privilegio sudo.
- Il runtime .NET non di anteprima più recente installato nel server.
- Un'app ASP.NET Core esistente.
In qualsiasi momento in futuro dopo l'aggiornamento del framework condiviso, riavviare le app ASP.NET Core ospitate dal server.
Pubblicare e copiare l'app
Configurare l'app per una distribuzione dipendente dal framework.
Se l'app viene eseguita localmente nell'ambiente di sviluppo e non è configurata dal server per stabilire connessioni HTTPS sicure, adottare uno degli approcci seguenti:
Configurare l'app per la gestione di connessioni locali sicure. Per altre informazioni, vedere la sezione Configurazione HTTPS.
Configurare l'app per l'esecuzione nell'endpoint non sicuro:
Disattivare il middleware di reindirizzamento HTTPS nell'ambiente di sviluppo (
Program.cs
):if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
Rimuovere
https://localhost:5001
(se presente) dallaapplicationUrl
proprietà nelProperties/launchSettings.json
file.
Per altre informazioni sulla configurazione per ambiente, vedere Usare più ambienti in ASP.NET Core.
Eseguire dotnet publish dall'ambiente di sviluppo per creare un pacchetto di un'app in una directory ( ad esempio , bin/Release/{TARGET FRAMEWORK MONIKER}/publish
dove il segnaposto {TARGET FRAMEWORK MONIKER}
è il moniker/TFM del framework di destinazione) che può essere eseguito nel server:
dotnet publish --configuration Release
È anche possibile pubblicare l'app come distribuzione completa se si preferisce non mantenere il runtime .NET Core nel server.
Copiare l'app ASP.NET Core nel server usando uno strumento che si integra nel flusso di lavoro dell'organizzazione ( ad esempio , SCP
). SFTP
È comune individuare le app Web nella var
directory , ad esempio var/www/helloapp
.
Nota
In uno scenario di distribuzione di produzione un flusso di lavoro di integrazione continua esegue le operazioni di pubblicazione dell'app e di copia degli asset nel server.
Eseguire il test dell'app:
- Dalla riga di comando, eseguire l'app:
dotnet <app_assembly>.dll
. - In un browser passare a
http://<serveraddress>:<port>
per verificare se l'app funziona in Linux in locale.
Configurare un server proxy inverso
Un proxy inverso è una configurazione comune per la gestione delle app Web dinamiche. Un proxy inverso termina la richiesta HTTP e la inoltra all'app ASP.NET Core.
Usare un server proxy inverso
Kestrel è ideale per gestire contenuto dinamico da ASP.NET Core. Tuttavia, le funzionalità di gestione Web sono meno avanzate rispetto a quelle offerte da server come IIS, Apache o Nginx. Un server proxy inverso è in grado di eseguire l'offload di attività come la gestione del contenuto statico, la memorizzazione nella cache delle richieste, la compressione delle richieste e la terminazione HTTPS dal server HTTP. Un server proxy inverso può risiedere in un computer dedicato o essere distribuito insieme a un server HTTP.
Ai fini di questa guida viene usata una singola istanza di Nginx. Viene eseguito sullo stesso server, insieme al server HTTP. In base ai requisiti, è possibile scegliere una configurazione diversa.
Poiché le richieste vengono inoltrate tramite proxy inverso, usare il middleware delle intestazioni inoltrate dal Microsoft.AspNetCore.HttpOverrides
pacchetto. Il middleware aggiorna Request.Scheme
usando l'intestazione X-Forwarded-Proto
, in modo che gli URI di reindirizzamento e altri criteri di sicurezza funzionino correttamente.
Il middleware delle intestazioni inoltrate deve essere eseguito prima di altro middleware. Questo ordine garantisce che il middleware basato sulle intestazioni inoltrate possa usare i valori di intestazione per l'elaborazione. Per eseguire il middleware delle intestazioni inoltrate dopo il middleware di diagnostica e gestione degli errori, vedere Ordine del middleware delle intestazioni inoltrate.
Richiamare il UseForwardedHeaders metodo nella parte superiore di prima di Program.cs
chiamare un altro middleware. Configurare il middleware per l'inoltro delle intestazioni X-Forwarded-For
e X-Forwarded-Proto
:
// requires using Microsoft.AspNetCore.HttpOverrides;
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
Se non vengono specificate opzioni ForwardedHeadersOptions per il middleware, le intestazioni predefinite per l'inoltro sono None
.
I proxy in esecuzione negli indirizzi di loopback (127.0.0.0/8
, [::1]
), incluso l'indirizzo localhost standard (127.0.0.1
), sono considerati attendibili per impostazione predefinita. Se le richieste tra Internet e il server Web vengono gestite anche da altri proxy o reti attendibili all'interno dell'organizzazione, aggiungerli all'elenco di KnownProxies o KnownNetworks con ForwardedHeadersOptions. L'esempio seguente aggiunge un server proxy attendibile all'indirizzo IP 10.0.0.100 nel middleware delle intestazioni inoltrate KnownProxies
in Program.cs
:
using System.Net;
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.
Installare Nginx
Usare apt-get
per installare Nginx. Il programma di installazione crea uno systemd
script init che esegue Nginx come daemon all'avvio del sistema. Seguire le istruzioni di installazione per Ubuntu riportate nell'articolo Nginx: Official Debian/Ubuntu packages (Nginx: pacchetti Debian/Ubuntu ufficiali).
Nota
Se sono richiesti moduli Nginx facoltativi, potrebbe essere necessario compilare Nginx dall'origine.
Poiché Nginx è stato installato per la prima volta, avviarlo in modo esplicito eseguendo:
sudo service nginx start
Verificare che un browser visualizzi la pagina di destinazione predefinita per Nginx. La pagina di destinazione è raggiungibile all'indirizzo http://<server_IP_address>/index.nginx-debian.html
.
Configurare Nginx
Per configurare Nginx come proxy inverso per inoltrare le richieste HTTP all'app ASP.NET Core, modificare /etc/nginx/sites-available/default
. Aprirlo in un editor di testo e sostituire il contenuto con il frammento di codice seguente:
server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Se l'app è un'app SignalR o Blazor Server , vedere ASP.NET Hosting di produzione core SignalR e ridimensionamento e Host e distribuire rispettivamente ASP.NET app sul lato Blazor server Core per altre informazioni.
Se nessun server_name
corrisponde, Nginx usa il server predefinito. Se non è definito alcun server predefinito, il primo server nel file di configurazione è il server predefinito. Come procedura consigliata, aggiungere un server predefinito specifico che restituisce un codice di stato 444 nel file di configurazione. Un esempio di configurazione del server predefinito è il seguente:
server {
listen 80 default_server;
# listen [::]:80 default_server deferred;
return 444;
}
Con il file di configurazione precedente e il server predefinito, Nginx accetta il traffico pubblico sulla porta 80 con l'intestazione host example.com
o *.example.com
. Le richieste che non corrispondono a questi host non verranno inoltrate a Kestrel. Nginx inoltra le richieste corrispondenti a in Kestrel http://127.0.0.1:5000
. Per altre informazioni, vedere Come nginx elabora una richiesta. Per modificare Kestrell'INDIRIZZO IP/porta, vedere Kestrel: Configurazione dell'endpoint.
Avviso
Se non si specifica una direttiva server_name corretta, l'app può risultare esposta a vulnerabilità di sicurezza. L'associazione con caratteri jolly del sottodominio (ad esempio, *.example.com
) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com
, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Semantica HTTP (sezione 7.2: host e :authority).
Una volta stabilita la configurazione di Nginx, eseguire sudo nginx -t
per verificare la sintassi dei file di configurazione. Se il test dei file di configurazione ha esito positivo, è possibile forzare Nginx ad applicare le modifiche eseguendo sudo nginx -s reload
.
Per eseguire direttamente l'app nel server:
- Passare alla directory dell'app.
- Eseguire l'app:
dotnet <app_assembly.dll>
, doveapp_assembly.dll
è il nome di file di assembly dell'app.
Se l'app viene eseguita sul server ma non risponde su Internet, controllare il firewall del server e verificare che la porta 80 sia aperta. Se si usa una macchina virtuale Ubuntu di Azure, aggiungere una regola del gruppo di sicurezza di rete (NSG) che abiliti il traffico in ingresso della porta 80. Non è necessario abilitare una regola per il traffico in uscita della porta 80, poiché il traffico in uscita viene autorizzato automaticamente quando viene abilitata la regola in ingresso.
Al termine del test dell'app, arrestare l'app con CTRL+C (Windows) o ⌘+C (macOS) al prompt dei comandi.
Monitorare l'app
Il server è configurato per inoltrare le richieste effettuate a http://<serveraddress>:80
all'app ASP.NET Core in esecuzione Kestrel in .http://127.0.0.1:5000
Tuttavia, Nginx non è configurato per gestire il Kestrel processo. systemd
può essere usato per creare un file di servizio per avviare e monitorare l'app Web sottostante. systemd
è un sistema init che offre molte potenti funzionalità per l'avvio, l'arresto e la gestione dei processi.
Creare il file del servizio
Creare il file di definizione del servizio:
sudo nano /etc/systemd/system/kestrel-helloapp.service
L'esempio seguente è un file di servizio per l'app:
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_NOLOGO=true
[Install]
WantedBy=multi-user.target
Nell'esempio precedente l'utente che gestisce il servizio viene specificato dall'opzione User
. L'utente (www-data
) deve esistere e avere la proprietà appropriata dei file dell'app.
Usare TimeoutStopSec
per configurare il tempo di attesa prima che l'app si arresti dopo aver ricevuto il segnale di interrupt iniziale. Se l'app non si arresta in questo periodo, viene emesso il comando SIGKILL per terminare l'app. Specificare il valore in secondi senza unità di misura (ad esempio, 150
), un valore per l'intervallo di tempo (ad esempio, 2min 30s
) o infinity
per disabilitare il timeout. TimeoutStopSec
per impostazione predefinita il valore di nel file di configurazione di DefaultTimeoutStopSec
gestione (systemd-system.conf
, system.conf.d
, systemd-user.conf
, user.conf.d
). Il timeout predefinito per la maggior parte delle distribuzioni è di 90 secondi.
# The default value is 90 seconds for most distributions.
TimeoutStopSec=90
Linux dispone di un file system con distinzione tra maiuscole e minuscole. Se si imposta ASPNETCORE_ENVIRONMENT
su Production
viene eseguita la ricerca del file appsettings.Production.json
di configurazione , non appsettings.production.json
.
Per alcuni valori (ad esempio, le stringhe di connessione SQL) è necessario usare caratteri di escape, in modo da consentire ai provider di configurazione di leggere le variabili di ambiente. Usare il comando seguente per generare un valore con caratteri di escape corretti per l'uso nel file di configurazione:
systemd-escape "<value-to-escape>"
I due punti (:
) separatori non sono supportati nei nomi delle variabili di ambiente. Usare un doppio carattere di sottolineatura (__
) al posto dei due punti. Il provider di configurazione delle variabili di ambiente converte le doppie sottolineature in due punti quando le variabili di ambiente vengono lette nella configurazione. Nell'esempio seguente la chiave della stringa di connessione ConnectionStrings:DefaultConnection
è impostata nel file di definizione del servizio come ConnectionStrings__DefaultConnection
:
Environment=ConnectionStrings__DefaultConnection={Connection String}
Salvare il file e abilitare il servizio.
sudo systemctl enable kestrel-helloapp.service
Avviare il servizio e verificare che sia in esecuzione.
sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service
◝ kestrel-helloapp.service - Example .NET Web API App running on Ubuntu
Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
CGroup: /system.slice/kestrel-helloapp.service
└─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
Con il proxy inverso configurato e Kestrel gestito tramite systemd
, l'app Web è completamente configurata e accessibile da un browser nel computer locale all'indirizzo http://localhost
. È anche possibile accedervi da un computer remoto, escludendo eventuali firewall che potrebbero impedirlo. Esaminando le intestazioni di risposta, l'intestazione Server
mostra l'app ASP.NET Core gestita da Kestrel.
HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Visualizzare i log
Poiché l'app Web che usa Kestrel viene gestita tramite systemd
, tutti gli eventi e i processi vengono registrati in un journal centralizzato. Tuttavia, questo giornale include tutte le voci per tutti i servizi e i processi gestiti da systemd
. Per visualizzare le voci specifiche di kestrel-helloapp.service
, usare il comando seguente:
sudo journalctl -fu kestrel-helloapp.service
Per filtrare ulteriormente, le opzioni temporali, --since today
ad esempio , --until 1 hour ago
o una combinazione di queste opzioni, possono ridurre il numero di voci restituite.
sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"
Protezione dei dati
Lo stack di protezione dei dati core ASP.NET viene usato da diversi middleware di base ASP.NET, tra cui il middleware di autenticazione (ad esempio, cookie middleware) e le protezioni di richiesta intersito (CSRF). Anche se le DPAPI (Data Protection API) non vengono chiamate dal codice dell'utente, è consigliabile configurare la protezione dati per la creazione di un archivio di chiavi crittografiche permanente. Se non si configura la protezione dei dati, le chiavi vengono mantenute in memoria ed eliminate al riavvio dell'app.
Se il gruppo di chiavi viene archiviato in memoria quando l'app viene riavviata:
- Tutti i token di autenticazione basati su cookie vengono invalidati.
- Gli utenti devono ripetere l'accesso alla richiesta successiva.
- Tutti i dati protetti con il gruppo di chiavi non possono più essere decrittografati. Possono essere inclusi i token CSRF e i cookie TempData di ASP.NET Core MVC.
Per configurare la protezione dei dati in modo da rendere persistente il gruppo di chiavi e crittografarlo, vedere:
- Provider di archiviazione chiavi in ASP.NET Core
- Crittografia delle chiavi rest in Windows e Azure con ASP.NET Core
Campi di intestazione della richiesta di grandi dimensioni
Le impostazioni predefinite del server proxy limitano in genere i campi di intestazione della richiesta a 4 K o 8 K a seconda della piattaforma. Un'app può richiedere campi più lunghi del valore predefinito, ad esempio le app che usano Azure Active Directory. Se sono necessari campi più lunghi, le impostazioni predefinite del server proxy richiedono la regolazione. I valori da applicare dipendono dallo scenario. Per altre informazioni, vedere la documentazione del server.
Avviso
Aumentare i valori predefiniti dei buffer proxy solo se necessario. Se si aumentano questi valori, si aumenta il rischio di sovraccarico del buffer (overflow) e di attacchi Denial of Service (DoS) da parte di utenti malintenzionati.
Proteggere l'app
Abilitare AppArmor
Linux Security Modules (LSM) è un framework che fa parte del kernel Linux a partire da Linux 2.6. LSM supporta diverse implementazioni di moduli di protezione. AppArmor è un LSM che implementa un sistema di Controllo di accesso obbligatorio, che consente di limitare il programma a un set limitato di risorse. Verificare che AppArmor sia abilitato e configurato correttamente.
Configurare il firewall
Chiudere tutte le porte esterne che non sono in uso. Il firewall non replicato (ufw) fornisce un front-end per iptables
fornendo un'interfaccia della riga di comando per la configurazione del firewall.
Avviso
Se non è configurato correttamente, un firewall impedisce l'accesso all'intero sistema. Se non si specifica la porta SSH corretta, non sarà possibile accedere al sistema se si usa SSH per la connessione. Il numero di porta predefinito è 22. Per altre informazioni, vedere l'introduzione a ufw e il manuale.
Installare ufw
e configurarlo per consentire il traffico su tutte le porte necessarie.
sudo apt-get install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Proteggere Nginx
Modificare il nome di risposta Nginx
Modificare src/http/ngx_http_header_filter_module.c
:
static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;
Configurare le opzioni
Configurare il server con moduli aggiuntivi obbligatori. Può essere utile usare un firewall per app Web, ad esempio ModSecurity, per la protezione avanzata dell'app.
Configurazione HTTPS
Configurare l'app per connessioni locali sicure (HTTPS)
Il comando dotnet run usa il file dell'app Properties/launchSettings.json
, che configura l'app per l'ascolto sugli URL forniti dalla applicationUrl
proprietà . Ad esempio: https://localhost:5001;http://localhost:5000
.
Configurare l'app per l'uso di un certificato in fase di sviluppo per il comando o l'ambiente dotnet run
di sviluppo (F5 o CTRL+F5 in Visual Studio Code) usando uno degli approcci seguenti:
- Sostituire il certificato predefinito della configurazione (consigliato)
- KestrelServerOptions.ConfigureHttpsDefaults
Configurare il proxy inverso per connessioni client sicure (HTTPS)
Avviso
La configurazione di sicurezza in questa sezione è una configurazione generale da usare come punto di partenza per un'ulteriore personalizzazione. Non è possibile fornire supporto per strumenti, server e sistemi operativi di terze parti. Usare la configurazione in questa sezione a proprio rischio. Per altre informazioni, accedere alle risorse seguenti:
- Configurazione dei server HTTPS (documentazione di Nginx)
- generatore di configurazione SSL mozilla.org
Configurare il server per l'ascolto del traffico HTTPS sulla porta 443 specificando un certificato valido emesso da un'autorità di certificazione (CA) attendibile.
Rafforzare la protezione adottando alcune delle procedure descritte nel file /etc/nginx/nginx.conf che segue.
L'esempio seguente non configura il server per reindirizzare le richieste non sicure. È consigliabile usare il middleware di reindirizzamento HTTPS. Per altre informazioni, vedere Applicare HTTPS in ASP.NET Core.
Nota
Per gli ambienti di sviluppo in cui la configurazione del server gestisce il reindirizzamento sicuro anziché il middleware di reindirizzamento HTTPS, è consigliabile usare reindirizzamenti temporanei (302) anziché reindirizzamenti permanenti (301). La memorizzazione nella cache dei collegamenti può causare un comportamento instabile negli ambienti di sviluppo.
L'aggiunta di un'intestazione
Strict-Transport-Security
(HSTS) garantisce che tutte le richieste successive effettuate dal client siano tramite HTTPS. Per indicazioni sull'impostazione dell'intestazioneStrict-Transport-Security
, vedere Applicare HTTPS in ASP.NET Core.Se HTTPS verrà disabilitato in futuro, usare uno degli approcci seguenti:
- Non aggiungere l'intestazione HSTS.
- Scegliere un valore breve
max-age
.
Aggiungere il file di configurazione /etc/nginx/proxy.conf:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Sostituire il contenuto del file di configurazione /etc/nginx/nginx.conf con il file seguente. L'esempio contiene entrambe le sezioni http
e server
in un unico file di configurazione.
http {
include /etc/nginx/proxy.conf;
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
server_tokens off;
sendfile on;
# Adjust keepalive_timeout to the lowest possible value that makes sense
# for your use case.
keepalive_timeout 29;
client_body_timeout 10; client_header_timeout 10; send_timeout 10;
upstream helloapp{
server 127.0.0.1:5000;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com *.example.com;
ssl_certificate /etc/ssl/certs/testCert.crt;
ssl_certificate_key /etc/ssl/certs/testCert.key;
ssl_session_timeout 1d;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling off;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
#Redirects all traffic
location / {
proxy_pass http://helloapp;
limit_req zone=one burst=10 nodelay;
}
}
}
Nota
Blazor WebAssembly Le app richiedono un valore di parametro maggiore burst
per supportare il numero maggiore di richieste effettuate da un'app. Per altre informazioni, vedere Ospitare e distribuire ASP.NET Core Blazor WebAssembly.
Nota
L'esempio precedente disabilita l'associazione OCSP (Online Certificate Status Protocol). Se abilitata, verificare che il certificato supporti la funzionalità. Per altre informazioni e indicazioni sull'abilitazione di OCSP, vedere le proprietà seguenti nell'articolo Module ngx_http_ssl_module (documentazione di Nginx):
ssl_stapling
ssl_stapling_file
ssl_stapling_responder
ssl_stapling_verify
Proteggere Nginx dal clickjacking
Il clickjacking, anche noto come attacco UI Redress, è un attacco dannoso in cui un visitatore di un sito Web viene indotto a fare clic su un collegamento o un pulsante in una pagina diversa da quella che sta attualmente visualizzando. Usare X-FRAME-OPTIONS
per proteggere il sito.
Per contrastare gli attacchi di clickjacking:
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
Aggiungere la riga:
add_header X-Frame-Options "SAMEORIGIN";
Salvare il file.
Riavviare Nginx.
Analisi del tipo MIME
Questa intestazione impedisce alla maggior parte dei browser di dedurre dall'analisi del tipo MIME un tipo di contenuto diverso da quello dichiarato, poiché l'intestazione indica al browser di non eseguire l'override del tipo di contenuto della risposta. Con l'opzione nosniff
, se il server indica che il contenuto è text/html
, il browser lo esegue come text/html
.
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
Aggiungere la riga:
add_header X-Content-Type-Options "nosniff";
Salvare il file.
Riavviare Nginx.
Altri suggerimenti di Nginx
Dopo aver aggiornato il framework condiviso nel server, riavviare le app core ASP.NET ospitate dal server.
Risorse aggiuntive
- Prerequisiti per .NET Core in Linux
- Nginx: Binary Releases: Official Debian/Ubuntu packages (Nginx: Versioni binarie: Pacchetti ufficiali Debian/Ubuntu)
- Risolvere i problemi ed eseguire il debug di progetti ASP.NET Core
- Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico
- NGINX: Using the Forwarded header (NGINX: Uso dell'intestazione Forwarded)
Questa guida descrive come configurare un ambiente ASP.NET Core pronto per la produzione in un server Ubuntu 16.04. Queste istruzioni si applicano probabilmente anche alle versioni più recenti di Ubuntu, sebbene non siano state testate con le versioni più recenti.
Per informazioni su altre distribuzioni Linux supportate da ASP.NET Core, vedere Prerequisiti per .NET Core in Linux.
Nota
Per Ubuntu 14.04, supervisord
è consigliabile come soluzione per il monitoraggio del Kestrel processo. systemd
non è disponibile in Ubuntu 14.04. Per le istruzioni per Ubuntu 14.04, vedere la versione precedente di questo argomento.
In questa guida:
- Posizionare un'app ASP.NET Core esistente dietro un server proxy inverso.
- Imposta il server proxy inverso per inoltrare le richieste al Kestrel server Web.
- Verificare che l'app Web venga eseguita all'avvio come daemon.
- Configurare uno strumento di gestione del processo per consentire il riavvio dell'app Web.
Prerequisiti
- Accedere a un server Ubuntu 16.04 con un account utente standard con privilegio sudo.
- Il runtime .NET non di anteprima più recente installato nel server.
- Un'app ASP.NET Core esistente.
In qualsiasi momento in futuro dopo l'aggiornamento del framework condiviso, riavviare le app ASP.NET Core ospitate dal server.
Pubblicare e copiare l'app
Configurare l'app per una distribuzione dipendente dal framework.
Se l'app viene eseguita localmente nell'ambiente di sviluppo e non è configurata dal server per stabilire connessioni HTTPS sicure, adottare uno degli approcci seguenti:
Configurare l'app per la gestione di connessioni locali sicure. Per altre informazioni, vedere la sezione Configurazione HTTPS.
Configurare l'app per l'esecuzione nell'endpoint non sicuro:
Disattivare il middleware di reindirizzamento HTTPS nell'ambiente di sviluppo (
Program.cs
):if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Per altre informazioni, vedere Usare più ambienti in ASP.NET Core.
Rimuovere
https://localhost:5001
(se presente) dallaapplicationUrl
proprietà nelProperties/launchSettings.json
file.
Per altre informazioni sulla configurazione per ambiente, vedere Usare più ambienti in ASP.NET Core.
Eseguire dotnet publish dall'ambiente di sviluppo per creare un pacchetto di un'app in una directory ( ad esempio , bin/Release/{TARGET FRAMEWORK MONIKER}/publish
dove il segnaposto {TARGET FRAMEWORK MONIKER}
è il moniker/TFM del framework di destinazione) che può essere eseguito nel server:
dotnet publish --configuration Release
È anche possibile pubblicare l'app come distribuzione completa se si preferisce non mantenere il runtime .NET Core nel server.
Copiare l'app ASP.NET Core nel server usando uno strumento che si integra nel flusso di lavoro dell'organizzazione ( ad esempio , SCP
). SFTP
È comune individuare le app Web nella var
directory , ad esempio var/www/helloapp
.
Nota
In uno scenario di distribuzione di produzione un flusso di lavoro di integrazione continua esegue le operazioni di pubblicazione dell'app e di copia degli asset nel server.
Eseguire il test dell'app:
- Dalla riga di comando, eseguire l'app:
dotnet <app_assembly>.dll
. - In un browser passare a
http://<serveraddress>:<port>
per verificare se l'app funziona in Linux in locale.
Configurare un server proxy inverso
Un proxy inverso è una configurazione comune per la gestione delle app Web dinamiche. Un proxy inverso termina la richiesta HTTP e la inoltra all'app ASP.NET Core.
Usare un server proxy inverso
Kestrel è ideale per gestire contenuto dinamico da ASP.NET Core. Tuttavia, le funzionalità di gestione Web sono meno avanzate rispetto a quelle offerte da server come IIS, Apache o Nginx. Un server proxy inverso è in grado di eseguire l'offload di attività come la gestione del contenuto statico, la memorizzazione nella cache delle richieste, la compressione delle richieste e la terminazione HTTPS dal server HTTP. Un server proxy inverso può risiedere in un computer dedicato o essere distribuito insieme a un server HTTP.
Ai fini di questa guida viene usata una singola istanza di Nginx. Viene eseguito sullo stesso server, insieme al server HTTP. In base ai requisiti, è possibile scegliere una configurazione diversa.
Poiché le richieste vengono inoltrate tramite proxy inverso, usare il middleware delle intestazioni inoltrate dal Microsoft.AspNetCore.HttpOverrides
pacchetto. Il middleware aggiorna Request.Scheme
usando l'intestazione X-Forwarded-Proto
, in modo che gli URI di reindirizzamento e altri criteri di sicurezza funzionino correttamente.
Il middleware delle intestazioni inoltrate deve essere eseguito prima di altro middleware. Questo ordine garantisce che il middleware basato sulle intestazioni inoltrate possa usare i valori di intestazione per l'elaborazione. Per eseguire il middleware delle intestazioni inoltrate dopo il middleware di diagnostica e gestione degli errori, vedere Ordine del middleware delle intestazioni inoltrate.
Richiamare il UseForwardedHeaders metodo nella parte superiore di prima di Startup.Configure
chiamare un altro middleware. Configurare il middleware per l'inoltro delle intestazioni X-Forwarded-For
e X-Forwarded-Proto
:
using Microsoft.AspNetCore.HttpOverrides;
...
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
Se non vengono specificate opzioni ForwardedHeadersOptions per il middleware, le intestazioni predefinite per l'inoltro sono None
.
I proxy in esecuzione negli indirizzi di loopback (127.0.0.0/8
, [::1]
), incluso l'indirizzo localhost standard (127.0.0.1
), sono considerati attendibili per impostazione predefinita. Se le richieste tra Internet e il server Web vengono gestite anche da altri proxy o reti attendibili all'interno dell'organizzazione, aggiungerli all'elenco di KnownProxies o KnownNetworks con ForwardedHeadersOptions. L'esempio seguente aggiunge un server proxy attendibile all'indirizzo IP 10.0.0.100 nel middleware delle intestazioni inoltrate KnownProxies
in Startup.ConfigureServices
:
using System.Net;
...
services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
Per altre informazioni, vedere Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico.
Installare Nginx
Usare apt-get
per installare Nginx. Il programma di installazione crea uno systemd
script init che esegue Nginx come daemon all'avvio del sistema. Seguire le istruzioni di installazione per Ubuntu riportate nell'articolo Nginx: Official Debian/Ubuntu packages (Nginx: pacchetti Debian/Ubuntu ufficiali).
Nota
Se sono richiesti moduli Nginx facoltativi, potrebbe essere necessario compilare Nginx dall'origine.
Poiché Nginx è stato installato per la prima volta, avviarlo in modo esplicito eseguendo:
sudo service nginx start
Verificare che un browser visualizzi la pagina di destinazione predefinita per Nginx. La pagina di destinazione è raggiungibile all'indirizzo http://<server_IP_address>/index.nginx-debian.html
.
Configurare Nginx
Per configurare Nginx come proxy inverso per inoltrare le richieste HTTP all'app ASP.NET Core, modificare /etc/nginx/sites-available/default
. Aprirlo in un editor di testo e sostituire il contenuto con il frammento di codice seguente:
server {
listen 80;
server_name example.com *.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Se l'app è un'app SignalR o Blazor Server , vedere ASP.NET Hosting di produzione core SignalR e ridimensionamento e Host e distribuire rispettivamente ASP.NET app sul lato Blazor server Core per altre informazioni.
Se nessun server_name
corrisponde, Nginx usa il server predefinito. Se non è definito alcun server predefinito, il primo server nel file di configurazione è il server predefinito. Come procedura consigliata, aggiungere un server predefinito specifico che restituisce un codice di stato 444 nel file di configurazione. Un esempio di configurazione del server predefinito è il seguente:
server {
listen 80 default_server;
# listen [::]:80 default_server deferred;
return 444;
}
Con il file di configurazione precedente e il server predefinito, Nginx accetta il traffico pubblico sulla porta 80 con l'intestazione host example.com
o *.example.com
. Le richieste che non corrispondono a questi host non verranno inoltrate a Kestrel. Nginx inoltra le richieste corrispondenti a in Kestrel http://127.0.0.1:5000
. Per altre informazioni, vedere Come nginx elabora una richiesta. Per modificare Kestrell'INDIRIZZO IP/porta, vedere Kestrel: Configurazione dell'endpoint.
Avviso
Se non si specifica una direttiva server_name corretta, l'app può risultare esposta a vulnerabilità di sicurezza. L'associazione con caratteri jolly del sottodominio (ad esempio, *.example.com
) non costituisce un rischio per la sicurezza se viene controllato l'intero dominio padre (a differenza di *.com
, che è vulnerabile). Per altre informazioni, vedere RFC 9110: Semantica HTTP (sezione 7.2: host e :authority).
Una volta stabilita la configurazione di Nginx, eseguire sudo nginx -t
per verificare la sintassi dei file di configurazione. Se il test dei file di configurazione ha esito positivo, è possibile forzare Nginx ad applicare le modifiche eseguendo sudo nginx -s reload
.
Per eseguire direttamente l'app nel server:
- Passare alla directory dell'app.
- Eseguire l'app:
dotnet <app_assembly.dll>
, doveapp_assembly.dll
è il nome di file di assembly dell'app.
Se l'app viene eseguita sul server ma non risponde su Internet, controllare il firewall del server e verificare che la porta 80 sia aperta. Se si usa una macchina virtuale Ubuntu di Azure, aggiungere una regola del gruppo di sicurezza di rete (NSG) che abiliti il traffico in ingresso della porta 80. Non è necessario abilitare una regola per il traffico in uscita della porta 80, poiché il traffico in uscita viene autorizzato automaticamente quando viene abilitata la regola in ingresso.
Al termine del test dell'app, arrestare l'app con CTRL+C (Windows) o ⌘+C (macOS) al prompt dei comandi.
Monitorare l'app
Il server è configurato per inoltrare le richieste effettuate a http://<serveraddress>:80
all'app ASP.NET Core in esecuzione Kestrel in .http://127.0.0.1:5000
Tuttavia, Nginx non è configurato per gestire il Kestrel processo. systemd
può essere usato per creare un file di servizio per avviare e monitorare l'app Web sottostante. systemd
è un sistema init che offre molte potenti funzionalità per l'avvio, l'arresto e la gestione dei processi.
Creare il file del servizio
Creare il file di definizione del servizio:
sudo nano /etc/systemd/system/kestrel-helloapp.service
L'esempio seguente è un file di servizio per l'app:
[Unit]
Description=Example .NET Web API App running on Ubuntu
[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target
Nell'esempio precedente l'utente che gestisce il servizio viene specificato dall'opzione User
. L'utente (www-data
) deve esistere e avere la proprietà appropriata dei file dell'app.
Usare TimeoutStopSec
per configurare il tempo di attesa prima che l'app si arresti dopo aver ricevuto il segnale di interrupt iniziale. Se l'app non si arresta in questo periodo, viene emesso il comando SIGKILL per terminare l'app. Specificare il valore in secondi senza unità di misura (ad esempio, 150
), un valore per l'intervallo di tempo (ad esempio, 2min 30s
) o infinity
per disabilitare il timeout. TimeoutStopSec
per impostazione predefinita il valore di nel file di configurazione di DefaultTimeoutStopSec
gestione (systemd-system.conf
, system.conf.d
, systemd-user.conf
, user.conf.d
). Il timeout predefinito per la maggior parte delle distribuzioni è di 90 secondi.
# The default value is 90 seconds for most distributions.
TimeoutStopSec=90
Linux dispone di un file system con distinzione tra maiuscole e minuscole. Se si imposta ASPNETCORE_ENVIRONMENT
su Production
viene eseguita la ricerca del file appsettings.Production.json
di configurazione , non appsettings.production.json
.
Per alcuni valori (ad esempio, le stringhe di connessione SQL) è necessario usare caratteri di escape, in modo da consentire ai provider di configurazione di leggere le variabili di ambiente. Usare il comando seguente per generare un valore con caratteri di escape corretti per l'uso nel file di configurazione:
systemd-escape "<value-to-escape>"
I due punti (:
) separatori non sono supportati nei nomi delle variabili di ambiente. Usare un doppio carattere di sottolineatura (__
) al posto dei due punti. Il provider di configurazione delle variabili di ambiente converte le doppie sottolineature in due punti quando le variabili di ambiente vengono lette nella configurazione. Nell'esempio seguente la chiave della stringa di connessione ConnectionStrings:DefaultConnection
è impostata nel file di definizione del servizio come ConnectionStrings__DefaultConnection
:
Environment=ConnectionStrings__DefaultConnection={Connection String}
Salvare il file e abilitare il servizio.
sudo systemctl enable kestrel-helloapp.service
Avviare il servizio e verificare che sia in esecuzione.
sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service
◝ kestrel-helloapp.service - Example .NET Web API App running on Ubuntu
Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
CGroup: /system.slice/kestrel-helloapp.service
└─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
Con il proxy inverso configurato e Kestrel gestito tramite systemd
, l'app Web è completamente configurata e accessibile da un browser nel computer locale all'indirizzo http://localhost
. È anche possibile accedervi da un computer remoto, escludendo eventuali firewall che potrebbero impedirlo. Esaminando le intestazioni di risposta, l'intestazione Server
mostra l'app ASP.NET Core gestita da Kestrel.
HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked
Visualizzare i log
Poiché l'app Web che usa Kestrel viene gestita tramite systemd
, tutti gli eventi e i processi vengono registrati in un journal centralizzato. Tuttavia, questo giornale include tutte le voci per tutti i servizi e i processi gestiti da systemd
. Per visualizzare le voci specifiche di kestrel-helloapp.service
, usare il comando seguente:
sudo journalctl -fu kestrel-helloapp.service
Per filtrare ulteriormente, le opzioni temporali, --since today
ad esempio , --until 1 hour ago
o una combinazione di queste opzioni, possono ridurre il numero di voci restituite.
sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"
Protezione dei dati
Lo stack di protezione dei dati core ASP.NET viene usato da diversi middleware di base ASP.NET, tra cui il middleware di autenticazione (ad esempio, cookie middleware) e le protezioni di richiesta intersito (CSRF). Anche se le DPAPI (Data Protection API) non vengono chiamate dal codice dell'utente, è consigliabile configurare la protezione dati per la creazione di un archivio di chiavi crittografiche permanente. Se non si configura la protezione dei dati, le chiavi vengono mantenute in memoria ed eliminate al riavvio dell'app.
Se il gruppo di chiavi viene archiviato in memoria quando l'app viene riavviata:
- Tutti i token di autenticazione basati su cookie vengono invalidati.
- Gli utenti devono ripetere l'accesso alla richiesta successiva.
- Tutti i dati protetti con il gruppo di chiavi non possono più essere decrittografati. Possono essere inclusi i token CSRF e i cookie TempData di ASP.NET Core MVC.
Per configurare la protezione dei dati in modo da rendere persistente il gruppo di chiavi e crittografarlo, vedere:
- Provider di archiviazione chiavi in ASP.NET Core
- Crittografia delle chiavi rest in Windows e Azure con ASP.NET Core
Campi di intestazione della richiesta di grandi dimensioni
Le impostazioni predefinite del server proxy limitano in genere i campi di intestazione della richiesta a 4 K o 8 K a seconda della piattaforma. Un'app può richiedere campi più lunghi del valore predefinito, ad esempio le app che usano Azure Active Directory. Se sono necessari campi più lunghi, le impostazioni predefinite del server proxy richiedono la regolazione. I valori da applicare dipendono dallo scenario. Per altre informazioni, vedere la documentazione del server.
Avviso
Aumentare i valori predefiniti dei buffer proxy solo se necessario. Se si aumentano questi valori, si aumenta il rischio di sovraccarico del buffer (overflow) e di attacchi Denial of Service (DoS) da parte di utenti malintenzionati.
Proteggere l'app
Abilitare AppArmor
Linux Security Modules (LSM) è un framework che fa parte del kernel Linux a partire da Linux 2.6. LSM supporta diverse implementazioni di moduli di protezione. AppArmor è un LSM che implementa un sistema di Controllo di accesso obbligatorio, che consente di limitare il programma a un set limitato di risorse. Verificare che AppArmor sia abilitato e configurato correttamente.
Configurare il firewall
Chiudere tutte le porte esterne che non sono in uso. Il firewall non replicato (ufw) fornisce un front-end per iptables
fornendo un'interfaccia della riga di comando per la configurazione del firewall.
Avviso
Se non è configurato correttamente, un firewall impedisce l'accesso all'intero sistema. Se non si specifica la porta SSH corretta, non sarà possibile accedere al sistema se si usa SSH per la connessione. Il numero di porta predefinito è 22. Per altre informazioni, vedere l'introduzione a ufw e il manuale.
Installare ufw
e configurarlo per consentire il traffico su tutte le porte necessarie.
sudo apt-get install ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Proteggere Nginx
Modificare il nome di risposta Nginx
Modificare src/http/ngx_http_header_filter_module.c
:
static char ngx_http_server_string[] = "Server: Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Web Server" CRLF;
Configurare le opzioni
Configurare il server con moduli aggiuntivi obbligatori. Può essere utile usare un firewall per app Web, ad esempio ModSecurity, per la protezione avanzata dell'app.
Configurazione HTTPS
Configurare l'app per connessioni locali sicure (HTTPS)
Il comando dotnet run usa il file dell'app Properties/launchSettings.json
, che configura l'app per l'ascolto sugli URL forniti dalla applicationUrl
proprietà . Ad esempio: https://localhost:5001;http://localhost:5000
.
Configurare l'app per l'uso di un certificato in fase di sviluppo per il comando o l'ambiente dotnet run
di sviluppo (F5 o CTRL+F5 in Visual Studio Code) usando uno degli approcci seguenti:
- Sostituire il certificato predefinito della configurazione (consigliato)
- KestrelServerOptions.ConfigureHttpsDefaults
Configurare il proxy inverso per connessioni client sicure (HTTPS)
Avviso
La configurazione di sicurezza in questa sezione è una configurazione generale da usare come punto di partenza per un'ulteriore personalizzazione. Non è possibile fornire supporto per strumenti, server e sistemi operativi di terze parti. Usare la configurazione in questa sezione a proprio rischio. Per altre informazioni, accedere alle risorse seguenti:
- Configurazione dei server HTTPS (documentazione di Nginx)
- generatore di configurazione SSL mozilla.org
Configurare il server per l'ascolto del traffico HTTPS sulla porta 443 specificando un certificato valido emesso da un'autorità di certificazione (CA) attendibile.
Rafforzare la protezione adottando alcune delle procedure descritte nel file /etc/nginx/nginx.conf che segue.
L'esempio seguente non configura il server per reindirizzare le richieste non sicure. È consigliabile usare il middleware di reindirizzamento HTTPS. Per altre informazioni, vedere Applicare HTTPS in ASP.NET Core.
Nota
Per gli ambienti di sviluppo in cui la configurazione del server gestisce il reindirizzamento sicuro anziché il middleware di reindirizzamento HTTPS, è consigliabile usare reindirizzamenti temporanei (302) anziché reindirizzamenti permanenti (301). La memorizzazione nella cache dei collegamenti può causare un comportamento instabile negli ambienti di sviluppo.
L'aggiunta di un'intestazione
Strict-Transport-Security
(HSTS) garantisce che tutte le richieste successive effettuate dal client siano tramite HTTPS. Per indicazioni sull'impostazione dell'intestazioneStrict-Transport-Security
, vedere Applicare HTTPS in ASP.NET Core.Se HTTPS verrà disabilitato in futuro, usare uno degli approcci seguenti:
- Non aggiungere l'intestazione HSTS.
- Scegliere un valore breve
max-age
.
Aggiungere il file di configurazione /etc/nginx/proxy.conf:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
Sostituire il contenuto del file di configurazione /etc/nginx/nginx.conf con il file seguente. L'esempio contiene entrambe le sezioni http
e server
in un unico file di configurazione.
http {
include /etc/nginx/proxy.conf;
limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
server_tokens off;
sendfile on;
# Adjust keepalive_timeout to the lowest possible value that makes sense
# for your use case.
keepalive_timeout 29;
client_body_timeout 10; client_header_timeout 10; send_timeout 10;
upstream helloapp{
server 127.0.0.1:5000;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com *.example.com;
ssl_certificate /etc/ssl/certs/testCert.crt;
ssl_certificate_key /etc/ssl/certs/testCert.key;
ssl_session_timeout 1d;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling off;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
#Redirects all traffic
location / {
proxy_pass http://helloapp;
limit_req zone=one burst=10 nodelay;
}
}
}
Nota
Blazor WebAssembly Le app richiedono un valore di parametro maggiore burst
per supportare il numero maggiore di richieste effettuate da un'app. Per altre informazioni, vedere Ospitare e distribuire ASP.NET Core Blazor WebAssembly.
Nota
L'esempio precedente disabilita l'associazione OCSP (Online Certificate Status Protocol). Se abilitata, verificare che il certificato supporti la funzionalità. Per altre informazioni e indicazioni sull'abilitazione di OCSP, vedere le proprietà seguenti nell'articolo Module ngx_http_ssl_module (documentazione di Nginx):
ssl_stapling
ssl_stapling_file
ssl_stapling_responder
ssl_stapling_verify
Proteggere Nginx dal clickjacking
Il clickjacking, anche noto come attacco UI Redress, è un attacco dannoso in cui un visitatore di un sito Web viene indotto a fare clic su un collegamento o un pulsante in una pagina diversa da quella che sta attualmente visualizzando. Usare X-FRAME-OPTIONS
per proteggere il sito.
Per contrastare gli attacchi di clickjacking:
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
Aggiungere la riga:
add_header X-Frame-Options "SAMEORIGIN";
Salvare il file.
Riavviare Nginx.
Analisi del tipo MIME
Questa intestazione impedisce alla maggior parte dei browser di dedurre dall'analisi del tipo MIME un tipo di contenuto diverso da quello dichiarato, poiché l'intestazione indica al browser di non eseguire l'override del tipo di contenuto della risposta. Con l'opzione nosniff
, se il server indica che il contenuto è text/html
, il browser lo esegue come text/html
.
Modificare il file nginx.conf:
sudo nano /etc/nginx/nginx.conf
Aggiungere la riga:
add_header X-Content-Type-Options "nosniff";
Salvare il file.
Riavviare Nginx.
Altri suggerimenti di Nginx
Dopo aver aggiornato il framework condiviso nel server, riavviare le app core ASP.NET ospitate dal server.
Risorse aggiuntive
- Prerequisiti per .NET Core in Linux
- Nginx: Binary Releases: Official Debian/Ubuntu packages (Nginx: Versioni binarie: Pacchetti ufficiali Debian/Ubuntu)
- Risolvere i problemi ed eseguire il debug di progetti ASP.NET Core
- Configurare ASP.NET Core per l'utilizzo di server proxy e servizi di bilanciamento del carico
- NGINX: Using the Forwarded header (NGINX: Uso dell'intestazione Forwarded)