1

I have two VPCs: A and B.

I want any node in A to be able to open a TCP connection to any node in B, but not the other way around. Any node in B must also be able to open outgoing connections to public internet hosts. What is the best way to achieve this?

Use case: VPC A contains many sensitive internal services, and VPC B contains nodes that run completely untrusted code. VPC A needs to make HTTP requests to VPC B, but none of the internal services must be exposed.

VPC peering allows direct connections between any nodes in A and B - this cannot be restricted on a routing level. Security groups can be used to block outgoing connections, but is slightly tricky to configure since there is no DENY rule.

Network ACLs aren't useful here, since return traffic must be allowed back from B -> A.

Are there any other options? Something like a NAT gateway, that only allows opening connections in one direction? AWS does support private NAT gateways, but I cannot find any documentation for a configuration like this.

Ralf
  • 169
  • 7

2 Answers2

3

I didn't read your answer in detail but it seems a bit off. I don't know why you're using NAT gateways at all, they're purely to allow instances in private subnet to access the internet.

A key here is the single direction communication which strongly suggests security groups are the answer. My solution (without thinking too hard would be):

  • VPC peering between the two VPCs, different CIDR ranges
  • Route table in both VPCs to enable communications
  • Security groups in VPC A to allow outgoing traffic to VPC B CIDR ranges, but not incoming. This will allow outward traffic and return traffic but not traffic initiated in VPC A
  • Security groups in VPC B allow incoming traffic from VPC A CIDR, but does not allow outgoing. This lets traffic in and lets it return but does not let traffic initiated in A to get to B
  • Internet gateway in VPC B. If you don't need the internet to reach into VPC B then you can use a NAT gateway in VPC B.
Tim
  • 31,888
  • 7
  • 52
  • 78
  • The trickiest part in this setup is "Security groups in VPC B allow incoming traffic from VPC A CIDR, but does not allow outgoing". I need to allow outgoing traffic to the public internet from VPC B, but not to VPC A. Since there are no "DENY" rules in security groups, I do have the workaround of allowing outgoing traffic to a list of 33 CIDR blocks that _should_ cover all public internet access. NAT gateways do seem to work perfectly fine for internal traffic, even if it's not a common setup. – Ralf Dec 22 '21 at 08:43
  • I strongly suggest you do some AWS training, or at least do some reading on security groups. This is not a difficult scenario, you've solved it in quite a bizarre way that may have repercussions, and will cost you more in data / NAT charges. I'm fairly well trained / certified / experienced with AWS I had no idea that a NAT gateway could do anything other than provide private subnets internet access - you seem to be using it to get around the non-transitive nature of AWS VPC. This is really a simple problem and can be addressed with a simple solution. – Tim Dec 22 '21 at 18:04
  • The NAT gateway does add overheads and costs (negligible for this use case). It may be unconventional, but it adds options for additional layers of security on the subnet level, instead of only security groups. In the same way in more typical scenarios that you could use a public subnet and protect it with security groups, you get better isolation with private subnets + NAT gateway for internet access. The same applies here to a large extent. – Ralf Dec 23 '21 at 18:29
  • Ok, whatever works for you. Maybe keep in mind I've never heard of NAT Gateway being used like that before and there may be drawbacks that aren't obvious. You're not really using best practice, but if it works for you, great. – Tim Dec 23 '21 at 19:47
0

It seems like this can work by adding a private NAT gateway in a dedicated subnet.

This setup seems to work:

VPC A: 10.1.0.0/16

Subnet A1: 10.1.1.0/24. Main subnet containing the nodes in A.
Subnet A2: 10.1.2.0/24. Dedicated subnet for NAT gateway.

VPC B: 10.2.0.0/16

Subnet B1: 10.2.3.0/24: Main subnet containing the nodes in B.

Private NAT gateway in subnet A2. (nat-1)
VPC peering between VPC A and B. (pcx-1)

Route table for A1:

10.1.0.0/16 (A): local
10.2.3.0/24 (B1): nat-1

Route table for A2:

10.1.0.0/16 (A): local
10.2.3.0/24 (B1): pcx-1

Route table for B1:

10.2.0.0/16 (B): local
10.1.2.0/24 (A2): pcx-1

Since there is no direct route between A1 and B1, all traffic has to go through the NAT gateway. And the NAT gateway only allows incoming connections from the same VPC, so there is no way for a node in B1 to open a connection to a node in A1.

Security groups and network ACLs can be used as additional layers of security here, and the config would be fairly simple with this split in subnets. But it would also be redundant, since there is no route from B1 to A1.

Ralf
  • 169
  • 7
  • If there's no route from B to A then you won't get any return data. "It won't know where to go". Tim's answer is right on point. – Oscar De León Dec 18 '21 at 10:53
  • There is no _direct_ route from B1 to A1. There is a route from B1 to A2, and return traffic passes back through that NAT gateway. – Ralf Dec 22 '21 at 08:45