Udostępnij przez


Hostowanie aplikacji ASP.NET Core w systemie Linux z serwerem Nginx

Przez Sourabh Shirhatti

Note

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.

Warning

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.

W tym przewodniku opisano konfigurowanie gotowego do produkcji środowiska ASP.NET Core dla systemów Ubuntu, Red Hat Enterprise (RHEL) i SUSE Linux Enterprise Server.

Aby uzyskać informacje na temat innych dystrybucji systemu Linux obsługiwanych przez platformę ASP.NET Core, zobacz Wymagania wstępne dotyczące platformy .NET w systemie Linux.

Ten przewodnik:

  • Umieszcza istniejącą aplikację ASP.NET Core za zwrotnym serwerem proxy.
  • Konfiguruje zwrotny serwer proxy do przekazywania żądań do serwera internetowego Kestrel .
  • Zapewnia, że aplikacja internetowa uruchamia się przy starcie jako demon.
  • Konfiguruje narzędzie do zarządzania procesami, aby ułatwić ponowne uruchomienie aplikacji internetowej.

Prerequisites

  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

W dowolnym momencie po uaktualnieniu platformy udostępnionej uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Publikowanie i kopiowanie w aplikacji

Skonfiguruj aplikację na potrzeby wdrożenia zależnego od platformy.

Jeśli aplikacja jest uruchamiana lokalnie w Development środowisku i nie jest skonfigurowana przez serwer w celu zapewnienia bezpiecznych połączeń HTTPS, zastosuj jedną z następujących metod:

  • Skonfiguruj aplikację do obsługi bezpiecznych połączeń lokalnych. Aby uzyskać więcej informacji, zobacz sekcję Konfiguracja protokołu HTTPS.

  • Skonfiguruj aplikację do uruchamiania w niezabezpieczonym punkcie końcowym:

    • Dezaktywacja Development oprogramowania pośredniczącego w przekierowaniu HTTPS w środowisku (Program.cs):

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

      Aby uzyskać więcej informacji, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe ASP.NET Core).

    • Usuń https://localhost:5001 z właściwości applicationUrl w pliku Properties/launchSettings.json (jeśli jest obecny).

Aby uzyskać więcej informacji na temat konfiguracji według środowiska, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe platformy ASP.NET Core).

Uruchom dotnet publish z Development środowiska, aby spakować aplikację do katalogu (na przykład bin/Release/{TARGET FRAMEWORK MONIKER}/publish), gdzie {TARGET FRAMEWORK MONIKER} to symbol zastępczy dla Target Framework Moniker (TFM), który można uruchomić na serwerze:

dotnet publish --configuration Release

Aplikację można również opublikować jako wdrożenie samodzielne , jeśli nie chcesz obsługiwać środowiska uruchomieniowego platformy .NET na serwerze.

Skopiuj aplikację ASP.NET Core na serwer przy użyciu narzędzia integrującego się z przepływem pracy organizacji (na przykład SCP, SFTP). Często lokalizuje się aplikacje internetowe w katalogu var (na przykład var/www/helloapp).

Note

W scenariuszu wdrażania produkcyjnego zadanie integracji ciągłej obejmuje publikowanie aplikacji oraz kopiowanie zasobów na serwer.

Przetestuj aplikację:

  1. W wierszu polecenia uruchom aplikację: dotnet <app_assembly>.dll.
  2. W przeglądarce przejdź do adresu http://<serveraddress>:<port>, aby sprawdzić, czy aplikacja działa lokalnie w systemie Linux.

Konfigurowanie zwrotnego serwera proxy

Zwrotny serwer proxy to typowa konfiguracja obsługi dynamicznych aplikacji internetowych. Zwrotny serwer proxy kończy żądanie HTTP i przekazuje je do aplikacji ASP.NET Core.

Używanie zwrotnego serwera proxy

Kestrel doskonale nadaje się do obsługi zawartości dynamicznej z platformy ASP.NET Core. Jednak funkcje serwera sieciowego nie są tak bogate, jak w przypadku serwerów takich jak IIS, Apache lub Nginx. Zwrotny serwer proxy może odciążać pracę, taką jak obsługa zawartości statycznej, buforowanie żądań, kompresowanie żądań i terminacja HTTPS z serwera HTTP. Zwrotny serwer proxy może znajdować się na dedykowanej maszynie lub może zostać wdrożony wraz z serwerem HTTP.

Na potrzeby tego przewodnika jest używane pojedyncze wystąpienie serwera Nginx. Działa on na tym samym serwerze wraz z serwerem HTTP. W zależności od wymagań można wybrać inną konfigurację.

Ponieważ żądania są przekazywane przez zwrotny serwer proxy, należy użyć oprogramowania pośredniczącego Forwarded Headers z pakietu Microsoft.AspNetCore.HttpOverrides, który jest automatycznie uwzględniany w aplikacjach ASP.NET Core za pośrednictwem metapakiety Microsoft.AspNetCore.App platformy. Middleware aktualizuje Request.Scheme element przy użyciu nagłówka X-Forwarded-Proto, aby URI przekierowania i inne polityki bezpieczeństwa działały poprawnie.

Oprogramowanie pośredniczące przekazanych nagłówków powinno być uruchamiane przed innym oprogramowaniem pośredniczącym. Ustalenie kolejności gwarantuje, że oprogramowanie pośredniczące oparte na informacjach przesłanych nagłówków może wykorzystywać wartości nagłówków do przetwarzania. Aby uruchomić środowisko pośredniczące przekazywania nagłówków po oprogramowaniu pośredniczącym diagnostyki i obsługi błędów, zobacz Kolejność środowiska pośredniczącego przekazywania nagłówków.

Wywołaj metodę UseForwardedHeaders przed wywołaniem innego oprogramowania pośredniczącego. Skonfiguruj oprogramowanie pośredniczące, aby przekazywać nagłówki X-Forwarded-For i 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();

Jeśli w oprogramowaniu pośredniczącym nie określono ForwardedHeadersOptions, domyślne nagłówki do przekazania to None.

Serwery proxy uruchomione na adresach sprzężenia zwrotnego (127.0.0.0/8, [::1]), w tym standardowy adres localhost (127.0.0.1), są domyślnie zaufane. Jeśli inne zaufane serwery proxy lub sieci w organizacji obsługują żądania między internetem a serwerem internetowym, dodaj je do listy KnownProxies lub KnownNetworks za pomocą polecenia ForwardedHeadersOptions. Poniższy przykład dodaje zaufany serwer proxy pod adresem 10.0.0.100 IP do oprogramowania KnownProxiespośredniczącego nagłówków przekazywanych:

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

Aby uzyskać więcej informacji, zobacz Konfigurowanie platformy ASP.NET Core pod kątem pracy z serwerami proxy i modułami równoważenia obciążenia.

Instalowanie serwera Nginx

  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

Użyj polecenia apt-get , aby zainstalować serwer Nginx. Instalator tworzy systemd skrypt init, który uruchamia serwer Nginx jako daemona przy starcie systemu. Postępuj zgodnie z instrukcjami instalacji systemu Ubuntu w witrynie Nginx: Pakiety systemu Linux — Ubuntu.

Note

Jeśli wymagane są opcjonalne moduły Nginx, może być wymagane utworzenie serwera Nginx ze źródła.

Ponieważ serwer Nginx został zainstalowany po raz pierwszy, jawnie uruchom go, uruchamiając polecenie:

sudo service nginx start

Sprawdź, czy przeglądarka wyświetla domyślną stronę docelową serwera Nginx. Strona docelowa jest osiągalna pod adresem http://<server_IP_address>/index.nginx-debian.html.

Konfigurowanie serwera Nginx

  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

Aby skonfigurować serwer Nginx jako zwrotny serwer proxy do przesyłania dalej żądań HTTP do aplikacji ASP.NET Core, zmodyfikuj /etc/nginx/sites-available/default i utwórz ponownie dowiązanie symboliczne. Po utworzeniu /etc/nginx/sites-available/default pliku użyj następującego polecenia, aby utworzyć dowiązanie symboliczne:

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

Otwórz /etc/nginx/sites-available/default plik w edytorze tekstów i zastąp zawartość następującym fragmentem kodu:

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

Jeśli aplikacja jest aplikacją SignalR lub Blazor Server, zobacz Hostowanie i skalowanie produkcyjne w ASP.NET CoreSignalR oraz Hostuj i wdrażaj aplikacje po stronie serwera ASP.NET CoreBlazor, aby uzyskać więcej informacji.

W przypadku gdy nie ma dopasowań server_name, serwer Nginx używa serwera domyślnego. Jeśli serwer domyślny nie jest zdefiniowany, pierwszy serwer w pliku konfiguracji jest serwerem domyślnym. Najlepszym rozwiązaniem jest dodanie określonego domyślnego serwera, który zwraca kod stanu 444 w pliku konfiguracji. Domyślny przykład konfiguracji serwera to:

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

