Public ELB accessible only from API Gateway


Is there a way to restrict my ELB to accept only calls from the API Gateway? I assume if it’s possible, it can be done with the Client side certificate of the API Gateway.

Generally I’m open to any alternative solution. What I need is to expose 1 api endpoint without making my EC2 instance/ELB completely public. I want calls coming in only via the API Gateway where I can limit the number of calls per second.


You’re correct, a client TLS (SSL) certificate on the back-side of API gateway would be the way to handle this, but ELB doesn’t currently support client side certificates when operating in http mode.

AWS support forum posts include AWS personnel mentioning the consideration of this capability as a feature request, but:

Unfortunately, at this moment we are not able to provide an ETA for this.

Of course, if the ELB were in TCP mode instead of HTTP, then your web servers could handle all of the SSL, including client side certificate validation, but TCP mode does not have the same advantages as HTTP mode in ELB.

My solution for this is HAProxy running on a separate instance, performing the same functionality as an ELB, including SSL termination and client cert validation. The instance is open to the world on port 443, but only SSL connections where the API gateway client certificate is presented are allowed to continue negotiating SSL and make an actual HTTP request, which is passed through to one of the back-end instances.

HAProxy is some very lean code, and I have systems handling hundreds of thousands of requests every day, with SSL, on t2.micro instances. I’ve also tested it successfully on the new t2.nano instances, which for < $5/month per machine is pretty much a no-brainer, and will have some of those going into production soon on relatively low traffic systems… just keep an eye on your credit balance so that you know when you need to scale it up.

You can also place HAProxy instances behind an ELB in TCP mode, with the proxy protocol enabled, if you want the front-end Internet-facing redundancy to be provided by ELB, with multiple HAProxy instances between the ELB and the app servers. This is a common configuration for me because HAProxy has HTTP routing capability, allowing the selection of the back-end group of servers to be chosen on a per-request basis so that, e.g., could be on one set of servers, and could be on a different set, all under the same domain name. (This is also a solid way to integrate S3 content without cross-origin issues, since the proxy can forward requests for certain paths to an S3 bucket, for example).

Of course, HAProxy can also limit the number of requests per second, itself, as well as the number of concurrent requests allowed, and can even enqueue a backlog of requests, releasing them one at a time to the back-end servers as other requests finish and open up a free slot.

Leave a Reply