对不起的编辑历史,但这个问题是真的不清楚我,很难找到确切的问题。
我有一个**.Net-CoreWeb应用程序,它在Nginx**后面运行,X-Forwarded-Proto总是传递http
而不是https
。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//first middlewear
app.UseForwardedHeaders();
//and the rest
}
字符串
Nginx配置文件
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:5001/;
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;
}
}
型
Nginx.conf
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
#cloudflare real ip
#https://support.cloudflare.com/hc/en-us/articles/200170786-Restoring-original-visitor-IPs-Logging-visitor-IP-addresses-with-mod-cloudflare-#12345681
set_real_ip_from 173.245.48.0/20;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
log_format main '"$scheme" $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
型
access.log记录
"http" 185.108.83.156 - - [03/Oct/2019:19:59:33 +0300] "GET /auth/signin/Facebook?returnUrl=%2F HTTP/1.1" 302 0 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" "156"
型
正如你所看到的,我记录的**$scheme总是HTTP**。
解决这个问题的一个解决方案是强制Scheme成为HTTPS,如下所示:
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
型
从https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#forwarded-headers-middleware-options下载
但是使用这个解决方案,我不传递头,并丢失了一些信息。
有没有人对这个案子有什么解决办法?
6条答案
按热度按时间mwecs4sa1#
您的Startup.cs文件正常,但您没有为Kesterl配置ssl。
您需要为.net core应用程序配置X.509 ssl证书
来自https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2#when-to-use-kestrel-with-a-reverse-proxy-1
只有反向代理服务器需要X.509证书,并且该服务器可以使用普通HTTP与内部网络上的应用程序服务器通信
所以,在你的情况下,你有7个主要步骤要做:
**1)从CloudFlare ORIGIN CA获取SSL证书 *2)在您的服务器上安装SSL证书 *3)创建PFX文件,以便您的Kesterl服务器可以读取它。*4)配置Kesterl https端点。5)修改Nginx服务器以侦听端口443,然后重定向到Kestrel侦听端口 6)根据您的配置修改服务文件 * 7)将Cloudflare更改为运行严格模式
步骤1 -从cloudflare获取ssl证书:
转到Cloudflare的 Jmeter 板并选择SSL/TLS --> Origin Server -->Create Certificate。按照说明操作,您将在过程结束时获得2个文件:
example.com.key
example.com.pem
第2步-将文件放在您的服务器上的
etc/ssl
文件夹第3步-创建PFX文件,以便Kesterl可以使用证书:
在你的服务器上运行这个:
字符串
这将生成example.pfx,将其放在同一个文件夹中。
步骤4 -配置Kesterl https端点。
从第3步开始,您应该已经获得了在此步骤中需要使用的密码。
在您的
appsetting.json
中放置以下行:型
Step 5 -配置Nginx监听443端口,如下所示:
型
第六步-配置服务文件:
型
第7步-在SSL/TLS上更改Cloudflare以使用严格模式
重新启动你的应用程序+ Nginx,你的服务器现在应该像这样工作:
请求--> Cloudflare(HTTPS)--> Nginx(HTTPS)--> Example.com
11dmarpk2#
你只在80端口上运行nginx,没有ssl,所以,
$scheme
变量将永远是http
。参见http://nginx.org/r/$scheme。如果您关心HTTPS,那么也使用HTTPS保护Cloudflare和后端之间的连接可能是一个好主意;这样,您的
$scheme
变量将被正确填充。否则,您也可以硬编码https
来代替$scheme
,但这样就无法在真实的和最终的.Net后端上进行条件测试和重定向。wfsdck303#
一般来说,HTTP的Header不接受非ASCII字符。URL在生成时必须正确编码,Redirect方法不会为您做这件事。
一个快速修复可能是使用
WebUtility.UrlEncode
字符串
j5fpnvbx4#
请在nginx文件中设置适当的字符集。
以下是文档http://nginx.org/en/docs/http/ngx_http_charset_module.html#charset_types
pdtvr36n5#
这看起来是你的NGinx文件和Cloudflare设置方式的问题。从配置中,你的设置是
HTTPS->Cloudflare->HTTP->您的服务器
这就是为什么Scheme在你的nginx日志中总是“http”。由于Cloudflare通过HTTP将请求传递到你的服务器。你应该在Cloudflare和你之间设置TLS,这将在你的nginx配置上启用端口443,这将把scheme设置为HTTPS。强迫dotnet相信它是通过HTTPS处理的是无效的,因为Cloudflare正在通过公共互联网发送未加密的客户端数据。
https://support.cloudflare.com/hc/en-us/articles/115000479507-Managing-Cloudflare-Origin-CA-certificates
Cloudflare的文档列出了如何使用NGinx进行设置。
lo8azlld6#
我也遇到过类似的问题。默认情况下,
ForwardedHeadersOptions.KnownProxies
只允许代理IP为127.0.0.1
- Source。如果启用Microsoft: Debug
日志,您将看到类似以下内容:[12:25:25 DBG] Unknown proxy: [::ffff:x.x.x.x]:xxxxx
的值。该值为要解决此问题,您需要允许任何代理IP或将您的代理IP添加到KnownProxies和KnownNetworks:
字符串