Host ASP.NET Core no Linux com Nginx

Por Sourabh Shirhatti

Observação

Esta não é a versão mais recente deste artigo. Para obter a versão atual, confira a versão do ASP.NET Core 8.0 deste artigo.

Este guia explica como configurar um ambiente ASP.NET Core pronto para produção para Ubuntu, Red Hat Enterprise (RHEL) e SUSE Linux Enterprise Server.

Para saber mais sobre outras distribuições do Linux compatíveis com o ASP.NET Core, veja Pré-requisitos para o .NET Core no Linux.

Este guia:

  • Coloca um aplicativo ASP.NET Core existente em um servidor proxy reverso.
  • Configura o servidor proxy reverso para encaminhar solicitações ao servidor Web do Kestrel.
  • Assegura que o aplicativo Web seja executado na inicialização como um daemon.
  • Configura uma ferramenta de gerenciamento de processo para ajudar a reiniciar o aplicativo Web.

Pré-requisitos

A qualquer momento no futuro, depois de atualizar a estrutura compartilhada, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Publicar e copiar o aplicativo

Configurar o aplicativo para um implantação dependente de estrutura.

Se o aplicativo for executado localmente no Ambiente de desenvolvimento e não estiver configurado pelo servidor para fazer conexões HTTPS seguras, adote uma das seguintes abordagens:

  • Configure o aplicativo para lidar com conexões seguras locais. Para obter mais informações, veja a seção Configuração de HTTPS.

  • Configure o aplicativo para ser executado no ponto de extremidade inseguro:

    • Desativar o middleware de redirecionamento HTTPS no ambiente de desenvolvimento (Program.cs):

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

      Para obter mais informações, confira Usar vários ambientes no ASP.NET Core.

    • Remova https://localhost:5001 (se houver) da propriedade applicationUrl no arquivo Properties/launchSettings.json.

Para obter mais informações sobre a configuração por ambiente, consulte Use vários ambientes no ASP.NET Core.

Execute dotnet publish do ambiente de desenvolvimento para empacotar um aplicativo em um diretório (por exemplo, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, onde o espaço reservado {TARGET FRAMEWORK MONIKER} é o TFM (Moniker da Estrutura de Destino)) que pode ser executado no servidor:

dotnet publish --configuration Release

O aplicativo também poderá ser publicado como uma implantação autossuficiente se você preferir não manter o runtime do .NET Core no servidor.

Copie o aplicativo ASP.NET Core para o servidor usando uma ferramenta que se integre ao fluxo de trabalho da organização (por exemplo, SCP, SFTP). É comum localizar aplicativos Web no diretório var (por exemplo, var/www/helloapp).

Observação

Em um cenário de implantação de produção, um fluxo de trabalho de integração contínua faz o trabalho de publicar o aplicativo e copiar os ativos para o servidor.

Teste o aplicativo:

  1. Na linha de comando, execute o aplicativo: dotnet <app_assembly>.dll.
  2. Em um navegador, vá para http://<serveraddress>:<port> para verificar se o aplicativo funciona no Linux localmente.

Configurar um servidor proxy reverso

Um proxy reverso é uma configuração comum para atender a aplicativos Web dinâmicos. Um proxy reverso encerra a solicitação HTTP e a encaminha para o aplicativo ASP.NET Core.

Usar um servidor proxy reverso

O Kestrel é excelente para servir conteúdo dinâmico do ASP.NET Core. No entanto, as funcionalidades de servidor Web não têm tantos recursos quanto servidores como IIS, Apache ou Nginx. Um servidor proxy reverso pode descarregar trabalho como servir conteúdo estático, armazenar solicitações em cache, compactar solicitações e terminar HTTPS do servidor HTTP. Um servidor proxy reverso pode residir em um computador dedicado ou pode ser implantado junto com um servidor HTTP.

Para os fins deste guia, uma única instância de Nginx é usada. Ela é executada no mesmo servidor, junto com o servidor HTTP. Com base nos requisitos, uma configuração diferente pode ser escolhida.

Como as solicitações são encaminhadas por proxy reverso, use o Middleware de Cabeçalhos Encaminhados do pacote Microsoft.AspNetCore.HttpOverrides, que é incluído automaticamente nos aplicativos ASP.NET Core por meio de metapacotes Microsoft.AspNetCore.App da estrutura compartilhada. O middleware atualiza o Request.Scheme usando o cabeçalho X-Forwarded-Proto, de forma que URIs de redirecionamento e outras políticas de segurança funcionam corretamente.

Middlewares de Cabeçalhos Encaminhados devem ser executados antes de outros middlewares. Essa ordenação garantirá que o middleware conte com informações de cabeçalhos encaminhadas que podem consumir os valores de cabeçalho para processamento. Para executar o Middleware de Cabeçalhos Encaminhados após o diagnóstico e o middleware de tratamento de erros, consulte Ordem do Middleware de Cabeçalhos Encaminhados.

Invoque o método UseForwardedHeaders antes de chamar outro middleware. Configure o middleware para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAuthentication();

var app = builder.Build();

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

app.UseAuthentication();

app.MapGet("/", () => "Hello ForwardedHeadersOptions!");

app.Run();

Se nenhum ForwardedHeadersOptions for especificado para o middleware, os cabeçalhos padrão para encaminhar serão None.

Os proxies em execução em endereços de loopback (127.0.0.0/8, [::1]), incluindo o endereço de host local padrão (127.0.0.1), são confiáveis por padrão. Se outros proxies ou redes confiáveis em que a organização trata solicitações entre a Internet e o servidor Web, adicione-os à lista de KnownProxies ou KnownNetworks com ForwardedHeadersOptions. O exemplo a seguir adiciona um servidor proxy confiável no endereço IP 10.0.0.100 ao Middleware dos cabeçalhos encaminhados KnownProxies:

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

Para obter mais informações, veja Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Instalar o Nginx

Use apt-get para instalar o Nginx. O instalador cria um script de inicialização systemd que executa o Nginx como daemon na inicialização do sistema. Siga as instruções de instalação para o Ubuntu em Nginx: pacotes Debian/Ubuntu oficiais.

Observação

Se módulos Nginx opcionais forem exigidos, poderá haver necessidade de criar o Nginx da origem.

Já que Nginx foi instalado pela primeira vez, inicie-o explicitamente executando:

sudo service nginx start

Verifique se um navegador exibe a página de aterrissagem padrão do Nginx. A página de aterrissagem é acessível em http://<server_IP_address>/index.nginx-debian.html.

Configurar o Nginx

Para configurar o Nginx como um proxy reverso para encaminhar solicitações HTTP para o aplicativo ASP.NET Core, modifique /etc/nginx/sites-available/default e recrie o link simbólico. Após a criação do arquivo /etc/nginx/sites-available/default, utilize o seguinte comando para criar o link simbólico:

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

Abra /etc/nginx/sites-available/default em um editor de texto e substitua o conteúdo pelo seguinte trecho:

http {
  map $http_connection $connection_upgrade {
    "~*Upgrade" $http_connection;
    default keep-alive;
  }

  server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000/;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection $connection_upgrade;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
  }
}

Se o aplicativo for um aplicativo SignalR ou Blazor Server, consulte Hospedagem e dimensionamento SignalR do ASP.NET Core e Hospedar e implantar aplicativos do ASP.NET Core do lado do servidorBlazor respectivamente para obter mais informações.

Quando nenhum server_name corresponde, o Nginx usa o servidor padrão. Se nenhum servidor padrão é definido, o primeiro servidor no arquivo de configuração é o servidor padrão. Como prática recomendada, adicione um servidor padrão específico que retorna um código de status 444 no arquivo de configuração. Um exemplo de configuração de servidor padrão é:

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

