2 ec2 instance interacting with each other - amazon-web-services

I am new to aws and ec2 interaction with traffic flow.
I have one ec2 instance which I am using as a web server and other as an application server.
how can my two ec2 interact with each other maintaining all the security required?
Both the ec2 machines are on the ubuntu image.
I tried adding All ICMP - IPv4 with source 0.0.0.0/0. I feel it's not the correct way I want only my other instance to access it.
I also tried adding source as other instance security group but didn't work. I was not able to ping from one machine to other

The recommended security configuration would be:
Create a Security Group for the web server (Web-SG) that permits Inbound traffic for HTTP and HTTPS (ports 80, 443). Leave the Outbound configuration as the default "Allow All".
Create a Security Group for the app server (App-SG) that permits Inbound traffic from Web-SG on the desired ports. Leave the Outbound configuration as the default "Allow All".
That is, App-SG should specifically refer to Web-SG in the Inbound rules. This will permit traffic from Web-SG to enter App-SG.
You might want to add additional access so that you can manage the instances (eg SSH), or you can use AWS Systems Manager Session Manager to connect.
Do not use Ping to test access since that requires additional settings and only proves that Ping works. Instead, test the actual access on the desired ports (eg port 80).

Related

How to properly create security groups for instance classes in AWS?

So right now I have 4 subnets per availability zone: The internet facing "entrypoint" subnet (associated with a load balancer), the generic "service" subnet for internal computation, the "database" subnet for all things data related, and the "external request" subnet for making requests out to the internet. This defines essentially 4 classes of EC2 instances.
I am supposed to now create security groups for these 4 classes of EC2 instances. What I'm wondering is how to do that correctly (I am using terraform).
Can I create 1 security group for "ingress" (incoming) traffic, and a 2nd security group for "egress" (outgoing) traffic, for each class, for each connection type?
So basically, I want this. I want the internet entrypoint to talk to the service. The service can only respond to requests from the internet, it doesn't make any external internet requests itself. The service can talk to the database and the external requesting class. The database can only talk to the service, and the external request can only respond back to the service. The entrypoint can come in as HTTP or HTTPS (or websockets, is that just HTTPS?). It comes in on port 443. This is the load balancer. It then converts the request to HTTP and connects to the compute with port 3000. Should I have a separate port for each different connection type? (So the service layer would have 1 port for the database to respond to like 4000, 1 port for the external request layer to respond to like 5000, etc.). Or does that part matter? Lets say we have the ports thing though.
sg1 (security group 1): ingress 443 -> 3000 (load balancer -> service)
sg2: egress 3000 -> internet? is that 0.0.0.0/0? I don't want it to make free requests out, only to connected clients.
sg3: ingress 3000 -> 4000 (service -> database), specifying the database subnet
sg3: egress 4000 -> 3000 (database -> service), specifying the service subnet, etc.
Am I on the right track? I am new to this and trying to figure it out. Any guidance would be much appreciated, I've been reading the AWS docs for the past week but there's little in terms of best practices and architecture.
You can specify upto 5 individual security groups per ENI (Elastic Network Interface). All available rules are evaluated whenever either the inbound or outbound ingress rule is established.
Regarding communication, security group rules establish a tunnel (allowing stateful communication) during any network communication allowing bi-directional communication as long as the initial connection was allowed by the security group.
Security groups are stateful — if you send a request from your instance, the response traffic for that request is allowed to flow in regardless of inbound security group rules. Responses to allowed inbound traffic are allowed to flow out, regardless of outbound rules.
For example:
Inbound rule allows SSH on port 22 from a specific IP address, no outbound rules for port 22 exist. A user can safely SSH to the server with no connection issues, but is unable to SSH to another server. Add outbound rules if the server should be able to speak outbound, by default it will be allow all.
From this above example this means if you allow no outbound rules for HTTP/HTTPS only inbound connections over HTTP/HTTPS will allow it to return. Also be aware for patching that you will not be able to download from the internet.
Regarding the source, perhaps rather than specifying subnets you can reference the logical security group name instead. This would mean if a resource in any subnet has that security group attached the target resource would allow inbound access (this only works if the connection is private host to private host).
The source of the traffic and the destination port or port range. The source can be another security group, an IPv4 or IPv6 CIDR block, a single IPv4 or IPv6 address, or a prefix list ID.
I would recommend trying to keep the resource realm within a single security group (i.e. DB server all in a single security group) primarily to reduce the overhead of management.
More information is available at the Security groups for your VPC page.

