Hosten von ASP.NET Core unter Linux mit Nginx

Von Sourabh Shirhatti

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

In diesem Leitfaden wird das Einrichten einer produktionsbereiten ASP.NET Core-Umgebung für Ubuntu, Red Hat Enterprise Linux (RHEL) und SUSE Linux Enterprise Server erläutert.

Weitere Informationen zu anderen Linux-Distributionen, die von ASP.NET Core unterstützt werden, finden Sie unter Voraussetzungen für .NET Core unter Linux.

In diesem Leitfaden:

  • Wird eine bestehende ASP.NET Core-App hinter einem Reverseproxyserver eingefügt.
  • wird der Reverseproxyserver zum Weiterleiten von Anforderungen an den Kestrel-Webserver eingerichtet.
  • Wird sichergestellt, dass die Web-App beim Start als Daemon ausgeführt wird.
  • Wird ein Prozessverwaltungstool konfiguriert, das die Web-App beim Neustarten unterstützt.

Voraussetzungen

  • Zugriff auf Ubuntu 20.04 mit einem Standardbenutzerkonto mit sudo-Berechtigung
  • Die neueste stabile .NET-Runtime ist auf dem Server installiert.
  • Eine vorhandene ASP.NET Core-App.

Starten Sie die vom Server gehosteten ASP.NET Core-Apps zu einem beliebigen Zeitpunkt nach dem Upgrade des freigegebenen Frameworks neu.

Veröffentlichen und Kopieren der App

Konfigurieren Sie die App für eine Framework-abhängige Bereitstellung.

Wenn die App lokal in der Entwicklungsumgebung ausgeführt wird und vom Server nicht für abgesicherte HTTPS-Verbindungen konfiguriert ist, wählen Sie einen der folgenden Ansätze:

  • Konfigurieren der App, sodass diese sichere lokale Verbindungen verarbeitet. Weitere Informationen finden Sie im Abschnitt HTTPS-Konfiguration.

  • Konfigurieren der App so, dass sie am unsicheren Endpunkt ausgeführt wird:

    • Deaktivieren der Middleware für HTTPS-Umleitung in der Entwicklungsumgebung (Program.cs):

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Weitere Informationen finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

    • Entfernen Sie https://localhost:5001 (falls vorhanden) aus der applicationUrl-Eigenschaft in der Datei Properties/launchSettings.json.

Weitere Informationen zur umgebungsabhängigen Konfiguration finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

Führen Sie in der Entwicklungsumgebung dotnet publish aus, um eine App in ein Verzeichnis zu packen (z. B. bin/Release/{TARGET FRAMEWORK MONIKER}/publish, wobei der Platzhalter {TARGET FRAMEWORK MONIKER} der TFM [Target Framework Moniker, Zielframeworkmoniker] ist), der auf dem Server ausgeführt werden kann:

dotnet publish --configuration Release

Die App kann auch als eine eigenständige Bereitstellung veröffentlicht werden, wenn Sie die .NET Core-Runtime nicht auf dem Server verwalten möchten.

Kopieren Sie die ASP.NET Core-App auf den Server, indem Sie ein beliebiges Tool verwenden, das in den Workflow der Organisation integriert ist (z. B. SCP oder SFTP). Web-Apps befinden sich üblicherweise im Verzeichnis var (z.B. var/www/helloapp).

Hinweis

In einem Szenario für die Bereitstellung in der Produktion übernimmt ein Continuous Integration-Workflow die Veröffentlichung der App und das Kopieren der Objekte auf den Server.

Testen der App:

  1. Führen Sie die App über die Befehlszeile aus: dotnet <app_assembly>.dll.
  2. Navigieren Sie in einem Browser zu http://<serveraddress>:<port>, und überprüfen Sie, ob die App lokal unter Linux funktioniert.

Konfigurieren eines Reverseproxyservers

Ein Reverseproxy wird im Allgemeinen zur Unterstützung dynamischer Web-Apps eingerichtet. Ein Reverseproxy beendet die HTTP-Anforderung und leitet diese an die ASP.NET Core-App weiter.

Verwenden eines Reverseproxyservers

Kestrel eignet sich hervorragend für die Bereitstellung dynamischer Inhalte von ASP.NET Core. Die Webbereitstellungsfunktionen sind jedoch nicht so umfangreich wie bei Servern wie IIS, Apache oder Nginx. Ein Reverseproxyserver kann Arbeiten wie das Verarbeiten von statischen Inhalten, das Zwischenspeichern und Komprimieren von Anforderungen und das Beenden von HTTPS vom HTTP-Server auslagern. Ein Reverseproxyserver kann sich auf einem dedizierten Computer befinden oder zusammen mit einem HTTP-Server bereitgestellt werden.

Für diesen Leitfaden wird eine einzelne Instanz von Nginx verwendet. Diese wird auf demselben Server ausgeführt, zusammen mit dem HTTP-Server. Je nach Anforderungen kann ein anderes Setup ausgewählt werden.

Da Anforderungen vom Reverseproxy weitergeleitet werden, verwenden Sie die Forwarded Headers Middleware aus dem Microsoft.AspNetCore.HttpOverrides-Paket, das automatisch in ASP.NET Core-Apps über das Microsoft.AspNetCore.App-Metapaket des freigegebenen Frameworks enthalten ist. Diese Middleware aktualisiert Request.Scheme mithilfe des X-Forwarded-Proto-Headers, sodass Umleitungs-URIs und andere Sicherheitsrichtlinien ordnungsgemäß funktionieren.

Die Middleware für weitergeleitete Header muss noch vor einer anderen Middleware ausgeführt werden. Mit dieser Reihenfolge wird sichergestellt, dass die auf Informationen von weitergeleiteten Headern basierende Middleware die zu verarbeitenden Headerwerte nutzen kann. Unter Middleware für weitergeleitete Header: Auftrag finden Sie Informationen zum Ausführen der Middleware für weitergeleitete Header nach der diagnostischen Middleware und der Middleware für die Fehlerbehandlung.

Rufen Sie die Methode UseForwardedHeaders auf, bevor Sie andere Middleware aufrufen. Konfigurieren Sie die Middleware so, dass die Header X-Forwarded-For und X-Forwarded-Proto weitergeleitet werden:

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();

Wenn für die Middleware keine ForwardedHeadersOptions angegeben sind, lauten die weiterzuleitenden Standardheader None.

Proxys, die unter Loopbackadressen (127.0.0.0/8, [::1]) ausgeführt werden, einschließlich der standardmäßigen Adresse von localhost (127.0.0.1), werden standardmäßig als vertrauenswürdig eingestuft. Wenn andere vertrauenswürdige Proxys oder Netzwerke innerhalb der Organisation Anforderungen zwischen dem Internet und dem Webserver verarbeiten, fügen Sie diese den Listen KnownProxies oder KnownNetworks mit ForwardedHeadersOptions hinzu. Das folgende Beispiel fügt einen vertrauenswürdigen Proxyserver mit der IP-Adresse 10.0.0.100 der Middleware KnownProxies für weitergeleitete Header hinzu:

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();

Weitere Informationen finden Sie unter Konfigurieren von ASP.NET Core für die Arbeit mit Proxyservern und Lastenausgleichen.

Installieren von Nginx

Verwenden Sie apt-get zum Installieren von Nginx. Das Installationsprogramm erstellt ein systemd-Initialisierungsskript, das Nginx beim Systemstart als Dämon ausführt. Befolgen Sie die Installationsanleitungen für Ubuntu auf NGINX: Official Debian/Ubuntu packages.

Hinweis

Wenn optionale Nginx-Module benötigt werden, kann die Erstellung von Nginx aus der Quelle erforderlich sein.

Da Nginx zum ersten Mal installiert wurde, starten Sie es explizit, indem Sie Folgendes ausführen:

sudo service nginx start

Stellen Sie sicher, dass ein Browser die Standardangebotsseite für Nginx anzeigt. Die Landing Page ist unter http://<server_IP_address>/index.nginx-debian.html erreichbar.

Konfigurieren von Nginx

Um Nginx als Reverseproxy zu konfigurieren, um HTTP-Anforderungen an die ASP.NET Core-App weiterzuleiten, ändern Sie /etc/nginx/sites-available/default, und erstellen Sie den Symlink neu. Verwenden Sie nach dem Erstellen der /etc/nginx/sites-available/default-Datei den folgenden Befehl, um den Symlink zu erstellen:

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

Öffnen Sie /etc/nginx/sites-available/default in einem Text-Editor, und ersetzen Sie den Inhalt durch den folgenden Codeausschnitt:

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;
    }
  }
}

Wenn es sich um eine SignalR- oder Blazor Server-App handelt, finden Sie weitere Informationen unter ASP.NET Core SignalR: Hosten in der Produktion und Skalieren und Hosten und Bereitstellen von serverseitigen ASP.NET Core Blazor-Apps.

Wenn keine Übereinstimmung mit server_name gefunden wird, verwendet Nginx den Standardserver. Wenn kein Server definiert ist, ist der erste Server in der Konfigurationsdatei der Standardserver. Als Best Practice gilt, einen bestimmten Standardserver hinzuzufügen, der den Statuscode 444 in Ihrer Konfigurationsdatei zurückgibt. Im Folgenden wird ein Beispiel für eine Standardserverkonfiguration aufgeführt:

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Mit der vorhergehenden Konfigurationsdatei und dem vorhergehenden Standardserver akzeptiert Nginx den öffentlichen Datenverkehr über Port 80 mit dem Hostheader example.com oder *.example.com. Anforderungen, die nicht mit diesen Hosts übereinstimmen, werden nicht an Kestrel weitergeleitet. Nginx leitet die übereinstimmenden Anforderungen an Kestrel unter http://127.0.0.1:5000/ weiter. Weitere Informationen finden Sie unter Verarbeitung einer Anforderung mit Nginx. Informationen zum Ändern der IP-Adresse oder des Ports von Kestrel finden Sie unter Kestrel: Endpunktkonfiguration.

