简体   繁体   English

Nginx 反向代理,带 SSL 和 Asp.NET 核心 ZDB974238714CA8DE634A7CE1D083A4

[英]Nginx Reverse Proxy With SSL and Asp.NET Core API

I am currently trying to build an API for a client interface-server interaction.我目前正在尝试为客户端接口-服务器交互构建一个 API。 I have decided to use ASP.NET Core for the API with Nginx as the hosting platform (On Ubuntu 18.04). I have decided to use ASP.NET Core for the API with Nginx as the hosting platform (On Ubuntu 18.04). Since ASP.NET uses Kestrel, we have set up a reverse proxy to forward requests from Nginx to Kestrel-- what is hosting the API.由于 ASP.NET 使用 Kestrel,我们设置了一个反向代理来将请求从 Nginx 转发到 Kestrel——托管 API 的东西。 We have SSL set up on the NGINX server, however it is not set up on the Kestrel Server.我们在 NGINX 服务器上设置了 SSL,但在 Kestrel 服务器上没有设置。

Simply put, I do not know how to set up SSL on the Kestrel Server with another layer of SSL on the NGINX side.简单来说就是不知道如何在Kestrel Server上设置SSL,在NGINX侧再一层SSL。 How can I do this?我怎样才能做到这一点?

Model: Client --> GET Request over HTTPS --> NGINX with SSL --> HTTP Kestrel Server and vice versa Model: Client --> GET Request over HTTPS --> NGINX with SSL --> HTTP Kestrel Server and vice versa

Output: SSL_PROTOCOL_ERROR Output:SSL_PROTOCOL_ERROR

Temporary Solution: Use HTTP with port 5000 in the link.-- No error, however, data is not secure.临时解决方案:使用 HTTP 与链路中的端口 5000。-- 没有错误,但是,数据不安全。

Optimal Solution: Use HTTPS without port 5000 in the link.最佳解决方案:使用 HTTPS 链路中没有端口 5000。 Data is secure.数据是安全的。

NGINX Config: NGINX 配置:

    if ($host = api.OURSITENAME.co) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name api.OURSITENAME.co;
    return 301 https://$server_name$request_uri;


}

server {
    listen 443 ssl http2;
    include /etc/nginx/proxy_params;
    server_name api.OURSITENAME.co;
    access_log /var/log/nginx/api.access.log;
    error_log /var/log/nginx/api.error.log error;
    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/api.OURSITENAME.co/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.OURSITENAME.co/privkey.pem; # managed by Certbot
    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header Upgrade $http_upgrade;

    location / {
        proxy_pass         http://172.18.0.2:5000; <-- Docker Container. Can easily be switched out with localhost if we want to run on dotnet directly.
    }
}

As I understand the problem, when you use HTTP to access your application directly on port 5000 you get an SSL error.据我了解,当您使用 HTTP 直接在端口 5000 上访问您的应用程序时,您会收到 SSL 错误。 Even though you don't use HTTPS.即使您不使用 HTTPS。

If you have app.UseHsts();如果你有app.UseHsts(); and/or app.UseHttpsRedirection();和/或app.UseHttpsRedirection(); in your Startup code then it will use HTTPS.在您的启动代码中,它将使用 HTTPS。

If you are letting nginx handle the SSL then you can remove code from your app Startup.cs如果您让 nginx 处理 SSL 那么您可以从您的应用 Startup.cs 中删除代码

Typical startup code:典型的启动代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else // Production
    {
        app.UseExceptionHandler("/Error");
        // Remove to use HTTP only
        app.UseHsts(); // HTTPS Strict mode
    }

    // Remove to use HTTP only
    app.UseHttpsRedirection(); // Redirects HTTP to HTTPS
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseAuthentication();

    app.UseMvc();

}

Documentation on enforcing SSL in dotnet core 有关在 dotnet 核心中执行 SSL 的文档

This simply happens because Kestrel is not configured to handle HTTPS requests.这很简单,因为 Kestrel 未配置为处理 HTTPS 请求。 A quick look at MS Docs shows you how.快速浏览MS Docs会向您展示如何操作。

You can use listenOptions and its various extensions to specify your SSL certificate and other configurations您可以使用listenOptions及其各种扩展来指定您的 SSL 证书和其他配置

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

Also, if you used CreateDefaultBuilder from your Program.cs , then you can configure your SSL/HTTPS from appsettings.json because CreateDefaultBuilder calls Configure(context.Configuration.GetSection("Kestrel")) by default to load Kestrel configurations.此外,如果您从Program.cs使用CreateDefaultBuilder ,那么您可以从appsettings.json配置 SSL/HTTPS,因为CreateDefaultBuilder默认调用Configure(context.Configuration.GetSection("Kestrel"))来加载 Kestrel 配置。 A sample config file highlighting Kestrel config (from MS Docs) is shown below:突出显示 Kestrel 配置(来自 MS Docs)的示例配置文件如下所示:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "HttpsInlineCertFile": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      },
      "HttpsInlineCertStore": {
        "Url": "https://localhost:5002",
        "Certificate": {
          "Subject": "<subject; required>",
          "Store": "<certificate store; required>",
          "Location": "<location; defaults to CurrentUser>",
          "AllowInvalid": "<true or false; defaults to false>"
        }
      },
      "HttpsDefaultCert": {
        "Url": "https://localhost:5003"
      },
      "Https": {
        "Url": "https://*:5004",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    },
    "Certificates": {
      "Default": {
        "Path": "<path to .pfx file>",
        "Password": "<certificate password>"
      }
    }
  }
}

Make sure to visit the docs if you need more info.如果您需要更多信息,请务必访问文档

Nevertheless, in my opinion, I don't see much advantage with a double layer of SSL protection.尽管如此,在我看来,双层 SSL 保护并没有太大优势。 One downside I can immediately notice is some delay as a result of encryption/decryption.我可以立即注意到的一个缺点是加密/解密导致的一些延迟。 A single layer of SSL on your reverse proxy should be more than enough.反向代理上的单层 SSL 应该绰绰有余。

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

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