点赞
评论
收藏
分享
举报
使用Nginx在Linux上托管ASP.NET Core
发表于2021-04-06 09:39

浏览 805

本指南介绍了在Ubuntu 16.04服务器上设置可用于生产环境的ASP.NET Core环境。这些说明可能适用于较新版本的Ubuntu,但尚未针对较新版本进行过测试。

有关ASP.NET Core支持的其他Linux发行版的信息,请参见Linux上.NET Core的先决条件

笔记

对于Ubuntu 14.04,supervisord建议将其作为监视Kestrel进程的解决方案。systemd在Ubuntu 14.04上不可用。有关Ubuntu 14.04的说明,请参见本主题先前版本


指南:

  • 将现有的ASP.NET Core应用程序放置在反向代理服务器后面。
  • 设置反向代理服务器以将请求转发到Kestrel Web服务器。
  • 确保Web应用程序在启动时作为守护程序运行。
  • 配置流程管理工具以帮助重新启动Web应用程序。


先决条件

  • 使用具有sudo特权的标准用户帐户访问Ubuntu 16.04服务器。
  • 服务器上安装了最新的非预览版.NET运行时
  • 现有的ASP.NET Core应用程序。

升级共享框架后,在将来的任何时候,重新启动服务器托管的ASP.NET Core应用程序。


通过应用发布和复制

配置应用程序以进行框架相关的部署

如果该应用程序在本地运行,并且未配置为建立安全连接(HTTPS),请采用以下两种方法之一:

  • 配置应用程序以处理安全的本地连接。有关更多信息,请参见HTTPS配置部分。
  • https://localhost:5001从文件的applicationUrl属性中删除(如果存在)Properties/launchSettings.json

从开发环境运行dotnet publish,以将应用程序打包到可以在服务器上运行的目录(例如,bin/Release/{TARGET FRAMEWORK MONIKER}/publish占位符{TARGET FRAMEWORK MONIKER}是Target Framework Moniker / TFM)。


.NET Core CLI
dotnet publish --configuration Release

如果您不想在服务器上维护.NET Core运行时,则该应用程序还可以作为独立的部署发布。

使用集成到组织工作流中的工具(例如SCPSFTP)将ASP.NET Core应用程序复制到服务器。通常在var目录下找到Web应用程序(例如var/www/helloapp)。

 笔记

在生产部署方案下,持续集成工作流完成发布应用程序并将资产复制到服务器的工作。
测试应用程序:
  1. 从命令行运行应用程序:dotnet <app_assembly>.dll
  1. 在浏览器中,导航以http://<serveraddress>:<port>确认该应用程序可在本地Linux上运行。


配置反向代理服务器

反向代理是用于提供动态Web应用程序的常用设置。反向代理会终止HTTP请求,并将其转发到ASP.NET Core应用。

使用反向代理服务器

Kestrel非常适合从ASP.NET Core提供动态内容。但是,Web服务功能不像IIS,Apache或Nginx这样的服务器具有丰富的功能。反向代理服务器可以从HTTP服务器上卸载诸如提供静态内容,缓存请求,压缩请求以及HTTPS终止之类的工作。反向代理服务器可以驻留在专用计算机上,也可以与HTTP服务器一起部署。

为了本指南的目的,使用了Nginx的单个实例。它与HTTP服务器一起在同一服务器上运行。根据要求,可以选择其他设置。

由于请求是通过反向代理转发的,因此请使用程序包中的“转发的头中间件” Microsoft.AspNetCore.HttpOverrides。中间件Request.Scheme使用X-Forwarded-Proto标头更新,以便重定向URI和其他安全策略正常工作。

转发的报头中间件应在其他中间件之前运行。此排序确保依赖于转发的标头信息的中间件可以使用标头值进行处理。要在诊断和错误处理中间件之后运行转发的头中间件,请参阅转发的头中间件顺序

在调用其他中间件之前,请先调用顶部的UseForwardedHeaders方法Startup.Configure。配置中间件以转发X-Forwarded-ForX-Forwarded-Proto标头:

C#
using Microsoft.AspNetCore.HttpOverrides;

...

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

app.UseAuthentication();

如果未向中间件指定ForwardedHeadersOptions,则要转发的默认头为None

在环回地址(运行代理127.0.0.0/8[::1]),包括标准的本地主机地址(127.0.0.1),默认情况下信任。如果组织中的其他受信任代理或网络处理Internet和Web服务器之间的请求,请将其添加到带有ForwardedHeadersOptionsKnownProxiesKnownNetworks列表中。下面的示例将IP地址为10.0.0.100的受信任代理服务器添加到位于中的Forwarded Headers Middleware中:KnownProxiesStartup.ConfigureServices

C#
using System.Net;

...

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