Warnung

Schlägt die Angabe einer ordnungsgemäßen server_name-Anweisung fehlt, ist Ihre App Sicherheitsrisiken ausgesetzt. Platzhalterbindungen in untergeordneten Domänen (z.B. *.example.com) verursachen kein Sicherheitsrisiko, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: HTTP-Semantik (Abschnitt 7.2. Host und :authority).

Wenn die Nginx-Konfiguration eingerichtet ist, können Sie zur Überprüfung der Syntax der Konfigurationsdateien sudo nginx -t ausführen. Wenn der Test der Konfigurationsdatei erfolgreich ist, können Sie durch Ausführen von sudo nginx -s reload erzwingen, dass Nginx die Änderungen übernimmt.

Gehen Sie wie folgt vor, um die App auf dem Server direkt auszuführen:

  1. Navigieren Sie zum Verzeichnis der App.
  2. Führen Sie die App dotnet <app_assembly.dll> aus, wobei app_assembly.dll der Name der Assemblydatei der App ist.

Wenn die App auf dem Server ausgeführt wird, über das Internet jedoch nicht reagiert, sollten Sie die Firewall des Servers überprüfen und sicherstellen, dass Port 80 geöffnet ist. Fügen Sie bei Verwendung einer Azure-Ubuntu-VM eine Regel der Netzwerksicherheitsgruppe (NSG) zur Aktivierung des eingehenden Datenverkehrs an Port 80 hinzu. Eine Regel für ausgehenden Datenverkehr an Port 80 muss nicht aktiviert werden, da der ausgehende Datenverkehr automatisch gewährt wird, wenn die Regel für den eingehenden Datenverkehr aktiviert ist.

Nach dem Testen der App können Sie die App über STRG+C (Windows) oder +C (macOS) in der Eingabeaufforderung beenden.

Erhöhen von keepalive_requests

keepalive_requests kann für eine höhere Leistung erhöht werden. Weitere Informationen finden Sie in diesem GitHub-Issue.

Überwachen der App

Der Server ist dafür eingerichtet, Anforderungen an http://<serveraddress>:80 an die ASP.NET Core-App weiterzuleiten, die unter Kestrel unter http://127.0.0.1:5000 ausgeführt wird. Nginx wurde jedoch nicht dafür eingerichtet, den Kestrel-Prozess zu verwalten. systemd kann für die Erstellung einer Dienstdatei verwendet werden, um die zugrunde liegende Web-App zu starten und zu überwachen. systemd ist ein Initialisierungssystem, das viele leistungsstarke Features zum Starten, Beenden und Verwalten von Prozessen bereitstellt.

Erstellen der Dienstdatei

Erstellen Sie die Dienstdefinitionsdatei:

sudo nano /etc/systemd/system/kestrel-helloapp.service

Bei Folgendem handelt es sich um eine .ini-Dienstdatei für die 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

Im vorherigen Beispiel wird der Benutzer, der den Dienst verwaltet, durch die Option User angegeben. Der Benutzer (www-data) muss vorhanden und der ordnungsgemäße Besitzer der App-Dateien sein.

Verwenden Sie TimeoutStopSec, um die Dauer der Wartezeit bis zum Herunterfahren der App zu konfigurieren, nachdem diese das anfängliche Interruptsignal empfangen hat. Wenn die App in diesem Zeitraum nicht heruntergefahren wird, wird SIGKILL ausgegeben, um die App zu beenden. Geben Sie den Wert als einheitenlose Sekunden (z.B. 150), einen Zeitspannenwert (z.B. 2min 30s) oder infinity an, um das Timeout zu deaktivieren. TimeoutStopSec hat den Standardwert DefaultTimeoutStopSec in der Manager-Konfigurationsdatei (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Das Standardtimeout für die meisten Distributionen beträgt 90 Sekunden.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux verfügt über ein Dateisystem, bei dem die Groß-/Kleinschreibung beachtet wird. Wenn Sie ASPNETCORE_ENVIRONMENT auf Production festlegen, wird die Konfigurationsdatei appsettings.Production.json und nicht appsettings.production.json gesucht.

Einige Werte (z.B. SQL-Verbindungszeichenfolgen) müssen mit Escapezeichen versehen werden, damit die Konfigurationsanbieter die Umgebungsvariablen lesen können. Mit dem folgenden Befehl können Sie einen ordnungsgemäß mit Escapezeichen versehenen Wert für die Verwendung in der Konfigurationsdatei generieren:

systemd-escape "<value-to-escape>"

Doppelpunkte (:) als Trennzeichen werden in Umgebungsvariablennamen nicht unterstützt. Verwenden Sie statt eines Doppelpunkts zwei Unterstriche (__). Der Umgebungsvariablen-Konfigurationsanbieter konvertiert jeweils die zwei Unterstriche in einen Doppelpunkt, wenn die Umgebungsvariablen in die Konfiguration gelesen werden. Im folgenden Beispiel wird der Verbindungszeichenfolgeschlüssel ConnectionStrings:DefaultConnection als ConnectionStrings__DefaultConnection in die Dienstdefinitionsdatei platziert:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Speichern Sie die Datei, und aktivieren Sie den Dienst.

sudo systemctl enable kestrel-helloapp.service

Starten Sie den Dienst, und überprüfen Sie, ob er ausgeführt wird.

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

Wenn der Reverseproxy konfiguriert ist und Kestrel durch systemd verwaltet wird, ist die Webanwendung vollständig konfiguriert. Auf diese kann dann über einen Browser auf dem lokalen Computer unter http://localhost zugegriffen werden. Der Zugriff ist auch von einem Remotecomputer aus möglich, sofern keine Firewall diesen blockiert. Beim Überprüfen der Antwortheader zeigt der Header Server die ASP.NET Core-App an, die von Kestrel verarbeitet wird.

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

Anzeigen von Protokollen

Da die Web-App, die Kestrel verwendet, von systemd verwaltet wird, werden alle Ereignisse und Prozesse in einem zentralen Journal protokolliert. Dieses Journal enthält jedoch alle Einträge für alle Dienste und Prozesse, die von systemd verwaltet werden. Verwenden Sie folgenden Befehl, um die kestrel-helloapp.service-spezifischen Elemente anzuzeigen:

sudo journalctl -fu kestrel-helloapp.service

Für weiteres Filtern können Zeitoptionen wie --since today, --until 1 hour ago oder eine Kombination aus diesen die Menge der zurückgegebenen Einträge verringern.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Schutz von Daten

Der Stapel zum Schutz von Daten in ASP.NET Core wird von mehreren ASP.NET Core-Middlewares verwendet. Hierzu gehören die Authentifizierungsmiddleware (zum Beispiel die cookiemiddleware) und Maßnahmen zum Schutz vor websiteübergreifenden Anforderungsfälschungen (CSRF). Selbst wenn Datenschutz-APIs nicht im Benutzercode aufgerufen werden, sollte der Schutz von Daten konfiguriert werden, um einen persistenten kryptografischen Schlüsselspeicher zu erstellen. Wenn der Schutz von Daten nicht konfiguriert ist, werden die Schlüssel beim Neustarten der App im Arbeitsspeicher gespeichert und verworfen.

Falls der Schlüsselbund im Arbeitsspeicher gespeichert wird, wenn die App neu gestartet wird, gilt Folgendes:

  • Alle cookiebasierten Authentifizierungstoken werden für ungültig erklärt.
  • Benutzer müssen sich bei ihrer nächsten Anforderung erneut anmelden.
  • Alle mit dem Schlüsselbund geschützte Daten können nicht mehr entschlüsselt werden. Dies kann CSRF-Token und ASP.NET Core-MVC-TempData-Cookies einschließen.

Wenn Sie den Schutz von Daten konfigurieren möchten, um den Schlüsselring persistent zu speichern und zu verschlüsseln, finden Sie in den folgenden Artikeln weitere Informationen:

Lange Anforderungsheaderfelder

Die Standardeinstellungen für den Proxyserver schränken die Anforderungsheaderfelder in der Regel je nach Plattform auf 4 K oder 8 K ein. Eine App erfordert möglicherweise Felder länger als die Standardeinstellung (z. B. Apps, die Microsoft Entra ID verwenden). Wenn längere Felder erforderlich sind, müssen die Standardeinstellungen des Proxyservers angepasst werden. Die anzuwendenden Werte hängen vom jeweiligen Szenario ab. Weitere Informationen finden Sie in der Dokumentation Ihres Servers.

Warnung

Erhöhen Sie die Standardwerte der Proxypuffer nur dann, wenn dies absolut erforderlich ist. Ein Erhöhen dieser Werte vergrößert das Risiko von Pufferüberlauf- (Überlauf-) und Denial-of-Service-Angriffen durch böswillige Benutzer.

Sichern der App

Aktivieren von AppArmor

Bei Linux Security Modules (LSM) handelt es sich um ein Framework, das seit Linux 2.6 Teil des Linux-Kernels ist. LSM unterstützt verschiedene Implementierungen von Sicherheitsmodulen. AppArmor ist ein LSM, das ein obligatorisches Zugriffssteuerungssystem implementiert, das das Programm auf eine beschränkte Menge an Ressourcen begrenzt. Versichern Sie sich, dass AppArmor aktiviert und ordnungsgemäß konfiguriert ist.

Konfigurieren der Firewall

Schließen Sie alle externen Ports, die nicht verwendet werden. „Uncomplicated Firewall“ (UFW) stellt ein Front-End für iptables bereit, indem eine CLI zum Konfigurieren der Firewall bereitgestellt wird.

Warnung

Eine Firewall verhindert, wenn sie nicht ordnungsgemäß konfiguriert ist, den Zugriff auf das gesamte System. Falls Sie für den Verbindungsaufbau SSH verwenden und den falschen SSH-Port angeben, können Sie nicht mehr auf das System zugreifen. Der Standardport ist 22. Weitere Informationen finden Sie unter introduction to ufw (Einführung in ufw) und in den Manpages.

Installieren Sie ufw, und konfigurieren Sie das Tool so, dass der Datenverkehr auf allen erforderlich Ports zugelassen wird.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sichern von Nginx

Ändern des Namens der Nginx-Antwort

Bearbeiten Sie 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;

Konfigurieren von Optionen

Konfigurieren Sie den Server mit zusätzlichen erforderlichen Modulen. Erwägen Sie zum Schutz der App die Verwendung einer Web-App-Firewall wie z.B. ModSecurity.

HTTPS-Konfiguration

Konfigurieren der App für sichere (HTTPS) lokale Verbindungen

Der Befehl dotnet run verwendet die Datei Properties/launchSettings.json der App, die die App so konfiguriert, dass diese an den URLs lauscht, die von der applicationUrl-Eigenschaft bereitgestellt werden. Beispiel: https://localhost:5001;http://localhost:5000.

Konfigurieren Sie mithilfe eines der folgenden Ansätze die App so, dass sie bei der Entwicklung für den Befehl dotnet run oder die Entwicklungsumgebung (F5 oder STRG+F5 in Visual Studio Code) ein Zertifikat verwendet:

Konfigurieren des Reverseproxys für sichere (HTTPS) Clientverbindungen

Warnung

Die Sicherheitskonfiguration in diesem Abschnitt ist eine allgemeine Konfiguration, die als Ausgangspunkt für weitere Anpassungen verwendet werden kann. Wir können keine Unterstützung für Tools, Server und Betriebssysteme von Drittanbietern bereitstellen. Die Verwendung der Konfiguration in diesem Abschnitt erfolgt auf eigene Gefahr. Weitere Informationen finden Sie in den folgenden Ressourcen:

  • Konfigurieren Sie den Server so, dass dieser für den HTTPS-Datenverkehr an Port 443 lauscht, indem Sie ein gültiges Zertifikat angeben, das von einer vertrauenswürdigen Zertifizierungsstelle (Certificate Authority, CA) ausgestellt wurde.

  • Stärken Sie Ihre Sicherheit, indem Sie einige der in der folgenden Datei ( /etc/nginx/nginx.conf) dargestellten Methoden verwenden.

  • Im folgenden Beispiel wird der Server nicht für Umleitung unsicherer Anforderungen konfiguriert. Wir empfehlen die Verwendung von HTTPS-Umleitungsmiddleware. Weitere Informationen finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

    Hinweis

    Für Entwicklungsumgebungen, in denen die Serverkonfiguration anstelle der HTTPS-Umleitungsmiddleware die sichere Umleitung verarbeitet, empfehlen wir die Verwendung von temporären Umleitungen (302) anstelle von permanenten Umleitungen (301). Das Zwischenspeichern von Links kann in Entwicklungsumgebungen zu instabilem Verhalten führen.

  • Durch das Hinzufügen eines Strict-Transport-Security-Headers (HSTS) wird sichergestellt, dass alle nachfolgenden Anforderungen vom Client über HTTPS erfolgen. Anweisungen zum Festlegen des Strict-Transport-Security-Headers finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

  • Wenn HTTPS in Zukunft deaktiviert wird, halten Sie sich an einen der folgenden Ansätze:

    • Fügen Sie den HSTS-Header nicht hinzu.
    • Wählen Sie einen kurzen max-age-Wert aus.

Fügen Sie die Konfigurationsdatei /etc/nginx/proxy.conf hinzu:

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;

Ersetzen Sie die Inhalte der Konfigurationsdatei /etc/nginx/nginx.conf durch die folgende Datei. Das Beispiel enthält die Abschnitte http und server in einer Konfigurationsdatei.

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;
        }
    }
}

