17

I want to configure Nginx reverse proxy server which will redirect all of the requests it gets by HTTP to my AWS Api Gateway endpoint which is HTTPS (its a GET method). (If you want to know why, the reason for this is that I have an AWS Lambda function which I want a 3rd party vendor to call via Api Gateway, but he currently has a bug with ssl_handshake with AWS, probably because of SNI. So I will give him this HTTP proxy server).

I've tried something like this:

server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  MY_SERVER_NAME;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_pass https://SOMETHING.execute-api.REGION.amazonaws.com/dev/RESOURCE/METHOD;               
                proxy_ssl_server_name on;
                proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                proxy_buffering off;
        }
}

But currently I'm getting 403 from CloudFront when I try to call to

http://MY_SERVER_NAME

I feel like I'm missing something in my SSL configurations at Nginx but I'm not sure what.

yishaiz
  • 2,433
  • 4
  • 28
  • 49
  • 1
    Other customers have opted to put a CloudFront distribution in front of their API Gateway API to work around API Gateway's SNI requirements. – Bob Kinney Sep 20 '16 at 15:48
  • This is working! Thanks. Is there any guide out there to do that? It wasn't easy. Also, its quite ugly to use CDN service to be a proxy without cache as I just did - could it work with other service, maybe AWS LoadBalancer? – yishaiz Sep 21 '16 at 15:30
  • Elastic Load Balancer can only send traffic to EC2 instances. – Bob Kinney Sep 21 '16 at 19:32

2 Answers2

17

Your issue was that you were setting the HTTP Host header that will be sent to AWS API Gateway to the wrong value.

API Gateway needs the HTTP Host header to be set to its own host, e.g. to SOMETHING.execute-api.REGION.amazonaws.com

So you should have:

proxy_set_header Host $proxy_host;

instead of:

proxy_set_header Host $host;

In fact you don't have to explicitly set the proxy Host header because, if not set, Nginx will default it to $proxy_host

See Nginx docs on this

Otto
  • 1,787
  • 1
  • 17
  • 25
1

As @Bob Kinney suggested in the comments, I've implemented the Proxy by using AWS CloudFront instead of this Nginx custom Proxy server.

These are the steps:

  1. Go to Distributions and create new Distribution.
  2. Set the Origin as the S3 bucket of the Lambda function.
  3. Create new Origin in this distribution and leave fields as default except of:
    • set its Origin Domain Name to the ApiGateway endpoint of the Lambda function. E.g. t7mcsqqzcl.execute-api.us-west-1.amazonaws.com
    • Set Origin Protocol Policy as HTTPS Only
  4. Create new Behaviour for the new Origin and set the following:
    • Path Pattern: *
    • Viewer Protocol Policy: HTTP and HTTPS
    • Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
    • Forward Headers: None
    • Forward Cookies: None
    • Query String Forwarding and Caching: Forward all, cache based on all
  5. Check that the new Behaviour is with Precedence 0 so it’s before the other default behaviour of the S3 Origin.

Now we have the Domain Name for our distribution, e.g. d12q4segwfrwl5.cloudfront.net, and we can activate our API, e.g. call http://d12q4segwfrwl5.cloudfront.net/dev/person/name

An example of the json configurations of the CloudFront distribution can be found here.

yishaiz
  • 2,433
  • 4
  • 28
  • 49
  • Why is there a need of point 2.Set the Origin as the S3 bucket of the Lambda function? – Sachin Gupta Jan 28 '17 at 09:55
  • Sorry but I don't remember now the reason. That's what I saw was done in the little docs I've found for this in the internet. Maybe for serving the Lambda code? You are welcome to try without it, if it works please post an update. – yishaiz Jan 29 '17 at 08:56
  • 1
    This is not an answers, the question is about nginx -> aws api gateway. – code_ada Aug 25 '18 at 09:17
  • @code_ada you are right - so I've marked the other answer as accepted. I'm keeping this answer as well in case it will help someone as it helped me. – yishaiz Jan 10 '19 at 14:46