如何检测是否已从 ssl 连接转发了 tcp 连接?
How can I detect if a tcp connection has been forwarded from a ssl connection?
我正在处理的具体情况是尝试连接到 AWS 弹性负载均衡器后面的 websocket 连接,同时强制执行 https/ssl 而不是 http/tcp。
要从 http/s 启用 TCP/SSL 升级,负载均衡器上的协议必须在端口 80 上设置为 TCP 而不是 HTTP,在 443 上设置为 SSL 而不是 HTTPS,这两者使用 TCP 转发到实例端口 80。
但是,将协议设置为 TCP/SSL 的一个副作用是 x-forwarded-proto
header 不再设置,如此处所示:
Amazon Elastic load balancer is not populating x-forwarded-proto header
这使得使用 http/tcp 到 https/ssl 对任何传入请求进行 301 处理的下一个挑战有些问题,因为这通常依赖于检查 x-forwarded-proto
header。
关于具体情况的更多细节:存在一个 docker 容器,其中有一个 Meteor.js 进程 运行,它又位于 AWS Elastic 中Beanstalk 应用程序(默认情况下有一个 Nginx 代理层,但由于使用 docker 只是从 docker 集线器中提取容器定义而无法访问),它位于上述 ELB 后面。
最终,当请求通过 ELB、Nginx 和 docker 代理层时,我将检查可供我的应用程序使用的 headers,试图计算出如果客户端发出的原始请求以 http 或 https
开头
传入 https://
请求 headers:
{
host: 'whatever.elasticbeanstalk.com',
'x-real-ip': '999.99.99.99',
'x-forwarded-for': '999.99.99.99',
'cache-control': 'max-age=0',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8'
}
传入 http://
请求 headers:
{
host: 'whatever.elasticbeanstalk.com',
'x-real-ip': '999.99.99.99',
'x-forwarded-for': '999.99.99.99',
'cache-control': 'max-age=0',
accept: 'image/webp,image/*,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8',
'if-none-match': '"141699-1446507991000"',
'if-modified-since': 'Mon, 02 Nov 2015 23:46:31 GMT'
}
其中唯一看起来有点用处的是 upgrade-insecure-requests
header,但基于此
我很确定不是。
也许我遗漏了什么...
当您使用 TCP 时,ELB 不会注入 HTTP headers,例如 x-forwarded-proto 或 x-forwarded-for。您也许可以在 configuring Proxy Protocol.
之前得到您需要的东西
如果问题实际上是"How can I ensure anyone visiting my website via http is redirected to https/ssl"(事实证明这就是我的意思),这可以通过
设置 Elastic Load Balancer 将 80 上的 HTTP 转发到实例上 80 上的 HTTP(而不是像以前那样在 80 上转发 TCP),然后将 443 上的 HTTPS 转发到实例上 80 上的 TCP实例.
"Assuming HTTPS/SSL" 在检测协议时:即检查是否存在x-forwarded-proto
,如果存在,则来自http请求,因此301到https。如果不存在,假设它是 https,不要重定向它(实际上我觉得我最好在重定向之前检查以确保协议是 http,但在当前设置中我很确定这是唯一的情况这可能会发生)。
我正在处理的具体情况是尝试连接到 AWS 弹性负载均衡器后面的 websocket 连接,同时强制执行 https/ssl 而不是 http/tcp。
要从 http/s 启用 TCP/SSL 升级,负载均衡器上的协议必须在端口 80 上设置为 TCP 而不是 HTTP,在 443 上设置为 SSL 而不是 HTTPS,这两者使用 TCP 转发到实例端口 80。
但是,将协议设置为 TCP/SSL 的一个副作用是 x-forwarded-proto
header 不再设置,如此处所示:
Amazon Elastic load balancer is not populating x-forwarded-proto header
这使得使用 http/tcp 到 https/ssl 对任何传入请求进行 301 处理的下一个挑战有些问题,因为这通常依赖于检查 x-forwarded-proto
header。
关于具体情况的更多细节:存在一个 docker 容器,其中有一个 Meteor.js 进程 运行,它又位于 AWS Elastic 中Beanstalk 应用程序(默认情况下有一个 Nginx 代理层,但由于使用 docker 只是从 docker 集线器中提取容器定义而无法访问),它位于上述 ELB 后面。
最终,当请求通过 ELB、Nginx 和 docker 代理层时,我将检查可供我的应用程序使用的 headers,试图计算出如果客户端发出的原始请求以 http 或 https
开头传入 https://
请求 headers:
{
host: 'whatever.elasticbeanstalk.com',
'x-real-ip': '999.99.99.99',
'x-forwarded-for': '999.99.99.99',
'cache-control': 'max-age=0',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8'
}
传入 http://
请求 headers:
{
host: 'whatever.elasticbeanstalk.com',
'x-real-ip': '999.99.99.99',
'x-forwarded-for': '999.99.99.99',
'cache-control': 'max-age=0',
accept: 'image/webp,image/*,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8',
'if-none-match': '"141699-1446507991000"',
'if-modified-since': 'Mon, 02 Nov 2015 23:46:31 GMT'
}
其中唯一看起来有点用处的是 upgrade-insecure-requests
header,但基于此
我很确定不是。
也许我遗漏了什么...
当您使用 TCP 时,ELB 不会注入 HTTP headers,例如 x-forwarded-proto 或 x-forwarded-for。您也许可以在 configuring Proxy Protocol.
之前得到您需要的东西如果问题实际上是"How can I ensure anyone visiting my website via http is redirected to https/ssl"(事实证明这就是我的意思),这可以通过
设置 Elastic Load Balancer 将 80 上的 HTTP 转发到实例上 80 上的 HTTP(而不是像以前那样在 80 上转发 TCP),然后将 443 上的 HTTPS 转发到实例上 80 上的 TCP实例.
"Assuming HTTPS/SSL" 在检测协议时:即检查是否存在
x-forwarded-proto
,如果存在,则来自http请求,因此301到https。如果不存在,假设它是 https,不要重定向它(实际上我觉得我最好在重定向之前检查以确保协议是 http,但在当前设置中我很确定这是唯一的情况这可能会发生)。