Com o servidor padrão e o arquivo de configuração anterior, o Nginx aceita tráfego público na porta 80 com um cabeçalho de host example.com ou *.example.com. Solicitações que não correspondam a esses hosts não serão encaminhadas para o Kestrel. O Nginx encaminha as solicitações correspondentes para o Kestrel em http://127.0.0.1:5000/. Veja Como o nginx processa uma solicitação para obter mais informações. Para alterar o IP/porta do Kestrel, veja Kestrel: configuração de ponto de extremidade.

Aviso

Falha ao especificar uma diretiva server_name expõe seu aplicativo para vulnerabilidades de segurança. Associações de curinga de subdomínio (por exemplo, *.example.com) não oferecerão esse risco de segurança se você controlar o domínio pai completo (em vez de *.com, o qual é vulnerável). Para obter mais informações, consulte RFC 9110: Semântica HTTP (Seção 7.2: Host e :authority).

Quando a configuração Nginx é estabelecida, execute sudo nginx -t para verificar a sintaxe dos arquivos de configuração. Se o teste do arquivo de configuração for bem-sucedido, você poderá forçar o Nginx a acompanhar as alterações executando sudo nginx -s reload.

Para executar o aplicativo diretamente no servidor:

  1. Navegue até o diretório do aplicativo.
  2. Execute o aplicativo: dotnet <app_assembly.dll>, em que app_assembly.dll é o nome do arquivo do assembly do aplicativo.

Se o aplicativo for executado no servidor, mas não responder pela Internet, verifique o firewall do servidor e confirme se a porta 80 está aberta. Se você estiver usando uma VM do Azure Ubuntu, adicione uma regra NSG (Grupo de Segurança de Rede) que permite tráfego de entrada na porta 80. Não é necessário habilitar uma regra de saída da porta 80, uma vez que o tráfego de saída é concedido automaticamente quando a regra de entrada é habilitada.

Quando terminar de testar o aplicativo, desligue o aplicativo com Ctrl+C (Windows) ou +C (macOS) no prompt de comando.

Aumentar keepalive_requests

keepalive_requests pode ser aumentado para maior desempenho. Para obter mais informações, confira este problema do GitHub.

Monitorar o aplicativo

O servidor agora está configurado para encaminhar solicitações feitas a http://<serveraddress>:80 ao aplicativo ASP.NET Core em execução no Kestrel em http://127.0.0.1:5000. No entanto, o Nginx não está configurado para gerenciar o processo do Kestrel. É possível usar o systemd para criar um arquivo de serviço para iniciar e monitorar o aplicativo Web subjacente. systemd é um sistema de inicialização que fornece muitos recursos avançados para iniciar, interromper e gerenciar processos.

Criar o arquivo de serviço

Crie o arquivo de definição de serviço:

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

O exemplo abaixo é um arquivo de serviço .ini para o aplicativo:

