node.jsamazon-web-servicesamazon-ec2aws-lambda

Security group setup to restrict EC2 to VPC lambda


I have an EC2 and lambda in the same VPC. The EC2 is running a web server, and I only want it accessible via my lambda (and ssh), so I set the EC2 security group to have inbound rule http-tcp-80-LambdaSecurityGroup (and ssh-tcp-22-MyHomeIP).

The LambdaSecurityGroup allows all outbound traffic (1 rule: AllTraffic-All-All-0.0.0.0/0). The lambda is in private subnets, and connects to the internet using a NAT gateway. Basically I setup lambda as described in Access Resources in a VPC from Your Lambda Functions, Giving Lambda functions access to resources in an Amazon VPC, and the first answer in Stack Overflow - AWS security group inbound rule.

When I (use AWS console's Test to) run my lambda, it does not connect to EC2 (times out after 10-11 seconds). But if I change the EC2 security group to allow inbound http-tcp-80-0.0.0.0/0 (Anywhere IPv4), then everything works as expected (EC2 web server receives lambda request and replies).

But of course I don't want to open up my EC2 web server to the entire public, so how can I get my EC2 to only allow the http (post) requests coming from my lambda?

Reasoning / Debugging:

Additional Details:

const postRequestData = { key1: value1, key2: value2 };
return new Promise((resolve, reject) => {
    fetch('http://1.2.3.4/post:80', {   // Note: uses EC2 public IPv4 address
        method: 'post',
        body: JSON.stringify(postRequestData),
        headers: {'Content-Type': 'application/json'}
    })
    .then((response) => {
        console.log("Response: ", response);
        resolve(response);
    })
    .catch(err => {
        console.log("ERROR: Could not fetch response: ", err);
        reject("EC2 unavailable.");
    });
});

Solution

  • The issue is actually with using the public EC2 IP, isn't it?

    When you use the public IP, the Lambda function exits your VPC. So, within a VPC, it's generally more effective and secure to use the private IP for communication.