What are the reasons to use private subnet in aws vpc? - amazon-web-services

I am trying to evaluate private and public subnets while creating a new VPC.
Is seclusion from inbound traffic from internet the only reason to go ahead with a private subnet? These points also need to be taken into account when considering the private subnet.
NAT Gateway is chargeable - 0.045$/hour and 0.045$ for per GB of data transferred. So there is cost consideration. I would need NAT gateway for pulling code or updates from internet.
I should be able to secure instances in my public subnets by using security groups with different levels of strictness.
When launching an instance I would assign a public ip to only those instances which I want to access from outside the VPC.
I went through this question but it didn't solve my doubts with respect to above points. Any help is appreciated.

From 7 Security Measures to Protect Your Servers:
Isolated Execution Environments
How Do They Enhance Security?
Isolating your processes into individual execution environments
increases your ability to isolate any security problems that may
arise. Similar to how bulkheads and compartments can help contain hull
breaches in ships, separating your individual components can limit the
access that an intruder has to other pieces of your infrastructure.
So, IMHO, do you need private subnets? Depends. In a production environment with public and private services, VPN, databases, etc., yes; but if you have only one server, and you don't want to deal with the configuration of network ACLs, routing, NAT, and so on, maybe a public subnet with your server and a well configured security group could be enough.

To answer your questions:
Use NAT instance (t2.small or m3.medium) instead of NAT gateway. Far cheaper.
Why launch them in public subnet and then tweak the security group if there is no need to accept the incoming internet traffic. There is always a chance to make a mistake in SG rules and allow malicious traffic unintentionally. Even if you want to accept internet traffic, I suggest using a reverse proxy like haproxy
Then launch only those instances in public subnet or use a reverse proxy
The private subnet is an extremely useful feature to protect your instances from DDoS, unauthorized access etc., Do not bypass it for the sake of convenience.

Related

Why do AWS recommend public and private subnets with a nat gateway?

I'll be complying with AWS best practise and having e.g. database instances inside a private subnet but I am wondering why this architecture is recommended?
AWS recommend this architecture so that the DBMS is not accessible to the outside world. If you want to patch it, or some other operation and it needs access to the internet, you should provision a NAT gateway in your public subnet. The DBMS instance in the private subnet can then get access to internet through this NAT gateway.
Could the same be achieved via security groups with the DBMS instance in the public subnet? It's worth noting that AWS charge around 40 USD / month for a NAT gateway.
On the DBMS instance you could have a security group rule which allows all outbound traffic but blocks inbound traffic (which I think is the default rule). This rule could be extended to only allow inbound traffic from a specific web server in the public subnet.
Is the answer that instances inside a public subnet automatically get a public IPv4 address? This would be undesirable for my DBMS instance even though it is effectively fire-walled through my security group rules as outlined above.
Thanks for your help in assisting me to understand AWS networking better.
You are right that this is the reference architecture, and you are indeed the not the first person to raise an eyebrow regarding the cost for the NAT Gateway.
It is true that the separation of public and private networks is an additional security layer that can prevent inadvertent exposure of your critical infrastructure to the public internet, but also to less privileged resources in your VPC.
Keep in mind that not every private subnet needs a NAT gateway; this is only necessary if the machines need to initiate traffic to the internet themselves. You could for example have pre-baked, regularily updated AMIs that don’t need the usual yum update at boot or any other such activities, and you might get away without the NAT Gateway.
Also, best practices doesn’t mean that it’s mandatory. For instance, if you deploy via Cloudformation, do regular security and architectural reviews and are sure to have SGs/NACLs/etc. set up properly, you could place the database in a “public” subnet as well. TL;DR: Use your own judgement to assess the tradeoff between security and cost, one way or the other.
Disclaimer: This is not the official position of AWS but my personal perspective.

Downside of using public subnet with strict whitelisting vs using private subnet for AWS cloud resources

