This has probably been answered elsewhere but I can't seem to find it!
I have a number of AWS EC2 instances that I am using as part of a project being built and I am now looking into securing the setup a bit. I want to lock down access to some of the ports.
For example I want to have one of the instances act as a database server (hosting mysql). I want this to be closed to public access but open to access from my other EC2 instances on their private IP's.
I also use the AWS auto-scaler to add/remove instances as required and need these to be able to access the DB server without having to manually add its IP to a list.
Similarly if possible I want to lock down some instances so that they can only accept traffic from an AWS Load Balancer. So port 80 is open on the instance but only for traffic coming from the Load Balancer.
I've looked at specifying the IP's using CIDR notation but can't seem to get it working. From the look of the private IP's being assigned to my instances the first two octets remain the same and the last two vary. But opening it to all instances with the same first two octets doesn't seem that secure either?!
Thanks
What you want to do is all pretty standard stuff, and is extensively documented in the AWS VPC documentation for Virtual Private Clouds. If your EC2 instances are not running in a VPC, they should be.
The link below should help, it seems to be your scenario:
Scenario 2: VPC with Public and Private Subnets (NAT)
The configuration for this scenario includes a VPC with a public
subnet and private subnet, and a network address translation (NAT)
instance in the public subnet. A NAT instance enables instances in the
private subnet to initiate outbound traffic to the Internet. We
recommend this scenario if you want to run a public-facing web
application, while maintaining back-end servers that aren't publicly
accessible. A common example is a multi-tier website, with the web
servers in a public subnet and the database servers in a private
subnet. You can set up security and routing so that the web servers
can communicate with the database servers.
http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario2.html
Related
Question
Can we make a route table which has both igw-id (Internet gateway ID) and vgw-id (VPN gateway ID)? If we can't/shouldn't do it, why?
Example
10.0.0.0/16 --> Local
172.16.0.0/12 --> vgw-id
0.0.0.0/0 --> igw-id
Reference
https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario3.html
(I mainly refer to "Overview" section and "Alternate routing" section.)
Explanation
This webpage above shows the scenario where one VPC has one public subnet, one private subnet and one VPN gateway. In this example, the VPN gateway is always accessed from instances in the private subnet (meaning its route table doesn't have the record "igw-id"). I wonder why one route table doesn't have both "igw-id" and "vgw-id".
Yes, we can have both igw and vgw. In fact, the example above would be a perfect for a public subnet which can connect to your corporate network through direct connect or site-to-site VPN, and also have internet access and be accessible from the internet.
Now, weather you would want this or not, it is an architectural decision. In the example scenario given by AWS, they try to segregate subnets by having a public subnet (with the igw) which can contain services accessible from the internet and a private subnet for other backend services (exmaple: databases). These backend services can be accessed from the corporate network using a site-to-site VPN, this is why the subnet has the vgw.
Yes, you can have a route table with the 3 routes you specified. However, bear in mind that with a route 0.0.0.0/0 --> igw-id, hosts on the internet can initiate connections with the instances in that subnet. Typically, you would want to secure the instances in a subnet that you allow a route to your on-premise network, and not expose it to the internet. If these instances require to connect to the internet, AWS recommends NAT devices for your VPC.
While it's technically possible, the main reason not to do that is due to a concept called network segmentation. It basically follows a "defense in depth" approach that network layers should be separated in a "public" and a "private" part (more zones are also often used like third tier for data storage and a fourth for infra used to manage the other three tiers).
Since your public subnet is directly exposed to the internet, it'most likely to be breached when you misconfigure something. If you would have routes in your public subnet to your VPN gateway, a single breach enables an attacker to attack your on-prem environment as well.
This is why its best practice to add one or two network tiers to your architecture. Even when the public tier is compromised, they still need to get into an instance in the private tier before they can attack your on prem environment.
It's recommended that your public subnet only contains an elastic load balancer or similar when possible. Its a pretty good way to reduce the attack surface of your application servers (less chance that you expose an unwanted port etc.).
A nice guide on this can be found here. It doenst include vpns, but you can condisider them part of the app layer.
I have recently setup a EKS cluster in AWS for my company's new project. Before I get into my issue, here is some info of my setup. There are two nodes (at the moment) in the nodegroup with auto-scaling. At first, I created the nodes in the private subnet as I think it is more secure. But my supervisor told me that we will need the capability to SSH to the node directly, so I recreated the nodes in the public subnet so that we can SSH to the node using public key.
We have two CMS instances sitting in AWS (for example aws.example.com) and DigitalOcean (for example do.example.com) that contains some data. When the containers in EKS cluster start, some of them will need to access the instance in AWS by using the url aws.example.com or do.example.com. If the containers in EKS failed to access the instances, the container will still run but the app in it won't. So I need to whitelist the public IP of all my EKS nodes on the two CMS instances in order for the app work. And it works.
I am using ingress in my EKS cluster. When I created the ingress object, the AWS created an application load balancer for me. All the inbound traffic is being handled by the ALB, it is great. But here comes the issue. When more containers are created, the auto-scaling spin up new nodes in my EKS cluster (with different public IP every time), then I will have to go to the two CMS instances to whitelist the new public IP address.
So, is there any way to configure in such a way that all the nodes to use a single fixed IP address for outbound traffic? or maybe configure them to use the ALB created by ingress for outbound traffic as well? or I need to create a server to do that? I am very lost right now.
Here is what I have tried:
When the cluster is created, it seems like it created a private subnet as well even though I specify the nodes to be created in public subnet. There is a nat-gateway (ngw-xxxxxx) created for the private subnet and it comes with an Elastic IP (for example 1.2.3.4). The routetable of the public subnet is as below:
192.168.0.0/16 local
0.0.0.0/0 igw-xxxxxx
So I thought by changing igw-xxxxxx to ngw-xxxxxx, all the outbound traffic will use the ngw-xxxxxx and send the traffic to the outside world using IP address 1.2.3.4, which I just need to whitelist 1.2.3.4 on my two CMS instances. But right after I applied the changes, all containers are terminated and all things stopped working.
Exactly, as #Marcin mentioned in the comment above.
You should move your node-group to the private subnet.
Private subnet
As the docs tell:
Use a public subnet for resources that must be connected to the internet, and a private subnet for resources that won't be connected to the internet
The idea of private subnet is to forbid access to resources inside directly from the internet.
You can read really good part of AWS documentation here: https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html
For private subnet you need to setup outgoing traffic thru your Nat gateway in the Route Table (read here: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).
Public subnet
If you need your cluster in the public subnet for some reasons, but it is BAD parctice, you can do the trick:
You can route traffic via Nat Gateways from public subnet only to a specific server(your CMS).
Your public subnet route table may look like:
Destination
Target
10.0.0.0/16
local
W.X.Y.Z/32
nat-gateway-id
0.0.0.0/0
igw-id
Where W.X.Y.Z/32 is your CMS IP address.
Some hint
Moreover good practice is to allocate a pool of EIP and attach them to NAT Gateway to be sure it is not changed in the future.
When you want to modify infrastructure and create more complicated Nat (e.g. you want to filtering traffic on layer 7), you can createHigh Availability Nat instances, and attach the IP to NAT instances instead of NAT Gateways.
In that situation you will avoid mailing some 3-rd party APIs to whitelist your new IPs.
We are trying to use Elastic Load Balancing in AWS with auto-scaling so we can scale in and out as needed.
Our application consists of several smaller applications, they are all on the same subnet and the same VPC.
We want to put our ELB between one of our apps and the rest.
Problem is we want the load balancer to be working both internally between different apps using an API and also internet-facing because our application still has some usage that should be done externally and not through the API.
I've read this question but I could not figure out exactly how to do it from there, it does not really specify any steps or maybe I did understand it very well.
Can we have an ELB that is both internal and external?
For the record, I can only access this network through a VPN.
It is not possible to for an Elastic Load Balancer to have both a public IP address and a private IP address. It is one or the other, but not both.
If you want your ELB to have a private IP address, then it cannot listen to requests from the internet.
If your ELB is public-facing, you can still call to it from your internal EC2 instances using the public endpoint. However, there are some caveats that goes with this:
The traffic will exit your VPC and re-enter it. It will not be direct instance-to-ELB connection that a private IP address will afford you.
You also cannot use security groups in your security group rules.
There are 3 alternative scenarios:
Duplicate the ELB and EC2 instances, one dedicated to private traffic, one dedicated to public traffic.
Have 2 ELBs (one public, one private) that share the same back-end EC2 instances.
Don't use an ELB for either private or public traffic, and instead use an Elastic IP address (if public) or a private IP address (if private) on a single EC2 instance.
I disagree with #MattHouser answer. Actually, in a VPC, your ELB have all its internal interfaces listed in Network Interfaces with Public IP AND Primary private IP.
I've tested the private IP of my public ELB and it's working exactly like the external one.
The problem is : theses IPs are not listed anywhere in a up to date manner like on a private ELB DNS. So you have to do it by yourself.
I've made a little POC script on this, with an internal Route53 hosted zone : https://gist.github.com/darylounet/3c6253c60b7dc52da927b80a0ae8d428
I made a Lambda function that checks which private IPs are set to the loadbalancer and will update Route53 record when it changes: https://github.com/Bramzor/lambda-sync-private-elb-ips
Using this function, you can easily make use of the ELB for private traffic. I personally use it to connect multiple regions to each other over a VPC inter-region peering without needing an additional ELB.
The standard AWS solution would be to have an extra internal ELB for this.
Looks like #DaryL has an interesting workaround, but it could fail for 5 minutes if the DNS is not updated. Also there is no way to have a separate security group for the internal IPs since they share the ENI and security of the external IP of the ELB.
I faced the same challenge and I can confirm the best solution so far is to have two different ALBs, one internet-facing and the other internal. You can attach both ALBs to a single AutoScaling Group so you can access the same cluster.
Make sure the networking options (Subnets, security groups) of both ALBs are the same in order for both to access the same cluster instances. Autoscaling and Launch Configuration works seamlessly with both ALBs attached to the same AutoSacling Group. This is also working with ALBs created from ElasticBeanstalk environments.
I'm learning AWS and how to configure networking for EC2 instances and have a few questions. I'm using CentOS 7 in t2.micro instances.
The private IP is tied to the NIC in the instance as shown by ifconfig -a. The purpose seems to be a single point of contact for the server. Adding another network interface does NOT add another NIC as shown by ifconfig -a. Since the primary network interface cannot be a static IP, a secondary network interface is necessary for most configurations. For example, to connect the application to the database server, use the static IP assigned to the second network interface. Am I understanding this correctly?
The public IP is shown in the AWS console and provides a means to connect to the instance via SSH, assuming you configure the SG. The public IP also provides a means to access the internet for system updates. This seems to contradict the AWS documentation for NAT. If the public IP already provides internet access, why is a NAT (instance or gateway) needed? This is in reference to system updates which the documentation references.
You can use a NAT device to enable instances in a private subnet to connect to the Internet (for example, for software updates) or other AWS services, but prevent the Internet from initiating connections with the instances. A NAT device forwards traffic from the instances in the private subnet to the Internet or other AWS services, and then sends the response back to the instances.
Is a public IP and private IP are always assigned to each instance? I haven't walked through the process of creating an [new] AMI to verify if there's an option to not have a public IP. If the instance doesn't have a public IP, will the AWS console Connect button still allow you to connect to it to administer the server? Under what scenario will an instance NOT have a public IP? How do you connect to that instance to administer it?
I have read the NAT Gateway documentation and understand much of it. I'm having trouble understanding the pieces that state a NAT gateway or internet gateway is necessary to enable internet access, when it seems this is enabled by default. What am I missing?
I think your confusion stems from your third question. A public IP is not always assigned to an instance. Public IP is an option that you can enable or disable in public VPC subnets, and in private VPC subnets public IP isn't an option at all. For EC2 instances without a public IP a NAT gateway (or NAT instance) is required in order to access anything outside of the VPC.
You may want to place something like a database server in a private subnet so that nothing outside your VPC can ever access it. However you might want the database server to be able to access the Internet to download patches or something, or you may want it to access the AWS API in order to copy backups to S3 or something, in which case you would need a NAT Gateway to provide the server access to resources outside your VPC.
I need to design a cross-region cross-VPC architecture and i am not sure how i can restrict access to my resources
The requirement is that i need to run my web app in one region and my database in an another region.
Both the servers are inside private subnets. The web app has an auto scaling group and load balancer attached. The database server in the other region should only be accessible from this web app. I cannot use ip based restrictions as the IP of load balancer changes with time. What other option do i have?
The IP address of your Load Balancer is irrelevant because the Load Balancer is only used for incoming connections to your web server.
First, I should point out that having your database remote from your application is a poor architectural decision, which will slow down your application. Please reconsider it if possible!
You have not provided much information, so I will make the following assumptions:
VPC in Region A contains:
A Load Balancer in a public subnet
Web servers in a private subnet
VPC in Region B contains:
A database in a private subnet
In this situation, you wish to communicate between two private subnets in different VPCs that reside in different regions. For this, you could consider creating a private VPN connection via Amazon EC2 instances located in the public subnets of each VPC. This would use a software VPN such as OpenVPN or OpenSwan.
You should also consider how to achieve a High Availability option for this solution. A well-architected VPC would have your web servers deployed across multiple Availability Zones in Region A, with your database preferably in a multi-AZ configuration in Region B (assuming that you are using Amazon RDS). You should similarly design your VPN solution to be highly-available in case of failure.
An alternative is to put a NAT Server in the public subnet of the VPC in Region A and configure the private Route Table to send traffic through the NAT Server. This means that traffic going from the web servers to the Internet would all come from the public IP address associate with the NAT Server (not the Load Balancer).
However, the database is in a private subnet, so the traffic cannot be directly routed to the database so this is only half a solution. It would then either require the database to be in a public subnet (with a Security Group that only accepts connections from the NAT Server) or some type of proxy server in the public subnet that would forward traffic to the database. This would become way too complex compared to the Software VPN option.