[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

No exemplo anterior, o usuário que gerencia o serviço é especificado pela opção User. O usuário (www-data) deve existir e ter a propriedade adequada dos arquivos do aplicativo.

Use TimeoutStopSec para configurar a duração do tempo de espera para o aplicativo desligar depois de receber o sinal de interrupção inicial. Se o aplicativo não desligar nesse período, o SIGKILL será emitido para encerrá-lo. Forneça o valor como segundos sem unidade (por exemplo, 150), um valor de duração (por exemplo, 2min 30s) ou infinity para desabilitar o tempo limite. TimeoutStopSec assume como padrão o valor de DefaultTimeoutStopSec no arquivo de configuração do gerenciador (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). O tempo limite padrão para a maioria das distribuições é de 90 segundos.

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

O Linux tem um sistema de arquivos que diferencia maiúsculas de minúsculas. A configuração ASPNETCORE_ENVIRONMENT para Production resultar na pesquisa do arquivo de configuração appsettings.Production.json, não appsettings.production.json.

Alguns valores (por exemplo, cadeias de conexão de SQL) devem ser escapadas para que os provedores de configuração leiam as variáveis de ambiente. Use o seguinte comando para gerar um valor corretamente com caracteres de escape para uso no arquivo de configuração:

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

Separadores do tipo dois-pontos (:) não são compatíveis com nomes de variáveis de ambiente. Use um sublinhado duplo (__) no lugar de dois-pontos. O provedor de configuração de Variáveis de Ambiente converte caracteres de sublinhado duplo em dois-pontos quando as variáveis de ambiente são lidas na configuração. No exemplo a seguir, a chave de cadeia de conexão ConnectionStrings:DefaultConnection está definida no arquivo de definição de serviço como ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Salve o arquivo e habilite o serviço.

sudo systemctl enable kestrel-helloapp.service

Inicie o serviço e verifique se ele está em execução.

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

Com o proxy reverso configurado e o Kestrel gerenciado por meio de systemd, o aplicativo Web está totalmente configurado e pode ser acessado em um navegador no computador local em http://localhost. Ele também é acessível por meio de um computador remoto, bloqueando qualquer firewall que o possa estar bloqueando. Inspecionando os cabeçalhos de resposta, o cabeçalho Server mostra o aplicativo ASP.NET Core sendo servido pelo 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

Exibir logs

Já que o aplicativo Web que usa o Kestrel é gerenciado com systemd, todos os eventos e os processos são registrados em um diário centralizado. No entanto, esse diário contém todas as entradas para todos os serviços e processos gerenciados pelo systemd. Para exibir os itens específicos de kestrel-helloapp.service, use o seguinte comando:

sudo journalctl -fu kestrel-helloapp.service

Para obter mais filtragem, opções de hora como --since today, --until 1 hour ago ou uma combinação delas, pode reduzir o número de entradas retornadas.

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

Proteção de dados

A pilha de proteção de dados do ASP.NET Core é usada por vários middlewares do ASP.NET Core, incluindo o middleware de autenticação (por exemplo, o middleware de cookie) e as proteções de CSRF (solicitação intersite forjada). Mesmo se as APIs de Proteção de Dados não forem chamadas pelo código do usuário, a proteção de dados deverá ser configurada para criar um repositório de chaves criptográfico persistente. Se a proteção de dados não estiver configurada, as chaves serão mantidas na memória e descartadas quando o aplicativo for reiniciado.

Se o token de autenticação for armazenado na memória quando o aplicativo for reiniciado:

  • Todos os tokens de autenticação baseados em cookie serão invalidados.
  • Os usuários precisam entrar novamente na próxima solicitação deles.
  • Todos os dados protegidos com o token de autenticação não poderão mais ser descriptografados. Isso pode incluir os tokens CSRF e cookies TempData do MVC do ASP.NET Core.

Para configurar a proteção de dados de modo que ela mantenha e criptografe o token de autenticação, consulte:

Campos de cabeçalho da solicitação muito grandes

As configurações padrão do servidor proxy normalmente limitam os campos de cabeçalho de solicitação a 4 K ou 8 K, dependendo da plataforma. Um aplicativo pode exigir campos maiores que o padrão (por exemplo, aplicativos que utilizam o Microsoft Entra ID). Se forem necessários campos mais longos, as configurações padrão do servidor proxy exigirão ajuste. Os valores a serem aplicados dependem do cenário. Para obter mais informações, confira a documentação do servidor.

Aviso

Não aumente os valores padrão de buffers de proxy a menos que necessário. Aumentar esses valores aumenta o risco de estouro de buffer (estouro) e ataques de DoS (negação de serviço) por usuários mal-intencionados.

Proteger o aplicativo

Habilitar AppArmor

O LSM (Módulos de Segurança do Linux) é uma estrutura que é parte do kernel do Linux desde o Linux 2.6. O LSM dá suporte a diferentes implementações de módulos de segurança. O AppArmor é um LSM que implementa um sistema de controle de acesso obrigatório que permite restringir o programa a um conjunto limitado de recursos. Verifique se o AppArmor está habilitado e configurado corretamente.

Configurar o firewall

Feche todas as portas externas que não estão em uso. Firewall descomplicado (ufw) fornece um front-end para iptables fornecendo uma CLI para configurar o firewall.

Aviso

Um firewall impede o acesso a todo o sistema quando não está configurado corretamente. Quando há falha ao especificar a porta SSH correta, você é bloqueado do sistema ao usar o SSH para se conectar a ele. A porta padrão é a 22. Para obter mais informações, consulte a introdução ao ufw e o manual.

Instale o ufw e configure-o para permitir o tráfego em todas as portas necessárias.

sudo apt-get install ufw

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

sudo ufw enable

Proteger o Nginx

Alterar o nome da resposta do Nginx

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

Configurar opções

Configure o servidor com os módulos adicionais necessários. Considere usar um firewall de aplicativo Web como ModSecurity para fortalecer o aplicativo.

Configuração de HTTPS

Configurar o aplicativo para conexões seguras (HTTPS) locais

O comando dotnet run usa o arquivo Properties/launchSettings.json do aplicativo, que configura o aplicativo para escutar nas URLs fornecidas pela propriedade applicationUrl. Por exemplo, https://localhost:5001;http://localhost:5000.

Configure o aplicativo para usar um certificado no desenvolvimento para o comando dotnet run ou no ambiente de desenvolvimento (F5 ou Ctrl+F5 no Visual Studio Code) usando uma das seguintes abordagens:

Configurar o proxy reverso para conexões de cliente seguras (HTTPS)

Aviso

A configuração de segurança nesta seção é uma configuração geral a ser usada como ponto de partida para personalização adicional. Não é possível fornecer suporte para ferramentas, servidores e sistemas operacionais de terceiros. Use a configuração nesta seção por sua conta e risco. Para obter mais informações, acesse os seguintes recursos:

  • Configure o servidor para escutar tráfego HTTPS na porta 443 especificando um certificado válido emitido por uma AC (autoridade de certificação) confiável.

  • Aprimore a segurança, empregando algumas das práticas descritas no arquivo /etc/nginx/nginx.conf a seguir.

  • O exemplo a seguir não configura o servidor para redirecionar solicitações inseguras. É recomendável usar o Middleware de Redirecionamento HTTPS. Para obter mais informações, confira Impor HTTPS no ASP.NET Core.

    Observação

    Para ambientes de desenvolvimento em que a configuração do servidor manipula o redirecionamento seguro em vez do Middleware de Redirecionamento HTTPS, recomendamos usar redirecionamentos temporários (302) em vez de permanentes (301). O cache de link pode causar um comportamento instável em ambientes de desenvolvimento.

  • A adição de um cabeçalho Strict-Transport-Security (HSTS) garante que todas as próximas solicitações feitas pelo cliente sejam por HTTPS. Para obter diretrizes sobre como definir o Strict-Transport-Security cabeçalho, confira Impor HTTPS em ASP.NET Core.

  • Se o HTTPS for desabilitado no futuro, use uma das seguintes abordagens:

    • Não adicione o cabeçalho HSTS.
    • Escolha um valor max-age curto.

Adicione o arquivo de configuração /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;

Substituir o conteúdo do arquivo de configuração /etc/nginx/nginx.conf pelo arquivo a seguir. O exemplo contém ambas as seções http e server em um arquivo de configuração.

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

Observação

Os aplicativos Blazor WebAssembly exigem um valor de parâmetro burst maior para acomodar o maior número de solicitações feitas por um aplicativo. Para obter mais informações, confira Hospedar e implantar Blazor WebAssembly do ASP.NET Core.

Observação

O exemplo anterior desabilita a associação do protocolo OCSP. Se habilitado, confirme se o certificado dá suporte ao recurso. Para obter mais informações e diretrizes sobre como habilitar o OCSP, confira as seguintes propriedades no artigo Módulo ngx_http_ssl_module (documentação do Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Proteger o Nginx de clickjacking

Clickjacking, também conhecido como um ataque por inferência na interface do usuário, é um ataque mal-intencionado em que o visitante do site é levado a clicar em um link ou botão em uma página diferente daquela que está visitando atualmente. Use X-FRAME-OPTIONS para proteger o site.

Para atenuar ataques de clickjacking:

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    No bloco de código http{}, adicione a linha: add_header X-Frame-Options "SAMEORIGIN";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Detecção de tipo MIME

Esse cabeçalho evita que a maioria dos navegadores faça detecção MIME de uma resposta distante do tipo de conteúdo declarado, visto que o cabeçalho instrui o navegador para não substituir o tipo de conteúdo de resposta. Com a opção nosniff, se o servidor informa que o conteúdo é text/html, o navegador renderiza-a como text/html.

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    No bloco de código http{}, adicione a linha: add_header X-Content-Type-Options "nosniff";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Sugestões adicionais do Nginx

Depois de atualizar a estrutura compartilhada no servidor, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Recursos adicionais

Este guia explica como configurar um ambiente ASP.NET Core pronto para produção em um servidor Ubuntu 16.04. Essas instruções provavelmente funcionarão com versões mais recentes do Ubuntu, mas as instruções não foram testadas com versões mais recentes.

Para saber mais sobre outras distribuições do Linux compatíveis com o ASP.NET Core, veja Pré-requisitos para o .NET Core no Linux.

Observação

No caso do Ubuntu 14.04, supervisord é recomendado como uma solução para monitorar o processo do Kestrel. O systemd não está disponível no Ubuntu 14.04. Para obter instruções Ubuntu 14.04, veja a versão anterior deste tópico.

Este guia:

  • Coloca um aplicativo ASP.NET Core existente em um servidor proxy reverso.
  • Configura o servidor proxy reverso para encaminhar solicitações ao servidor Web do Kestrel.
  • Assegura que o aplicativo Web seja executado na inicialização como um daemon.
  • Configura uma ferramenta de gerenciamento de processo para ajudar a reiniciar o aplicativo Web.

Pré-requisitos

  • Acesso a um servidor Ubuntu 16.04 com uma conta de usuário padrão com privilégio sudo.
  • A última versão não prévia do runtime do .NET instalada no servidor.
  • Um aplicativo ASP.NET Core existente.

A qualquer momento no futuro, depois de atualizar a estrutura compartilhada, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Publicar e copiar o aplicativo

Configurar o aplicativo para um implantação dependente de estrutura.

Se o aplicativo for executado localmente no Ambiente de desenvolvimento e não estiver configurado pelo servidor para fazer conexões HTTPS seguras, adote uma das seguintes abordagens:

  • Configure o aplicativo para lidar com conexões seguras locais. Para obter mais informações, veja a seção Configuração de HTTPS.

  • Configure o aplicativo para ser executado no ponto de extremidade inseguro:

    • Desativar o middleware de redirecionamento HTTPS no ambiente de desenvolvimento (Program.cs):

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

      Para obter mais informações, confira Usar vários ambientes no ASP.NET Core.

    • Remova https://localhost:5001 (se houver) da propriedade applicationUrl no arquivo Properties/launchSettings.json.

Para obter mais informações sobre a configuração por ambiente, consulte Use vários ambientes no ASP.NET Core.

Execute dotnet publish do ambiente de desenvolvimento para empacotar um aplicativo em um diretório (por exemplo, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, onde o espaço reservado {TARGET FRAMEWORK MONIKER} é o TFM (Moniker da Estrutura de Destino)) que pode ser executado no servidor:

dotnet publish --configuration Release

O aplicativo também poderá ser publicado como uma implantação autossuficiente se você preferir não manter o runtime do .NET Core no servidor.

Copie o aplicativo ASP.NET Core para o servidor usando uma ferramenta que se integre ao fluxo de trabalho da organização (por exemplo, SCP, SFTP). É comum localizar aplicativos Web no diretório var (por exemplo, var/www/helloapp).

Observação

Em um cenário de implantação de produção, um fluxo de trabalho de integração contínua faz o trabalho de publicar o aplicativo e copiar os ativos para o servidor.

Teste o aplicativo:

  1. Na linha de comando, execute o aplicativo: dotnet <app_assembly>.dll.
  2. Em um navegador, vá para http://<serveraddress>:<port> para verificar se o aplicativo funciona no Linux localmente.

Configurar um servidor proxy reverso

Um proxy reverso é uma configuração comum para atender a aplicativos Web dinâmicos. Um proxy reverso encerra a solicitação HTTP e a encaminha para o aplicativo ASP.NET Core.

Usar um servidor proxy reverso

O Kestrel é excelente para servir conteúdo dinâmico do ASP.NET Core. No entanto, as funcionalidades de servidor Web não têm tantos recursos quanto servidores como IIS, Apache ou Nginx. Um servidor proxy reverso pode descarregar trabalho como servir conteúdo estático, armazenar solicitações em cache, compactar solicitações e terminar HTTPS do servidor HTTP. Um servidor proxy reverso pode residir em um computador dedicado ou pode ser implantado junto com um servidor HTTP.

Para os fins deste guia, uma única instância de Nginx é usada. Ela é executada no mesmo servidor, junto com o servidor HTTP. Com base nos requisitos, uma configuração diferente pode ser escolhida.

Já que as solicitações são encaminhadas pelo proxy reverso, use o Middleware de Cabeçalhos Encaminhados do pacote Microsoft.AspNetCore.HttpOverrides. O middleware atualiza o Request.Scheme usando o cabeçalho X-Forwarded-Proto, de forma que URIs de redirecionamento e outras políticas de segurança funcionam corretamente.

Middlewares de Cabeçalhos Encaminhados devem ser executados antes de outros middlewares. Essa ordenação garantirá que o middleware conte com informações de cabeçalhos encaminhadas que podem consumir os valores de cabeçalho para processamento. Para executar o Middleware de Cabeçalhos Encaminhados após o diagnóstico e o middleware de tratamento de erros, consulte Ordem do Middleware de Cabeçalhos Encaminhados.

Invocar o método UseForwardedHeaders na parte superior de Program.cs antes de chamar outro middleware. Configure o middleware para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto:

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

app.UseAuthentication();

Se nenhum ForwardedHeadersOptions for especificado para o middleware, os cabeçalhos padrão para encaminhar serão None.

Os proxies em execução em endereços de loopback (127.0.0.0/8, [::1]), incluindo o endereço de host local padrão (127.0.0.1), são confiáveis por padrão. Se outros proxies ou redes confiáveis em que a organização trata solicitações entre a Internet e o servidor Web, adicione-os à lista de KnownProxies ou KnownNetworks com ForwardedHeadersOptions. O exemplo a seguir adiciona um servidor proxy confiável no endereço IP 10.0.0.100 ao Middleware de cabeçalhos encaminhados KnownProxies em Program.cs:

using System.Net;

var builder = WebApplication.CreateBuilder(args);

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

Para obter mais informações, veja Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Instalar o Nginx

Use apt-get para instalar o Nginx. O instalador cria um script de inicialização systemd que executa o Nginx como daemon na inicialização do sistema. Siga as instruções de instalação para o Ubuntu em Nginx: pacotes Debian/Ubuntu oficiais.

Observação

Se módulos Nginx opcionais forem exigidos, poderá haver necessidade de criar o Nginx da origem.

Já que Nginx foi instalado pela primeira vez, inicie-o explicitamente executando:

sudo service nginx start

Verifique se um navegador exibe a página de aterrissagem padrão do Nginx. A página de aterrissagem é acessível em http://<server_IP_address>/index.nginx-debian.html.

Configurar o Nginx

Para configurar o Nginx como um proxy inverso para encaminhar solicitações HTTP para o nosso aplicativo ASP.NET Core, modifique /etc/nginx/sites-available/default. Abra-o em um editor de texto arquivo e substitua o conteúdo pelo snippet mostrado abaixo:

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Se o aplicativo for um aplicativo SignalR ou Blazor Server, consulte Hospedagem e dimensionamento SignalR do ASP.NET Core e Hospedar e implantar aplicativos do ASP.NET Core do lado do servidorBlazor respectivamente para obter mais informações.

Quando nenhum server_name corresponde, o Nginx usa o servidor padrão. Se nenhum servidor padrão é definido, o primeiro servidor no arquivo de configuração é o servidor padrão. Como prática recomendada, adicione um servidor padrão específico que retorna um código de status 444 no arquivo de configuração. Um exemplo de configuração de servidor padrão é:

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

Com o servidor padrão e o arquivo de configuração anterior, o Nginx aceita tráfego público na porta 80 com um cabeçalho de host example.com ou *.example.com. Solicitações que não correspondam a esses hosts não serão encaminhadas para o Kestrel. O Nginx encaminha as solicitações correspondentes para o Kestrel em http://127.0.0.1:5000. Veja Como o nginx processa uma solicitação para obter mais informações. Para alterar o IP/porta do Kestrel, veja Kestrel: configuração de ponto de extremidade.

Aviso

Falha ao especificar uma diretiva server_name expõe seu aplicativo para vulnerabilidades de segurança. Associações de curinga de subdomínio (por exemplo, *.example.com) não oferecerão esse risco de segurança se você controlar o domínio pai completo (em vez de *.com, o qual é vulnerável). Para obter mais informações, consulte RFC 9110: Semântica HTTP (Seção 7.2: Host e :authority).

Quando a configuração Nginx é estabelecida, execute sudo nginx -t para verificar a sintaxe dos arquivos de configuração. Se o teste do arquivo de configuração for bem-sucedido, você poderá forçar o Nginx a acompanhar as alterações executando sudo nginx -s reload.

Para executar o aplicativo diretamente no servidor:

  1. Navegue até o diretório do aplicativo.
  2. Execute o aplicativo: dotnet <app_assembly.dll>, em que app_assembly.dll é o nome do arquivo do assembly do aplicativo.

Se o aplicativo for executado no servidor, mas não responder pela Internet, verifique o firewall do servidor e confirme se a porta 80 está aberta. Se você estiver usando uma VM do Azure Ubuntu, adicione uma regra NSG (Grupo de Segurança de Rede) que permite tráfego de entrada na porta 80. Não é necessário habilitar uma regra de saída da porta 80, uma vez que o tráfego de saída é concedido automaticamente quando a regra de entrada é habilitada.

Quando terminar de testar o aplicativo, desligue o aplicativo com Ctrl+C (Windows) ou +C (macOS) no prompt de comando.

Monitorar o aplicativo

O servidor agora está configurado para encaminhar solicitações feitas a http://<serveraddress>:80 ao aplicativo ASP.NET Core em execução no Kestrel em http://127.0.0.1:5000. No entanto, o Nginx não está configurado para gerenciar o processo do Kestrel. É possível usar o systemd para criar um arquivo de serviço para iniciar e monitorar o aplicativo Web subjacente. systemd é um sistema de inicialização que fornece muitos recursos avançados para iniciar, interromper e gerenciar processos.

Criar o arquivo de serviço

Crie o arquivo de definição de serviço:

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

O exemplo abaixo é um arquivo de serviço para o aplicativo:

[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

No exemplo anterior, o usuário que gerencia o serviço é especificado pela opção User. O usuário (www-data) deve existir e ter a propriedade adequada dos arquivos do aplicativo.

Use TimeoutStopSec para configurar a duração do tempo de espera para o aplicativo desligar depois de receber o sinal de interrupção inicial. Se o aplicativo não desligar nesse período, o SIGKILL será emitido para encerrá-lo. Forneça o valor como segundos sem unidade (por exemplo, 150), um valor de duração (por exemplo, 2min 30s) ou infinity para desabilitar o tempo limite. TimeoutStopSec assume como padrão o valor de DefaultTimeoutStopSec no arquivo de configuração do gerenciador (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). O tempo limite padrão para a maioria das distribuições é de 90 segundos.

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

O Linux tem um sistema de arquivos que diferencia maiúsculas de minúsculas. A configuração ASPNETCORE_ENVIRONMENT para Production resultar na pesquisa do arquivo de configuração appsettings.Production.json, não appsettings.production.json.

Alguns valores (por exemplo, cadeias de conexão de SQL) devem ser escapadas para que os provedores de configuração leiam as variáveis de ambiente. Use o seguinte comando para gerar um valor corretamente com caracteres de escape para uso no arquivo de configuração:

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

Separadores do tipo dois-pontos (:) não são compatíveis com nomes de variáveis de ambiente. Use um sublinhado duplo (__) no lugar de dois-pontos. O provedor de configuração de Variáveis de Ambiente converte caracteres de sublinhado duplo em dois-pontos quando as variáveis de ambiente são lidas na configuração. No exemplo a seguir, a chave de cadeia de conexão ConnectionStrings:DefaultConnection está definida no arquivo de definição de serviço como ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Salve o arquivo e habilite o serviço.

sudo systemctl enable kestrel-helloapp.service

Inicie o serviço e verifique se ele está em execução.

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

Com o proxy reverso configurado e o Kestrel gerenciado por meio de systemd, o aplicativo Web está totalmente configurado e pode ser acessado em um navegador no computador local em http://localhost. Ele também é acessível por meio de um computador remoto, bloqueando qualquer firewall que o possa estar bloqueando. Inspecionando os cabeçalhos de resposta, o cabeçalho Server mostra o aplicativo ASP.NET Core sendo servido pelo 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

Exibir logs

Já que o aplicativo Web que usa o Kestrel é gerenciado com systemd, todos os eventos e os processos são registrados em um diário centralizado. No entanto, esse diário contém todas as entradas para todos os serviços e processos gerenciados pelo systemd. Para exibir os itens específicos de kestrel-helloapp.service, use o seguinte comando:

sudo journalctl -fu kestrel-helloapp.service

Para obter mais filtragem, opções de hora como --since today, --until 1 hour ago ou uma combinação delas, pode reduzir o número de entradas retornadas.

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

Proteção de dados

A pilha de proteção de dados do ASP.NET Core é usada por vários middlewares do ASP.NET Core, incluindo o middleware de autenticação (por exemplo, o middleware de cookie) e as proteções de CSRF (solicitação intersite forjada). Mesmo se as APIs de Proteção de Dados não forem chamadas pelo código do usuário, a proteção de dados deverá ser configurada para criar um repositório de chaves criptográfico persistente. Se a proteção de dados não estiver configurada, as chaves serão mantidas na memória e descartadas quando o aplicativo for reiniciado.

Se o token de autenticação for armazenado na memória quando o aplicativo for reiniciado:

  • Todos os tokens de autenticação baseados em cookie serão invalidados.
  • Os usuários precisam entrar novamente na próxima solicitação deles.
  • Todos os dados protegidos com o token de autenticação não poderão mais ser descriptografados. Isso pode incluir os tokens CSRF e cookies TempData do MVC do ASP.NET Core.

Para configurar a proteção de dados de modo que ela mantenha e criptografe o token de autenticação, consulte:

Campos de cabeçalho da solicitação muito grandes

As configurações padrão do servidor proxy normalmente limitam os campos de cabeçalho de solicitação a 4 K ou 8 K, dependendo da plataforma. Um aplicativo pode exigir campos mais longos que o padrão (por exemplo, aplicativos que usam o Azure Active Directory). Se forem necessários campos mais longos, as configurações padrão do servidor proxy exigirão ajuste. Os valores a serem aplicados dependem do cenário. Para obter mais informações, confira a documentação do servidor.

Aviso

Não aumente os valores padrão de buffers de proxy a menos que necessário. Aumentar esses valores aumenta o risco de estouro de buffer (estouro) e ataques de DoS (negação de serviço) por usuários mal-intencionados.

Proteger o aplicativo

Habilitar AppArmor

O LSM (Módulos de Segurança do Linux) é uma estrutura que é parte do kernel do Linux desde o Linux 2.6. O LSM dá suporte a diferentes implementações de módulos de segurança. O AppArmor é um LSM que implementa um sistema de controle de acesso obrigatório que permite restringir o programa a um conjunto limitado de recursos. Verifique se o AppArmor está habilitado e configurado corretamente.

Configurar o firewall

Feche todas as portas externas que não estão em uso. Firewall descomplicado (ufw) fornece um front-end para iptables fornecendo uma CLI para configurar o firewall.

Aviso

Um firewall impedirá o acesso a todo o sistema se não ele estiver configurado corretamente. Se houver falha ao especificar a porta SSH correta, você será bloqueado do sistema se estiver usando o SSH para se conectar a ele. A porta padrão é a 22. Para obter mais informações, consulte a introdução ao ufw e o manual.

Instale o ufw e configure-o para permitir o tráfego em todas as portas necessárias.

sudo apt-get install ufw

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

sudo ufw enable

Proteger o Nginx

Alterar o nome da resposta do Nginx

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

Configurar opções

Configure o servidor com os módulos adicionais necessários. Considere usar um firewall de aplicativo Web como ModSecurity para fortalecer o aplicativo.

Configuração de HTTPS

Configurar o aplicativo para conexões seguras (HTTPS) locais

O comando dotnet run usa o arquivo Properties/launchSettings.json do aplicativo, que configura o aplicativo para escutar nas URLs fornecidas pela propriedade applicationUrl. Por exemplo, https://localhost:5001;http://localhost:5000.

Configure o aplicativo para usar um certificado no desenvolvimento para o comando dotnet run ou no ambiente de desenvolvimento (F5 ou Ctrl+F5 no Visual Studio Code) usando uma das seguintes abordagens:

Configurar o proxy reverso para conexões de cliente seguras (HTTPS)

Aviso

A configuração de segurança nesta seção é uma configuração geral a ser usada como ponto de partida para personalização adicional. Não é possível fornecer suporte para ferramentas, servidores e sistemas operacionais de terceiros. Use a configuração nesta seção por sua conta e risco. Para obter mais informações, acesse os seguintes recursos:

  • Configure o servidor para escutar tráfego HTTPS na porta 443 especificando um certificado válido emitido por uma AC (autoridade de certificação) confiável.

  • Aprimore a segurança, empregando algumas das práticas descritas no arquivo /etc/nginx/nginx.conf a seguir.

  • O exemplo a seguir não configura o servidor para redirecionar solicitações inseguras. É recomendável usar o Middleware de Redirecionamento HTTPS. Para obter mais informações, confira Impor HTTPS no ASP.NET Core.

    Observação

    Para ambientes de desenvolvimento em que a configuração do servidor manipula o redirecionamento seguro em vez do Middleware de Redirecionamento HTTPS, recomendamos usar redirecionamentos temporários (302) em vez de permanentes (301). O cache de link pode causar um comportamento instável em ambientes de desenvolvimento.

  • A adição de um cabeçalho Strict-Transport-Security (HSTS) garante que todas as próximas solicitações feitas pelo cliente sejam por HTTPS. Para obter diretrizes sobre como definir o Strict-Transport-Security cabeçalho, confira Impor HTTPS em ASP.NET Core.

  • Se o HTTPS for desabilitado no futuro, use uma das seguintes abordagens:

    • Não adicione o cabeçalho HSTS.
    • Escolha um valor max-age curto.

Adicione o arquivo de configuração /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;

Substituir o conteúdo do arquivo de configuração /etc/nginx/nginx.conf pelo arquivo a seguir. O exemplo contém ambas as seções http e server em um arquivo de configuração.

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

Observação

Os aplicativos Blazor WebAssembly exigem um valor de parâmetro burst maior para acomodar o maior número de solicitações feitas por um aplicativo. Para obter mais informações, confira Hospedar e implantar Blazor WebAssembly do ASP.NET Core.

Observação

O exemplo anterior desabilita a associação do protocolo OCSP. Se habilitado, confirme se o certificado dá suporte ao recurso. Para obter mais informações e diretrizes sobre como habilitar o OCSP, confira as seguintes propriedades no artigo Módulo ngx_http_ssl_module (documentação do Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Proteger o Nginx de clickjacking

Clickjacking, também conhecido como um ataque por inferência na interface do usuário, é um ataque mal-intencionado em que o visitante do site é levado a clicar em um link ou botão em uma página diferente daquela que está visitando atualmente. Use X-FRAME-OPTIONS para proteger o site.

Para atenuar ataques de clickjacking:

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Adicione a linha: add_header X-Frame-Options "SAMEORIGIN";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Detecção de tipo MIME

Esse cabeçalho evita que a maioria dos navegadores faça detecção MIME de uma resposta distante do tipo de conteúdo declarado, visto que o cabeçalho instrui o navegador para não substituir o tipo de conteúdo de resposta. Com a opção nosniff, se o servidor informa que o conteúdo é text/html, o navegador renderiza-a como text/html.

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Adicione a linha: add_header X-Content-Type-Options "nosniff";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Sugestões adicionais do Nginx

Depois de atualizar a estrutura compartilhada no servidor, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Recursos adicionais

Este guia explica como configurar um ambiente ASP.NET Core pronto para produção em um servidor Ubuntu 16.04. Essas instruções provavelmente funcionarão com versões mais recentes do Ubuntu, mas as instruções não foram testadas com versões mais recentes.

Para saber mais sobre outras distribuições do Linux compatíveis com o ASP.NET Core, veja Pré-requisitos para o .NET Core no Linux.

Observação

No caso do Ubuntu 14.04, supervisord é recomendado como uma solução para monitorar o processo do Kestrel. O systemd não está disponível no Ubuntu 14.04. Para obter instruções Ubuntu 14.04, veja a versão anterior deste tópico.

Este guia:

  • Coloca um aplicativo ASP.NET Core existente em um servidor proxy reverso.
  • Configura o servidor proxy reverso para encaminhar solicitações ao servidor Web do Kestrel.
  • Assegura que o aplicativo Web seja executado na inicialização como um daemon.
  • Configura uma ferramenta de gerenciamento de processo para ajudar a reiniciar o aplicativo Web.

Pré-requisitos

  • Acesso a um servidor Ubuntu 16.04 com uma conta de usuário padrão com privilégio sudo.
  • A última versão não prévia do runtime do .NET instalada no servidor.
  • Um aplicativo ASP.NET Core existente.

A qualquer momento no futuro, depois de atualizar a estrutura compartilhada, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Publicar e copiar o aplicativo

Configurar o aplicativo para um implantação dependente de estrutura.

Se o aplicativo for executado localmente no Ambiente de desenvolvimento e não estiver configurado pelo servidor para fazer conexões HTTPS seguras, adote uma das seguintes abordagens:

  • Configure o aplicativo para lidar com conexões seguras locais. Para obter mais informações, veja a seção Configuração de HTTPS.

  • Configure o aplicativo para ser executado no ponto de extremidade inseguro:

    • Desativar o middleware de redirecionamento HTTPS no ambiente de desenvolvimento (Program.cs):

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

      Para obter mais informações, confira Usar vários ambientes no ASP.NET Core.

    • Remova https://localhost:5001 (se houver) da propriedade applicationUrl no arquivo Properties/launchSettings.json.

Para obter mais informações sobre a configuração por ambiente, consulte Use vários ambientes no ASP.NET Core.

Execute dotnet publish do ambiente de desenvolvimento para empacotar um aplicativo em um diretório (por exemplo, bin/Release/{TARGET FRAMEWORK MONIKER}/publish, onde o espaço reservado {TARGET FRAMEWORK MONIKER} é o TFM (Moniker da Estrutura de Destino)) que pode ser executado no servidor:

dotnet publish --configuration Release

O aplicativo também poderá ser publicado como uma implantação autossuficiente se você preferir não manter o runtime do .NET Core no servidor.

Copie o aplicativo ASP.NET Core para o servidor usando uma ferramenta que se integre ao fluxo de trabalho da organização (por exemplo, SCP, SFTP). É comum localizar aplicativos Web no diretório var (por exemplo, var/www/helloapp).

Observação

Em um cenário de implantação de produção, um fluxo de trabalho de integração contínua faz o trabalho de publicar o aplicativo e copiar os ativos para o servidor.

Teste o aplicativo:

  1. Na linha de comando, execute o aplicativo: dotnet <app_assembly>.dll.
  2. Em um navegador, vá para http://<serveraddress>:<port> para verificar se o aplicativo funciona no Linux localmente.

Configurar um servidor proxy reverso

Um proxy reverso é uma configuração comum para atender a aplicativos Web dinâmicos. Um proxy reverso encerra a solicitação HTTP e a encaminha para o aplicativo ASP.NET Core.

Usar um servidor proxy reverso

O Kestrel é excelente para servir conteúdo dinâmico do ASP.NET Core. No entanto, as funcionalidades de servidor Web não têm tantos recursos quanto servidores como IIS, Apache ou Nginx. Um servidor proxy reverso pode descarregar trabalho como servir conteúdo estático, armazenar solicitações em cache, compactar solicitações e terminar HTTPS do servidor HTTP. Um servidor proxy reverso pode residir em um computador dedicado ou pode ser implantado junto com um servidor HTTP.

Para os fins deste guia, uma única instância de Nginx é usada. Ela é executada no mesmo servidor, junto com o servidor HTTP. Com base nos requisitos, uma configuração diferente pode ser escolhida.

Já que as solicitações são encaminhadas pelo proxy reverso, use o Middleware de Cabeçalhos Encaminhados do pacote Microsoft.AspNetCore.HttpOverrides. O middleware atualiza o Request.Scheme usando o cabeçalho X-Forwarded-Proto, de forma que URIs de redirecionamento e outras políticas de segurança funcionam corretamente.

Middlewares de Cabeçalhos Encaminhados devem ser executados antes de outros middlewares. Essa ordenação garantirá que o middleware conte com informações de cabeçalhos encaminhadas que podem consumir os valores de cabeçalho para processamento. Para executar o Middleware de Cabeçalhos Encaminhados após o diagnóstico e o middleware de tratamento de erros, consulte Ordem do Middleware de Cabeçalhos Encaminhados.

Invocar o método UseForwardedHeaders na parte superior de Startup.Configure antes de chamar outro middleware. Configure o middleware para encaminhar os cabeçalhos X-Forwarded-For e X-Forwarded-Proto:

using Microsoft.AspNetCore.HttpOverrides;

...

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

app.UseAuthentication();

Se nenhum ForwardedHeadersOptions for especificado para o middleware, os cabeçalhos padrão para encaminhar serão None.

Os proxies em execução em endereços de loopback (127.0.0.0/8, [::1]), incluindo o endereço de host local padrão (127.0.0.1), são confiáveis por padrão. Se outros proxies ou redes confiáveis em que a organização trata solicitações entre a Internet e o servidor Web, adicione-os à lista de KnownProxies ou KnownNetworks com ForwardedHeadersOptions. O exemplo a seguir adiciona um servidor proxy confiável no endereço IP 10.0.0.100 ao Middleware de cabeçalhos encaminhados KnownProxies em Startup.ConfigureServices:

using System.Net;

...

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

Para obter mais informações, veja Configurar o ASP.NET Core para trabalhar com servidores proxy e balanceadores de carga.

Instalar o Nginx

Use apt-get para instalar o Nginx. O instalador cria um script de inicialização systemd que executa o Nginx como daemon na inicialização do sistema. Siga as instruções de instalação para o Ubuntu em Nginx: pacotes Debian/Ubuntu oficiais.

Observação

Se módulos Nginx opcionais forem exigidos, poderá haver necessidade de criar o Nginx da origem.

Já que Nginx foi instalado pela primeira vez, inicie-o explicitamente executando:

sudo service nginx start

Verifique se um navegador exibe a página de aterrissagem padrão do Nginx. A página de aterrissagem é acessível em http://<server_IP_address>/index.nginx-debian.html.

Configurar o Nginx

Para configurar o Nginx como um proxy inverso para encaminhar solicitações HTTP para o nosso aplicativo ASP.NET Core, modifique /etc/nginx/sites-available/default. Abra-o em um editor de texto arquivo e substitua o conteúdo pelo snippet mostrado abaixo:

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Se o aplicativo for um aplicativo SignalR ou Blazor Server, consulte Hospedagem e dimensionamento SignalR do ASP.NET Core e Hospedar e implantar aplicativos do ASP.NET Core do lado do servidorBlazor respectivamente para obter mais informações.

Quando nenhum server_name corresponde, o Nginx usa o servidor padrão. Se nenhum servidor padrão é definido, o primeiro servidor no arquivo de configuração é o servidor padrão. Como prática recomendada, adicione um servidor padrão específico que retorna um código de status 444 no arquivo de configuração. Um exemplo de configuração de servidor padrão é:

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

Com o servidor padrão e o arquivo de configuração anterior, o Nginx aceita tráfego público na porta 80 com um cabeçalho de host example.com ou *.example.com. Solicitações que não correspondam a esses hosts não serão encaminhadas para o Kestrel. O Nginx encaminha as solicitações correspondentes para o Kestrel em http://127.0.0.1:5000. Veja Como o nginx processa uma solicitação para obter mais informações. Para alterar o IP/porta do Kestrel, veja Kestrel: configuração de ponto de extremidade.

Aviso

Falha ao especificar uma diretiva server_name expõe seu aplicativo para vulnerabilidades de segurança. Associações de curinga de subdomínio (por exemplo, *.example.com) não oferecerão esse risco de segurança se você controlar o domínio pai completo (em vez de *.com, o qual é vulnerável). Para obter mais informações, consulte RFC 9110: Semântica HTTP (Seção 7.2: Host e :authority).

Quando a configuração Nginx é estabelecida, execute sudo nginx -t para verificar a sintaxe dos arquivos de configuração. Se o teste do arquivo de configuração for bem-sucedido, você poderá forçar o Nginx a acompanhar as alterações executando sudo nginx -s reload.

Para executar o aplicativo diretamente no servidor:

  1. Navegue até o diretório do aplicativo.
  2. Execute o aplicativo: dotnet <app_assembly.dll>, em que app_assembly.dll é o nome do arquivo do assembly do aplicativo.

Se o aplicativo for executado no servidor, mas não responder pela Internet, verifique o firewall do servidor e confirme se a porta 80 está aberta. Se você estiver usando uma VM do Azure Ubuntu, adicione uma regra NSG (Grupo de Segurança de Rede) que permite tráfego de entrada na porta 80. Não é necessário habilitar uma regra de saída da porta 80, uma vez que o tráfego de saída é concedido automaticamente quando a regra de entrada é habilitada.

Quando terminar de testar o aplicativo, desligue o aplicativo com Ctrl+C (Windows) ou +C (macOS) no prompt de comando.

Monitorar o aplicativo

O servidor agora está configurado para encaminhar solicitações feitas a http://<serveraddress>:80 ao aplicativo ASP.NET Core em execução no Kestrel em http://127.0.0.1:5000. No entanto, o Nginx não está configurado para gerenciar o processo do Kestrel. É possível usar o systemd para criar um arquivo de serviço para iniciar e monitorar o aplicativo Web subjacente. systemd é um sistema de inicialização que fornece muitos recursos avançados para iniciar, interromper e gerenciar processos.

Criar o arquivo de serviço

Crie o arquivo de definição de serviço:

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

O exemplo abaixo é um arquivo de serviço para o aplicativo:

[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

No exemplo anterior, o usuário que gerencia o serviço é especificado pela opção User. O usuário (www-data) deve existir e ter a propriedade adequada dos arquivos do aplicativo.

Use TimeoutStopSec para configurar a duração do tempo de espera para o aplicativo desligar depois de receber o sinal de interrupção inicial. Se o aplicativo não desligar nesse período, o SIGKILL será emitido para encerrá-lo. Forneça o valor como segundos sem unidade (por exemplo, 150), um valor de duração (por exemplo, 2min 30s) ou infinity para desabilitar o tempo limite. TimeoutStopSec assume como padrão o valor de DefaultTimeoutStopSec no arquivo de configuração do gerenciador (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d). O tempo limite padrão para a maioria das distribuições é de 90 segundos.

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

O Linux tem um sistema de arquivos que diferencia maiúsculas de minúsculas. A configuração ASPNETCORE_ENVIRONMENT para Production resultar na pesquisa do arquivo de configuração appsettings.Production.json, não appsettings.production.json.

Alguns valores (por exemplo, cadeias de conexão de SQL) devem ser escapadas para que os provedores de configuração leiam as variáveis de ambiente. Use o seguinte comando para gerar um valor corretamente com caracteres de escape para uso no arquivo de configuração:

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

Separadores do tipo dois-pontos (:) não são compatíveis com nomes de variáveis de ambiente. Use um sublinhado duplo (__) no lugar de dois-pontos. O provedor de configuração de Variáveis de Ambiente converte caracteres de sublinhado duplo em dois-pontos quando as variáveis de ambiente são lidas na configuração. No exemplo a seguir, a chave de cadeia de conexão ConnectionStrings:DefaultConnection está definida no arquivo de definição de serviço como ConnectionStrings__DefaultConnection:

Environment=ConnectionStrings__DefaultConnection={Connection String}

Salve o arquivo e habilite o serviço.

sudo systemctl enable kestrel-helloapp.service

Inicie o serviço e verifique se ele está em execução.

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

Com o proxy reverso configurado e o Kestrel gerenciado por meio de systemd, o aplicativo Web está totalmente configurado e pode ser acessado em um navegador no computador local em http://localhost. Ele também é acessível por meio de um computador remoto, bloqueando qualquer firewall que o possa estar bloqueando. Inspecionando os cabeçalhos de resposta, o cabeçalho Server mostra o aplicativo ASP.NET Core sendo servido pelo 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

Exibir logs

Já que o aplicativo Web que usa o Kestrel é gerenciado com systemd, todos os eventos e os processos são registrados em um diário centralizado. No entanto, esse diário contém todas as entradas para todos os serviços e processos gerenciados pelo systemd. Para exibir os itens específicos de kestrel-helloapp.service, use o seguinte comando:

sudo journalctl -fu kestrel-helloapp.service

Para obter mais filtragem, opções de hora como --since today, --until 1 hour ago ou uma combinação delas, pode reduzir o número de entradas retornadas.

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

Proteção de dados

A pilha de proteção de dados do ASP.NET Core é usada por vários middlewares do ASP.NET Core, incluindo o middleware de autenticação (por exemplo, o middleware de cookie) e as proteções de CSRF (solicitação intersite forjada). Mesmo se as APIs de Proteção de Dados não forem chamadas pelo código do usuário, a proteção de dados deverá ser configurada para criar um repositório de chaves criptográfico persistente. Se a proteção de dados não estiver configurada, as chaves serão mantidas na memória e descartadas quando o aplicativo for reiniciado.

Se o token de autenticação for armazenado na memória quando o aplicativo for reiniciado:

  • Todos os tokens de autenticação baseados em cookie serão invalidados.
  • Os usuários precisam entrar novamente na próxima solicitação deles.
  • Todos os dados protegidos com o token de autenticação não poderão mais ser descriptografados. Isso pode incluir os tokens CSRF e cookies TempData do MVC do ASP.NET Core.

Para configurar a proteção de dados de modo que ela mantenha e criptografe o token de autenticação, consulte:

Campos de cabeçalho da solicitação muito grandes

As configurações padrão do servidor proxy normalmente limitam os campos de cabeçalho de solicitação a 4 K ou 8 K, dependendo da plataforma. Um aplicativo pode exigir campos mais longos que o padrão (por exemplo, aplicativos que usam o Azure Active Directory). Se forem necessários campos mais longos, as configurações padrão do servidor proxy exigirão ajuste. Os valores a serem aplicados dependem do cenário. Para obter mais informações, confira a documentação do servidor.

Aviso

Não aumente os valores padrão de buffers de proxy a menos que necessário. Aumentar esses valores aumenta o risco de estouro de buffer (estouro) e ataques de DoS (negação de serviço) por usuários mal-intencionados.

Proteger o aplicativo

Habilitar AppArmor

O LSM (Módulos de Segurança do Linux) é uma estrutura que é parte do kernel do Linux desde o Linux 2.6. O LSM dá suporte a diferentes implementações de módulos de segurança. O AppArmor é um LSM que implementa um sistema de controle de acesso obrigatório que permite restringir o programa a um conjunto limitado de recursos. Verifique se o AppArmor está habilitado e configurado corretamente.

Configurar o firewall

Feche todas as portas externas que não estão em uso. Firewall descomplicado (ufw) fornece um front-end para iptables fornecendo uma CLI para configurar o firewall.

Aviso

Um firewall impedirá o acesso a todo o sistema se não ele estiver configurado corretamente. Se houver falha ao especificar a porta SSH correta, você será bloqueado do sistema se estiver usando o SSH para se conectar a ele. A porta padrão é a 22. Para obter mais informações, consulte a introdução ao ufw e o manual.

Instale o ufw e configure-o para permitir o tráfego em todas as portas necessárias.

sudo apt-get install ufw

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

sudo ufw enable

Proteger o Nginx

Alterar o nome da resposta do Nginx

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

Configurar opções

Configure o servidor com os módulos adicionais necessários. Considere usar um firewall de aplicativo Web como ModSecurity para fortalecer o aplicativo.

Configuração de HTTPS

Configurar o aplicativo para conexões seguras (HTTPS) locais

O comando dotnet run usa o arquivo Properties/launchSettings.json do aplicativo, que configura o aplicativo para escutar nas URLs fornecidas pela propriedade applicationUrl. Por exemplo, https://localhost:5001;http://localhost:5000.

Configure o aplicativo para usar um certificado no desenvolvimento para o comando dotnet run ou no ambiente de desenvolvimento (F5 ou Ctrl+F5 no Visual Studio Code) usando uma das seguintes abordagens:

Configurar o proxy reverso para conexões de cliente seguras (HTTPS)

Aviso

A configuração de segurança nesta seção é uma configuração geral a ser usada como ponto de partida para personalização adicional. Não é possível fornecer suporte para ferramentas, servidores e sistemas operacionais de terceiros. Use a configuração nesta seção por sua conta e risco. Para obter mais informações, acesse os seguintes recursos:

  • Configure o servidor para escutar tráfego HTTPS na porta 443 especificando um certificado válido emitido por uma AC (autoridade de certificação) confiável.

  • Aprimore a segurança, empregando algumas das práticas descritas no arquivo /etc/nginx/nginx.conf a seguir.

  • O exemplo a seguir não configura o servidor para redirecionar solicitações inseguras. É recomendável usar o Middleware de Redirecionamento HTTPS. Para obter mais informações, confira Impor HTTPS no ASP.NET Core.

    Observação

    Para ambientes de desenvolvimento em que a configuração do servidor manipula o redirecionamento seguro em vez do Middleware de Redirecionamento HTTPS, recomendamos usar redirecionamentos temporários (302) em vez de permanentes (301). O cache de link pode causar um comportamento instável em ambientes de desenvolvimento.

  • A adição de um cabeçalho Strict-Transport-Security (HSTS) garante que todas as próximas solicitações feitas pelo cliente sejam por HTTPS. Para obter diretrizes sobre como definir o Strict-Transport-Security cabeçalho, confira Impor HTTPS em ASP.NET Core.

  • Se o HTTPS for desabilitado no futuro, use uma das seguintes abordagens:

    • Não adicione o cabeçalho HSTS.
    • Escolha um valor max-age curto.

Adicione o arquivo de configuração /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;

Substituir o conteúdo do arquivo de configuração /etc/nginx/nginx.conf pelo arquivo a seguir. O exemplo contém ambas as seções http e server em um arquivo de configuração.

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

Observação

Os aplicativos Blazor WebAssembly exigem um valor de parâmetro burst maior para acomodar o maior número de solicitações feitas por um aplicativo. Para obter mais informações, confira Hospedar e implantar Blazor WebAssembly do ASP.NET Core.

Observação

O exemplo anterior desabilita a associação do protocolo OCSP. Se habilitado, confirme se o certificado dá suporte ao recurso. Para obter mais informações e diretrizes sobre como habilitar o OCSP, confira as seguintes propriedades no artigo Módulo ngx_http_ssl_module (documentação do Nginx):

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify

Proteger o Nginx de clickjacking

Clickjacking, também conhecido como um ataque por inferência na interface do usuário, é um ataque mal-intencionado em que o visitante do site é levado a clicar em um link ou botão em uma página diferente daquela que está visitando atualmente. Use X-FRAME-OPTIONS para proteger o site.

Para atenuar ataques de clickjacking:

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Adicione a linha: add_header X-Frame-Options "SAMEORIGIN";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Detecção de tipo MIME

Esse cabeçalho evita que a maioria dos navegadores faça detecção MIME de uma resposta distante do tipo de conteúdo declarado, visto que o cabeçalho instrui o navegador para não substituir o tipo de conteúdo de resposta. Com a opção nosniff, se o servidor informa que o conteúdo é text/html, o navegador renderiza-a como text/html.

  1. Edite o arquivo nginx.conf:

    sudo nano /etc/nginx/nginx.conf
    

    Adicione a linha: add_header X-Content-Type-Options "nosniff";

  2. Salve o arquivo.

  3. Reinicie o Nginx.

Sugestões adicionais do Nginx

Depois de atualizar a estrutura compartilhada no servidor, reinicie os aplicativos ASP.NET Core hospedados pelo servidor.

Recursos adicionais