龙空技术网

使用 Nginx 在 Linux 上托管 ASP.NET Core

自由的孔雀 382

前言:

此刻朋友们对“nginx配置 asp”大体比较注意,你们都想要剖析一些“nginx配置 asp”的相关文章。那么小编在网络上收集了一些关于“nginx配置 asp””的相关资讯,希望咱们能喜欢,小伙伴们快快来了解一下吧!

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

升级共享框架后,可随时重启服务器托管的 ASP.NET Core 应用。

通过应用发布和复制

配置应用以进行依赖框架的部署。

如果应用在本地运行,且未配置为建立安全连接 (HTTPS),则采用以下任一方法:

配置应用,以处理安全的本地连接。 有关详细信息,请参阅 HTTPS 配置部分。从 Properties/launchSettings.json 文件的 applicationUrl 属性中删除 (如果存在)。

在开发环境中运行 dotnet publish,将应用打包到可在服务器上运行的目录中(例如 bin/Release/{TARGET FRAMEWORK MONIKER}/publish,其中 {TARGET FRAMEWORK MONIKER} 占位符表示目标框架名字对象/TFM):

.NET CLI

dotnet publish --configuration Release

如果不希望维护服务器上的 .NET Core 运行时,还可将应用发布为独立部署。

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

备注

在生产部署方案中,持续集成工作流会执行发布应用并将资产复制到服务器的工作。

测试应用:

在命令行中运行应用:dotnet <app_assembly>.dll。在浏览器中,导航到 ;serveraddress>:<port> 以确认应用在 Linux 本地正常运行。配置反向代理服务器

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

使用反向代理服务器

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

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

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

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

调用其他中间件之前,请先在 Startup.Configure 的基础上调用 UseForwardedHeaders 方法。 配置中间件以转接 X-Forwarded-For 和 X-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])(包括标准 localhost 地址 (127.0.0.1))上运行的代理受信任。 如果组织内的其他受信任代理或网络处理 Internet 与 Web 服务器之间的请求,请使用 ForwardedHeadersOptions 将其添加到 KnownProxies 或 KnownNetworks 的列表。 以下示例会将 IP 地址为 10.0.0.100 的受信任代理服务器添加到 Startup.ConfigureServices 中的转接头中间件 KnownProxies:

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 init 脚本,该脚本运行 Nginx,作为系统启动时的守护程序。 按照以下网站上的 Ubuntu 安装说明操作:Nginx:官方 Debian/Ubuntu 包。

备注

如果需要可选 Nginx 模块,则可能需要从源代码生成 Nginx。

因为是首次安装 Nginx,通过运行以下命令显式启动:

Bash

sudo service nginx start

确认浏览器显示 Nginx 的默认登陆页。 可在 ;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         ;        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 应用,请分别参阅 SignalRASP.NET Core生产托管和缩放 和 托管和部署 ASP.NET Core Blazor Server 以了解详细信息。

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

nginx

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

使用上述配置文件和默认服务器,Nginx 接受主机标头 example.com 或 *.example.com 端口 80 上的公共流量。 与这些主机不匹配的请求不会转发到 Kestrel。 Nginx 将匹配的请求转发到 中的 Kestrel。 有关详细信息,请参阅 nginx 如何处理请求。 要更改 Kestrel 的 IP/端口,请参阅 Kestrel:终结点配置。

警告

未能指定正确的 server_name 指令会公开应用的安全漏洞。 如果可控制整个父域(区别于易受攻击的 *.com),则子域通配符绑定(例如,*.example.com)不具有此安全风险。

完成配置 Nginx 后,运行 sudo nginx -t 来验证配置文件的语法。 如果配置文件测试成功,可以通过运行 sudo nginx -s reload 强制 Nginx 选取更改。

要直接在服务器上运行应用:

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

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

完成应用测试后,请在命令提示符处按 Ctrl + C 关闭应用。

监视应用

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

创建服务文件

创建服务定义文件:

Bash

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

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

ini

[Unit]Description=Example .NET Web API App running on Ubuntu[Service]WorkingDirectory=/var/www/helloappExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dllRestart=always# Restart service after 10 seconds if the dotnet service crashes:RestartSec=10KillSignal=SIGINTSyslogIdentifier=dotnet-exampleUser=www-dataEnvironment=ASPNETCORE_ENVIRONMENT=ProductionEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false[Install]WantedBy=multi-user.target

在前面的示例中,管理服务的用户由 User 选项指定。 用户 (www-data) 必须存在并且拥有正确应用文件的所有权。

使用 TimeoutStopSec 配置在收到初始中断信号后等待应用程序关闭的持续时间。 如果应用程序在此时间段内未关闭,则将发出 SIGKILL 以终止该应用程序。 提供作为无单位秒数的值(例如,150)、时间跨度值(例如,2min 30s)或 infinity 以禁用超时。 TimeoutStopSec 默认为管理器配置文件 (systemd-system.conf, system.conf.d, systemd-user.conf, user.conf.d) 中 DefaultTimeoutStopSec 的值。 大多数分发版的默认超时时间为 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}

保存该文件并启用该服务。

Bash

sudo systemctl enable kestrel-helloapp.service

启用该服务,并确认它正在运行。

sudo systemctl start kestrel-helloapp.servicesudo 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 agoMain PID: 9021 (dotnet)    CGroup: /system.slice/kestrel-helloapp.service            └─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll

在配置了反向代理并通过 systemd 管理 Kestrel 后,Web 应用现已完全配置,并能在本地计算机上的浏览器中从 进行访问。 也可以从远程计算机进行访问,同时限制可能进行阻止的任何防火墙。 检查响应标头,Server 标头显示由 Kestrel 所提供的 ASP.NET Core 应用。

