1

I have an nginx server running on port 8080 that sits behind an AWS Application Load Balancer. I have the following location block in the nginx.conf,

location / {
            limit_except GET { deny all; }
            root /root/of/project/;
            index index.html;
            try_files $uri $uri/ /index.html;
}

When I run the server locally, I am able to hit /some/path/ and /some/path and get the same response, i.e. the trailing slash doesn't affect anything. I would expect the same behavior when I deploy the application.

I set up the AWS ALB with an HTTP listener on port 80 that redirects all traffic to the HTTPS listener on port 443. The HTTPS listener simply forwards to the target group where the nginx server lives. Those are the only two load balancer rules I have, nothing else.

After I deploy the app, when I hit a url with a trailing slash (say, https://example.com/about/), everything is fine. It loads as expected. No redirects or anything. I can see the request come through in the nginx logs.

However, if I hit a URL without a trailing slash, e.g.

https://example.com/about

The ALB redirects to

http://example.com:8080/about/

and then never loads. I never see any logs on the nginx server for that request, which means it never got passed from the ALB to the target group. The request times out after a few minutes.

It seems like the ALB might be trying to forward the request to the target group, since 8080 is the port the nginx server runs on, but I'm not sure why the request never arrives. It doesn't seem like the trailing slash should affect whether or not the request is forwarded, but I'm not sure.

I thought maybe I could set up a rule that redirects a route without a trailing slash to the same route with a trailing slash on the ALB level, but load balancer rules only have wildcards, no regular expressions. So, that's a deadend. I'm not sure that would even solve the problem, though, since the problem seems to be on the ALB level, not the application level.

Does anyone have any idea what's going on?

EDIT: Load balancer rules: http load balancer rule https load balancer rule

Grant Moore
  • 153
  • 1
  • 10
  • This setup makes no sense to me. You should do SSL termination at ALB. Can you show your redirect rules? – StefanN Jul 21 '21 at 15:23
  • images now included of the load balancer rules. what would be a better setup? – Grant Moore Jul 21 '21 at 16:06
  • The rules in the screenshot are doing the opposite of the behavior you describe, so I don't see how it could be the load balancer. It sounds like you may have some sort of redirect happening in Nginx, or in a proxy target of Nginx. – Mark B Jul 23 '21 at 19:55
  • Traffic -> HTTP Listener -> Redirect To -> HTTPS Listener -> Forward To -> Target Group. Before it reaches the target group, it gets decrypted by the load balancer. That is where I have the certificate deployed. The target group receives normal HTTP traffic. What is incorrect in that setup? Where is my misunderstanding? – Grant Moore Jul 24 '21 at 16:28

2 Answers2

2

Had this problem yesterday, I only have an ALB listener on 443 and nginx is open on 80, I think I fixed it with "absolute_redirect off;" in nginx config. My full conf file:

server {
listen       80;
absolute_redirect off;

location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ $uri/index.html =404;
}

error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /usr/share/nginx/html;
}
}
0

A better setup would be to simply do SSL termination at your ALB and then create a HTTP listener with a forward rule which has your target group as the destination. This has multiple benefits in terms of simplified management of the certificates, performance and so forth.

Read here about setting up HTTP listener

Best, Stefan

StefanN
  • 527
  • 1
  • 4
  • 12
  • i'm confused. the certificate exists on the load balancer level, not the server. i thought the HTTPS listener automatically decrypted the request before forwarding it to the target group? isn't that the point of specifying the ip and protocol in the target group? are you telling me the load balancer forwards HTTPS to the server without decrypting it? because that wouldn't make sense, as the current set up works fine when the trailing slash is included in the URL. – Grant Moore Jul 22 '21 at 10:12
  • Yes, this is correct: "the certificate exists on the load balancer level, not the server." And also the HTTPS listener will terminate SSL (decrypt request). I am suggesting to set it up like that and use forwarding rule instead of the redirect rule in your HTTPS listener. – StefanN Jul 22 '21 at 10:58
  • i don't have a redirect rule on the HTTPS listener. i have a forwarding rule that routes traffic to the target group where the nginx server is. – Grant Moore Jul 22 '21 at 13:09
  • Sorry, I misread your question. The ALB setup looks good to me. It think the issue is not on ALB side, but on the target group instances. – StefanN Jul 23 '21 at 11:12
  • As in the target group configuration or the nginx configuration from the instance itself? – Grant Moore Jul 23 '21 at 13:44
  • I mean the nginx configuration. Try removing all locations if you have some. I think it should work fine with the "default config". – StefanN Jul 23 '21 at 13:46
  • If it were the nginx configuration, it should exhibit the same behavior locally, I would think. But when I run the server locally, I don't have the trailing slash issue. I feel like the crux of the issue is why the ALB appends a trailing slash when it forwards to the target group. The request hangs when you hit /some/path and the ALB forwards it to the target as /some/path/, but not when you hit /some/path/, which is very strange to me. I'm not sure how the ALB is forwarding the request in the second case. It's like the ALB is issuing a redirect to HTTP in the second case instead of fowarding. – Grant Moore Jul 23 '21 at 14:07