ELB 将 443/80 重定向到 nginx docker 容器上的单个端口
ELB redirecting 443/80 to single port on nginx docker container
我们有一个 public AWS ELB,它正在像这样重定向流量:
HTTP 80 HTTP 9001
TCP 443 TCP 9001
目标实例是 运行 docker 带有 nginx 容器的 AWS ECS 实例。
Docker转发9001->8080,nginx监听8080。
这是 nginx 配置的片段:
server {
ssl on;
ssl_certificate /etc/nginx/mydomain.crt;
ssl_certificate_key /etc/nginx/mydomain.key;
listen 8080;
server_name %{ROUTER_CLEARCARE_SERVER_NAME};
access_log /var/log/nginx/access.log logstash_json;
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
set $target_web "web.mydomain.com:80";
location / {
proxy_read_timeout 180;
proxy_connect_timeout 2;
proxy_send_timeout 180;
keepalive_timeout 180;
resolver 10.10.0.2 valid=30s;
proxy_set_header Host $host;
proxy_pass http://$target_web;
proxy_set_header X-Unique-ID $request_id;
}
}
我需要在 nginx 容器上执行 SSL 终止,因为我们有多个域的多个证书,并且我们正在使用具有不同超时的基于路径的路由(ELB 仅支持单个证书,而 ALB 不支持基于路径的路由具有不同的超时和证书)。
关键是:nginx 只能监听一个端口(我们正在使用一个名为 Empire 的工具将 nginx 容器部署到 AWS ECS,他们目前只支持这种配置)。
nginx 可以在单个端口上支持 http 和 https 吗?
现在,使用该配置,我在尝试点击 http://example.com:
时遇到此错误
The plain HTTP request was sent to HTTPS port
当我尝试点击 https://example.com 时出现此错误 我收到此错误:
mydomain.com redirected you too many times.
我发现了一个声明,在 this serverfault page (check out 2nd answer from Komu). I repeat it below, so you can find it more easily. Can you try it? If you are not bound to NginX, you might als be interested in this node.js plugin 上 NginX 应该可以监听 HTTP 和 HTTPS,这也允许在同一端口上监听 HTTP 和 HTTPS。
quoted from here:
According to wikipedia article on status codes, Nginx has a custom
error code when http traffic is sent to https port (error code 497)
And according to nginx docs on error_page, you can define a URI that
will be shown for a specific error. Thus we can create a uri that
clients will be sent to when error code 497 is raised.
#lets assume your IP address is 89.89.89.89 and also that you want nginx to listen on port 7000 and your app is running on port 3000
server {
listen 7000 ssl;
ssl_certificate /path/to/ssl_certificate.cer;
ssl_certificate_key /path/to/ssl_certificate_key.key;
ssl_client_certificate /path/to/ssl_client_certificate.cer;
error_page 497 301 =307 https://89.89.89.89:7000$request_uri;
location / {
proxy_pass http://89.89.89.89:3000/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
However if a client makes a request via any other method except a GET,
that request will be turned into a GET. Thus to preserve the request
method that the client came in via; we use error processing redirects
as shown in nginx docs on error_page
And thats why we use the 301 =307 redirect.
Using the nginx.conf file shown here, we are able to have http and
https listen in on the same port
我们有一个 public AWS ELB,它正在像这样重定向流量:
HTTP 80 HTTP 9001
TCP 443 TCP 9001
目标实例是 运行 docker 带有 nginx 容器的 AWS ECS 实例。
Docker转发9001->8080,nginx监听8080。 这是 nginx 配置的片段:
server {
ssl on;
ssl_certificate /etc/nginx/mydomain.crt;
ssl_certificate_key /etc/nginx/mydomain.key;
listen 8080;
server_name %{ROUTER_CLEARCARE_SERVER_NAME};
access_log /var/log/nginx/access.log logstash_json;
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
set $target_web "web.mydomain.com:80";
location / {
proxy_read_timeout 180;
proxy_connect_timeout 2;
proxy_send_timeout 180;
keepalive_timeout 180;
resolver 10.10.0.2 valid=30s;
proxy_set_header Host $host;
proxy_pass http://$target_web;
proxy_set_header X-Unique-ID $request_id;
}
}
我需要在 nginx 容器上执行 SSL 终止,因为我们有多个域的多个证书,并且我们正在使用具有不同超时的基于路径的路由(ELB 仅支持单个证书,而 ALB 不支持基于路径的路由具有不同的超时和证书)。
关键是:nginx 只能监听一个端口(我们正在使用一个名为 Empire 的工具将 nginx 容器部署到 AWS ECS,他们目前只支持这种配置)。
nginx 可以在单个端口上支持 http 和 https 吗?
现在,使用该配置,我在尝试点击 http://example.com:
时遇到此错误The plain HTTP request was sent to HTTPS port
当我尝试点击 https://example.com 时出现此错误 我收到此错误:
mydomain.com redirected you too many times.
我发现了一个声明,在 this serverfault page (check out 2nd answer from Komu). I repeat it below, so you can find it more easily. Can you try it? If you are not bound to NginX, you might als be interested in this node.js plugin 上 NginX 应该可以监听 HTTP 和 HTTPS,这也允许在同一端口上监听 HTTP 和 HTTPS。
quoted from here:
According to wikipedia article on status codes, Nginx has a custom error code when http traffic is sent to https port (error code 497)
And according to nginx docs on error_page, you can define a URI that will be shown for a specific error. Thus we can create a uri that clients will be sent to when error code 497 is raised.
#lets assume your IP address is 89.89.89.89 and also that you want nginx to listen on port 7000 and your app is running on port 3000 server { listen 7000 ssl; ssl_certificate /path/to/ssl_certificate.cer; ssl_certificate_key /path/to/ssl_certificate_key.key; ssl_client_certificate /path/to/ssl_client_certificate.cer; error_page 497 301 =307 https://89.89.89.89:7000$request_uri; location / { proxy_pass http://89.89.89.89:3000/; proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Protocol $scheme; } }
However if a client makes a request via any other method except a GET, that request will be turned into a GET. Thus to preserve the request method that the client came in via; we use error processing redirects as shown in nginx docs on error_page
And thats why we use the 301 =307 redirect.
Using the nginx.conf file shown here, we are able to have http and https listen in on the same port