问题描述
我正在尝试将我的 ASP.NET Web 应用程序(使用 .NET 5.0 和 ASP.NET MVC)部署到带有 Nginx 的 debian 10 服务器。我遵循了 Microsoft 的教程,经过多次测试,找不到可行的方法。
我当前的 Nginx 配置:
server {
listen 80 default_server;
location / {
proxy_pass http://localhost: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;
}
}
使用 curl -v localhost:5000
查询 localhost 给了我 HTTP 307 重定向。
查询 curl -v --insecure https://localhost:5001
会返回我网页的实际内容,因此 kestrel 运行良好。
我的 Startup.cs 如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SmapOneUpdater.Frontend.Model.sortenumbuchung.Data;
namespace SmapOneUpdater.Frontend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddDbContext<SortenumbuchungContext>(options =>
options.Usesqlite(Configuration.GetConnectionString("SortenumbuchungContext")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
app.UseForwardedHeaders();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios,see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",pattern: "{controller=Overview}/{action=Index}/{id?}");
});
}
}
}
连接到我的服务器的 ip 地址返回“无法访问此站点 x.x.x.x 意外关闭了连接”。它会自动将 url 更改为 x.x.x.x:5001,这应该是错误的,因为我没有尝试直接访问端口 5001,还是我?
尽管如此,我很确定这不是我的 Nginx 配置,因为我的浏览器以某种方式获取了他需要端口 5001 的信息,并且因为如果我将 proxy_pass 更改为 https://www.google.com 它可以工作并将我重定向到谷歌>
编辑:已解决
问题出在我的 Properties/launchSettings.json 中。我将 applicationUrl 设置为 http://localhost:5000;https://localhost:5001
似乎 ASP 只允许调用本地主机(或 127.0.0.1)的连接。由于通过 ip 调用时我无法从服务器访问 kestrel。之后,我不得不更改Nginx以转发服务器IP地址,因此访问客户端不会尝试访问localhost:5001,而是尝试访问端口为5001的服务器IP地址。
我现在正在使用 --urls
命令在运行时环境中设置 url。
所以我的电话看起来像这样:
dotnet /path/to/application/dll --urls "http://*:5000;https://*:5001"
至于 Nginx,在阅读 TheRoadrunner 的回答后,我更改了配置以将 HTTP 请求重定向到 HTTPS。在 the tutorial from NGINX 之后,我还创建了一个自签名 ssl 证书:
openssl req -x509 -subj /CN=localhost -days 365 -set_serial 2 -newkey rsa:4096 -keyout /etc/Nginx/cert.key -nodes -out /etc/Nginx/cert.pem
我的 Nginx 配置如下所示:
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
ssl_certificate /etc/Nginx/cert.pem;
ssl_certificate_key /etc/Nginx/cert.key;
location / {
proxy_pass https://192.168.4.156:5001;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
有趣的是,通过这种工作配置,浏览器中我的 url 栏中的端口没有显示,它正在访问端口 5001
我是怎么发现的
也许这对一些读者来说会很有趣。我通过使用 virtualBox 创建本地 debian 实例解决了这个问题。我将它配置为我的真实服务器。但是我安装了 GNOME,因为我想确定我是否真的可以使用本地浏览器看到页面(回想起来,我可能可以通过 curl 实现这一点)。
这对我来说似乎很有趣,因为重定向在 vm 上有效。在 Firefox 中输入 localhost:80 将我重定向到 localhost:5001 并且我看到了该页面。经过一些测试后,我使用 VM 的 IP 进行了尝试,并且遇到了与其他机器上完全相同的问题。所以我尝试更改应用程序 URL。
我认为这很有趣,因为它看起来很明显,但文档中从未提到过。作为代理/Nginx/webdev 新手,我不确定所有这些是如何工作的。特别是因为文档提到将 HTTPS 重定向到 http://localhost:5000
解决方法
我认为您的 nginx 配置中需要两个部分,一个用于端口 80,重定向到 443 上的另一个。
类似于:
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
location / {
http://localhost:5000
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
此外,您必须处理证书以避免浏览器警告。