简体   繁体   English

编辑: NGINX 反向代理 ASP.NET Core 5.0: localhost:5000 关闭连接但 www.google.com 工作

[英]EDIT: NGINX reverse proxy ASP.NET Core 5.0: localhost:5000 closes connection but www.google.com works

I'm trying to deploy my ASP.NET web Application (with .NET 5.0 and ASP.NET MVC) to an debian 10 server with NGINX. I'm trying to deploy my ASP.NET web Application (with .NET 5.0 and ASP.NET MVC) to an debian 10 server with NGINX. I followed Microsoft's tutorial and after numerous testings can't find something that will work.我按照微软的教程进行了多次测试,但找不到可行的方法。

My current NGINX configuration:我目前的 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;
    }
}

Querying localhost with curl -v localhost:5000 gives me HTTP 307 redirect.使用curl -v localhost:5000查询 localhost 会给我 HTTP 307 重定向。

Querying curl -v --insecure https://localhost:5001 returns the actual content of my webpage, so kestrel is running fine.查询curl -v --insecure https://localhost:5001返回我网页的实际内容,因此 kestrel 运行良好。

My Startup.cs looks like this:我的 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?}");
            });
        }
    }
}

Connecting to the ip-address of my server returns "This site can't be reached xxxx unexpectedly closed the connection" after some loading.连接到我的服务器的 IP 地址在加载后返回“无法访问此站点 xxxx 意外关闭了连接”。 and it automatically changes the url to xxxx:5001 which should be wrong since I'm not trying to directly access port 5001, or am I?它会自动将 url 更改为 xxxx:5001 这应该是错误的,因为我没有尝试直接访问端口 5001,还是我?

Nevertheless, I'm pretty sure it's not my NGINX configuration, since my browser somehow gets the information that he needs port 5001 AND because if I change the proxy_pass to https://www.google.com it works and redirects me to google尽管如此,我很确定这不是我的 NGINX 配置,因为我的浏览器以某种方式获取了他需要端口 5001 的信息,并且因为如果我将 proxy_pass 更改为https://www.google.Z4D236D1并将其重定向到 google5ADDA4 google5ADDA 将起作用

EDIT: SOLVED编辑:已解决

The problem was inside my Properties/launchSettings.json.问题出在我的 Properties/launchSettings.json 中。 I had the applicationUrl set to http://localhost:5000;https://localhost:5001 It seems like ASP then only allows connections which call localhost (or 127.0.0.1).我将 applicationUrl 设置为http://localhost:5000;https://localhost:5001似乎 ASP 然后只允许调用 localhost(或 127.0.0.1)的连接。 Since I couldn't reach kestrel from the server when calling it by ip.由于在通过 ip 调用它时,我无法从服务器访问红隼。 After that, I had to change nginx to forward the servers IP address, so the accessing client won't try to access localhost:5001 but the servers IP address with port 5001.之后,我不得不更改 nginx 以转发服务器 IP 地址,因此访问客户端不会尝试访问 localhost:5001 而是服务器 IP 地址与端口 5001。

I'm setting the urls on the runtime environment now with the --urls command.我现在使用--urls命令在运行时环境中设置 url。 So my call looks like this:所以我的电话看起来像这样:

dotnet /path/to/application/dll --urls "http://*:5000;https://*:5001"

As for NGINX, after reading TheRoadrunner's answer, I changed the config to redirect HTTP requests to HTTPS.至于 NGINX,在阅读了 TheRoadrunner 的回答后,我将配置更改为将 HTTP 请求重定向到 HTTPS。 Following the tutorial from NGINX I also created a self signed ssl certificate with:按照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

My working NGINX config looks like this:我的工作 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;
    }
}

Interestengly enough, with this working configuration the port in my url bar in the browser does not show, that it's accessing port 5001有趣的是,通过这种工作配置,浏览器中我的 url 栏中的端口没有显示,它正在访问端口 5001

How did I found out我是怎么发现的

Maybe this will be interesting for some readers.也许这对一些读者来说会很有趣。 I figured the issue out, by creating a local debian instance with virtualbox.我通过使用 virtualbox 创建一个本地 debian 实例解决了这个问题。 I configured it just as my real server.我将它配置为我的真实服务器。 But I installed GNOME, because I wanted to make sure, whether I can actually see the page with a local browser or not (In retrospective, I probably could've achieved this with curl).但是我安装了 GNOME,因为我想确定是否可以使用本地浏览器查看页面(回想起来,我可能已经使用 curl 实现了这一点)。

It seemed interesting to me, since the redirect worked on the vm.这对我来说似乎很有趣,因为重定向在 vm 上起作用。 entering localhost:80 in firefox redirected me to localhost:5001 and I saw the page.在 firefox 中输入 localhost:80 将我重定向到 localhost:5001 并且我看到了该页面。 After some testing I tried it with the IP of the VM and had the exact same issue as on the other machines.经过一些测试后,我使用 VM 的 IP 进行了尝试,并且遇到了与其他机器完全相同的问题。 So I tried to change the application URL.所以我尝试更改应用程序 URL。

I think this is interesting, since it seems so obvious, but was never mentioned in the documentation.我认为这很有趣,因为它看起来很明显,但从未在文档中提及。 As a proxy/nginx/webdev newbie I was not exactly sure how all of this works.作为代理/nginx/webdev 新手,我并不确定这一切是如何工作的。 Especially since the documentation mentions to redirect HTTPS to http://localhost:5000特别是因为文档提到将 HTTPS 重定向到 http://localhost:5000

I think you need two sections in your nginx config one for port 80 that redirects to the other on 443.我认为您在 nginx 配置中需要两个部分,一个用于端口 80,该端口重定向到 443 上的另一个。

Something like:就像是:

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

In addition you will have to handle certificates to avoid browser warnings.此外,您必须处理证书以避免浏览器警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM