Protect your AWS Webservers from Port Scanning attacks

Tom MooreTom Moore
5 min read

When I started working with AWS a little over 8 years ago, one of the first things I did was set up a simple web server. Being a "Windows Guy," I created an EC2 instance running Windows Server, installed IIS, put it into a public subnet in the default VPC, opened up the security groups... and then sat back with a smile and looked at what I had accomplished...

**Record Screech** ... Creating a security nightmare...

I am typing this blog post at the AWS Summit in New York 2024. It's awesome to meet old friends and colleagues, so what better environment to do a "Do what I say, not what I do" blog?

This morning, I kicked off a new EC2 instance that used Windows. I turned off the Windows Firewall completely. (Please don't do this.) Then I created a new security group and allowed HTTP, HTTPS, SSH and RDP through to the server from anywhere. (Again, please DO NOT do this.)

None of these things are really specific to cloud computing; every one of these things can be done at home, in the data center, or in any cloud environment. Please don't... you get the idea...

While I generally don't subscribe to the idea of security through obscurity... the first line of defense for any of your EC2 instances is to close entry points to malicious traffic getting to those instances in the first place. Sitting an EC2 instance on the internet in a publically accessible subnet is an open invitation to anyone who wants to attempt to compromise that instance. And you can be sure that someone, somewhere, wants to compromise your instance, even if only to turn it into a short-term {Incert Crypto Currency of choice} mining node.

After getting this node set up, I launched a port scan from my laptop. Warning: Doing a port scan from an EC2 instance is a violation of AWS Terms of service. You should not do this. Port scanning of this instance, provides your attacker with some information that can be used to start attacking your instance.

This image shows a potential attacker being provided with a range of details about things like open ports that are available for scanning and potential discovery.

Furthermore, an attacker can find details about the services that are exposed to the world from this machine. The most interesting, and dangerous options are 22 and 3389. If you have ever been to one of my AWS 101 sessions talking about security you would have heard me say NEVER LEAVE THESE OPEN!

What could possibly go wrong?

Well, in the short time that this server has been sitting on the internet, there have been a little over 1,200 failed attempts to log into it. Thankfully I haven't changed the default random password to something like "P@ssword1."

Side Note: I did this once, and the instance was hijacked within about 10 minutes.

Of course, we want to validate that the instance is accessible as a web server.

So... what should you do?

Clearly, you need to be able to access your web server for it to be useful. So, how can we fix these issues? The first thing to do is create a pair of security groups. The first security group is for a load balancer, and the second security group is for the instance.

The security group for the load balancer:

This new security group will be applied to a load balancer and will only allow traffic to cports 80 and 443 from anywhere on the internet.

The security group for the web server instance:

This matching security group includes rules that allow HTTP and HTTPS traffic, but only from the load balancer. This way, even if the IP address for the server is exposed, users can't bypass the load balancer and get access to my instance.

Next I am going to set up a load balancer, assign the load balancer security group, and then replace the security group on the instance. I won't walk through this here as there are already countless tutorials.

Original Design

Updated design

Results

So what are the results of our changes as someone tries to port scan our instances?

If the user attempts to scan the load balancer, they get a very different view.

Right away, they see a Linux host with only a single port open. (The instance still has the Windows firewall disabled.) This is because the load balancer is running Linux and forwarding the traffic via the port mapping to your instance, which is still running Windows. The security group does have 2 ports open (80 and 443); however, I haven't set up HTTPS on my Windows server and haven't set up a forwarding rule on the load balancer.

Further, if the underlying IP address for your instance is exposed, attackers are not going to be able to try to scan the instance directly.

The updates port scan fails, reporting that the instance appears down.

Additional Improvement

For additional security, you should create both public and private subnets for your applications. Place the load balancers in the public subnet and the EC2 instances in the private subnet. This will add an additional level of protection to the instance and allow you to remove the public IP address for the instance. Additionally you can create NACLS to block traffic to the subnets from external addresses as well.

Summary

Protecting your instances from malicious attacks should be incorporated into your design from the start. Leveraging AWS load balancers to protect your instances and applications, even if you are only running a single instance to start, will improve your security posture and help to protect your instances from some common entry points.

0
Subscribe to my newsletter

Read articles from Tom Moore directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tom Moore
Tom Moore

I am an AWS Community Builder focused on Dev Tools. My goal is to help developers to understand the best ways to run their .NET applications in the cloud, and how to pick the best services to fit their use cases. I am available for in-person speaking events in the New England area, and virtual sessions worldwide. Opinions expressed on my blog are my own, and should not be considered to be the opinions of my employer.