text

HTTP/1.1 200 OKDate: Tue, 11 Oct 2016 16:22:23 GMTServer: KestrelKeep-Alive: timeout=5, max=98Connection: Keep-AliveTransfer-Encoding: chunked
查看日志

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

Bash

sudo journalctl -fu kestrel-helloapp.service

有关进一步筛选,使用时间选项(如 --since today、--until 1 hour ago)或这些选项的组合可以减少返回的条目数。

Bash

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

ASP.NET Core 数据保护堆栈由多个 ASP.NET Core 中间件(包括 cookie 中间件等身份验证中间件)和跨站点请求伪造 (CSRF) 保护使用。 即使用户代码不调用数据保护 API,也应该配置数据保护,以创建持久的加密密钥存储。 如果不配置数据保护,则密钥存储在内存中。重启应用时,密钥会被丢弃。

如果密钥环存储于内存中,则在应用重启时:

所有基于 cookie 的身份验证令牌都无效。用户需要在下一次请求时再次登录。无法再解密使用密钥环保护的任何数据。 这可能包括 CSRF 令牌和 ASP.NET Core MVC TempData cookie。

若要配置数据保护以持久保存并加密密钥环,请参阅:

ASP.NET Core 中的密钥存储提供程序使用 ASP.NET Core 在 Windows 和 Azure 中静态 ASP.NET 加密较长的请求标头字段

代理服务器默认设置通常将请求标头字段限制为 4 K 或 8 K,具体取决于平台。 某些应用可能需要超过默认值的字段(例如,使用 Azure Active Directory 的应用)。 如果需要更长的字段,则代理服务器的默认设置需要进行调整。 要应用的值具体取决于方案。 有关详细信息,请参见服务器文档。

proxy_buffer_sizeproxy_buffersproxy_busy_buffers_sizelarge_client_header_buffers

警告

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

保护应用启用 AppArmor

Linux 安全模块 (LSM) 是一个框架,它是自 Linux 2.6 后的 Linux kernel 的一部分。 LSM 支持安全模块的不同实现。 AppArmor 是实现强制访问控制系统的 LSM,它允许将程序限制在一组有限的资源内。 确保已启用并成功配置 AppArmor。

配置防火墙

关闭所有未使用的外部端口。 通过为配置防火墙提供 CLI,不复杂的防火墙 (ufw) 为 iptables 提供了前端。

警告

如果未正确配置,防火墙将阻止对整个系统的访问。 在使用 SSH 进行连接时,未能指定正确的 SSH 端口最终会将你关在系统之外。 默认端口为 22。

安装 ufw,并将其配置为允许所需任何端口上的流量。

Bash

sudo apt-get install ufwsudo ufw allow 22/tcpsudo ufw allow 80/tcpsudo ufw allow 443/tcpsudo 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;
配置选项

用其他必需模块配置服务器。 请考虑使用 ModSecurity 等 Web 应用防火墙来加强对应用的保护。

HTTPS 配置

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

dotnet run 命令使用应用的 Properties/launchSettings.json 文件,该文件将应用配置为侦听 applicationUrl 属性提供的 URL。 例如,;。

使用以下方法之一配置应用,使其在开发过程中将证书用于 dotnet run 命令或开发环境(Visual Studio Code 中的 F5 或 Ctrl+F5):

从配置中替换默认证书(推荐)KestrelServerOptions.ConfigureHttpsDefaults

配置反向代理,以便进行安全 (HTTPS) 客户端连接

警告

本部分中的安全配置是一种常规配置,可以作为进一步进行自定义的起点。 我们无法为第三方工具、服务器和操作系统提供支持。 如果使用本部分中的配置,请自行承担风险。 有关更多信息,请访问以下资源:

配置 HTTPS 服务器(Nginx 文档)mozilla.org SSL Configuration Generator通过指定由受信任的证书颁发机构 (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 配置文件的内容替换为以下文件。 示例包含一个配置文件中的 http 和 server 部分。

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 ;            limit_req  zone=one burst=10 nodelay;        }    }}

备注

Blazor WebAssembly 应用需要更大的 burst 参数值才能容纳应用发出的更大量的请求。

备注

上面的示例禁用了在线证书状态协议 (OCSP) 装订。 如果启用,请确认证书支持该功能。

ssl_stapling

ssl_stapling_file

ssl_stapling_responder

ssl_stapling_verify

保护 Nginx 免受点击劫持的侵害

点击劫持(也称为 UI 伪装攻击)是一种恶意攻击,其中网站访问者会上当受骗,从而导致在与当前要访问的页面不同的页面上单击链接或按钮。 使用 X-FRAME-OPTIONS 可保护网站。

缓解点击劫持攻击:

编辑 nginx.conf 文件:Bash复制sudo nano /etc/nginx/nginx.conf 添加行:add_header X-Frame-Options "SAMEORIGIN";保存该文件。重启 Nginx。MIME 类型探查

此标头可阻止大部分浏览器通过 MIME 方式探查来自已声明内容类型的响应,因为标头会指示浏览器不要替代响应内容类型。 使用 nosniff 选项后,如果服务器认为内容是“text/html”,则浏览器将其显示为“text/html”。

编辑 nginx.conf 文件:Bash复制sudo nano /etc/nginx/nginx.conf 添加行:add_header X-Content-Type-Options "nosniff";保存该文件。重启 Nginx。其他 Nginx 建议

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

标签: #nginx配置 asp #linux运行asp网站 #asp nginx