Hinweis

Blazor WebAssembly-Apps erfordern einen größeren burst-Parameterwert, damit die größere Anzahl von Anforderungen verarbeitet werden kann, die von einer App ausgeführt werden. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor WebAssembly in ASP.NET Core.

Hinweis

Im Beispiel oben wird OCSP-Stapling (Online Certificate Status Protocol) deaktiviert. Wenn Sie dieses Feature aktivieren, vergewissern Sie sich, dass das Zertifikat die Funktion unterstützt. Weitere Informationen und Anleitungen zum Aktivieren von OCSP finden Sie unter den folgenden Eigenschaften im Artikel Modul ngx_http_ssl_module (Nginx-Dokumentation):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sichern von Nginx vor Clickjacking

Clickjacking, auch bekannt als UI Redress-Angriff, ist ein böswilliger Angriff, bei dem ein Websitebesucher dazu verleitet wird, auf einen Link oder eine Schaltfläche zu klicken, der bzw. die sich auf einer anderen Seite als der aktuell besuchten Seite befindet. Verwenden Sie X-FRAME-OPTIONS zum Sichern der Website.

So wehren Sie Clickjacking-Angriffe ab:

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie innerhalb des Codeblocks http{} die Zeile add_header X-Frame-Options "SAMEORIGIN"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

MIME-Typermittlung

Dieser Header hindert die meisten Browser an der MIME-Ermittlung einer Antwort vom deklarierten Inhaltstyp weg, da der Header den Browser anweist, den Inhaltstyp der Antwort nicht zu überschreiben. Durch die Option nosniff wird der Inhalt vom Browser als text/html gerendert, wenn der Server sagt, dass es sich bei diesem um text/html handelt.

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie innerhalb des Codeblocks http{} die Zeile add_header X-Content-Type-Options "nosniff"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

Zusätzliche Vorschläge zu Nginx

Starten Sie die vom Server gehosteten ASP.NET Core-Apps nach dem Upgrade des freigegebenen Frameworks neu.

Zusätzliche Ressourcen

In diesem Leitfaden wird das Einrichten einer produktionsbereiten ASP.NET Core-Umgebung auf einem Ubuntu 16.04-Server erläutert. Diese Anweisungen sind wahrscheinlich auf neuere Versionen von Ubuntu anwendbar, sie wurden jedoch noch nicht mit neueren Versionen getestet.

Weitere Informationen zu anderen Linux-Distributionen, die von ASP.NET Core unterstützt werden, finden Sie unter Voraussetzungen für .NET Core unter Linux.

Hinweis

Für Ubuntu 14.04 wird supervisord als Lösung zum Überwachen des Kestrel-Prozesses empfohlen. systemd ist unter Ubuntu 14.04 nicht verfügbar. Anweisungen zu Ubuntu 14.04 finden Sie in der vorherigen Version dieses Themas.

In diesem Leitfaden:

  • Wird eine bestehende ASP.NET Core-App hinter einem Reverseproxyserver eingefügt.
  • wird der Reverseproxyserver zum Weiterleiten von Anforderungen an den Kestrel-Webserver eingerichtet.
  • Wird sichergestellt, dass die Web-App beim Start als Daemon ausgeführt wird.
  • Wird ein Prozessverwaltungstool konfiguriert, das die Web-App beim Neustarten unterstützt.

Voraussetzungen

  • Greifen Sie auf einen Ubuntu 16.04-Server mit einem Standardbenutzerkonto mit sudo-Berechtigung zu.
  • Die neueste .NET-Runtime, die keine Vorschauversion ist, ist auf dem Server installiert.
  • Eine vorhandene ASP.NET Core-App.

Starten Sie die vom Server gehosteten ASP.NET Core-Apps zu einem beliebigen Zeitpunkt nach dem Upgrade des freigegebenen Frameworks neu.

Veröffentlichen und Kopieren der App

Konfigurieren Sie die App für eine Framework-abhängige Bereitstellung.

Wenn die App lokal in der Entwicklungsumgebung ausgeführt wird und vom Server nicht für abgesicherte HTTPS-Verbindungen konfiguriert ist, wählen Sie einen der folgenden Ansätze:

  • Konfigurieren der App, sodass diese sichere lokale Verbindungen verarbeitet. Weitere Informationen finden Sie im Abschnitt HTTPS-Konfiguration.

  • Konfigurieren der App so, dass sie am unsicheren Endpunkt ausgeführt wird:

    • Deaktivieren der Middleware für HTTPS-Umleitung in der Entwicklungsumgebung (Program.cs):

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Weitere Informationen finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

    • Entfernen Sie https://localhost:5001 (falls vorhanden) aus der applicationUrl-Eigenschaft in der Datei Properties/launchSettings.json.

Weitere Informationen zur umgebungsabhängigen Konfiguration finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

Führen Sie in der Entwicklungsumgebung dotnet publish aus, um eine App in ein Verzeichnis zu packen (z. B. bin/Release/{TARGET FRAMEWORK MONIKER}/publish, wobei der Platzhalter {TARGET FRAMEWORK MONIKER} der TFM [Target Framework Moniker, Zielframeworkmoniker] ist), das auf dem Server ausgeführt werden kann:

dotnet publish --configuration Release

Die App kann auch als eine eigenständige Bereitstellung veröffentlicht werden, wenn Sie die .NET Core-Runtime nicht auf dem Server verwalten möchten.

