使用SSL和Asp.NET核心API的Nginx反向代理

使用SSL和Asp.NET核心API的Nginx反向代理,asp.net,asp.net-core,ssl,nginx,reverse-proxy,Asp.net,Asp.net Core,Ssl,Nginx,Reverse Proxy,我目前正在尝试为客户端接口服务器交互构建一个API。我已经决定使用ASP.NETCore作为API,Nginx作为宿主平台(在Ubuntu18.04上)。因为ASP.NET使用Kestrel,所以我们设置了一个反向代理,将请求从Nginx转发到Kestrel——这就是API的宿主。我们在NGINX服务器上设置了SSL,但是在Kestrel服务器上没有设置SSL 简单地说,我不知道如何在Kestrel服务器上设置SSL,在NGINX端使用另一层SSL。我该怎么做 型号: 客户端-->使用SSL--

我目前正在尝试为客户端接口服务器交互构建一个API。我已经决定使用ASP.NETCore作为API,Nginx作为宿主平台(在Ubuntu18.04上)。因为ASP.NET使用Kestrel,所以我们设置了一个反向代理,将请求从Nginx转发到Kestrel——这就是API的宿主。我们在NGINX服务器上设置了SSL,但是在Kestrel服务器上没有设置SSL

简单地说,我不知道如何在Kestrel服务器上设置SSL,在NGINX端使用另一层SSL。我该怎么做

型号: 客户端-->使用SSL-->HTTP Kestrel服务器通过HTTPS-->NGINX获取请求,反之亦然

输出:SSL_协议_错误

临时解决方案:将HTTP与链接中的端口5000一起使用。--没有错误,但是,数据不安全

最佳解决方案:使用链接中没有端口5000的HTTPS。数据是安全的

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.
    }
}
if($host=api.OURSITENAME.co){
返回301 https://$host$request\u uri;
}#由Certbot管理
听80;
服务器名称api.OURSITENAME.co;
返回301 https://$server\u name$request\u uri;
}
服务器{
监听443sslhttp2;
包括/etc/nginx/proxy_参数;
服务器名称api.OURSITENAME.co;
access_log/var/log/nginx/api.access.log;
error\u log/var/log/nginx/api.error.log error;
#SSL配置
ssl_certificate/etc/letsencrypt/live/api.OURSITENAME.co/fullchain.pem;#由Certbot管理
ssl_certificate_key/etc/letsencrypt/live/api.OURSITENAME.co/privkey.pem;#由Certbot管理
proxy_http_版本1.1;
代理缓存绕过$http\u升级;
代理设置头连接$http\U连接;
代理设置头升级$http\U升级;
地点/{

代理通行证http://172.18.0.2:5000据我所知,当您使用HTTP直接在端口5000上访问应用程序时,会出现SSL错误。即使您不使用HTTPS

如果启动代码中有
app.UseHsts();
和/或
app.usehttpseredirection();
,则它将使用HTTPS

如果您让nginx处理SSL,那么您可以从app Startup.cs中删除代码

典型启动代码:

public void配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
其他//生产
{
app.UseExceptionHandler(“/Error”);
//删除以仅使用HTTP
app.UseHsts();//HTTPS严格模式
}
//删除以仅使用HTTP
app.UseHttpsRedirection();//将HTTP重定向到HTTPS
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc();
}

之所以会发生这种情况,是因为Kestrel没有配置为处理HTTPS请求。下面简要介绍一下

您可以使用
listenOptions
及其各种扩展来指定SSL证书和其他配置

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});
另外,如果从
程序.cs
使用
CreateDefaultBuilder
,则可以从
appsettings.json
配置SSL/HTTPS,因为
CreateDefaultBuilder
调用
配置(context.Configuration.GetSection(“Kestrel”))
默认情况下加载Kestrel配置。突出显示Kestrel配置的示例配置文件(来自MS文档)如下所示:

{
  "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>"
      }
    }
  }
}
{
“红隼”:{
“端点”:{
“Http”:{
“Url”:”http://localhost:5000"
},
“HttpsInlineCertFile”:{
“Url”:”https://localhost:5001",
“证书”:{
“路径”:“,
“密码”:”
}
},
“HttpsInlineCertStore”:{
“Url”:”https://localhost:5002",
“证书”:{
“主题”:“,
“存储”:“存储”,
“地点”:“,
“AllowInvalid”:”
}
},
“HttpsDefaultCert”:{
“Url”:”https://localhost:5003"
},
“Https”:{
“Url”:“https://*:5004”,
“证书”:{
“路径”:“,
“密码”:”
}
}
},
“证书”:{
“默认值”:{
“路径”:“,
“密码”:”
}
}
}
}
如果需要更多信息,请务必访问


然而,在我看来,双层SSL保护并没有什么好处。我可以立即注意到的一个缺点是由于加密/解密造成的延迟。在反向代理上使用单层SSL就足够了。

如果nginx和kestrel在同一台服务器上(或在专用网络中)那么你不需要kestrel上的SSL。nginx处理公共请求和SSL,你的应用程序不会公开发送数据。这是你的情况吗?@Rosco我知道我不认为我需要kestrel上的SSL,但是尝试通过HTTPS连接到网站时,我得到一个504超时。在链接中插入端口5000后,kestrel服务器当我使用5000直接在HTTP上访问站点时,“它可以完全正常工作。如果我尝试使用https访问站点时,无论是否使用端口5000,都会出现SSL协议错误。”“或者。“反向代理服务器在SSL上,所以我真的很难找出问题所在。顺便说一句:“站点”不是我的网站,所以我会避免点击这些链接。你的nginx设置正确吗?nginx请求https或http吗?我会将配置添加到主post。nginx设置看起来不错。你还有app.UseHsts()吗?”;和/或应用程序启动时的app.UseHttpsRedirection()?或者可能是certbot安装程序有问题,与应用程序无关。我已尝试添加和删除这两个选项。我们将尝试certbot配置,并相应更新。