Hosting di ASP.NET Core in Linux con Nginx

Di Sourabh Shirhatti

Nota

Questa non è la versione più recente di questo articolo. 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 8 di questo articolo.

Questa guida illustra la configurazione di un ambiente ASP.NET Core pronto per la produzione per Ubuntu, Red Hat Enterprise (RHEL) e SU edizione Standard 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) dalla applicationUrl proprietà nel Properties/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}/publishdove 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:

  1. Dalla riga di comando, eseguire l'app: dotnet <app_assembly>.dll.
  2. 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 KnownProxiesdelle 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 Kestrelhttp://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:

  1. Passare alla directory dell'app.
  2. Eseguire l'app: dotnet <app_assembly.dll>, dove app_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.jsondi 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 todayad esempio , --until 1 hour agoo 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:

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:

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:

  • 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'intestazione Strict-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:

  1. 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";

  2. Salvare il file.

  3. 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.

  1. 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";

  2. Salvare il file.

  3. 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

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) dalla applicationUrl proprietà nel Properties/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}/publishdove 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:

  1. Dalla riga di comando, eseguire l'app: dotnet <app_assembly>.dll.
  2. 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 Kestrelhttp://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:

  1. Passare alla directory dell'app.
  2. Eseguire l'app: dotnet <app_assembly.dll>, dove app_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.jsondi 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 todayad esempio , --until 1 hour agoo 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:

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:

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:

  • 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'intestazione Strict-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:

  1. Modificare il file nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Aggiungere la riga: add_header X-Frame-Options "SAMEORIGIN";

  2. Salvare il file.

  3. 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.

  1. Modificare il file nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Aggiungere la riga: add_header X-Content-Type-Options "nosniff";

  2. Salvare il file.

  3. 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

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) dalla applicationUrl proprietà nel Properties/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}/publishdove 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:

  1. Dalla riga di comando, eseguire l'app: dotnet <app_assembly>.dll.
  2. 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 Kestrelhttp://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:

  1. Passare alla directory dell'app.
  2. Eseguire l'app: dotnet <app_assembly.dll>, dove app_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.jsondi 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 todayad esempio , --until 1 hour agoo 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:

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:

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:

  • 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'intestazione Strict-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:

  1. Modificare il file nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Aggiungere la riga: add_header X-Frame-Options "SAMEORIGIN";

  2. Salvare il file.

  3. 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.

  1. Modificare il file nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Aggiungere la riga: add_header X-Content-Type-Options "nosniff";

  2. Salvare il file.

  3. 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