Kopieren Sie die ASP.NET Core-App auf den Server, indem Sie ein beliebiges Tool verwenden, das in den Workflow der Organisation integriert ist (z. B. SCP oder SFTP). Web-Apps befinden sich üblicherweise im Verzeichnis var (z.B. var/www/helloapp).

Hinweis

In einem Szenario für die Bereitstellung in der Produktion übernimmt ein Continuous Integration-Workflow die Veröffentlichung der App und das Kopieren der Objekte auf den Server.

Testen der App:

  1. Führen Sie die App über die Befehlszeile aus: dotnet <app_assembly>.dll.
  2. Navigieren Sie in einem Browser zu http://<serveraddress>:<port>, und überprüfen Sie, ob die App lokal unter Linux funktioniert.

Konfigurieren eines Reverseproxyservers

Ein Reverseproxy wird im Allgemeinen zur Unterstützung dynamischer Web-Apps eingerichtet. Ein Reverseproxy beendet die HTTP-Anforderung und leitet diese an die ASP.NET Core-App weiter.

Verwenden eines Reverseproxyservers

Kestrel eignet sich hervorragend für die Bereitstellung dynamischer Inhalte von ASP.NET Core. Die Webbereitstellungsfunktionen sind jedoch nicht so umfangreich wie bei Servern wie IIS, Apache oder Nginx. Ein Reverseproxyserver kann Arbeiten wie das Verarbeiten von statischen Inhalten, das Zwischenspeichern und Komprimieren von Anforderungen und das Beenden von HTTPS vom HTTP-Server auslagern. Ein Reverseproxyserver kann sich auf einem dedizierten Computer befinden oder zusammen mit einem HTTP-Server bereitgestellt werden.

Für diesen Leitfaden wird eine einzelne Instanz von Nginx verwendet. Diese wird auf demselben Server ausgeführt, zusammen mit dem HTTP-Server. Je nach Anforderungen kann ein anderes Setup ausgewählt werden.

Da Anforderungen vom Reverseproxy weitergeleitet werden, verwenden Sie die Middleware für weitergeleitete Header im Paket Microsoft.AspNetCore.HttpOverrides. Diese Middleware aktualisiert Request.Scheme mithilfe des X-Forwarded-Proto-Headers, sodass Umleitungs-URIs und andere Sicherheitsrichtlinien ordnungsgemäß funktionieren.

Die Middleware für weitergeleitete Header muss noch vor einer anderen Middleware ausgeführt werden. Mit dieser Reihenfolge wird sichergestellt, dass die auf Informationen von weitergeleiteten Headern basierende Middleware die zu verarbeitenden Headerwerte nutzen kann. Unter Middleware für weitergeleitete Header: Auftrag finden Sie Informationen zum Ausführen der Middleware für weitergeleitete Header nach der diagnostischen Middleware und der Middleware für die Fehlerbehandlung.

Rufen Sie die Methode UseForwardedHeaders am Anfang von Program.cs auf, bevor Sie andere Middleware aufrufen. Konfigurieren Sie die Middleware so, dass die Header X-Forwarded-For und X-Forwarded-Proto weitergeleitet werden:

// requires using Microsoft.AspNetCore.HttpOverrides;
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

Wenn für die Middleware keine ForwardedHeadersOptions angegeben sind, lauten die weiterzuleitenden Standardheader None.

Proxys, die unter Loopbackadressen (127.0.0.0/8, [::1]) ausgeführt werden, einschließlich der standardmäßigen Adresse von localhost (127.0.0.1), werden standardmäßig als vertrauenswürdig eingestuft. Wenn andere vertrauenswürdige Proxys oder Netzwerke innerhalb des Unternehmens Anforderungen zwischen dem Internet und dem Webserver verarbeiten, fügen Sie diese der Liste der KnownProxies oder KnownNetworks mit ForwardedHeadersOptions hinzu. Das folgende Beispiel fügt einen vertrauenswürdigen Proxyserver mit der IP-Adresse 10.0.0.0.100 der Middleware für weitergeleitete Header KnownProxies in Program.cs hinzu:

using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

Weitere Informationen finden Sie unter Konfigurieren von ASP.NET Core für die Arbeit mit Proxyservern und Lastenausgleichen.

Installieren von Nginx

Verwenden Sie apt-get zum Installieren von Nginx. Das Installationsprogramm erstellt ein systemd-Initialisierungsskript, das Nginx beim Systemstart als Dämon ausführt. Befolgen Sie die Installationsanleitungen für Ubuntu auf NGINX: Official Debian/Ubuntu packages.

Hinweis

Wenn optionale Nginx-Module benötigt werden, kann die Erstellung von Nginx aus der Quelle erforderlich sein.

Da Nginx zum ersten Mal installiert wurde, starten Sie es explizit, indem Sie Folgendes ausführen:

sudo service nginx start

Stellen Sie sicher, dass ein Browser die Standardangebotsseite für Nginx anzeigt. Die Landing Page ist unter http://<server_IP_address>/index.nginx-debian.html erreichbar.

Konfigurieren von Nginx

Ändern Sie /etc/nginx/sites-available/default, um Nginx als Reverseproxy für das Weiterleiten von Anforderungen zu Ihrer ASP.NET Core-App zu konfigurieren. Öffnen Sie die Datei in einem Text-Editor, und ersetzen Sie den Inhalt durch den folgenden Codeausschnitt:

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;
    }
}

Wenn es sich um eine SignalR- oder Blazor Server-App handelt, finden Sie weitere Informationen unter ASP.NET Core SignalR: Hosten in der Produktion und Skalieren und Hosten und Bereitstellen von serverseitigen ASP.NET Core Blazor-Apps.

Wenn keine Übereinstimmung mit server_name gefunden wird, verwendet Nginx den Standardserver. Wenn kein Server definiert ist, ist der erste Server in der Konfigurationsdatei der Standardserver. Als Best Practice gilt, einen bestimmten Standardserver hinzuzufügen, der den Statuscode 444 in Ihrer Konfigurationsdatei zurückgibt. Im Folgenden wird ein Beispiel für eine Standardserverkonfiguration aufgeführt:

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Mit der vorhergehenden Konfigurationsdatei und dem vorhergehenden Standardserver akzeptiert Nginx den öffentlichen Datenverkehr über Port 80 mit dem Hostheader example.com oder *.example.com. Anforderungen, die nicht mit diesen Hosts übereinstimmen, werden nicht an Kestrel weitergeleitet. Nginx leitet die übereinstimmenden Anforderungen an Kestrel unter http://127.0.0.1:5000 weiter. Weitere Informationen finden Sie unter Verarbeitung einer Anforderung mit Nginx. Informationen zum Ändern der IP-Adresse oder des Ports von Kestrel finden Sie unter Kestrel: Endpunktkonfiguration.

Warnung

Schlägt die Angabe einer ordnungsgemäßen server_name-Anweisung fehlt, ist Ihre App Sicherheitsrisiken ausgesetzt. Platzhalterbindungen in untergeordneten Domänen (z.B. *.example.com) verursachen kein Sicherheitsrisiko, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: HTTP-Semantik (Abschnitt 7.2. Host und :authority).

Wenn die Nginx-Konfiguration eingerichtet ist, können Sie zur Überprüfung der Syntax der Konfigurationsdateien sudo nginx -t ausführen. Wenn der Test der Konfigurationsdatei erfolgreich ist, können Sie durch Ausführen von sudo nginx -s reload erzwingen, dass Nginx die Änderungen übernimmt.

Gehen Sie wie folgt vor, um die App auf dem Server direkt auszuführen:

  1. Navigieren Sie zum Verzeichnis der App.
  2. Führen Sie die App dotnet <app_assembly.dll> aus, wobei app_assembly.dll der Name der Assemblydatei der App ist.

Wenn die App auf dem Server ausgeführt wird, über das Internet jedoch nicht reagiert, sollten Sie die Firewall des Servers überprüfen und sicherstellen, dass Port 80 geöffnet ist. Fügen Sie bei Verwendung einer Azure-Ubuntu-VM eine Regel der Netzwerksicherheitsgruppe (NSG) zur Aktivierung des eingehenden Datenverkehrs an Port 80 hinzu. Eine Regel für ausgehenden Datenverkehr an Port 80 muss nicht aktiviert werden, da der ausgehende Datenverkehr automatisch gewährt wird, wenn die Regel für den eingehenden Datenverkehr aktiviert ist.

Nach dem Testen der App können Sie die App über STRG+C (Windows) oder +C (macOS) in der Eingabeaufforderung beenden.

Überwachen der App

Der Server ist dafür eingerichtet, Anforderungen an http://<serveraddress>:80 an die ASP.NET Core-App weiterzuleiten, die unter Kestrel unter http://127.0.0.1:5000 ausgeführt wird. Nginx wurde jedoch nicht dafür eingerichtet, den Kestrel-Prozess zu verwalten. systemd kann für die Erstellung einer Dienstdatei verwendet werden, um die zugrunde liegende Web-App zu starten und zu überwachen. systemd ist ein Initialisierungssystem, das viele leistungsstarke Features zum Starten, Beenden und Verwalten von Prozessen bereitstellt.

Erstellen der Dienstdatei

Erstellen Sie die Dienstdefinitionsdatei:

sudo nano /etc/systemd/system/kestrel-helloapp.service

Bei Folgendem handelt es sich um eine Dienstdatei für die 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

Im vorherigen Beispiel wird der Benutzer, der den Dienst verwaltet, durch die Option User angegeben. Der Benutzer (www-data) muss vorhanden und der ordnungsgemäße Besitzer der App-Dateien sein.