AWS Session Manager can't connect unless opening SSH port

I'm trying to use AWS Systems Manager Session Manager to connect to my EC2 instances.
These are private EC2 instances, without public IP, sitting on a private subnet in a VPC with Internet access through a NAT Gateway.
Network ACLs are fully opened (both inbound and outbound), but there's no Security Group that allows SSH access into the instances.
I went through all the Session Manager prerequisites (SSM agent, Amazon Linux 2 AMI), however, when I try to connect to an instance through the AWS Console I get a red warning sign saying: "We weren’t able to connect to your instance. Common reasons for this include".
Then, if I add a Security Group to the instance that allows SSH access (inbound port 22) and wait a few seconds, repeat the same connection procedure and the red warning doesn't come up, and I can connect to the instance.
Even though I know these instances are safe (they don't have public IP and are located in a private subnet), opening the SSH port to them is not a requirement I would expect from Session Manager. In fact, the official documentation says that one of its benefits is: "No open inbound ports and no need to manage bastion hosts or SSH keys".
I searched for related posts but couldn't find anything specific. Any ideas what I might be missing?
Thanks!
Please make sure you are using Session Manager Console, not EC2 Console to establish the session.
From my own experience, I know that sometimes using EC2 Console option of "Connect" does not work at first.
However, if you go to AWS Systems Manager console, and then to Session Manager you will be able to Start session to your instance. This assumes that your SSM agent, role and internet connectivity are configured correctly. If yes, you should be able to see the SSM managed instances for which to start your ssh session.
Also Security Group should allow outbound connections. Inbound ssh are not needed if you setup up everything correctly.
Despite what all the documentation says, you need to enable HTTPS inbound and it'll work.
I had similar issue and what helped me was restarting SSM agent on a server. I've logged in with SSH and then run:
sudo systemctl restart amazon-ssm-agent
Session Manager Console immediately displayed EC2 instance as available.
Thanks for your response. I tried connecting using Session Manager Console instead of EC2 console and didn't work. Actually I get the red warning only the first time I try to connect without the SSH port opened. Then I assign a security group with inbound access to port 22 and can connect. Now, when I remove the security group and try connecting again, I don't get the red warning in the console but a blank screen, nothing happens and I can't get in.
That being said, I found that my EC2 instances didn't have any outbound port opened in the security groups. I opened the entire TCP port range for the output, without opening SSH inbound and could connect. Then I restricted the outbound port range a little bit: tried opening only the ephemeral range (reserved ports blocked) and that problem came up again.
My conclusion is that all the TCP port range has to be opened for the outbound. This is better than opening the SSH port 22 for inbound, but there's something I still don't fully understand. It is reasonable that outbound ports are needed in order to establish the connection and communicate with the instance, buy why reserved ports? Does the SSH server side use a reserved port for the backwards connection?
I was stuck with this similar issue. My Security Groups and NACLS had inbound and outbound ports open only to precise ports and IPs as needed in addition to ephemeral port range of 1024~65535 for all internal IPs.
Finally what worked was, opening up Port 443 outbound for all internet IPs. Even restricting 443 outbound to internal IP ranges did not work.
The easiest way to do this would be to create the 3 VPC interface endpoints that SSM requires in your VPC and associated subnets (Service Names: com.amazonaws.[REGION].ssm, com.amazonaws.[REGION].ssmmessages and com.amazonaws.[REGION].ec2messages).
Then, you can add an ingress and an egress rule for only port 443 that allows communication within the VPC.
This is more secure than opening up large swathes of the Internet to your private instances and faster since the traffic stays on AWS' own network and does not have to traverse NATs, or gateways.
Here are some helpful links to AWS documentation:
https://aws.amazon.com/premiumsupport/knowledge-center/ec2-systems-manager-vpc-endpoints/
https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-prereqs.html
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-privatelink.html
https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-create-vpc.html
Another item that tripped me up: Make sure the security group for your VPC endpoints is open to all inbound connections on 443, and all outbound.
I had mine originally tied to the security group of the EC2 instances I was connecting to (e.g. SG1), and when I created another security group (e.g. SG2), I could not connect. The above reason was why... originally I set up my VPC Endpoints Security Group to reference SG1, instead of all inbound connections on 443.

Cannot access EC2 via HTTP/HTTPS

I recently had to completely rebuild my AWS EC2 environment, because I accidentally deleted the SSH key, thinking it was something else. Unfortunately, I cannot access my Tomcat instance which I have confirmed is running on that EC2 instance.
I have added the following security groups for inbound HTTP traffic:
Type. Protocol Port Range Source
HTTP TCP 80 0.0.0.0/0
HTTP TCP 80 ::/0
Custom TCP Rule TCP 8080 0.0.0.0/0
Custom TCP Rule TCP 8080 ::/0
SSH TCP 22 (my IP address)
I have three security groups, and the above rules were added to the group named default:
rds-launch-wizard
launch-wizard-1
**default
I purchased a domain via AWS which I have pointed to this EC2 instance using Route 53. Previously, the DNS was available, but now it is not. However, there is a bigger fundamental problem here because I can't even ping the public IP of my EC2 instance.
I am in fact able to access my EC2 instance via SSH on port 22, which is why I was able to setup Java and Tomcat (both of which I have confirmed are running).
I suspect that some state from my previous configuration is responsible for this problem, but I don't even know where to begin looking for something.
Any help would be appreciated.
To have inbound/outbound internet access to your EC2, you need to look for three things:
Are you able to SSH from outside or inside AWS via an internet gateway (IGW)? If you can SSH from outside then you already have IGW setup properly. Otherwise, make sure your subnet's route table points to IGW by having a route like below:
0.0.0.0/0 igw-efxxxxxxx Active No
Network ACL: Go to your EC2's subnet and find its associated NACL
Create both inbound and outbound rules to ALLOW traffic to the above NACL by adding a rule like below:
100 ALL Traffic ALL ALL 0.0.0.0/0 ALLOW
Security Groups: Your security groups look good. No changes required there. However, based on the comments you made below it appears that, while you did define a security group with the proper inbound rules, for whatever reason you did not associate that security group with your EC2 instance. As a result, the inbound rules you defined were not being applied. To fix this, from the EC2 instance tag access the following:
Actions -> Networking -> Change Security Groups
Then, associate your security group with your instance by checking the appropriate box. After making these changes, your inbound rules should take effect, and you should be able to hit your Tomcat instance running on EC2.

Amazon AWS EC2, Allow inbound http Request

I have deployed a nodejs application in AWS EC2 instance. It has API gateway with '/api/companies' endpoint. After starting my server I am able to cURL from the instance terminal and it returns the result correctly. But I am not able to make the request from my browser to the EC2 instance. I am not sure exactly how to modify the inbound rules to make this work
You might want to check out the Security Group Rules documentation, but the gist is:
Create a new Security Group in your VPC for your EC2 instance
In the Inbound rules, create a new rule
Set the Source to your IP address. (Optional, if you want to allow access from any IP address, enter 0.0.0.0/0 in the Source)
Set the Protocol to tcp, and set the Port to 80 or 443 depending on what your application uses
Edit your existing security group or add a new security group
Select the VPC the instance is running in. The attached image shows No VPC, but you have to select your VPC
For Source, you can choose My IP if you want to allow inbound traffic from your IP only or from Anywhere in the world

Amazon EC2 Security Group with Host / Dynamic IP / DNS

I am seeking some guidance on the best approach to take with EC2 security groups and services with dynamic IP's. I want to make use of services such as SendGrid, Elastic Cloud etc which all use dyanmic IP's over port 80/443. However access to Port 80/443 is closed with the exception of whitelisted IPs. So far the solutions I have found are:
CRON Job to ping the service, take IP's and update EC2 Security Group via EC2 API.
Create a new EC2 to act as a proxy with port 80/443 open. New server communicates with Sendgrid/ElasticCloud, inspects responses and returns parts to main server.
Are there any other better solutions?
Firstly, please bear in mind that security groups in AWS are stateful, meaning that, for example, if you open ports 80 and 443 to all destinations (0.0.0.0/0) in your outbound rules, your EC2 machines will be able to connect to remote hosts and get the response back even if there are no inbound rules for a given IP.
However, this approach works only if the connection is always initiated by your EC2 instance and remote services are just responding. If you require the connections to your EC2 instances to be initiated from the outside, you do need to specify inbound rules in security group(s). If you know a CIDR block of their public IP addresses, that can solve the problem as you can specify it as a destination in security group rule. If you don't know IP range of the hosts that are going to reach your machines, then access restriction at network level is not feasible and you need to implement some form of authorisation of the requester.
P.S. Please also bear in mind that there is a soft default limit of 50 inbound or outbound rules per security group.