yishaiz
yishaiz

Reputation: 2583

Nginx proxy_pass to aws Api Gateway

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.

Upvotes: 17

Views: 14553

Answers (2)

Otto
Otto

Reputation: 2066

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

Upvotes: 17

yishaiz
yishaiz

Reputation: 2583

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.

Upvotes: 1

Related Questions