Verwenden Sie TimeoutStopSec, um die Dauer der Wartezeit bis zum Herunterfahren der App zu konfigurieren, nachdem diese das anfängliche Interruptsignal empfangen hat. Wenn die App in diesem Zeitraum nicht heruntergefahren wird, wird SIGKILL ausgegeben, um die App zu beenden. Geben Sie den Wert als einheitenlose Sekunden (z.B. 150), einen Zeitspannenwert (z.B. 2min 30s) oder infinity an, um das Timeout zu deaktivieren. TimeoutStopSec hat den Standardwert DefaultTimeoutStopSec in der Manager-Konfigurationsdatei (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Das Standardtimeout für die meisten Distributionen beträgt 90 Sekunden.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux verfügt über ein Dateisystem, bei dem die Groß-/Kleinschreibung beachtet wird. Wenn Sie ASPNETCORE_ENVIRONMENT auf Production festlegen, wird die Konfigurationsdatei appsettings.Production.json und nicht appsettings.production.json gesucht.

Einige Werte (z.B. SQL-Verbindungszeichenfolgen) müssen mit Escapezeichen versehen werden, damit die Konfigurationsanbieter die Umgebungsvariablen lesen können. Mit dem folgenden Befehl können Sie einen ordnungsgemäß mit Escapezeichen versehenen Wert für die Verwendung in der Konfigurationsdatei generieren:

systemd-escape "<value-to-escape>"

Doppelpunkte (:) als Trennzeichen werden in Umgebungsvariablennamen nicht unterstützt. Verwenden Sie statt eines Doppelpunkts zwei Unterstriche (__). Der Umgebungsvariablen-Konfigurationsanbieter konvertiert jeweils die zwei Unterstriche in einen Doppelpunkt, wenn die Umgebungsvariablen in die Konfiguration gelesen werden. Im folgenden Beispiel wird der Verbindungszeichenfolgeschlüssel ConnectionStrings:DefaultConnection als ConnectionStrings__DefaultConnection in die Dienstdefinitionsdatei platziert:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Speichern Sie die Datei, und aktivieren Sie den Dienst.

sudo systemctl enable kestrel-helloapp.service

Starten Sie den Dienst, und überprüfen Sie, ob er ausgeführt wird.

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

Wenn der Reverseproxy konfiguriert ist und Kestrel durch systemd verwaltet wird, ist die Webanwendung vollständig konfiguriert. Auf diese kann dann über einen Browser auf dem lokalen Computer unter http://localhost zugegriffen werden. Der Zugriff ist auch von einem Remotecomputer aus möglich, sofern keine Firewall diesen blockiert. Beim Überprüfen der Antwortheader zeigt der Header Server die ASP.NET Core-App an, die von Kestrel verarbeitet wird.

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

Anzeigen von Protokollen

Da die Web-App, die Kestrel verwendet, von systemd verwaltet wird, werden alle Ereignisse und Prozesse in einem zentralen Journal protokolliert. Dieses Journal enthält jedoch alle Einträge für alle Dienste und Prozesse, die von systemd verwaltet werden. Verwenden Sie folgenden Befehl, um die kestrel-helloapp.service-spezifischen Elemente anzuzeigen:

sudo journalctl -fu kestrel-helloapp.service

Für weiteres Filtern können Zeitoptionen wie --since today, --until 1 hour ago oder eine Kombination aus diesen die Menge der zurückgegebenen Einträge verringern.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Schutz von Daten

Der Stapel zum Schutz von Daten in ASP.NET Core wird von mehreren ASP.NET Core-Middlewares verwendet. Hierzu gehören die Authentifizierungsmiddleware (zum Beispiel die cookiemiddleware) und Maßnahmen zum Schutz vor websiteübergreifenden Anforderungsfälschungen (CSRF). Selbst wenn Datenschutz-APIs nicht im Benutzercode aufgerufen werden, sollte der Schutz von Daten konfiguriert werden, um einen persistenten kryptografischen Schlüsselspeicher zu erstellen. Wenn der Schutz von Daten nicht konfiguriert ist, werden die Schlüssel beim Neustarten der App im Arbeitsspeicher gespeichert und verworfen.

Falls der Schlüsselbund im Arbeitsspeicher gespeichert wird, wenn die App neu gestartet wird, gilt Folgendes:

  • Alle cookiebasierten Authentifizierungstoken werden für ungültig erklärt.
  • Benutzer müssen sich bei ihrer nächsten Anforderung erneut anmelden.
  • Alle mit dem Schlüsselbund geschützte Daten können nicht mehr entschlüsselt werden. Dies kann CSRF-Token und ASP.NET Core-MVC-TempData-Cookies einschließen.

Wenn Sie den Schutz von Daten konfigurieren möchten, um den Schlüsselring persistent zu speichern und zu verschlüsseln, finden Sie in den folgenden Artikeln weitere Informationen:

Lange Anforderungsheaderfelder

Die Standardeinstellungen für den Proxyserver schränken die Anforderungsheaderfelder in der Regel je nach Plattform auf 4 K oder 8 K ein. Eine App erfordert möglicherweise Felder, die länger als die Standardwerte sind (z. B. Apps, die Azure Active Directory verwenden). Wenn längere Felder erforderlich sind, müssen die Standardeinstellungen des Proxyservers angepasst werden. Die anzuwendenden Werte hängen vom jeweiligen Szenario ab. Weitere Informationen finden Sie in der Dokumentation Ihres Servers.

Warnung

Erhöhen Sie die Standardwerte der Proxypuffer nur dann, wenn dies absolut erforderlich ist. Ein Erhöhen dieser Werte vergrößert das Risiko von Pufferüberlauf- (Überlauf-) und Denial-of-Service-Angriffen durch böswillige Benutzer.

Sichern der App

Aktivieren von AppArmor

Bei Linux Security Modules (LSM) handelt es sich um ein Framework, das seit Linux 2.6 Teil des Linux-Kernels ist. LSM unterstützt verschiedene Implementierungen von Sicherheitsmodulen. AppArmor ist ein LSM, das ein obligatorisches Zugriffssteuerungssystem implementiert, das das Programm auf eine beschränkte Menge an Ressourcen begrenzt. Versichern Sie sich, dass AppArmor aktiviert und ordnungsgemäß konfiguriert ist.

Konfigurieren der Firewall

Schließen Sie alle externen Ports, die nicht verwendet werden. „Uncomplicated Firewall“ (UFW) stellt ein Front-End für iptables bereit, indem eine CLI zum Konfigurieren der Firewall bereitgestellt wird.

Warnung

Eine Firewall verhindert den Zugriff auf das gesamte System, wenn dieses nicht ordnungsgemäß konfiguriert ist. Falls Sie SSH zum Verbindungsaufbau verwenden und den falschen SSH-Port angeben, können Sie nicht mehr auf das System zugreifen. Der Standardport ist 22. Weitere Informationen finden Sie unter introduction to ufw (Einführung in ufw) und in den Manpages.

Installieren Sie ufw, und konfigurieren Sie das Tool so, dass der Datenverkehr auf allen erforderlich Ports zugelassen wird.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sichern von Nginx

Ändern des Namens der Nginx-Antwort

Bearbeiten Sie 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;

Konfigurieren von Optionen

Konfigurieren Sie den Server mit zusätzlichen erforderlichen Modulen. Erwägen Sie zum Schutz der App die Verwendung einer Web-App-Firewall wie z.B. ModSecurity.

HTTPS-Konfiguration

Konfigurieren der App für sichere (HTTPS) lokale Verbindungen

Der Befehl dotnet run verwendet die Datei Properties/launchSettings.json der App, die die App so konfiguriert, dass diese an den URLs lauscht, die von der applicationUrl-Eigenschaft bereitgestellt werden. Beispiel: https://localhost:5001;http://localhost:5000.

Konfigurieren Sie mithilfe eines der folgenden Ansätze die App so, dass sie bei der Entwicklung für den Befehl dotnet run oder die Entwicklungsumgebung (F5 oder STRG+F5 in Visual Studio Code) ein Zertifikat verwendet:

Konfigurieren des Reverseproxys für sichere (HTTPS) Clientverbindungen

Warnung

Die Sicherheitskonfiguration in diesem Abschnitt ist eine allgemeine Konfiguration, die als Ausgangspunkt für weitere Anpassungen verwendet werden kann. Wir können keine Unterstützung für Tools, Server und Betriebssysteme von Drittanbietern bereitstellen. Die Verwendung der Konfiguration in diesem Abschnitt erfolgt auf eigene Gefahr. Weitere Informationen finden Sie in den folgenden Ressourcen:

  • Konfigurieren Sie den Server so, dass dieser für den HTTPS-Datenverkehr an Port 443 lauscht, indem Sie ein gültiges Zertifikat angeben, das von einer vertrauenswürdigen Zertifizierungsstelle (Certificate Authority, CA) ausgestellt wurde.

  • Stärken Sie Ihre Sicherheit, indem Sie einige der in der folgenden Datei ( /etc/nginx/nginx.conf) dargestellten Methoden verwenden.

  • Im folgenden Beispiel wird der Server nicht für Umleitung unsicherer Anforderungen konfiguriert. Wir empfehlen die Verwendung von HTTPS-Umleitungsmiddleware. Weitere Informationen finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

    Hinweis

    Für Entwicklungsumgebungen, in denen die Serverkonfiguration anstelle der HTTPS-Umleitungsmiddleware die sichere Umleitung verarbeitet, empfehlen wir die Verwendung von temporären Umleitungen (302) anstelle von permanenten Umleitungen (301). Das Zwischenspeichern von Links kann in Entwicklungsumgebungen zu instabilem Verhalten führen.

  • Durch das Hinzufügen eines Strict-Transport-Security-Headers (HSTS) wird sichergestellt, dass alle nachfolgenden Anforderungen vom Client über HTTPS erfolgen. Anweisungen zum Festlegen des Strict-Transport-Security-Headers finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

  • Wenn HTTPS in Zukunft deaktiviert wird, halten Sie sich an einen der folgenden Ansätze:

    • Fügen Sie den HSTS-Header nicht hinzu.
    • Wählen Sie einen kurzen max-age-Wert aus.

Fügen Sie die Konfigurationsdatei /etc/nginx/proxy.conf hinzu:

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;

Ersetzen Sie die Inhalte der Konfigurationsdatei /etc/nginx/nginx.conf durch die folgende Datei. Das Beispiel enthält die Abschnitte http und server in einer Konfigurationsdatei.

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;
        }
    }
}