Po tym jak zastosowano poprzedni plik konfiguracyjny i serwer domyślny, serwer Nginx akceptuje ruch publiczny na porcie 80 z nagłówkiem hosta example.com lub *.example.com. Żądania, które nie pasują do tych hostów, nie będą przekazywane do usługi Kestrel. Serwer Nginx przekazuje pasujące żądania do obiektu Kestrel pod adresem http://127.0.0.1:5000/. Aby uzyskać więcej informacji, zobacz Jak serwer nginx przetwarza żądanie. Aby zmienić Kestreladres IP/port, zobacz Kestrel: Konfiguracja punktu końcowego.

Warning

Nieprawidłowe określenie dyrektywy server_name naraża Twoją aplikację na podatności bezpieczeństwa. Powiązanie symboli wieloznacznych poddomeny (na przykład *.example.com) nie stanowi tego ryzyka zabezpieczeń, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Http Semantics (Sekcja 7.2: Host i :authority).

Po ustanowieniu konfiguracji serwera Nginx uruchom polecenie sudo nginx -t , aby zweryfikować składnię plików konfiguracji. Jeśli test pliku konfiguracji zakończy się pomyślnie, wymusij na serwerze Nginx pobieranie zmian, uruchamiając polecenie sudo nginx -s reload.

Aby bezpośrednio uruchomić aplikację na serwerze:

  1. Przejdź do katalogu aplikacji.
  2. Uruchom aplikację: dotnet <app_assembly.dll>, gdzie app_assembly.dll jest nazwą pliku zestawu aplikacji.
  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

Jeśli aplikacja działa na serwerze, ale nie odpowiada przez Internet, sprawdź zaporę serwera i upewnij się, że port 80 jest otwarty. W przypadku korzystania z maszyny wirtualnej z systemem Ubuntu na platformie Azure, dodaj regułę Grupy zabezpieczeń sieci, która umożliwia ruch przychodzący na porcie 80. Nie ma potrzeby włączania reguły portu wychodzącego 80, ponieważ ruch wychodzący jest automatycznie udzielany po włączeniu reguły ruchu przychodzącego.

Po zakończeniu testowania aplikacji zamknij aplikację za pomocą Ctrl+C w wierszu poleceń.

Zwiększ liczbę keepalive_requests

keepalive_requests można zwiększyć dla wyższej wydajności. Aby uzyskać więcej informacji, zobacz ten wątek GitHub.

Monitorowanie aplikacji

Serwer jest skonfigurowany do przesyłania żądań kierowanych do http://<serveraddress>:80 do aplikacji ASP.NET Core działającej na Kestrel pod adresem http://127.0.0.1:5000. Jednak serwer Nginx nie jest skonfigurowany do zarządzania procesem Kestrel . systemd Umożliwia utworzenie pliku usługi w celu uruchomienia i monitorowania podstawowej aplikacji internetowej. systemd to system init, który udostępnia wiele zaawansowanych funkcji uruchamiania, zatrzymywania i zarządzania procesami.

Tworzenie pliku usługi

Utwórz plik definicji usługi:

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

Poniższy przykład to .ini plik usługi dla aplikacji:

[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

W poprzednim przykładzie użytkownik, który zarządza usługą, jest określony przez opcję User. Użytkownik (www-data) musi istnieć i mieć właściwą własność plików aplikacji.

Użyj TimeoutStopSec, aby skonfigurować czas oczekiwania na zamknięcie aplikacji po odebraniu sygnału przerwania. Jeśli aplikacja nie zostanie zamknięta w tym okresie, zostanie wysłany sygnał SIGKILL w celu zakończenia działania aplikacji. Podaj wartość w sekundach (na przykład 150), wartość przedziału czasu (na przykład 2min 30s), lub infinity, aby wyłączyć limit czasu. TimeoutStopSec wartość domyślna parametru DefaultTimeoutStopSec w pliku konfiguracji menedżera (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Domyślny limit czasu dla większości dystrybucji wynosi 90 sekund.

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

W systemie Linux system plików rozróżnia wielkość liter. Ustawienie ASPNETCORE_ENVIRONMENT na Production powoduje przeszukiwanie pliku appsettings.Production.json konfiguracji, a nie appsettings.production.json.

Niektóre wartości (na przykład parametry połączenia SQL) muszą być zamaskowane, aby dostawcy konfiguracji mogli odczytywać zmienne środowiskowe. Użyj następującego polecenia, aby wygenerować prawidłowo unikniętą wartość do użycia w pliku konfiguracji:

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

Dwukropki (:) nie są obsługiwane w nazwach zmiennych środowiskowych. Użyj podwójnego podkreślenia (__) zamiast dwukropka. Dostawca konfiguracji zmiennych środowiskowych konwertuje podwójne podkreślenia na dwukropki podczas odczytywania zmiennych środowiskowych do konfiguracji. W poniższym przykładzie klucz parametru połączenia ConnectionStrings:DefaultConnection jest ustawiony w pliku definicji usługi jako ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Zapisz plik i włącz usługę.

sudo systemctl enable kestrel-helloapp.service

Uruchom usługę i sprawdź, czy jest uruchomiona.

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

Po skonfigurowaniu zwrotnego serwera proxy i Kestrel zarządzanym za pośrednictwem systemdprogramu aplikacja internetowa jest w pełni skonfigurowana i może być dostępna z przeglądarki na komputerze lokalnym pod adresem http://localhost. Jest również dostępna z komputera zdalnego, o ile nie są blokowane przez zapory sieciowe. Sprawdzając nagłówki odpowiedzi, w nagłówku Server wyświetlana jest aplikacja ASP.NET Core obsługiwana przez 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

Wyświetlanie dzienników

Ponieważ aplikacja internetowa korzystająca z programu Kestrel jest zarządzana przy użyciu programu systemd, wszystkie zdarzenia i procesy są rejestrowane w scentralizowanym dzienniku. Jednak ten dziennik zawiera wszystkie wpisy dla wszystkich usług i procesów zarządzanych przez program systemd. Aby wyświetlić elementy specyficzne dla kestrel-helloapp.service, użyj następującego polecenia:

sudo journalctl -fu kestrel-helloapp.service

W celu dalszego filtrowania opcje czasu, takie jak --since today, --until 1 hour agolub kombinacja tych elementów, może zmniejszyć liczbę zwracanych wpisów.

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

Ochrona danych

Platforma ASP.NET Core Data Protection jest używana przez kilka ASP.NET Core middleware, w tym middleware uwierzytelniania (na przykład cookie middleware) oraz przeciwdziałanie fałszowaniu żądań między witrynami (CSRF). Nawet jeśli interfejsy API ochrony danych nie są wywoływane przez kod użytkownika, należy skonfigurować ochronę danych w celu utworzenia trwałego magazynu kluczy kryptograficznych. Jeśli ochrona danych nie jest skonfigurowana, klucze są przechowywane w pamięci i odrzucane po ponownym uruchomieniu aplikacji.

Jeśli pierścień kluczy jest przechowywany w pamięci po ponownym uruchomieniu aplikacji:

  • Wszystkie tokeny uwierzytelniania oparte na systemie cookie są unieważniane.
  • Użytkownicy są zobowiązani do ponownego zalogowania się podczas następnego żądania.
  • Nie można już odszyfrować żadnych danych chronionych za pomocą pierścienia kluczy. Może to obejmować tokeny CSRF i pliki cookie ASP.NET Core MVC TempData.

Aby skonfigurować ochronę danych w celu utrwalania i szyfrowania pierścienia kluczy, zobacz:

Długie pola nagłówka żądania

Domyślne ustawienia serwera proxy zwykle ograniczają pola nagłówka żądania do 4 K lub 8 K w zależności od platformy. Aplikacja może wymagać pól dłuższych niż domyślne (na przykład aplikacji korzystających z identyfikatora Entra firmy Microsoft). Jeśli wymagane są dłuższe pola, ustawienia domyślne serwera proxy wymagają dostosowania. Wartości do zastosowania zależą od scenariusza. Aby uzyskać więcej informacji, zobacz dokumentację serwera.

Warning

Nie zwiększaj domyślnych wartości buforów proxy, chyba że jest to konieczne. Zwiększenie tych wartości zwiększa ryzyko przepełnienia buforu (przepełnienia) i ataków typu "odmowa usługi" (DoS) przez złośliwych użytkowników.

Zabezpieczanie aplikacji

Włączanie aplikacji AppArmor

Moduły zabezpieczeń systemu Linux (LSM) to struktura, która jest częścią jądra systemu Linux od systemu Linux 2.6. Rozwiązanie LSM obsługuje różne implementacje modułów zabezpieczeń. AppArmor to LSM, który implementuje obowiązkowy system kontroli dostępu, który umożliwia ograniczenie programu do ograniczonego zestawu zasobów. Upewnij się, że aplikacja AppArmor jest włączona i prawidłowo skonfigurowana.

Konfigurowanie zapory

Zamknij wszystkie porty zewnętrzne, które nie są używane. Nieskomplikowana zapora (ufw) zapewnia interfejs dla iptables, udostępniając interfejs wiersza poleceń do konfigurowania zapory.

  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

Warning

Zapora uniemożliwia dostęp do całego systemu, jeśli nie został poprawnie skonfigurowany. Niewskazanie poprawnego portu SSH skutecznie blokuje dostęp do systemu, jeśli używasz SSH do połączenia z nim. Domyślny port jest 22. Aby uzyskać więcej informacji, zobacz wprowadzenie do ufw i podręcznik.

Zainstaluj ufw i skonfiguruj go, aby zezwolić na ruch na wszystkich wymaganych portach.

sudo apt-get install ufw

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

sudo ufw enable

Zabezpieczanie serwera Nginx

Zmienianie nazwy odpowiedzi serwera Nginx

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

Konfigurowanie opcji

Skonfiguruj serwer z dodatkowymi wymaganymi modułami. Rozważ użycie zapory aplikacji internetowej, takiej jak ModSecurity, w celu zabezpieczenia aplikacji.

Konfiguracja protokołu HTTPS

Konfigurowanie aplikacji pod kątem bezpiecznych połączeń lokalnych (HTTPS)

Polecenie dotnet run używa pliku aplikacji, Properties/launchSettings.json który konfiguruje aplikację do nasłuchiwania na adresy URL określone przez właściwość applicationUrl. Na przykład https://localhost:5001;http://localhost:5000.

Skonfiguruj aplikację tak, aby używała certyfikatu podczas programowania dla dotnet run polecenia lub środowiska programistycznego (F5 lub Ctrl+F5 w programie Visual Studio Code) przy użyciu jednej z następujących metod:

Konfigurowanie zwrotnego serwera proxy na potrzeby bezpiecznych połączeń klienckich (HTTPS)

Warning

Konfiguracja zabezpieczeń w tej sekcji jest ogólną konfiguracją, która ma być używana jako punkt wyjścia do dalszego dostosowywania. Nie możemy zapewnić obsługi narzędzi, serwerów i systemów operacyjnych innych firm. Użyj konfiguracji w tej sekcji na własne ryzyko. Aby uzyskać więcej informacji, uzyskaj dostęp do następujących zasobów:

  • Skonfiguruj serwer do nasłuchiwania ruchu HTTPS na porcie 443, określając prawidłowy certyfikat wystawiony przez zaufany urząd certyfikacji.

  • Wzmacnianie zabezpieczeń przez zastosowanie niektórych praktyk przedstawionych w poniższym pliku /etc/nginx/nginx.conf .

  • Poniższy przykład nie konfiguruje serwera do przekierowywania niezabezpieczonych żądań. Zalecamy używanie oprogramowania pośredniczącego przekierowania HTTPS. Aby uzyskać więcej informacji, zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

    Note

    W przypadku środowisk deweloperskich, w których konfiguracja serwera obsługuje bezpieczne przekierowywanie zamiast oprogramowania pośredniczącego przekierowania HTTPS, zalecamy używanie tymczasowych przekierowań (302), a nie stałych przekierowań (301). Buforowanie łączy może spowodować niestabilne zachowanie w środowiskach deweloperskich.

  • Dodanie nagłówka Strict-Transport-Security (HSTS) gwarantuje, że wszystkie kolejne żądania wysyłane przez klienta są za pośrednictwem protokołu HTTPS. Aby uzyskać wskazówki dotyczące ustawiania nagłówka Strict-Transport-Security , zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

  • Jeśli protokół HTTPS zostanie wyłączony w przyszłości, użyj jednego z następujących podejść:

    • Nie dodawaj nagłówka HSTS.
    • Wybierz krótką max-age wartość.

Dodaj plik konfiguracji /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;
  • Ubuntu
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server

Zastąp zawartość pliku konfiguracji /etc/nginx/nginx.conf następującym plikiem. W przykładzie znajdują się obie sekcje, http i server, w jednym pliku konfiguracyjnym.

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

Note

Blazor WebAssembly aplikacje wymagają większej burst wartości parametru, aby obsłużyć większą liczbę żądań wysyłanych przez aplikację. Aby uzyskać więcej informacji, zobacz Hostowanie i wdrażanie ASP.NET Core z Nginx.

Note

Powyższy przykład wyłącza Stapling protokołu OCSP (Online Certificate Status Protocol). Jeśli ta opcja jest włączona, upewnij się, że certyfikat obsługuje tę funkcję. Aby uzyskać więcej informacji i wskazówek dotyczących włączania OCSP, zobacz następujące właściwości w artykule Module ngx_http_ssl_module (dokumentacja Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Zabezpieczanie Nginx przed clickjackingiem

Clickjacking, znany również jako atak przekierowania interfejsu użytkownika, jest złośliwym atakiem, w którym odwiedzający witrynę internetową jest nakłaniany do kliknięcia linku lub przycisku na innej stronie niż ta, którą obecnie odwiedza. Użyj X-FRAME-OPTIONS, aby zabezpieczyć witrynę.

Aby zminimalizować ryzyko ataków typu clickjacking:

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    http{} W bloku kodu dodaj wiersz:add_header X-Frame-Options "SAMEORIGIN";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Rozpoznawanie typu MIME

Ten nagłówek uniemożliwia większości przeglądarek automatyczne rozpoznanie typu MIME odpowiedzi innego niż zadeklarowany, ponieważ nagłówek instruuje przeglądarkę, aby nie nadpisywała deklarowanego typu zawartości odpowiedzi. Z opcją nosniff, jeśli serwer określa zawartość jako text/html, przeglądarka renderuje ją jako text/html.

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    http{} W bloku kodu dodaj wiersz:add_header X-Content-Type-Options "nosniff";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Dodatkowe sugestie serwera Nginx

Po uaktualnieniu platformy udostępnionej na serwerze uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Dodatkowe zasoby

W tym przewodniku opisano konfigurowanie środowiska ASP.NET Core gotowego do produkcji na serwerze z systemem Ubuntu 16.04. Te instrukcje prawdopodobnie działają z nowszymi wersjami systemu Ubuntu, ale instrukcje nie zostały przetestowane z nowszymi wersjami.

Aby uzyskać informacje na temat innych dystrybucji systemu Linux obsługiwanych przez platformę ASP.NET Core, zobacz Wymagania wstępne dotyczące platformy .NET Core w systemie Linux.

Note

W przypadku Ubuntu 14.04 zaleca się supervisord jako rozwiązanie do monitorowania procesu Kestrel. systemd nie jest dostępny na Ubuntu 14.04. Instrukcje dotyczące systemu Ubuntu 14.04 można znaleźć w poprzedniej wersji tego tematu.

Ten przewodnik:

  • Umieszcza istniejącą aplikację ASP.NET Core za zwrotnym serwerem proxy.
  • Konfiguruje zwrotny serwer proxy do przekazywania żądań do serwera internetowego Kestrel .
  • Zapewnia, że aplikacja internetowa uruchamia się przy starcie jako demon.
  • Konfiguruje narzędzie do zarządzania procesami, aby ułatwić ponowne uruchomienie aplikacji internetowej.

Prerequisites

  • Dostęp do serwera z systemem Ubuntu 16.04 przy użyciu konta użytkownika standardowego z uprawnieniami sudo.
  • Najnowsze środowisko uruchomieniowe platformy .NET spoza wersji zapoznawczej zainstalowane na serwerze.
  • Istniejąca aplikacja ASP.NET Core.

W dowolnym momencie po uaktualnieniu platformy udostępnionej uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Publikowanie i kopiowanie w aplikacji

Skonfiguruj aplikację na potrzeby wdrożenia zależnego od platformy.

Jeśli aplikacja jest uruchamiana lokalnie w Development środowisku i nie jest skonfigurowana przez serwer w celu zapewnienia bezpiecznych połączeń HTTPS, zastosuj jedną z następujących metod:

  • Skonfiguruj aplikację do obsługi bezpiecznych połączeń lokalnych. Aby uzyskać więcej informacji, zobacz sekcję Konfiguracja protokołu HTTPS.

  • Skonfiguruj aplikację do uruchamiania w niezabezpieczonym punkcie końcowym:

    • Dezaktywacja Development oprogramowania pośredniczącego w przekierowaniu HTTPS w środowisku (Program.cs):

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

      Aby uzyskać więcej informacji, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe ASP.NET Core).

    • Usuń https://localhost:5001 z właściwości applicationUrl w pliku Properties/launchSettings.json (jeśli jest obecny).

Aby uzyskać więcej informacji na temat konfiguracji według środowiska, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe platformy ASP.NET Core).

Uruchom polecenie dotnet publish z środowiska, aby Development złożyć aplikację do katalogu (na przykład bin/Release/{TARGET FRAMEWORK MONIKER}/publish, gdzie symbol zastępczy {TARGET FRAMEWORK MONIKER} to Moniker Docelowego Systemu/TFM), który może działać na serwerze.

dotnet publish --configuration Release

Aplikację można również opublikować jako wdrożenie samodzielne, jeśli nie chcesz obsługiwać środowiska uruchomieniowego platformy .NET Core na serwerze.

Skopiuj aplikację ASP.NET Core na serwer przy użyciu narzędzia integrującego się z przepływem pracy organizacji (na przykład SCP, SFTP). Często lokalizuje się aplikacje internetowe w katalogu var (na przykład var/www/helloapp).

Note

W scenariuszu wdrażania produkcyjnego zadanie integracji ciągłej obejmuje publikowanie aplikacji oraz kopiowanie zasobów na serwer.

Przetestuj aplikację:

  1. W wierszu polecenia uruchom aplikację: dotnet <app_assembly>.dll.
  2. W przeglądarce przejdź do adresu http://<serveraddress>:<port>, aby sprawdzić, czy aplikacja działa lokalnie w systemie Linux.

Konfigurowanie zwrotnego serwera proxy

Zwrotny serwer proxy to typowa konfiguracja obsługi dynamicznych aplikacji internetowych. Zwrotny serwer proxy kończy żądanie HTTP i przekazuje je do aplikacji ASP.NET Core.

Używanie zwrotnego serwera proxy

Kestrel doskonale nadaje się do obsługi zawartości dynamicznej z platformy ASP.NET Core. Jednak funkcje serwera sieciowego nie są tak bogate, jak w przypadku serwerów takich jak IIS, Apache lub Nginx. Zwrotny serwer proxy może odciążać pracę, taką jak obsługa zawartości statycznej, buforowanie żądań, kompresowanie żądań i terminacja HTTPS z serwera HTTP. Zwrotny serwer proxy może znajdować się na dedykowanej maszynie lub może zostać wdrożony wraz z serwerem HTTP.

Na potrzeby tego przewodnika jest używane pojedyncze wystąpienie serwera Nginx. Działa on na tym samym serwerze wraz z serwerem HTTP. W zależności od wymagań można wybrać inną konfigurację.

Ponieważ żądania są przekazywane przez zwrotny serwer proxy, użyj Forwarded Headers Middleware z Microsoft.AspNetCore.HttpOverrides. Middleware aktualizuje Request.Scheme element przy użyciu nagłówka X-Forwarded-Proto, aby URI przekierowania i inne polityki bezpieczeństwa działały poprawnie.

Oprogramowanie pośredniczące przekazanych nagłówków powinno być uruchamiane przed innym oprogramowaniem pośredniczącym. Ustalenie kolejności gwarantuje, że oprogramowanie pośredniczące oparte na informacjach przesłanych nagłówków może wykorzystywać wartości nagłówków do przetwarzania. Aby uruchomić środowisko pośredniczące przekazywania nagłówków po oprogramowaniu pośredniczącym diagnostyki i obsługi błędów, zobacz Kolejność środowiska pośredniczącego przekazywania nagłówków.

Wywołaj metodę UseForwardedHeaders na początku Program.cs przed wywołaniem innych elementów pośredniczących. Skonfiguruj oprogramowanie pośredniczące, aby przekazywać nagłówki X-Forwarded-For i X-Forwarded-Proto.

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

app.UseAuthentication();

Jeśli w oprogramowaniu pośredniczącym nie określono ForwardedHeadersOptions, domyślne nagłówki do przekazania to None.

Serwery proxy uruchomione na adresach sprzężenia zwrotnego (127.0.0.0/8, [::1]), w tym standardowy adres localhost (127.0.0.1), są domyślnie zaufane. Jeśli inne zaufane serwery proxy lub sieci w organizacji obsługują żądania pomiędzy Internetem a serwerem WWW, dodaj je do listy KnownProxies lub KnownNetworks za pomocą ForwardedHeadersOptions. Poniższy przykład dodaje zaufany serwer proxy pod adresem IP 10.0.0.100 do oprogramowania pośredniczącego Forwarded Headers KnownProxies w Program.cs:

using System.Net;

var builder = WebApplication.CreateBuilder(args);

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

Aby uzyskać więcej informacji, zobacz Konfigurowanie platformy ASP.NET Core pod kątem pracy z serwerami proxy i modułami równoważenia obciążenia.

Instalowanie serwera Nginx

Użyj polecenia apt-get , aby zainstalować serwer Nginx. Instalator tworzy systemd skrypt init, który uruchamia serwer Nginx jako daemona przy starcie systemu. Postępuj zgodnie z instrukcjami instalacji systemu Ubuntu w witrynie Nginx: Oficjalne pakiety Debian/Ubuntu.

Note

Jeśli wymagane są opcjonalne moduły Nginx, może być wymagane utworzenie serwera Nginx ze źródła.

Ponieważ serwer Nginx został zainstalowany po raz pierwszy, jawnie uruchom go, uruchamiając polecenie:

sudo service nginx start

Sprawdź, czy przeglądarka wyświetla domyślną stronę docelową serwera Nginx. Strona docelowa jest osiągalna pod adresem http://<server_IP_address>/index.nginx-debian.html.

Konfigurowanie serwera Nginx

Aby skonfigurować serwer Nginx jako zwrotny serwer proxy do przekazywania żądań HTTP do aplikacji ASP.NET Core, zmodyfikuj polecenie /etc/nginx/sites-available/default. Otwórz go w edytorze tekstów i zastąp zawartość następującym fragmentem kodu:

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

Jeśli aplikacja jest aplikacją SignalR lub Blazor Server, zobacz Hostowanie i skalowanie produkcyjne w ASP.NET CoreSignalR oraz Hostuj i wdrażaj aplikacje po stronie serwera ASP.NET CoreBlazor, aby uzyskać więcej informacji.

W przypadku gdy nie ma dopasowań server_name, serwer Nginx używa serwera domyślnego. Jeśli serwer domyślny nie jest zdefiniowany, pierwszy serwer w pliku konfiguracji jest serwerem domyślnym. Najlepszym rozwiązaniem jest dodanie określonego domyślnego serwera, który zwraca kod stanu 444 w pliku konfiguracji. Domyślny przykład konfiguracji serwera to:

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

Po tym jak zastosowano poprzedni plik konfiguracyjny i serwer domyślny, serwer Nginx akceptuje ruch publiczny na porcie 80 z nagłówkiem hosta example.com lub *.example.com. Żądania, które nie pasują do tych hostów, nie będą przekazywane do usługi Kestrel. Serwer Nginx przekazuje pasujące żądania do obiektu Kestrel pod adresem http://127.0.0.1:5000. Aby uzyskać więcej informacji, zobacz Jak serwer nginx przetwarza żądanie. Aby zmienić Kestreladres IP/port, zobacz Kestrel: Konfiguracja punktu końcowego.

Warning

Nieprawidłowe określenie dyrektywy server_name naraża Twoją aplikację na podatności bezpieczeństwa. Powiązanie symboli wieloznacznych poddomeny (na przykład *.example.com) nie stanowi tego ryzyka zabezpieczeń, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Http Semantics (Sekcja 7.2: Host i :authority).

Po ustanowieniu konfiguracji serwera Nginx uruchom polecenie sudo nginx -t , aby zweryfikować składnię plików konfiguracji. Jeśli test pliku konfiguracji zakończy się pomyślnie, wymusij na serwerze Nginx pobieranie zmian, uruchamiając polecenie sudo nginx -s reload.

Aby bezpośrednio uruchomić aplikację na serwerze:

  1. Przejdź do katalogu aplikacji.
  2. Uruchom aplikację: dotnet <app_assembly.dll>, gdzie app_assembly.dll jest nazwą pliku zestawu aplikacji.

Jeśli aplikacja działa na serwerze, ale nie odpowiada przez Internet, sprawdź zaporę serwera i upewnij się, że port 80 jest otwarty. W przypadku korzystania z maszyny wirtualnej z systemem Ubuntu na platformie Azure, dodaj regułę Grupy zabezpieczeń sieci, która umożliwia ruch przychodzący na porcie 80. Nie ma potrzeby włączania reguły portu wychodzącego 80, ponieważ ruch wychodzący jest automatycznie udzielany po włączeniu reguły ruchu przychodzącego.

Po zakończeniu testowania aplikacji zamknij aplikację za pomocą Ctrl+C w wierszu poleceń.

Monitorowanie aplikacji

Serwer jest skonfigurowany do przesyłania żądań kierowanych do http://<serveraddress>:80 do aplikacji ASP.NET Core działającej na Kestrel pod adresem http://127.0.0.1:5000. Jednak serwer Nginx nie jest skonfigurowany do zarządzania procesem Kestrel . systemd Umożliwia utworzenie pliku usługi w celu uruchomienia i monitorowania podstawowej aplikacji internetowej. systemd to system init, który udostępnia wiele zaawansowanych funkcji uruchamiania, zatrzymywania i zarządzania procesami.

Tworzenie pliku usługi

Utwórz plik definicji usługi:

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

Poniższy przykład to plik usługi dla aplikacji:

[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

W poprzednim przykładzie użytkownik, który zarządza usługą, jest określony przez opcję User. Użytkownik (www-data) musi istnieć i mieć właściwą własność plików aplikacji.

Użyj TimeoutStopSec, aby skonfigurować czas oczekiwania na zamknięcie aplikacji po odebraniu sygnału przerwania. Jeśli aplikacja nie zostanie zamknięta w tym okresie, zostanie wysłany sygnał SIGKILL w celu zakończenia działania aplikacji. Podaj wartość w sekundach (na przykład 150), wartość przedziału czasu (na przykład 2min 30s), lub infinity, aby wyłączyć limit czasu. TimeoutStopSec wartość domyślna parametru DefaultTimeoutStopSec w pliku konfiguracji menedżera (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Domyślny limit czasu dla większości dystrybucji wynosi 90 sekund.

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

W systemie Linux system plików rozróżnia wielkość liter. Ustawienie ASPNETCORE_ENVIRONMENT na Production powoduje przeszukiwanie pliku appsettings.Production.json konfiguracji, a nie appsettings.production.json.

Niektóre wartości (na przykład parametry połączenia SQL) muszą być zamaskowane, aby dostawcy konfiguracji mogli odczytywać zmienne środowiskowe. Użyj następującego polecenia, aby wygenerować prawidłowo unikniętą wartość do użycia w pliku konfiguracji:

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

Dwukropki (:) nie są obsługiwane w nazwach zmiennych środowiskowych. Użyj podwójnego podkreślenia (__) zamiast dwukropka. Dostawca konfiguracji zmiennych środowiskowych konwertuje podwójne podkreślenia na dwukropki podczas odczytywania zmiennych środowiskowych do konfiguracji. W poniższym przykładzie klucz parametru połączenia ConnectionStrings:DefaultConnection jest ustawiony w pliku definicji usługi jako ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Zapisz plik i włącz usługę.

sudo systemctl enable kestrel-helloapp.service

Uruchom usługę i sprawdź, czy jest uruchomiona.

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

Po skonfigurowaniu zwrotnego serwera proxy i Kestrel zarządzanym za pośrednictwem systemdprogramu aplikacja internetowa jest w pełni skonfigurowana i może być dostępna z przeglądarki na komputerze lokalnym pod adresem http://localhost. Jest również dostępna z komputera zdalnego, o ile nie są blokowane przez zapory sieciowe. Sprawdzając nagłówki odpowiedzi, w nagłówku Server wyświetlana jest aplikacja ASP.NET Core obsługiwana przez 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

Wyświetlanie dzienników

Ponieważ aplikacja internetowa korzystająca z programu Kestrel jest zarządzana przy użyciu programu systemd, wszystkie zdarzenia i procesy są rejestrowane w scentralizowanym dzienniku. Jednak ten dziennik zawiera wszystkie wpisy dla wszystkich usług i procesów zarządzanych przez program systemd. Aby wyświetlić elementy specyficzne dla kestrel-helloapp.service, użyj następującego polecenia:

sudo journalctl -fu kestrel-helloapp.service

W celu dalszego filtrowania opcje czasu, takie jak --since today, --until 1 hour agolub kombinacja tych elementów, może zmniejszyć liczbę zwracanych wpisów.

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

Ochrona danych

Platforma ASP.NET Core Data Protection jest używana przez kilka ASP.NET Core middleware, w tym middleware uwierzytelniania (na przykład cookie middleware) oraz przeciwdziałanie fałszowaniu żądań między witrynami (CSRF). Nawet jeśli interfejsy API ochrony danych nie są wywoływane przez kod użytkownika, należy skonfigurować ochronę danych w celu utworzenia trwałego magazynu kluczy kryptograficznych. Jeśli ochrona danych nie jest skonfigurowana, klucze są przechowywane w pamięci i odrzucane po ponownym uruchomieniu aplikacji.

Jeśli pierścień kluczy jest przechowywany w pamięci po ponownym uruchomieniu aplikacji:

  • Wszystkie tokeny uwierzytelniania oparte na systemie cookie są unieważniane.
  • Użytkownicy są zobowiązani do ponownego zalogowania się podczas następnego żądania.
  • Nie można już odszyfrować żadnych danych chronionych za pomocą pierścienia kluczy. Może to obejmować tokeny CSRF i pliki cookie ASP.NET Core MVC TempData.

Aby skonfigurować ochronę danych w celu utrwalania i szyfrowania pierścienia kluczy, zobacz:

Długie nagłówki żądań

Domyślne ustawienia serwera proxy zwykle ograniczają pola nagłówka żądania do 4 K lub 8 K w zależności od platformy. Aplikacja może wymagać pól dłuższych niż domyślne (na przykład aplikacji korzystających z usługi Azure Active Directory). Jeśli wymagane są dłuższe pola, ustawienia domyślne serwera proxy wymagają dostosowania. Wartości do zastosowania zależą od scenariusza. Aby uzyskać więcej informacji, zobacz dokumentację serwera.

Warning

Nie należy zwiększać wartości domyślnych buforów proxy, chyba że jest to konieczne. Zwiększenie tych wartości zwiększa ryzyko przepełnienia buforu (przepełnienia) i ataków typu "odmowa usługi" (DoS) przez złośliwych użytkowników.

Zabezpieczanie aplikacji

Włączanie aplikacji AppArmor

Moduły zabezpieczeń systemu Linux (LSM) to struktura, która jest częścią jądra systemu Linux od systemu Linux 2.6. Rozwiązanie LSM obsługuje różne implementacje modułów zabezpieczeń. AppArmor to LSM, który implementuje obowiązkowy system kontroli dostępu, który umożliwia ograniczenie programu do ograniczonego zestawu zasobów. Upewnij się, że aplikacja AppArmor jest włączona i prawidłowo skonfigurowana.

Konfigurowanie zapory

Zamknij wszystkie porty zewnętrzne, które nie są używane. Nieskomplikowana zapora (ufw) zapewnia interfejs dla iptables, udostępniając interfejs wiersza poleceń do konfigurowania zapory.

Warning

Zapora uniemożliwi dostęp do całego systemu, jeśli nie zostanie poprawnie skonfigurowany. Brak określenia poprawnego portu SSH spowoduje zablokowanie dostępu do systemu, jeśli używasz SSH do połączenia z nim. Domyślny port jest 22. Aby uzyskać więcej informacji, zobacz wprowadzenie do ufw i podręcznik.

Zainstaluj ufw i skonfiguruj go, aby zezwolić na ruch na wszystkich wymaganych portach.

sudo apt-get install ufw

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

sudo ufw enable

Zabezpieczanie serwera Nginx

Zmienianie nazwy odpowiedzi serwera Nginx

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

Konfigurowanie opcji

Skonfiguruj serwer z dodatkowymi wymaganymi modułami. Rozważ użycie zapory aplikacji internetowej, takiej jak ModSecurity, w celu zabezpieczenia aplikacji.

Konfiguracja protokołu HTTPS

Konfigurowanie aplikacji pod kątem bezpiecznych połączeń lokalnych (HTTPS)

Polecenie dotnet run używa pliku aplikacji, Properties/launchSettings.json który konfiguruje aplikację do nasłuchiwania na adresy URL określone przez właściwość applicationUrl. Na przykład https://localhost:5001;http://localhost:5000.

Skonfiguruj aplikację tak, aby używała certyfikatu podczas programowania dla dotnet run polecenia lub środowiska programistycznego (F5 lub Ctrl+F5 w programie Visual Studio Code) przy użyciu jednej z następujących metod:

Konfigurowanie zwrotnego serwera proxy na potrzeby bezpiecznych połączeń klienckich (HTTPS)

Warning

Konfiguracja zabezpieczeń w tej sekcji jest ogólną konfiguracją, która ma być używana jako punkt wyjścia do dalszego dostosowywania. Nie możemy zapewnić obsługi narzędzi, serwerów i systemów operacyjnych innych firm. Użyj konfiguracji w tej sekcji na własne ryzyko. Aby uzyskać więcej informacji, uzyskaj dostęp do następujących zasobów:

  • Skonfiguruj serwer do nasłuchiwania ruchu HTTPS na porcie 443, określając prawidłowy certyfikat wystawiony przez zaufany urząd certyfikacji.

  • Wzmacnianie zabezpieczeń przez zastosowanie niektórych praktyk przedstawionych w poniższym pliku /etc/nginx/nginx.conf .

  • Poniższy przykład nie konfiguruje serwera do przekierowywania niezabezpieczonych żądań. Zalecamy używanie oprogramowania pośredniczącego przekierowania HTTPS. Aby uzyskać więcej informacji, zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

    Note

    W przypadku środowisk deweloperskich, w których konfiguracja serwera obsługuje bezpieczne przekierowywanie zamiast oprogramowania pośredniczącego przekierowania HTTPS, zalecamy używanie tymczasowych przekierowań (302), a nie stałych przekierowań (301). Buforowanie łączy może spowodować niestabilne zachowanie w środowiskach deweloperskich.

  • Dodanie nagłówka Strict-Transport-Security (HSTS) gwarantuje, że wszystkie kolejne żądania wysyłane przez klienta są za pośrednictwem protokołu HTTPS. Aby uzyskać wskazówki dotyczące ustawiania nagłówka Strict-Transport-Security , zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

  • Jeśli protokół HTTPS zostanie wyłączony w przyszłości, użyj jednego z następujących podejść:

    • Nie dodawaj nagłówka HSTS.
    • Wybierz krótką max-age wartość.

Dodaj plik konfiguracji /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;

Zastąp zawartość pliku konfiguracji /etc/nginx/nginx.conf następującym plikiem. W przykładzie znajdują się obie sekcje, http i server, w jednym pliku konfiguracyjnym.

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

Note

Blazor WebAssembly aplikacje wymagają większej burst wartości parametru, aby obsłużyć większą liczbę żądań wysyłanych przez aplikację. Aby uzyskać więcej informacji, zobacz Hostowanie i wdrażanie ASP.NET Core z Nginx.

Note

Powyższy przykład wyłącza Stapling protokołu OCSP (Online Certificate Status Protocol). Jeśli ta opcja jest włączona, upewnij się, że certyfikat obsługuje tę funkcję. Aby uzyskać więcej informacji i wskazówek dotyczących włączania OCSP, zobacz następujące właściwości w artykule Module ngx_http_ssl_module (dokumentacja Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Zabezpieczanie Nginx przed clickjackingiem

Clickjacking, znany również jako atak przekierowania interfejsu użytkownika, jest złośliwym atakiem, w którym odwiedzający witrynę internetową jest nakłaniany do kliknięcia linku lub przycisku na innej stronie niż ta, którą obecnie odwiedza. Użyj X-FRAME-OPTIONS, aby zabezpieczyć witrynę.

Aby zminimalizować ryzyko ataków typu clickjacking:

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Dodaj wiersz: add_header X-Frame-Options "SAMEORIGIN";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Rozpoznawanie typu MIME

Ten nagłówek uniemożliwia większości przeglądarek automatyczne rozpoznanie typu MIME odpowiedzi innego niż zadeklarowany, ponieważ nagłówek instruuje przeglądarkę, aby nie nadpisywała deklarowanego typu zawartości odpowiedzi. Z opcją nosniff, jeśli serwer określa zawartość jako text/html, przeglądarka renderuje ją jako text/html.

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Dodaj wiersz: add_header X-Content-Type-Options "nosniff";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Dodatkowe sugestie serwera Nginx

Po uaktualnieniu platformy udostępnionej na serwerze uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Dodatkowe zasoby

W tym przewodniku opisano konfigurowanie środowiska ASP.NET Core gotowego do produkcji na serwerze z systemem Ubuntu 16.04. Te instrukcje prawdopodobnie działają z nowszymi wersjami systemu Ubuntu, ale instrukcje nie zostały przetestowane z nowszymi wersjami.

Aby uzyskać informacje na temat innych dystrybucji systemu Linux obsługiwanych przez platformę ASP.NET Core, zobacz Wymagania wstępne dotyczące platformy .NET Core w systemie Linux.

Note

W przypadku Ubuntu 14.04 zaleca się supervisord jako rozwiązanie do monitorowania procesu Kestrel. systemd nie jest dostępny na Ubuntu 14.04. Instrukcje dotyczące systemu Ubuntu 14.04 można znaleźć w poprzedniej wersji tego tematu.

Ten przewodnik:

  • Umieszcza istniejącą aplikację ASP.NET Core za zwrotnym serwerem proxy.
  • Konfiguruje zwrotny serwer proxy do przekazywania żądań do serwera internetowego Kestrel .
  • Zapewnia, że aplikacja internetowa uruchamia się przy starcie jako demon.
  • Konfiguruje narzędzie do zarządzania procesami, aby ułatwić ponowne uruchomienie aplikacji internetowej.

Prerequisites

  • Dostęp do serwera z systemem Ubuntu 16.04 przy użyciu konta użytkownika standardowego z uprawnieniami sudo.
  • Najnowsze środowisko uruchomieniowe platformy .NET spoza wersji zapoznawczej zainstalowane na serwerze.
  • Istniejąca aplikacja ASP.NET Core.

W dowolnym momencie po uaktualnieniu platformy udostępnionej uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Publikowanie i kopiowanie w aplikacji

Skonfiguruj aplikację na potrzeby wdrożenia zależnego od platformy.

Jeśli aplikacja jest uruchamiana lokalnie w Development środowisku i nie jest skonfigurowana przez serwer w celu zapewnienia bezpiecznych połączeń HTTPS, zastosuj jedną z następujących metod:

  • Skonfiguruj aplikację do obsługi bezpiecznych połączeń lokalnych. Aby uzyskać więcej informacji, zobacz sekcję Konfiguracja protokołu HTTPS.

  • Skonfiguruj aplikację do uruchamiania w niezabezpieczonym punkcie końcowym:

    • Dezaktywacja Development oprogramowania pośredniczącego w przekierowaniu HTTPS w środowisku (Program.cs):

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

      Aby uzyskać więcej informacji, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe ASP.NET Core).

    • Usuń https://localhost:5001 z właściwości applicationUrl w pliku Properties/launchSettings.json (jeśli jest obecny).

Aby uzyskać więcej informacji na temat konfiguracji według środowiska, zobacz ASP.NET Core runtime environments (Środowiska uruchomieniowe platformy ASP.NET Core).

Uruchom polecenie dotnet publish z środowiska, aby Development złożyć aplikację do katalogu (na przykład bin/Release/{TARGET FRAMEWORK MONIKER}/publish, gdzie symbol zastępczy {TARGET FRAMEWORK MONIKER} to Moniker Docelowego Systemu/TFM), który może działać na serwerze.

dotnet publish --configuration Release

Aplikację można również opublikować jako wdrożenie samodzielne, jeśli nie chcesz obsługiwać środowiska uruchomieniowego platformy .NET Core na serwerze.

Skopiuj aplikację ASP.NET Core na serwer przy użyciu narzędzia integrującego się z przepływem pracy organizacji (na przykład SCP, SFTP). Często lokalizuje się aplikacje internetowe w katalogu var (na przykład var/www/helloapp).

Note

W scenariuszu wdrażania produkcyjnego zadanie integracji ciągłej obejmuje publikowanie aplikacji oraz kopiowanie zasobów na serwer.

Przetestuj aplikację:

  1. W wierszu polecenia uruchom aplikację: dotnet <app_assembly>.dll.
  2. W przeglądarce przejdź do adresu http://<serveraddress>:<port>, aby sprawdzić, czy aplikacja działa lokalnie w systemie Linux.

Konfigurowanie zwrotnego serwera proxy

Zwrotny serwer proxy to typowa konfiguracja obsługi dynamicznych aplikacji internetowych. Zwrotny serwer proxy kończy żądanie HTTP i przekazuje je do aplikacji ASP.NET Core.

Używanie zwrotnego serwera proxy

Kestrel doskonale nadaje się do obsługi zawartości dynamicznej z platformy ASP.NET Core. Jednak funkcje serwera sieciowego nie są tak bogate, jak w przypadku serwerów takich jak IIS, Apache lub Nginx. Zwrotny serwer proxy może odciążać pracę, taką jak obsługa zawartości statycznej, buforowanie żądań, kompresowanie żądań i terminacja HTTPS z serwera HTTP. Zwrotny serwer proxy może znajdować się na dedykowanej maszynie lub może zostać wdrożony wraz z serwerem HTTP.

Na potrzeby tego przewodnika jest używane pojedyncze wystąpienie serwera Nginx. Działa on na tym samym serwerze wraz z serwerem HTTP. W zależności od wymagań można wybrać inną konfigurację.

Ponieważ żądania są przekazywane przez zwrotny serwer proxy, użyj Forwarded Headers Middleware z Microsoft.AspNetCore.HttpOverrides. Middleware aktualizuje Request.Scheme element przy użyciu nagłówka X-Forwarded-Proto, aby URI przekierowania i inne polityki bezpieczeństwa działały poprawnie.

Oprogramowanie pośredniczące przekazanych nagłówków powinno być uruchamiane przed innym oprogramowaniem pośredniczącym. Ustalenie kolejności gwarantuje, że oprogramowanie pośredniczące oparte na informacjach przesłanych nagłówków może wykorzystywać wartości nagłówków do przetwarzania. Aby uruchomić środowisko pośredniczące przekazywania nagłówków po oprogramowaniu pośredniczącym diagnostyki i obsługi błędów, zobacz Kolejność środowiska pośredniczącego przekazywania nagłówków.

Wywołaj metodę UseForwardedHeaders na początku potoku przetwarzania żądań przed wywołaniem innego oprogramowania pośredniczącego. Skonfiguruj oprogramowanie pośredniczące, aby przekazywać nagłówki X-Forwarded-For i X-Forwarded-Proto.

using Microsoft.AspNetCore.HttpOverrides;

...

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

app.UseAuthentication();

Jeśli w oprogramowaniu pośredniczącym nie określono ForwardedHeadersOptions, domyślne nagłówki do przekazania to None.

Serwery proxy uruchomione na adresach sprzężenia zwrotnego (127.0.0.0/8, [::1]), w tym standardowy adres localhost (127.0.0.1), są domyślnie zaufane. Jeśli inne zaufane serwery proxy lub sieci w organizacji obsługują żądania pomiędzy Internetem a serwerem WWW, dodaj je do listy KnownProxies lub KnownNetworks za pomocą ForwardedHeadersOptions. Poniższy przykład dodaje zaufany serwer proxy pod adresem IP 10.0.0.100 do oprogramowania pośredniczącego Forwarded Headers KnownProxies w Startup.ConfigureServices:

using System.Net;

...

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

Aby uzyskać więcej informacji, zobacz Konfigurowanie platformy ASP.NET Core pod kątem pracy z serwerami proxy i modułami równoważenia obciążenia.

Instalowanie serwera Nginx

Użyj polecenia apt-get , aby zainstalować serwer Nginx. Instalator tworzy systemd skrypt init, który uruchamia serwer Nginx jako daemona przy starcie systemu. Postępuj zgodnie z instrukcjami instalacji systemu Ubuntu w witrynie Nginx: Oficjalne pakiety Debian/Ubuntu.

Note

Jeśli wymagane są opcjonalne moduły Nginx, może być wymagane utworzenie serwera Nginx ze źródła.

Ponieważ serwer Nginx został zainstalowany po raz pierwszy, jawnie uruchom go, uruchamiając polecenie:

sudo service nginx start

Sprawdź, czy przeglądarka wyświetla domyślną stronę docelową serwera Nginx. Strona docelowa jest osiągalna pod adresem http://<server_IP_address>/index.nginx-debian.html.

Konfigurowanie serwera Nginx

Aby skonfigurować serwer Nginx jako zwrotny serwer proxy do przekazywania żądań HTTP do aplikacji ASP.NET Core, zmodyfikuj polecenie /etc/nginx/sites-available/default. Otwórz go w edytorze tekstów i zastąp zawartość następującym fragmentem kodu:

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

Jeśli aplikacja jest aplikacją SignalR lub Blazor Server, zobacz Hostowanie i skalowanie produkcyjne w ASP.NET CoreSignalR oraz Hostuj i wdrażaj aplikacje po stronie serwera ASP.NET CoreBlazor, aby uzyskać więcej informacji.

W przypadku gdy nie ma dopasowań server_name, serwer Nginx używa serwera domyślnego. Jeśli serwer domyślny nie jest zdefiniowany, pierwszy serwer w pliku konfiguracji jest serwerem domyślnym. Najlepszym rozwiązaniem jest dodanie określonego domyślnego serwera, który zwraca kod stanu 444 w pliku konfiguracji. Domyślny przykład konfiguracji serwera to:

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

Po tym jak zastosowano poprzedni plik konfiguracyjny i serwer domyślny, serwer Nginx akceptuje ruch publiczny na porcie 80 z nagłówkiem hosta example.com lub *.example.com. Żądania, które nie pasują do tych hostów, nie będą przekazywane do usługi Kestrel. Serwer Nginx przekazuje pasujące żądania do obiektu Kestrel pod adresem http://127.0.0.1:5000. Aby uzyskać więcej informacji, zobacz Jak serwer nginx przetwarza żądanie. Aby zmienić Kestreladres IP/port, zobacz Kestrel: Konfiguracja punktu końcowego.

Warning

Nieprawidłowe określenie dyrektywy server_name naraża Twoją aplikację na podatności bezpieczeństwa. Powiązanie symboli wieloznacznych poddomeny (na przykład *.example.com) nie stanowi tego ryzyka zabezpieczeń, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Http Semantics (Sekcja 7.2: Host i :authority).

Po ustanowieniu konfiguracji serwera Nginx uruchom polecenie sudo nginx -t , aby zweryfikować składnię plików konfiguracji. Jeśli test pliku konfiguracji zakończy się pomyślnie, wymusij na serwerze Nginx pobieranie zmian, uruchamiając polecenie sudo nginx -s reload.

Aby bezpośrednio uruchomić aplikację na serwerze:

  1. Przejdź do katalogu aplikacji.
  2. Uruchom aplikację: dotnet <app_assembly.dll>, gdzie app_assembly.dll jest nazwą pliku zestawu aplikacji.

Jeśli aplikacja działa na serwerze, ale nie odpowiada przez Internet, sprawdź zaporę serwera i upewnij się, że port 80 jest otwarty. W przypadku korzystania z maszyny wirtualnej z systemem Ubuntu na platformie Azure, dodaj regułę Grupy zabezpieczeń sieci, która umożliwia ruch przychodzący na porcie 80. Nie ma potrzeby włączania reguły portu wychodzącego 80, ponieważ ruch wychodzący jest automatycznie udzielany po włączeniu reguły ruchu przychodzącego.

Po zakończeniu testowania aplikacji zamknij aplikację za pomocą Ctrl+C w wierszu poleceń.

Monitorowanie aplikacji

Serwer jest skonfigurowany do przesyłania żądań kierowanych do http://<serveraddress>:80 do aplikacji ASP.NET Core działającej na Kestrel pod adresem http://127.0.0.1:5000. Jednak serwer Nginx nie jest skonfigurowany do zarządzania procesem Kestrel . systemd Umożliwia utworzenie pliku usługi w celu uruchomienia i monitorowania podstawowej aplikacji internetowej. systemd to system init, który udostępnia wiele zaawansowanych funkcji uruchamiania, zatrzymywania i zarządzania procesami.

Tworzenie pliku usługi

Utwórz plik definicji usługi:

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

Poniższy przykład to plik usługi dla aplikacji:

[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

W poprzednim przykładzie użytkownik, który zarządza usługą, jest określony przez opcję User. Użytkownik (www-data) musi istnieć i mieć właściwą własność plików aplikacji.

Użyj TimeoutStopSec, aby skonfigurować czas oczekiwania na zamknięcie aplikacji po odebraniu sygnału przerwania. Jeśli aplikacja nie zostanie zamknięta w tym okresie, zostanie wysłany sygnał SIGKILL w celu zakończenia działania aplikacji. Podaj wartość w sekundach (na przykład 150), wartość przedziału czasu (na przykład 2min 30s), lub infinity, aby wyłączyć limit czasu. TimeoutStopSec wartość domyślna parametru DefaultTimeoutStopSec w pliku konfiguracji menedżera (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). Domyślny limit czasu dla większości dystrybucji wynosi 90 sekund.

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

W systemie Linux system plików rozróżnia wielkość liter. Ustawienie ASPNETCORE_ENVIRONMENT na Production powoduje przeszukiwanie pliku appsettings.Production.json konfiguracji, a nie appsettings.production.json.

Niektóre wartości (na przykład parametry połączenia SQL) muszą być zamaskowane, aby dostawcy konfiguracji mogli odczytywać zmienne środowiskowe. Użyj następującego polecenia, aby wygenerować prawidłowo unikniętą wartość do użycia w pliku konfiguracji:

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

Dwukropki (:) nie są obsługiwane w nazwach zmiennych środowiskowych. Użyj podwójnego podkreślenia (__) zamiast dwukropka. Dostawca konfiguracji zmiennych środowiskowych konwertuje podwójne podkreślenia na dwukropki podczas odczytywania zmiennych środowiskowych do konfiguracji. W poniższym przykładzie klucz parametru połączenia ConnectionStrings:DefaultConnection jest ustawiony w pliku definicji usługi jako ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Zapisz plik i włącz usługę.

sudo systemctl enable kestrel-helloapp.service

Uruchom usługę i sprawdź, czy jest uruchomiona.

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

Po skonfigurowaniu zwrotnego serwera proxy i Kestrel zarządzanym za pośrednictwem systemdprogramu aplikacja internetowa jest w pełni skonfigurowana i może być dostępna z przeglądarki na komputerze lokalnym pod adresem http://localhost. Jest również dostępna z komputera zdalnego, o ile nie są blokowane przez zapory sieciowe. Sprawdzając nagłówki odpowiedzi, w nagłówku Server wyświetlana jest aplikacja ASP.NET Core obsługiwana przez 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

Wyświetlanie dzienników

Ponieważ aplikacja internetowa korzystająca z programu Kestrel jest zarządzana przy użyciu programu systemd, wszystkie zdarzenia i procesy są rejestrowane w scentralizowanym dzienniku. Jednak ten dziennik zawiera wszystkie wpisy dla wszystkich usług i procesów zarządzanych przez program systemd. Aby wyświetlić elementy specyficzne dla kestrel-helloapp.service, użyj następującego polecenia:

sudo journalctl -fu kestrel-helloapp.service

W celu dalszego filtrowania opcje czasu, takie jak --since today, --until 1 hour agolub kombinacja tych elementów, może zmniejszyć liczbę zwracanych wpisów.

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

Ochrona danych

Platforma ASP.NET Core Data Protection jest używana przez kilka ASP.NET Core middleware, w tym middleware uwierzytelniania (na przykład cookie middleware) oraz przeciwdziałanie fałszowaniu żądań między witrynami (CSRF). Nawet jeśli interfejsy API ochrony danych nie są wywoływane przez kod użytkownika, należy skonfigurować ochronę danych w celu utworzenia trwałego magazynu kluczy kryptograficznych. Jeśli ochrona danych nie jest skonfigurowana, klucze są przechowywane w pamięci i odrzucane po ponownym uruchomieniu aplikacji.

Jeśli pierścień kluczy jest przechowywany w pamięci po ponownym uruchomieniu aplikacji:

  • Wszystkie tokeny uwierzytelniania oparte na systemie cookie są unieważniane.
  • Użytkownicy są zobowiązani do ponownego zalogowania się podczas następnego żądania.
  • Nie można już odszyfrować żadnych danych chronionych za pomocą pierścienia kluczy. Może to obejmować tokeny CSRF i pliki cookie ASP.NET Core MVC TempData.

Aby skonfigurować ochronę danych w celu utrwalania i szyfrowania pierścienia kluczy, zobacz:

Długie nagłówki żądań

Domyślne ustawienia serwera proxy zwykle ograniczają pola nagłówka żądania do 4 K lub 8 K w zależności od platformy. Aplikacja może wymagać pól dłuższych niż domyślne (na przykład aplikacji korzystających z usługi Azure Active Directory). Jeśli wymagane są dłuższe pola, ustawienia domyślne serwera proxy wymagają dostosowania. Wartości do zastosowania zależą od scenariusza. Aby uzyskać więcej informacji, zobacz dokumentację serwera.

Warning

Nie należy zwiększać wartości domyślnych buforów proxy, chyba że jest to konieczne. Zwiększenie tych wartości zwiększa ryzyko przepełnienia buforu (przepełnienia) i ataków typu "odmowa usługi" (DoS) przez złośliwych użytkowników.

Zabezpieczanie aplikacji

Włączanie aplikacji AppArmor

Moduły zabezpieczeń systemu Linux (LSM) to struktura, która jest częścią jądra systemu Linux od systemu Linux 2.6. Rozwiązanie LSM obsługuje różne implementacje modułów zabezpieczeń. AppArmor to LSM, który implementuje obowiązkowy system kontroli dostępu, który umożliwia ograniczenie programu do ograniczonego zestawu zasobów. Upewnij się, że aplikacja AppArmor jest włączona i prawidłowo skonfigurowana.

Konfigurowanie zapory

Zamknij wszystkie porty zewnętrzne, które nie są używane. Nieskomplikowana zapora (ufw) zapewnia interfejs dla iptables, udostępniając interfejs wiersza poleceń do konfigurowania zapory.

Warning

Zapora uniemożliwi dostęp do całego systemu, jeśli nie zostanie poprawnie skonfigurowany. Brak określenia poprawnego portu SSH spowoduje zablokowanie dostępu do systemu, jeśli używasz SSH do połączenia z nim. Domyślny port jest 22. Aby uzyskać więcej informacji, zobacz wprowadzenie do ufw i podręcznik.

Zainstaluj ufw i skonfiguruj go, aby zezwolić na ruch na wszystkich wymaganych portach.

sudo apt-get install ufw

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

sudo ufw enable

Zabezpieczanie serwera Nginx

Zmienianie nazwy odpowiedzi serwera Nginx

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

Konfigurowanie opcji

Skonfiguruj serwer z dodatkowymi wymaganymi modułami. Rozważ użycie zapory aplikacji internetowej, takiej jak ModSecurity, w celu zabezpieczenia aplikacji.

Konfiguracja protokołu HTTPS

Konfigurowanie aplikacji pod kątem bezpiecznych połączeń lokalnych (HTTPS)

Polecenie dotnet run używa pliku aplikacji, Properties/launchSettings.json który konfiguruje aplikację do nasłuchiwania na adresy URL określone przez właściwość applicationUrl. Na przykład https://localhost:5001;http://localhost:5000.

Skonfiguruj aplikację tak, aby używała certyfikatu podczas programowania dla dotnet run polecenia lub środowiska programistycznego (F5 lub Ctrl+F5 w programie Visual Studio Code) przy użyciu jednej z następujących metod:

Konfigurowanie zwrotnego serwera proxy na potrzeby bezpiecznych połączeń klienckich (HTTPS)

Warning

Konfiguracja zabezpieczeń w tej sekcji jest ogólną konfiguracją, która ma być używana jako punkt wyjścia do dalszego dostosowywania. Nie możemy zapewnić obsługi narzędzi, serwerów i systemów operacyjnych innych firm. Użyj konfiguracji w tej sekcji na własne ryzyko. Aby uzyskać więcej informacji, uzyskaj dostęp do następujących zasobów:

  • Skonfiguruj serwer do nasłuchiwania ruchu HTTPS na porcie 443, określając prawidłowy certyfikat wystawiony przez zaufany urząd certyfikacji.

  • Wzmacnianie zabezpieczeń przez zastosowanie niektórych praktyk przedstawionych w poniższym pliku /etc/nginx/nginx.conf .

  • Poniższy przykład nie konfiguruje serwera do przekierowywania niezabezpieczonych żądań. Zalecamy używanie oprogramowania pośredniczącego przekierowania HTTPS. Aby uzyskać więcej informacji, zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

    Note

    W przypadku środowisk deweloperskich, w których konfiguracja serwera obsługuje bezpieczne przekierowywanie zamiast oprogramowania pośredniczącego przekierowania HTTPS, zalecamy używanie tymczasowych przekierowań (302), a nie stałych przekierowań (301). Buforowanie łączy może spowodować niestabilne zachowanie w środowiskach deweloperskich.

  • Dodanie nagłówka Strict-Transport-Security (HSTS) gwarantuje, że wszystkie kolejne żądania wysyłane przez klienta są za pośrednictwem protokołu HTTPS. Aby uzyskać wskazówki dotyczące ustawiania nagłówka Strict-Transport-Security , zobacz Wymuszanie protokołu HTTPS w ASP.NET Core.

  • Jeśli protokół HTTPS zostanie wyłączony w przyszłości, użyj jednego z następujących podejść:

    • Nie dodawaj nagłówka HSTS.
    • Wybierz krótką max-age wartość.

Dodaj plik konfiguracji /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;

Zastąp zawartość pliku konfiguracji /etc/nginx/nginx.conf następującym plikiem. W przykładzie znajdują się obie sekcje, http i server, w jednym pliku konfiguracyjnym.

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

Note

Blazor WebAssembly aplikacje wymagają większej burst wartości parametru, aby obsłużyć większą liczbę żądań wysyłanych przez aplikację. Aby uzyskać więcej informacji, zobacz Hostowanie i wdrażanie ASP.NET Core z Nginx.

Note

Powyższy przykład wyłącza Stapling protokołu OCSP (Online Certificate Status Protocol). Jeśli ta opcja jest włączona, upewnij się, że certyfikat obsługuje tę funkcję. Aby uzyskać więcej informacji i wskazówek dotyczących włączania OCSP, zobacz następujące właściwości w artykule Module ngx_http_ssl_module (dokumentacja Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Zabezpieczanie Nginx przed clickjackingiem

Clickjacking, znany również jako atak przekierowania interfejsu użytkownika, jest złośliwym atakiem, w którym odwiedzający witrynę internetową jest nakłaniany do kliknięcia linku lub przycisku na innej stronie niż ta, którą obecnie odwiedza. Użyj X-FRAME-OPTIONS, aby zabezpieczyć witrynę.

Aby zminimalizować ryzyko ataków typu clickjacking:

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Dodaj wiersz: add_header X-Frame-Options "SAMEORIGIN";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Rozpoznawanie typu MIME

Ten nagłówek uniemożliwia większości przeglądarek automatyczne rozpoznanie typu MIME odpowiedzi innego niż zadeklarowany, ponieważ nagłówek instruuje przeglądarkę, aby nie nadpisywała deklarowanego typu zawartości odpowiedzi. Z opcją nosniff, jeśli serwer określa zawartość jako text/html, przeglądarka renderuje ją jako text/html.

  1. Edytuj plik nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Dodaj wiersz: add_header X-Content-Type-Options "nosniff";

  2. Zapisz plik.

  3. Uruchom ponownie serwer Nginx.

Dodatkowe sugestie serwera Nginx

Po uaktualnieniu platformy udostępnionej na serwerze uruchom ponownie aplikacje ASP.NET Core hostowane przez serwer.

Dodatkowe zasoby