AWS recommends using private subnets for private resources.
Use private subnets for your instances if they should not be accessed directly from the internet. Use a bastion host or NAT gateway for internet access from an instance in a private subnet.
However, I want to understand the rationale on how is this better on putting the resource, lets say an EC2 instance on a public subnet. Then add some very strict security group to prevent public access. How is this the less secure approach? Or is it technically the same outcome security wise?
I've never heard of a security group failing, so if you properly configure your security group with a restricted list of IP addresses/ports, you should be secure.
BUT
In a typical cloud-deployed application, you do not have or want strictly-controlled access. Instead, the typical cloud-deployed application is a web-app that exposes port 80 to the world.
And once you expose any port to the world, your security is entirely dependent on what is listening to that port. Do you have a vulnerability in your web-server? You've now given your attacker the ability to access resources inside your network. If your server has AWS access keys, then the attacker has them as well.
The goal of putting your servers in a private subnet, with a load balancer in front of them, is to reduce your attack surface. It's presumably less likely that attackers will be able to find an exploit in an ALB (versus Apache, nginx, or whatever you're using), and presumably more likely that AWS will be able to mitigate any such exploit faster than you can (because they don't need to wait for patches to become available from an external maintainer).
Of course, the code you wrote could have an exploit that's triggered from a standard HTTP(S) request. However, even in this case, you can reduce blast radius by controlling what your application can access. An instance with a public IP can access anything on the Internet unless you strictly control the egress rules in its security group. In a private subnet, it can only access stuff within the VPC.
So, ultimately, it's a matter of simplicity: yes, you can craft a secure environment where every host is on the Internet. That was, in fact, the way that AWS worked prior to the introduction of VPCs. But it's easier to rely on the VPC to provide a base level of security (just like, in non-cloud deployments, you rely on the corporate firewall to provide a base level of security).

Public/Private Subnet Architecture on AWS

I am having trouble understanding this image:
Specifically what I want to have is the Global Accelerator attached to every region, with each region having a VPC and Load Balancer. Then in each AZ in a region, have a public and private subnet. The private subnet or database servers will do all the computation and rendering. The public subnet is the Load Balancer (or does the public subnet need to be a set of instances?).
The public subnet also has an Internet Gateway and NAT Gateway attached. The docs say a private subnet can access the internet using a NAT Gateway in the public subnet, but I don't understand why it doesn't just use the Internet Gateway.
I have a route table in the public subnet, and the private subnet. In the public subnet, the route table goes to 0.0.0.0/0 pointing to the internet gateway. In the private subnet, it goes to 0.0.0.0/0 pointing to the NAT gateway.
There are also an Elastic IP associated with the NAT Gateway, presumably so that's what the internet sees when I make a request from a private server.
My question is, what is connected to what? The docs aren't clear enough on a practical example. I would like to have a public subnet, which I think doesn't require having any instances (am I wrong?), only the load balancer. Then the private subnet is the computation/database subnet which does consist of instances which can only connect to the internet through the load balancer connected to the NAT gateway.
I am confused. I have read the docs over and over again but still don't see how this is supposed to be wired up. Any help explaining what is connected to what in this diagram (extending it to include the Global Accelerator) would be greatly appreciated.
Please don't take this the wrong way, but I don't think you really need everything you are saying that you want.
I would recommend that you start with one region and no Global Accelerator. Implement your system and either creating a test platform that can simulate user traffic, or release your system to your customers and monitor it to determine performance.
If you run in multiple regions, you have a problem with where to keep your data -- data might be kept separate in each region, or replicated. This all depends upon your needs. I suggest you start simple, then expand if you need to operate differently.
Global Accelerator does not make sense when using multiple regions, since it is designed to send traffic to one location. Instead, consider Amazon CloudFront to cache data closer to your customers to provide better performance.
If your application runs on multiple web servers, put a Load Balancer in public subnet(s) and everything else in private subnet(s).
Put simply, start simple. Get your application working in the simplest possible way. Then, if you have greater requirements (eg low latency to users), look at adding Amazon CloudFront. Very few applications span multiple regions, so make that choice carefully and have a specific reason for doing so.
When you use AWS Global Accelerator, you can keep your ALB and instance private, without exposing them to the internet.
Such architecture is explained in the recent AWS blog post:
Accessing private Application Load Balancers and EC2 instances through AWS Global Accelerator
In this architecture, internal ALB is used, and there are no public subnets. The only requirements is the pretense of internet gateway in the VPC. It should be noted, that even though there is internet gateway, no routes are configured for the subnets to access the internet:
To avoid internet traffic from inadvertently flowing into a private subnet, we require that an internet gateway is attached to the VPC that contains resources when a client address-preserving accelerator is created.
I came in late but:
One rule is "if it can stay in private subnet then keep it in private subnet". Accessing the internet will always be costlier. When that is done if you must reach the internet then use VPC endpoints (if possible) instead of NATG and IGW. Endpoints are cheaper and make cheaper data transfers.
For Accelerator and Cloudfront, if data cacheing will be a pain for you then use Accelerator, if not, simply put, CloudFront is cheaper and better.
Despite all this, your architecture and use case will always decide your best and cheapest set up.

3-tier web application subnet segmentation in AWS VPC

I'm new to AWS VPC setup for 3-tier web application. I created a VPC with subnet 10.0.0.0/16, and what is the good best practice to do the subnet segmentation in AWS VPC for 3 tier web application? I have ELB with 2 EC2 instances, and RDS and S3 in the backend.
Please advise!! Thanks.
A common pattern you will find is:
VPC with /16 (eg 10.0.0.0/16, which gives all 10.0.x.x addresses)
Public subnets with /24 (eg 10.0.5.0/24, which gives all 10.0.5.x addresses)
Private subnets with /23 (eg 10.0.6.0/23, which gives all 10.0.6.x and 10.0.7.x) -- this is larger because most resources typically go into private subnets and it's a pain to have to make it bigger later
Of course, you can change these above sizes to whatever you want within allowed limits.
Rather than creating a 3-tier structure, consider a 2-tier structure:
1 x Public Subnet per AZ for the Load Balancer (and possibly a Bastion/Jump Box)
1 x Private Subnet per AZ for everything else — application, database, etc.
There is no need to have apps and databases in separate private subnets unless you are super-paranoid. You can use Security Groups to configure the additional layer of security without using separate subnets. This means less IP addresses are wasted (eg in a partially-used subnet).
Of course, you could just use Security Groups for everything and just use one tier, but using private subnets gives that extra level of assurance that things are configured safely.
The way we do it:
We create a VPC that is a /16, e.g. 172.20.0.0/16. Do not use the default VPC.
Then we create a set of subnets for each application “tier”.
Public - Anything with a public IP. Load balancers and NAT gateways are pretty much the only thing here.
Web DMZ - Web servers go here. Anything that is a target for the load balancer.
Data - Resources responsible for storing and retrieving data. RDS instances, EC2 database servers, ElastiCacahe instances
Private - For resources that are truly isolated from Internet traffic. Management and reporting. You may not need this in your environment.
Subnets are all /24. One subnet per availability zone. So there would be like 3 Public subnets, 3 Web DMZ subnets, etc.
Network ACLs control traffic between the subnets. Public subnets can talk to Web DMZ. Web DMZ can talk to Data. Data subnets can talk to each other to facilitate clustering. Private subnets can’t talk to anybody.
I intentionally keep things very coarse in the Network ACL. I do not restrict specific ports/applications. We do that at the Security Group level.
Pro tip: Align the Subnets groups on a /20 boundary to simplify your Network ACLs rules. Instead of listing each data subnet individually, you can just list a single /20 which encompasses all data subnets.
Some people would argue this level of separation is excessive. However I find it useful because it forces people to think about the logical structure of the application. It guards against someone doing something stupid with a Security Group. It’s not bulletproof, but it is a second layer of defense. Also, we sometimes get security audits from customers that expect to see a traditional structure like you would find in an on-prem network.

Why do we need a Private Subnet + NAT translation in AWS? Can't we just use a Public Subnet + a properly configured security group?

So the purpose of private subnets in AWS is for its instances to not be directly accessible from the outside world. There are however cases (successfully resisted the 'instances' pun) in which it's useful for the instances to have access to the internet. One such use-case may be to download software updates for example.
The "standard" way to achieve this would be with a NAT gateway and a rule in the routing table pointing all outbound traffic to it (0.0.0.0/0 -> nat-gw).
The thing that puzzles me is this:
Can't we just use a public subnet with a properly configured security group (SG) that denies inbound traffic and allows specific outbound traffic? Since SGs are stateful, they should allow the response to the outbound traffic to go through, just as a NAT gateway would.
I assume I'm just missing something, or that the above configuration is limited in some way that I'm just not seeing. However I can't find an answer to this.
Compliance is one of the primary reasons one may choose to have
private subnets. A lot of companies, especially financial institutions, have strict compliance requirements where there cannot
not be any public access
to the servers. When you create a public subnet, there is a
possibility of assigning a public IP address, which can make any
instance accessible from internet, (again as long as the security
group allows it).
Security Groups are a firewall provided at a logical level by AWS.
Creating a private subnet, ensures that even if an instance belongs
to a Security Group, that allows access to certain ports and
protocols, the server still won't be accessible publicly.
Another reason, you may choose for private subnets is to architect
your infrastructure in a way that all public servers are always in
the DMZ. Only DMZ has access to the internet. Every thing else is in
a private subnet. In the event something goes wrong, access to the
DMZ can be closed and further damage could be prevented.
The simple answer is... you're right!
You can certainly launch everything in a Public Subnet and use Security Groups to control traffic between the instances and to restrict inbound access from the Internet.
People use public & private subnets because this is the way that networks were traditionally designed, when firewalls only existed between subnets. Security Groups are an additional layer of security that works at the Elastic Network Interface, but that's a bit scary and new for many networking professionals (including people who design compliance requirements).