Hinweis

Blazor WebAssembly-Apps erfordern einen größeren burst-Parameterwert, damit die größere Anzahl von Anforderungen verarbeitet werden kann, die von einer App ausgeführt werden. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor WebAssembly in ASP.NET Core.

Hinweis

Im Beispiel oben wird OCSP-Stapling (Online Certificate Status Protocol) deaktiviert. Wenn Sie dieses Feature aktivieren, vergewissern Sie sich, dass das Zertifikat die Funktion unterstützt. Weitere Informationen und Anleitungen zum Aktivieren von OCSP finden Sie unter den folgenden Eigenschaften im Artikel Modul ngx_http_ssl_module (Nginx-Dokumentation):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sichern von Nginx vor Clickjacking

Clickjacking, auch bekannt als UI Redress-Angriff, ist ein böswilliger Angriff, bei dem ein Websitebesucher dazu verleitet wird, auf einen Link oder eine Schaltfläche zu klicken, der bzw. die sich auf einer anderen Seite als der aktuell besuchten Seite befindet. Verwenden Sie X-FRAME-OPTIONS zum Sichern der Website.

So wehren Sie Clickjacking-Angriffe ab:

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie die Zeile add_header X-Frame-Options "SAMEORIGIN"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

MIME-Typermittlung

Dieser Header hindert die meisten Browser an der MIME-Ermittlung einer Antwort vom deklarierten Inhaltstyp weg, da der Header den Browser anweist, den Inhaltstyp der Antwort nicht zu überschreiben. Durch die Option nosniff wird der Inhalt vom Browser als text/html gerendert, wenn der Server sagt, dass es sich bei diesem um text/html handelt.

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie die Zeile add_header X-Content-Type-Options "nosniff"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

Zusätzliche Vorschläge zu Nginx

Starten Sie die vom Server gehosteten ASP.NET Core-Apps nach dem Upgrade des freigegebenen Frameworks neu.

Zusätzliche Ressourcen

In diesem Leitfaden wird das Einrichten einer produktionsbereiten ASP.NET Core-Umgebung auf einem Ubuntu 16.04-Server erläutert. Diese Anweisungen sind wahrscheinlich auf neuere Versionen von Ubuntu anwendbar, sie wurden jedoch noch nicht mit neueren Versionen getestet.

Weitere Informationen zu anderen Linux-Distributionen, die von ASP.NET Core unterstützt werden, finden Sie unter Voraussetzungen für .NET Core unter Linux.

Hinweis

Für Ubuntu 14.04 wird supervisord als Lösung zum Überwachen des Kestrel-Prozesses empfohlen. systemd ist unter Ubuntu 14.04 nicht verfügbar. Anweisungen zu Ubuntu 14.04 finden Sie in der vorherigen Version dieses Themas.

In diesem Leitfaden:

  • Wird eine bestehende ASP.NET Core-App hinter einem Reverseproxyserver eingefügt.
  • wird der Reverseproxyserver zum Weiterleiten von Anforderungen an den Kestrel-Webserver eingerichtet.
  • Wird sichergestellt, dass die Web-App beim Start als Daemon ausgeführt wird.
  • Wird ein Prozessverwaltungstool konfiguriert, das die Web-App beim Neustarten unterstützt.

Voraussetzungen

  • Greifen Sie auf einen Ubuntu 16.04-Server mit einem Standardbenutzerkonto mit sudo-Berechtigung zu.
  • Die neueste .NET-Runtime, die keine Vorschauversion ist, ist auf dem Server installiert.
  • Eine vorhandene ASP.NET Core-App.

Starten Sie die vom Server gehosteten ASP.NET Core-Apps zu einem beliebigen Zeitpunkt nach dem Upgrade des freigegebenen Frameworks neu.

Veröffentlichen und Kopieren der App

Konfigurieren Sie die App für eine Framework-abhängige Bereitstellung.

Wenn die App lokal in der Entwicklungsumgebung ausgeführt wird und vom Server nicht für abgesicherte HTTPS-Verbindungen konfiguriert ist, wählen Sie einen der folgenden Ansätze:

  • Konfigurieren der App, sodass diese sichere lokale Verbindungen verarbeitet. Weitere Informationen finden Sie im Abschnitt HTTPS-Konfiguration.

  • Konfigurieren der App so, dass sie am unsicheren Endpunkt ausgeführt wird:

    • Deaktivieren der Middleware für HTTPS-Umleitung in der Entwicklungsumgebung (Program.cs):

      if (!app.Environment.IsDevelopment())
      {
          app.UseHttpsRedirection();
      }
      

      Weitere Informationen finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

    • Entfernen Sie https://localhost:5001 (falls vorhanden) aus der applicationUrl-Eigenschaft in der Datei Properties/launchSettings.json.

Weitere Informationen zur umgebungsabhängigen Konfiguration finden Sie unter Verwenden mehrerer Umgebungen in ASP.NET Core.

Führen Sie in der Entwicklungsumgebung dotnet publish aus, um eine App in ein Verzeichnis zu packen (z. B. bin/Release/{TARGET FRAMEWORK MONIKER}/publish, wobei der Platzhalter {TARGET FRAMEWORK MONIKER} der TFM [Target Framework Moniker, Zielframeworkmoniker] ist), das auf dem Server ausgeführt werden kann:

dotnet publish --configuration Release

Die App kann auch als eine eigenständige Bereitstellung veröffentlicht werden, wenn Sie die .NET Core-Runtime nicht auf dem Server verwalten möchten.

Kopieren Sie die ASP.NET Core-App auf den Server, indem Sie ein beliebiges Tool verwenden, das in den Workflow der Organisation integriert ist (z. B. SCP oder SFTP). Web-Apps befinden sich üblicherweise im Verzeichnis var (z.B. var/www/helloapp).

Hinweis

In einem Szenario für die Bereitstellung in der Produktion übernimmt ein Continuous Integration-Workflow die Veröffentlichung der App und das Kopieren der Objekte auf den Server.

Testen der App:

  1. Führen Sie die App über die Befehlszeile aus: dotnet <app_assembly>.dll.
  2. Navigieren Sie in einem Browser zu http://<serveraddress>:<port>, und überprüfen Sie, ob die App lokal unter Linux funktioniert.

Konfigurieren eines Reverseproxyservers

Ein Reverseproxy wird im Allgemeinen zur Unterstützung dynamischer Web-Apps eingerichtet. Ein Reverseproxy beendet die HTTP-Anforderung und leitet diese an die ASP.NET Core-App weiter.

Verwenden eines Reverseproxyservers

Kestrel eignet sich hervorragend für die Bereitstellung dynamischer Inhalte von ASP.NET Core. Die Webbereitstellungsfunktionen sind jedoch nicht so umfangreich wie bei Servern wie IIS, Apache oder Nginx. Ein Reverseproxyserver kann Arbeiten wie das Verarbeiten von statischen Inhalten, das Zwischenspeichern und Komprimieren von Anforderungen und das Beenden von HTTPS vom HTTP-Server auslagern. Ein Reverseproxyserver kann sich auf einem dedizierten Computer befinden oder zusammen mit einem HTTP-Server bereitgestellt werden.

Für diesen Leitfaden wird eine einzelne Instanz von Nginx verwendet. Diese wird auf demselben Server ausgeführt, zusammen mit dem HTTP-Server. Je nach Anforderungen kann ein anderes Setup ausgewählt werden.

Da Anforderungen vom Reverseproxy weitergeleitet werden, verwenden Sie die Middleware für weitergeleitete Header im Paket Microsoft.AspNetCore.HttpOverrides. Diese Middleware aktualisiert Request.Scheme mithilfe des X-Forwarded-Proto-Headers, sodass Umleitungs-URIs und andere Sicherheitsrichtlinien ordnungsgemäß funktionieren.

Die Middleware für weitergeleitete Header muss noch vor einer anderen Middleware ausgeführt werden. Mit dieser Reihenfolge wird sichergestellt, dass die auf Informationen von weitergeleiteten Headern basierende Middleware die zu verarbeitenden Headerwerte nutzen kann. Unter Middleware für weitergeleitete Header: Auftrag finden Sie Informationen zum Ausführen der Middleware für weitergeleitete Header nach der diagnostischen Middleware und der Middleware für die Fehlerbehandlung.

Rufen Sie die Methode UseForwardedHeaders am Anfang von Startup.Configure auf, bevor Sie andere Middleware aufrufen. Konfigurieren Sie die Middleware so, dass die Header X-Forwarded-For und X-Forwarded-Proto weitergeleitet werden:

using Microsoft.AspNetCore.HttpOverrides;

...

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

Wenn für die Middleware keine ForwardedHeadersOptions angegeben sind, lauten die weiterzuleitenden Standardheader None.

