简体   繁体   中英

AWS private API Gateway through VPC Endpoint

First of all I am very new to AWS. Here is what i'm trying to achieve:

  • 1 VPC
    • 2 Subnet
      • 1 public that contain some EC2 instance
      • 1 private that contain an API Gateway only accessible by the EC2 instance

The public subnet is working perfectly well, I can access SSH and HTTP. The private subnet cause me a little trouble. For debug purpose i launched off an EC2 instance in it. From one of the "public instance" I am able to ping the "private instance" private IP (Well there is no public IP obviously)

Following the documentation, I created a VPC Endpoint in my private subnet which created a Network interface where i attached a security group that allow HTTP(S) (80 and 443) from the whole VPC CIDR. The endpoint type is Interface

So, now i have a private subnet with an Endpoint that allow HTTP(S) traffic. That endpoint have some (private) DNS NAME and (probably) also a private IP (Could not find it)

Now I want to add an API Gateway to front some AWS lambda. I create said API and as an Endpoint Type -> Private

Following this : Official Documentation The "only" way to "link" the API Gateway to the VPC Endpoint is to add a resource policy. So I input the following

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Deny",
        "Principal": "*",
        "Action": "execute-api:Invoke",
        "Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API GATEWAY ID>/*/*/<MY RESOURCE>",
        "Condition": {
            "StringNotEquals": {
                "aws:sourceVpce": "<VPC ENDPOINT ID>"
            }
        }
    },
    {
        "Effect": "Allow",
        "Principal": "*",
        "Action": "execute-api:Invoke",
        "Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API GATEWAY ID>/*/*/<MY RESOURCE>"
    }
]

}

And for the sake of completeness here is my lambda (python3.6):

from __future__ import division
def lambda_handler(event, context):
  return {
      "statusCode":200,
      "headers": {"Content-Type": "application/json" },
      "body" : "It work!"
  }

Finally the problem:

What would be the URL to invoke this REST Api! API Gateway (In the lamdba Console) Tell me this:

https://<API GATEWAY ID>.<REGION>.amazonaws.com/<MY STAGE>/<MY RESOURCE>

Ok! Lets call that url: APIURL I ssh to the EC2 instance in the public subnet and run the following:

curl https://$APIURL

And it work: It output: "It work!" but that APIURL does not seem to come from the VPC endpoint so I try the following (still from the public subnet EC2):

curl https://vpce-XXXXXXX-XXXX.execute-api.REGION.vpce.amazonaws.com/<MY STAGE>/<MY RESOURCE>

And i get: {"message":"Forbidden"}

That does not seem right. As i test i change de API Gateway resource policy for the following:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Deny",
        "Principal": "*",
        "Action": "execute-api:Invoke",
        "Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API ID>/*/*/<MY RESOURCE>"
    }
]

}

And NOTHING changed. The APIURL is still working and the VPCE Url still give me forbidden.

What am I doing wrong? My apologies for the long post.

A policy role update does not take effect until the api has been deployed to a stage.

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-create-attach.html

If you update the resource policy after the API is created, you'll need to deploy the API to propagate the changes after you've attached the updated policy.

As your API url is working fine,there seems to be a problem with the policy.
In IAM policy Deny permission will override the Allow permission. Try changing your policy to the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws:execute-api:region:account-id:api-id/*",
            "Condition": {
              "StringEquals":{
                             "aws:SourceVpce": "<VPC Endpoint ID>"
                         }
                       }
                    ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws:execute-api:region:account-id:api-id/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "<VPC Endpoint ID>"
                }
            }
        }
    ]
}

For further reference, follow this link:
https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM