6

I'm trying to connect Api Gateway with my api in Elastic Beanstalk. I want my api only accesible by Api Gateway and for this I use client-side SSL certificate authorization in backend (like this aws publication Link:http://docs.aws.amazon.com/es_es/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html). So my arquitecture is like this:

API GATEWAY->ELASTIC LOAD BALANCER->EC2 (ELASTIC BEANSTALK)

My EC2 machine have NGINX and Ruby.

The connections work like this:

API GATEWAY -> (80 PORT) -> ELASTIC LOAD BALANCER -> (443 PORT) -> NGINX -> RUBY

I am doing the client auth in NGINX. When I access the Elastic Load Balancer using a browser, it shows 400 Bad Request - NGINX error: No required SSL certificate was sent (this is correct because I'm not sending the certificate). But when I access using Api Gateway and sending the client certificate I get the same error (I don't understand why).

When I configure the SSL connection in NGINX, I'm using SSL certificates signed by me (maybe this is the problem?)

Other posible cause for my problem is the port configuration in Elastic Load Balancer (in the picture). I have Backend Authentication: Disabled. Is this a problem? Pictura Port Config ELB

My nginx configuration is:

upstream my_app {
  server unix:///var/run/puma/my_app.sock;
}

log_format healthd '$msec"$uri"'
                '$status"$request_time"$upstream_response_time"'
                '$http_x_forwarded_for';

server {
listen       443 ssl;
listen       [::]:443 ssl;
server_name  localhost;
root         /usr/share/nginx/html;

ssl on;
ssl_certificate /etc/nginx/ssl/dev.crt;
ssl_certificate_key /etc/nginx/ssl/dev.key;
ssl_trusted_certificate /etc/nginx/ssl/api-gateway.pem;
ssl_client_certificate /etc/nginx/ssl/api-gateway.pem;
ssl_verify_client on;

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
if ($ssl_client_verify = FAILED) {
        return 495;
}
if ($ssl_client_verify = NONE) {
    return 402;
}
if ($ssl_client_verify != SUCCESS) {
    return 403;
}
try_files $uri/index.html $uri @my_app;
  location @my_app {
    proxy_set_header  Host $host;
    proxy_set_header  X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Host $server_name;
    proxy_set_header  Client-IP $remote_addr;
            proxy_pass        http://my_app;
    proxy_set_header X-Client-Verify $ssl_client_verify;
  }
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
    proxy_pass http://my_app; # match the name of upstream directive which is defined above
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header gonzalo1 $ssl_client_verify;
}
error_page 404 /404.html;
    location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
    location = /50x.html {
}

}

Gonzalo Garcia
  • 103
  • 1
  • 6
  • The doc link is about calling Api Gtw with a client certif not about calling your beanstalk with Api Gtw client certif. Do I missed something? You know Api Gtw client certificates are here for calling Api Gtw not calling other thing with Api Gtw! – fsenart Feb 01 '17 at 17:34
  • @fsenart, according to what i understand, the certificate in this case is for call to the back end from Api Gateway, and with the certificate the back end can auth that the request is from Api Gateway. In the first paragraph of the link is very clear. – Gonzalo Garcia Feb 01 '17 at 18:13
  • No, @fsenart, client certificates are used by API Gateway to authenticate itself to the app server. – Michael - sqlbot Feb 02 '17 at 00:19
  • ...but this doesn't work with the ELB listening on port 80 and doesn't work with the ELB in http mode. It has to be in TCP mode. – Michael - sqlbot Feb 02 '17 at 00:20

1 Answers1

2

Amazon API Gateway does not support self-signed certificates for integration endpoints. Have you tried using a certificate from Amazon Certificate Manager or Let's Encrypt?

Stefano Buliani
  • 974
  • 7
  • 8
  • That's also true, but not the cause of this particular issue. This will be the answer to OP's next question when solution here creates a new error. :) – Michael - sqlbot Feb 02 '17 at 00:17
  • Hi, where you able to accomplish this using nginx and how? – Manuel Ortiz Bey Feb 27 '17 at 13:20
  • @Stefano How do we push Client Side Certificate (the one provided by API Gateway) using AWS Certificate Manager. ? Any ideas, thoughts ? – Nishutosh Sharma Feb 14 '18 at 10:09
  • @NishutoshSharma Unfortunately there is no way to do this now. API Gateway does not give you access to the private key for the certificate. I'll add this as a feature request. – Stefano Buliani Feb 15 '18 at 20:55
  • @StefanoBuliani You can answer another question here. In detail for a solution ? https://stackoverflow.com/questions/48782619/aws-api-gatway-client-side-certificate-with-aws-certificate-manager-for-elastic – Nishutosh Sharma Feb 15 '18 at 22:34
  • @StefanoBuliani Can I configure the API Gateway's Client Side Certificate at ELB ? – Nishutosh Sharma Feb 19 '18 at 06:56
  • Unfortunately not. ELB currently does not support mutual TLS. The best way to do this at the moment is to set the ELB in TCP load balancer mode and terminate HTTPS on your hosts. You can then configure your web server to perform mutual TLS auth. API Gateway recently release VPC integration. I would probably look at this rather than mutual TLS at the moment: https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/ – Stefano Buliani Feb 20 '18 at 16:14