Proxys, die unter Loopbackadressen (127.0.0.0/8, [::1]) ausgeführt werden, einschließlich der standardmäßigen Adresse von localhost (127.0.0.1), werden standardmäßig als vertrauenswürdig eingestuft. Wenn andere vertrauenswürdige Proxys oder Netzwerke innerhalb des Unternehmens Anforderungen zwischen dem Internet und dem Webserver verarbeiten, fügen Sie diese der Liste der KnownProxies oder KnownNetworks mit ForwardedHeadersOptions hinzu. Das folgende Beispiel fügt einen vertrauenswürdigen Proxyserver mit der IP-Adresse 10.0.0.0.100 der Middleware für weitergeleitete Header KnownProxies in Startup.ConfigureServices hinzu:

using System.Net;

...

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

Weitere Informationen finden Sie unter Konfigurieren von ASP.NET Core für die Arbeit mit Proxyservern und Lastenausgleichen.

Installieren von Nginx

Verwenden Sie apt-get zum Installieren von Nginx. Das Installationsprogramm erstellt ein systemd-Initialisierungsskript, das Nginx beim Systemstart als Dämon ausführt. Befolgen Sie die Installationsanleitungen für Ubuntu auf NGINX: Official Debian/Ubuntu packages.

Hinweis

Wenn optionale Nginx-Module benötigt werden, kann die Erstellung von Nginx aus der Quelle erforderlich sein.

Da Nginx zum ersten Mal installiert wurde, starten Sie es explizit, indem Sie Folgendes ausführen:

sudo service nginx start

Stellen Sie sicher, dass ein Browser die Standardangebotsseite für Nginx anzeigt. Die Landing Page ist unter http://<server_IP_address>/index.nginx-debian.html erreichbar.

Konfigurieren von Nginx

Ändern Sie /etc/nginx/sites-available/default, um Nginx als Reverseproxy für das Weiterleiten von Anforderungen zu Ihrer ASP.NET Core-App zu konfigurieren. Öffnen Sie die Datei in einem Text-Editor, und ersetzen Sie den Inhalt durch den folgenden Codeausschnitt:

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;
    }
}

Wenn es sich um eine SignalR- oder Blazor Server-App handelt, finden Sie weitere Informationen unter ASP.NET Core SignalR: Hosten in der Produktion und Skalieren und Hosten und Bereitstellen von serverseitigen ASP.NET Core Blazor-Apps.

Wenn keine Übereinstimmung mit server_name gefunden wird, verwendet Nginx den Standardserver. Wenn kein Server definiert ist, ist der erste Server in der Konfigurationsdatei der Standardserver. Als Best Practice gilt, einen bestimmten Standardserver hinzuzufügen, der den Statuscode 444 in Ihrer Konfigurationsdatei zurückgibt. Im Folgenden wird ein Beispiel für eine Standardserverkonfiguration aufgeführt:

server {
    listen   80 default_server;
    # listen [::]:80 default_server deferred;
    return   444;
}

Mit der vorhergehenden Konfigurationsdatei und dem vorhergehenden Standardserver akzeptiert Nginx den öffentlichen Datenverkehr über Port 80 mit dem Hostheader example.com oder *.example.com. Anforderungen, die nicht mit diesen Hosts übereinstimmen, werden nicht an Kestrel weitergeleitet. Nginx leitet die übereinstimmenden Anforderungen an Kestrel unter http://127.0.0.1:5000 weiter. Weitere Informationen finden Sie unter Verarbeitung einer Anforderung mit Nginx. Informationen zum Ändern der IP-Adresse oder des Ports von Kestrel finden Sie unter Kestrel: Endpunktkonfiguration.

Warnung

Schlägt die Angabe einer ordnungsgemäßen server_name-Anweisung fehlt, ist Ihre App Sicherheitsrisiken ausgesetzt. Platzhalterbindungen in untergeordneten Domänen (z.B. *.example.com) verursachen kein Sicherheitsrisiko, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: HTTP-Semantik (Abschnitt 7.2. Host und :authority).

Wenn die Nginx-Konfiguration eingerichtet ist, können Sie zur Überprüfung der Syntax der Konfigurationsdateien sudo nginx -t ausführen. Wenn der Test der Konfigurationsdatei erfolgreich ist, können Sie durch Ausführen von sudo nginx -s reload erzwingen, dass Nginx die Änderungen übernimmt.

Gehen Sie wie folgt vor, um die App auf dem Server direkt auszuführen:

  1. Navigieren Sie zum Verzeichnis der App.
  2. Führen Sie die App dotnet <app_assembly.dll> aus, wobei app_assembly.dll der Name der Assemblydatei der App ist.

Wenn die App auf dem Server ausgeführt wird, über das Internet jedoch nicht reagiert, sollten Sie die Firewall des Servers überprüfen und sicherstellen, dass Port 80 geöffnet ist. Fügen Sie bei Verwendung einer Azure-Ubuntu-VM eine Regel der Netzwerksicherheitsgruppe (NSG) zur Aktivierung des eingehenden Datenverkehrs an Port 80 hinzu. Eine Regel für ausgehenden Datenverkehr an Port 80 muss nicht aktiviert werden, da der ausgehende Datenverkehr automatisch gewährt wird, wenn die Regel für den eingehenden Datenverkehr aktiviert ist.

Nach dem Testen der App können Sie die App über STRG+C (Windows) oder +C (macOS) in der Eingabeaufforderung beenden.

Überwachen der App

Der Server ist dafür eingerichtet, Anforderungen an http://<serveraddress>:80 an die ASP.NET Core-App weiterzuleiten, die unter Kestrel unter http://127.0.0.1:5000 ausgeführt wird. Nginx wurde jedoch nicht dafür eingerichtet, den Kestrel-Prozess zu verwalten. systemd kann für die Erstellung einer Dienstdatei verwendet werden, um die zugrunde liegende Web-App zu starten und zu überwachen. systemd ist ein Initialisierungssystem, das viele leistungsstarke Features zum Starten, Beenden und Verwalten von Prozessen bereitstellt.

Erstellen der Dienstdatei

Erstellen Sie die Dienstdefinitionsdatei:

sudo nano /etc/systemd/system/kestrel-helloapp.service

Bei Folgendem handelt es sich um eine Dienstdatei für die 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

Im vorherigen Beispiel wird der Benutzer, der den Dienst verwaltet, durch die Option User angegeben. Der Benutzer (www-data) muss vorhanden und der ordnungsgemäße Besitzer der App-Dateien sein.