有关更多信息,请参见配置ASP.NET Core与代理服务器和负载平衡器一起使用


安装Nginx

使用apt-get安装Nginx的。安装程序将创建一个systemd初始化脚本,该脚本在系统启动时作为守护程序运行Nginx。按照Nginx上Ubuntu的安装说明进行操作:Debian / Ubuntu官方软件包

 笔记

如果需要可选的Nginx模块,则可能需要从源代码构建Nginx。

自从首次安装Nginx以来,请通过运行以下命令显式启动它:

重击
sudo service nginx start

确认浏览器显示Nginx的默认登录页面。到达页面位于http://<server_IP_address>/index.nginx-debian.html


配置Nginx

要将Nginx配置为将HTTP请求转发到ASP.NET Core应用程序的反向代理,请修改/etc/nginx/sites-available/default。在文本编辑器中将其打开,然后将内容替换为以下片段:

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

如果该应用是SignalR或Blazor Server应用,请参阅ASP.NET Core SignalR生产托管和扩展以及分别托管和部署ASP.NET Core Blazor服务器以获取更多信息。

如果没有server_name匹配项,则Nginx使用默认服务器。如果未定义默认服务器,则配置文件中的第一台服务器是默认服务器。最佳做法是,添加一个特定的默认服务器,该服务器在配置文件中返回状态代码444。默认服务器配置示例为:

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

使用前面的配置文件和默认服务器,Nginx在主机头为example.com或的端口80上接受公共流量*.example.com。与这些主机不匹配的请求将不会转发到Kestrel。Nginx将匹配请求转发到位于的Kestrel http://127.0.0.1:5000。有关更多信息,请参见nginx如何处理请求。要更改Kestrel的IP /端口,请参阅Kestrel:端点配置


 警告

未指定正确的server_name指令会使您的应用暴露于安全漏洞。*.example.com如果您控制整个父域(相对于*.com易受攻击的),则子域通配符绑定(例如,)不会带来此安全风险。有关更多信息,请参见rfc7230第5.4节

一旦建立了Nginx配置,请运行sudo nginx -t以验证配置文件的语法。如果配置文件测试成功,则通过运行强制Nginx接收更改sudo nginx -s reload

要在服务器上直接运行该应用程序,请执行以下操作:

  1. 导航到应用程序的目录。
  2. 运行应用程序:dotnet <app_assembly.dll>,其中app_assembly.dll是应用程序的程序集文件名。

如果该应用程序在服务器上运行,但无法通过Internet响应,请检查服务器的防火墙并确认端口80已打开。如果使用Azure Ubuntu VM,请添加网络安全组(NSG)规则,以启用入站端口80流量。无需启用出站端口80规则,因为在启用入站规则时会自动授予出站流量。

测试完应用程序后,在命令提示符下使用Ctrl+关闭应用程序C


监控应用

服务器设置为将发出的请求转发到http://<serveraddress>:80在Kestrel上运行的ASP.NET Core应用http://127.0.0.1:5000。但是,未设置Nginx来管理Kestrel进程。systemd可用于创建服务文件以启动和监视基础Web应用程序。systemd是一个初始化系统,它提供了许多用于启动,停止和管理进程的强大功能。


创建服务文件

创建服务定义文件:

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

以下示例是该应用程序的服务文件:

伊尼
[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

在前面的示例中,该User选项指定了管理服务的用户。用户(www-data)必须存在并且对应用程序文件拥有适当的所有权。

使用TimeoutStopSec配置的持续时间,以等待应用程序关闭它接收到的初始中断信号之后。如果该应用程序在此期间没有关闭,则会发出SIGKILL终止该应用程序。将值提供为无单位秒(例如150),时间跨度值(例如2min 30s)或infinity禁用超时。TimeoutStopSec默认的值DefaultTimeoutStopSec的管理器配置文件中(systemd-system.confsystem.conf.dsystemd-user.confuser.conf.d)。大多数发行版的默认超时为90秒。

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

Linux具有区分大小写的文件系统。设置ASPNETCORE_ENVIRONMENT为会Production导致搜索配置文件appsettings.Production.json,而不是appsettings.production.json

必须使某些值(例如SQL连接字符串)转义,以便配置提供程序读取环境变量。使用以下命令来生成正确的转义值,以供在配置文件中使用:

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

:环境变量名称不支持冒号()分隔符。使用双下划线(__)代替冒号。将环境变量读入配置时,环境变量配置提供程序会将双下划线转换为冒号。在下面的示例中,将连接字符串键ConnectionStrings:DefaultConnection设置为服务定义文件ConnectionStrings__DefaultConnection

Environment=ConnectionStrings__DefaultConnection={Connection String}

保存文件并启用服务。

重击
sudo systemctl enable kestrel-helloapp.service

启动服务,并验证它正在运行。

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

配置反向代理并管理Kestrel后systemd,Web应用程序已完全配置,可以从本地计算机上的浏览器(位于)进行访问http://localhost。也可以从远程计算机上访问它,除非有任何可能阻止的防火墙。检查响应标头,Server标头显示Kestrel正在提供的ASP.NET Core应用程序。

文本
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

查看日志

由于使用Kestrel的Web应用程序是通过进行管理的systemd,因此所有事件和过程都将记录到集中式日志中。但是,此日志包含由管理的所有服务和流程的所有条目systemd。要查看kestrel-helloapp.service-specific项目,请使用以下命令:

重击
sudo journalctl -fu kestrel-helloapp.service

为了进一步滤波,时间选项,例如--since today--until 1 hour ago,或这些的组合可以降低返回的条目的数量。

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

ASP.NET核心数据保护堆是由几个ASP.NET芯中使用中间件,包括验证中间件(例如,饼干中间件)和跨站请求伪造(CSRF)保护。即使用户代码未调用数据保护API,也应将数据保护配置为创建持久性加密CSRF令牌

ASP.NET Core MVC TempData cookie

要配置数据保护以持久化和加密密钥环,请参阅:

ASP.NET Core MVC TempData cookie

使用ASP.NET Core在Windows和Azure中静止进行密钥加密


长请求标头字段

代理服务器默认设置通常根据平台将请求标头字段限制为4 K或8K。应用程序可能需要比默认字段长的字段(例如,使用Azure Active Directory的应用程序)。如果需要更长的字段,则需要调整代理服务器的默认设置。要应用的值取决于方案。有关更多信息,请参阅服务器的文档。

 

警告

除非必要,否则不要增加代理缓冲区的默认值。增加这些值会增加恶意用户进行缓冲区溢出(溢出)和拒绝服务(DoS)攻击的风险。


保护应用程序

启用AppArmor

自Linux 2.6起,Linux安全模块(LSM)是Linux内核的一部分。LSM支持安全模块的不同实现。AppArmor是一个LSM,它实现了强制访问控制系统,该系统允许将程序限制在有限的资源集中。确保已启用并正确配置了AppArmor。


配置防火墙

关闭所有未使用的外部端口。简单的防火墙(ufw)iptables通过提供用于配置防火墙的CLI来提供前端。

 警告

如果配置不正确,防火墙将阻止访问整个系统。如果使用SSH连接到SSH端口,则未能指定正确的SSH端口将有效地将您锁定在系统之外。默认端口为22。有关更多信息,请参见ufw简介手册

安装ufw并配置它以允许需要的任何端口上的流量。

重击
sudo apt-get install ufw

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

sudo ufw enable

安全Nginx

更改Nginx响应名称

编辑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;

配置选项

使用其他必需的模块配置服务器。考虑使用Web应用程序防火墙(例如ModSecurity)来加固应用程序。

HTTPS配置

配置应用程序以进行安全(HTTPS)本地连接

DOTNET运行命令使用应用程序的性能/ launchSettings.json文件,配置应用程序,听取对所提供的URLapplicationUrl属性。例如,https://localhost:5001;http://localhost:5000

配置应用程序使用证书在发展为dotnet run命令或开发环境(F5Ctrl+F5使用下列情况之一办法在Visual Studio代码):

配置反向代理以实现安全(HTTPS)客户端连接


 警告

本节中的安全性配置是常规配置,可以用作进一步定制的起点。我们无法为第三方工具,服务器和操作系统提供支持。使用本节中的配置,后果自负。有关更多信息,请访问以下资源:
  • 通过指定由受信任的证书颁发机构(CA)颁发的有效证书,将服务器配置为侦听端口443上的HTTPS通信。

  • 通过使用以下/etc/nginx/nginx.conf文件中描述的一些实践来加强安全性。

  • 以下示例未将服务器配置为重定向不安全的请求。我们建议使用HTTPS重定向中间件。有关更多信息,请参见在ASP.NET Core中强制实施HTTPS

     笔记

    对于服务器配置处理安全重定向而不是HTTPS重定向中间件的开发环境,我们建议使用临时重定向(302)而不是永久重定向(301)。链接缓存可能导致开发环境中的不稳定行为。

  • 添加Strict-Transport-Security(HSTS)标头可确保客户端发出的所有后续请求均通过HTTPS。有关设置Strict-Transport-Security标头的指导,请参阅在ASP.NET Core中强制执行HTTPS

  • 如果将来会禁用HTTPS,请使用以下方法之一:

    • 不要添加HSTS标头。
    • 选择一个短max-age值。

添加/etc/nginx/proxy.conf配置文件:

Nginx的
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;

更换的内容/etc/nginx/nginx.conf具有下列文件的配置文件。该示例在一个配置文件中同时包含httpserver部分。

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


 笔记

Blazor WebAssembly应用程序需要较大的burst参数值才能容纳应用程序发出的大量请求。有关更多信息,请参见托管和部署ASP.NET Core Blazor WebAssembly

[注意]前面的示例禁用了在线证书状态协议(OCSP)装订。如果启用,请确认证书支持该功能。有关启用OCSP的更多信息和指导,请参见“模块ngx_http_ssl_module”(Nginx文档)中的以下属性:

  • ssl_stapling
  • ssl_stapling_file
  • ssl_stapling_responder
  • ssl_stapling_verify


保护Nginx免受点击劫持

Clickjacking,也称为UI纠正攻击,是一种恶意攻击,其中,网站访问者被诱骗单击与他们当前访问的页面不同的链接或按钮。使用X-FRAME-OPTIONS固定的站点。

要缓解点击劫持攻击,请执行以下操作:

  1. 编辑nginx.conf文件:

    重击
    sudo nano /etc/nginx/nginx.conf
    

    添加行: add_header X-Frame-Options "SAMEORIGIN";

  2. 保存文件。

  3. 重新启动Nginx。

MIME类型嗅探

此标头可防止大多数浏览器通过MIME嗅探已声明内容类型的响应,因为标头指示浏览器不要覆盖响应内容类型。使用该nosniff选项,如果服务器说内容为text/html,则浏览器将其呈现为text/html

  1. 编辑nginx.conf文件:

    重击
    sudo nano /etc/nginx/nginx.conf
    

    添加行: add_header X-Content-Type-Options "nosniff";

  2. 保存文件。

  3. 重新启动Nginx。


其他Nginx建议

在服务器上升级共享框架后,重新启动服务器托管的ASP.NET Core应用程序。


已修改于2023-03-04 02:20
创作不易,留下一份鼓励
阿尔巴

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
阿尔巴
这家伙很懒还未留下介绍~
12
文章
10
问答
11
粉丝
相关文章
NginxPushStreamModuleApurestreamhttppushtechnologyforyourNginxsetup.Comet madeeasyand reallyscalable.Supports EventSource, WebSocket,LongPolling,andForeverIframe.See someexamples bellow.ThismoduleisnotdistributedwiththeNginxsource.See theinstallationinstructions.Availableongithubat nginx_push_stream_moduleChangelogAlwaystakealookat CHANGELOG.textile toseewhat’snew.ContributeAfteryoutrythismoduleand
点赞 1
浏览 1.2k
概述NGINX速率限制是一个很重要的流量管理模块,用来限制单位时间的请求数。通过正确有效地配置,特定客户端对某一个URI的访问频率频率可以得到有效地限制, 从而可以有效地减缓暴力密码破解攻击,也可以有效减缓DDOS攻击的破坏性,还可以防止上游服务器被大量并发的请求耗尽资源。本篇文章我们就速度限制功能的原理和源代码进行解析,从而可以更好地理解和使用速度限制功能。原理漏桶(LeakyBucket)算法和令牌桶(Token Bucket)算法被广泛使用于通信领域进行流量整形和速率控制。NGINX采用的是漏桶(Leaky Bucket)算法来实现速率控制。漏桶(LeakyBucket)算法思路很简单。我们可以把用户请求比做水先进入到漏桶里,漏桶以一定的速度出水(处理请求),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求。可以看出漏桶算法能强行限制数据的传输速率。使用一幅经典的图片来解释漏桶算法的原理:使用伪代码来表示漏桶算法就是:intspeed;//处理请求的速率,比如2r/s表示每秒处理2个请求intrequests;//当前系统的请求个数int
点赞 3
浏览 3.1k
概述前几篇文章,我们分别介绍了NGINX变量的基本特性和实现原理以及NGINX中复杂变量求值的原理。本篇,我们继续分析NGINX中rewrite模块定义的系列指令比如if/set/break/return等的实现原理。基本原理我们在分析NGINX复杂变量求值时,已经介绍和分析了NGINX脚本执行的基本原理。除了复杂变量求值涉及到NGINX脚本语言以外,另外一种显式地通过在配置脚本中配置的指令,比如NGINX的rewrite模块或者geo模块定义的指令也需要NGINX的脚本语言功能的支持。NGINX在启动阶段,会把一些指令比如set/rewrite/return等编译成一系列指令集,并且存放到每一个location中的ngx_http_rewrite_loc_conf_t结构体中。typedefstruct{  ngx_array_t *codes;//保存着所属location下的所有编译后脚本  ngx_uint_t   stack_size;//变量值栈sp的大小 &nb
点赞 3
浏览 1.6k