Search code examples
amazon-web-servicesnginxamazon-s3amazon-cloudfrontproxypass

NGINX proxy_pass 5xx errors showing html file hosted on S3+CloudFront


I'm struggling on my nginx 1.4.6 config because I can't proxy pass 5xx and 4xx errors setting an html file hosted in an S3 bucket, using the CDN address instead of the direct bucket address instead. I want to do this so that if I change the origin of the distribution, I don't have to manually change all my nginx configurations in all my servers.

the relevant part of my working config is:

error_page 400 404 @error;
error_page 502 503 @maintenance;

location @maintenance {
      rewrite ^(.*)$ /mybucket/error_pages/under_construction.html break;
                    proxy_pass https://s3-eu-west-1.amazonaws.com;
}

location @error {
      rewrite ^(.*)$ /mybucket/error_pages/under_construction.html break;
                    proxy_pass https://s3-eu-west-1.amazonaws.com;
}

but as you can see I had to proxy using the url of my S3 bucket. https://s3-eu-west-1.amazonaws.com

I then created a CloudFront distribution which origin is the S3 bucket mybucket with a CNAME mybucket.mywebsite.com.

I tried then to change the config to this:

error_page 400 404 @error;
error_page 502 503 @maintenance;

location @maintenance {
      rewrite ^(.*)$ /error_pages/under_construction.html break;
                    proxy_pass https://mybucket.mywebsite.com;
}

location @error {
      rewrite ^(.*)$ /error_pages/under_construction.html break;
                    proxy_pass https://mybucket.mywebsite.com;
}

but that doesn't work, and I don't get why.

Any suggestions about this? Is this a feasible thing to do?

Thanks, Simone


Solution

  • I finally found the solution myself.

    I added proxy_ssl_server_name on; in server context (so as it is included globally since I use it in several parts of my config) to enable passing of the server name through TLS Server Name Indication extension (SNI, RFC 6066) when establishing a connection with the proxied HTTPS server. This is necessary because the proxy target is a CloudFront distribution with http to https redirection and SSL.

    Unfortunately that option was introduced from nginx 1.7.0, so I had also to update my nginx version to the last (1.14 in my case), adding the nginx ppa.

    Once set that configuration, you are able to use this syntax without problems.

    error_page 400 404 @error;
    error_page 502 503 @maintenance;
    
    location @maintenance {
          rewrite ^(.*)$ /error_pages/under_construction.html break;
                        proxy_pass https://mybucket.mywebsite.com;
    }
    
    location @error {
          rewrite ^(.*)$ /error_pages/under_construction.html break;
                        proxy_pass https://mybucket.mywebsite.com;
    }
    

    Hope it could help others.

    Simone