Verwenden Sie TimeoutStopSec, um die Dauer der Wartezeit bis zum Herunterfahren der App zu konfigurieren, nachdem diese das anfängliche Interruptsignal empfangen hat. Wenn die App in diesem Zeitraum nicht heruntergefahren wird, wird SIGKILL ausgegeben, um die App zu beenden. Geben Sie den Wert als einheitenlose Sekunden (z.B. 150), einen Zeitspannenwert (z.B. 2min 30s) oder infinity an, um das Timeout zu deaktivieren. TimeoutStopSec hat den Standardwert DefaultTimeoutStopSec in der Manager-Konfigurationsdatei (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Das Standardtimeout für die meisten Distributionen beträgt 90 Sekunden.

# The default value is 90 seconds for most distributions.
TimeoutStopSec=90

Linux verfügt über ein Dateisystem, bei dem die Groß-/Kleinschreibung beachtet wird. Wenn Sie ASPNETCORE_ENVIRONMENT auf Production festlegen, wird die Konfigurationsdatei appsettings.Production.json und nicht appsettings.production.json gesucht.

Einige Werte (z.B. SQL-Verbindungszeichenfolgen) müssen mit Escapezeichen versehen werden, damit die Konfigurationsanbieter die Umgebungsvariablen lesen können. Mit dem folgenden Befehl können Sie einen ordnungsgemäß mit Escapezeichen versehenen Wert für die Verwendung in der Konfigurationsdatei generieren:

systemd-escape "<value-to-escape>"

Doppelpunkte (:) als Trennzeichen werden in Umgebungsvariablennamen nicht unterstützt. Verwenden Sie statt eines Doppelpunkts zwei Unterstriche (__). Der Umgebungsvariablen-Konfigurationsanbieter konvertiert jeweils die zwei Unterstriche in einen Doppelpunkt, wenn die Umgebungsvariablen in die Konfiguration gelesen werden. Im folgenden Beispiel wird der Verbindungszeichenfolgeschlüssel ConnectionStrings:DefaultConnection als ConnectionStrings__DefaultConnection in die Dienstdefinitionsdatei platziert:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Speichern Sie die Datei, und aktivieren Sie den Dienst.

sudo systemctl enable kestrel-helloapp.service

Starten Sie den Dienst, und überprüfen Sie, ob er ausgeführt wird.

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

Wenn der Reverseproxy konfiguriert ist und Kestrel durch systemd verwaltet wird, ist die Webanwendung vollständig konfiguriert. Auf diese kann dann über einen Browser auf dem lokalen Computer unter http://localhost zugegriffen werden. Der Zugriff ist auch von einem Remotecomputer aus möglich, sofern keine Firewall diesen blockiert. Beim Überprüfen der Antwortheader zeigt der Header Server die ASP.NET Core-App an, die von Kestrel verarbeitet wird.

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

Anzeigen von Protokollen

Da die Web-App, die Kestrel verwendet, von systemd verwaltet wird, werden alle Ereignisse und Prozesse in einem zentralen Journal protokolliert. Dieses Journal enthält jedoch alle Einträge für alle Dienste und Prozesse, die von systemd verwaltet werden. Verwenden Sie folgenden Befehl, um die kestrel-helloapp.service-spezifischen Elemente anzuzeigen:

sudo journalctl -fu kestrel-helloapp.service

Für weiteres Filtern können Zeitoptionen wie --since today, --until 1 hour ago oder eine Kombination aus diesen die Menge der zurückgegebenen Einträge verringern.

sudo journalctl -fu kestrel-helloapp.service --since "2016-10-18" --until "2016-10-18 04:00"

Schutz von Daten

Der Stapel zum Schutz von Daten in ASP.NET Core wird von mehreren ASP.NET Core-Middlewares verwendet. Hierzu gehören die Authentifizierungsmiddleware (zum Beispiel die cookiemiddleware) und Maßnahmen zum Schutz vor websiteübergreifenden Anforderungsfälschungen (CSRF). Selbst wenn Datenschutz-APIs nicht im Benutzercode aufgerufen werden, sollte der Schutz von Daten konfiguriert werden, um einen persistenten kryptografischen Schlüsselspeicher zu erstellen. Wenn der Schutz von Daten nicht konfiguriert ist, werden die Schlüssel beim Neustarten der App im Arbeitsspeicher gespeichert und verworfen.

Falls der Schlüsselbund im Arbeitsspeicher gespeichert wird, wenn die App neu gestartet wird, gilt Folgendes:

  • Alle cookiebasierten Authentifizierungstoken werden für ungültig erklärt.
  • Benutzer müssen sich bei ihrer nächsten Anforderung erneut anmelden.
  • Alle mit dem Schlüsselbund geschützte Daten können nicht mehr entschlüsselt werden. Dies kann CSRF-Token und ASP.NET Core-MVC-TempData-Cookies einschließen.

Wenn Sie den Schutz von Daten konfigurieren möchten, um den Schlüsselring persistent zu speichern und zu verschlüsseln, finden Sie in den folgenden Artikeln weitere Informationen:

Lange Anforderungsheaderfelder

Die Standardeinstellungen für den Proxyserver schränken die Anforderungsheaderfelder in der Regel je nach Plattform auf 4 K oder 8 K ein. Eine App erfordert möglicherweise Felder, die länger als die Standardwerte sind (z. B. Apps, die Azure Active Directory verwenden). Wenn längere Felder erforderlich sind, müssen die Standardeinstellungen des Proxyservers angepasst werden. Die anzuwendenden Werte hängen vom jeweiligen Szenario ab. Weitere Informationen finden Sie in der Dokumentation Ihres Servers.

Warnung

Erhöhen Sie die Standardwerte der Proxypuffer nur dann, wenn dies absolut erforderlich ist. Ein Erhöhen dieser Werte vergrößert das Risiko von Pufferüberlauf- (Überlauf-) und Denial-of-Service-Angriffen durch böswillige Benutzer.

Sichern der App

Aktivieren von AppArmor

Bei Linux Security Modules (LSM) handelt es sich um ein Framework, das seit Linux 2.6 Teil des Linux-Kernels ist. LSM unterstützt verschiedene Implementierungen von Sicherheitsmodulen. AppArmor ist ein LSM, das ein obligatorisches Zugriffssteuerungssystem implementiert, das das Programm auf eine beschränkte Menge an Ressourcen begrenzt. Versichern Sie sich, dass AppArmor aktiviert und ordnungsgemäß konfiguriert ist.

Konfigurieren der Firewall

Schließen Sie alle externen Ports, die nicht verwendet werden. „Uncomplicated Firewall“ (UFW) stellt ein Front-End für iptables bereit, indem eine CLI zum Konfigurieren der Firewall bereitgestellt wird.

Warnung

Eine Firewall verhindert den Zugriff auf das gesamte System, wenn dieses nicht ordnungsgemäß konfiguriert ist. Falls Sie SSH zum Verbindungsaufbau verwenden und den falschen SSH-Port angeben, können Sie nicht mehr auf das System zugreifen. Der Standardport ist 22. Weitere Informationen finden Sie unter introduction to ufw (Einführung in ufw) und in den Manpages.

Installieren Sie ufw, und konfigurieren Sie das Tool so, dass der Datenverkehr auf allen erforderlich Ports zugelassen wird.

sudo apt-get install ufw

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable

Sichern von Nginx

Ändern des Namens der Nginx-Antwort

Bearbeiten Sie 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;

Konfigurieren von Optionen

Konfigurieren Sie den Server mit zusätzlichen erforderlichen Modulen. Erwägen Sie zum Schutz der App die Verwendung einer Web-App-Firewall wie z.B. ModSecurity.

HTTPS-Konfiguration

Konfigurieren der App für sichere (HTTPS) lokale Verbindungen

Der Befehl dotnet run verwendet die Datei Properties/launchSettings.json der App, die die App so konfiguriert, dass diese an den URLs lauscht, die von der applicationUrl-Eigenschaft bereitgestellt werden. Beispiel: https://localhost:5001;http://localhost:5000.

Konfigurieren Sie mithilfe eines der folgenden Ansätze die App so, dass sie bei der Entwicklung für den Befehl dotnet run oder die Entwicklungsumgebung (F5 oder STRG+F5 in Visual Studio Code) ein Zertifikat verwendet:

Konfigurieren des Reverseproxys für sichere (HTTPS) Clientverbindungen

Warnung

Die Sicherheitskonfiguration in diesem Abschnitt ist eine allgemeine Konfiguration, die als Ausgangspunkt für weitere Anpassungen verwendet werden kann. Wir können keine Unterstützung für Tools, Server und Betriebssysteme von Drittanbietern bereitstellen. Die Verwendung der Konfiguration in diesem Abschnitt erfolgt auf eigene Gefahr. Weitere Informationen finden Sie in den folgenden Ressourcen:

  • Konfigurieren Sie den Server so, dass dieser für den HTTPS-Datenverkehr an Port 443 lauscht, indem Sie ein gültiges Zertifikat angeben, das von einer vertrauenswürdigen Zertifizierungsstelle (Certificate Authority, CA) ausgestellt wurde.

  • Stärken Sie Ihre Sicherheit, indem Sie einige der in der folgenden Datei ( /etc/nginx/nginx.conf) dargestellten Methoden verwenden.

  • Im folgenden Beispiel wird der Server nicht für Umleitung unsicherer Anforderungen konfiguriert. Wir empfehlen die Verwendung von HTTPS-Umleitungsmiddleware. Weitere Informationen finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

    Hinweis

    Für Entwicklungsumgebungen, in denen die Serverkonfiguration anstelle der HTTPS-Umleitungsmiddleware die sichere Umleitung verarbeitet, empfehlen wir die Verwendung von temporären Umleitungen (302) anstelle von permanenten Umleitungen (301). Das Zwischenspeichern von Links kann in Entwicklungsumgebungen zu instabilem Verhalten führen.

  • Durch das Hinzufügen eines Strict-Transport-Security-Headers (HSTS) wird sichergestellt, dass alle nachfolgenden Anforderungen vom Client über HTTPS erfolgen. Anweisungen zum Festlegen des Strict-Transport-Security-Headers finden Sie unter Erzwingen von HTTPS in ASP.NET Core.

  • Wenn HTTPS in Zukunft deaktiviert wird, halten Sie sich an einen der folgenden Ansätze:

    • Fügen Sie den HSTS-Header nicht hinzu.
    • Wählen Sie einen kurzen max-age-Wert aus.

Fügen Sie die Konfigurationsdatei /etc/nginx/proxy.conf hinzu:

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;

Ersetzen Sie die Inhalte der Konfigurationsdatei /etc/nginx/nginx.conf durch die folgende Datei. Das Beispiel enthält die Abschnitte http und server in einer Konfigurationsdatei.

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;
        }
    }
}

Hinweis

Blazor WebAssembly-Apps erfordern einen größeren burst-Parameterwert, damit die größere Anzahl von Anforderungen verarbeitet werden kann, die von einer App ausgeführt werden. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor WebAssembly in ASP.NET Core.

Hinweis

Im Beispiel oben wird OCSP-Stapling (Online Certificate Status Protocol) deaktiviert. Wenn Sie dieses Feature aktivieren, vergewissern Sie sich, dass das Zertifikat die Funktion unterstützt. Weitere Informationen und Anleitungen zum Aktivieren von OCSP finden Sie unter den folgenden Eigenschaften im Artikel Modul ngx_http_ssl_module (Nginx-Dokumentation):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Sichern von Nginx vor Clickjacking

Clickjacking, auch bekannt als UI Redress-Angriff, ist ein böswilliger Angriff, bei dem ein Websitebesucher dazu verleitet wird, auf einen Link oder eine Schaltfläche zu klicken, der bzw. die sich auf einer anderen Seite als der aktuell besuchten Seite befindet. Verwenden Sie X-FRAME-OPTIONS zum Sichern der Website.

So wehren Sie Clickjacking-Angriffe ab:

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie die Zeile add_header X-Frame-Options "SAMEORIGIN"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

MIME-Typermittlung

Dieser Header hindert die meisten Browser an der MIME-Ermittlung einer Antwort vom deklarierten Inhaltstyp weg, da der Header den Browser anweist, den Inhaltstyp der Antwort nicht zu überschreiben. Durch die Option nosniff wird der Inhalt vom Browser als text/html gerendert, wenn der Server sagt, dass es sich bei diesem um text/html handelt.

  1. Bearbeiten Sie die Datei nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Fügen Sie die Zeile add_header X-Content-Type-Options "nosniff"; hinzu:

  2. Speichern Sie die Datei.

  3. Starten Sie Nginx neu.

Zusätzliche Vorschläge zu Nginx

Starten Sie die vom Server gehosteten ASP.NET Core-Apps nach dem Upgrade des freigegebenen Frameworks neu.

Zusätzliche Ressourcen