For the practically paranoid, improving the security of your AWS infrastructure should be an ever-changing goal to strive towards. Large organizations understand this reality. That’s why they employ entire teams that are dedicated to continually reviewing and auditing their cloud security infrastructure.
For us startups, however, we’re focused on trying to run our company; this security stuff is just another thing to think about. That said, there are some quick and easy improvements we implement for all our customers that dramatically improve their hosting security.
In this post, I’ll provide 5 quick and easy steps that any company hosted on AWS should take to improve the security of their infrastructure.
1. Properly Configure IAM
IAM is a beast with many facets, which is probably why many shy away from getting deep into it. You don’t need to though, adhering to the following will get you 99% of the way there:
Short of memorizing and rotating long passwords with heavy entropy (randomness), Multi-Factor Authentication (MFA) is simply the best tool people have come up with for assisting systems to verify authentication. Anyone can do this, all you need is a free 2FA App, and to enforce 2FA with IAM. Here’s a great, short video that can walk you through it.
Don’t login as root! Use IAM Accounts!
Even though this may seem obvious to some, I have to call it out because we see it in the wild so much. If you haven’t done so already, go to IAM and create an IAM user account to login with. You can assign full privileges if you like, but at least restricting logging in via an IAM profile will accomplish the following:
- Allow you to more easily deal with canceling those credentials if they get compromised
- Restrict access to certain parts of AWS you don’t need to use on a daily basis.
Treat this new account like it is your primary account, and get in the habit of creating new accounts for your employees, contractors, friends, butler, etc. in this manner. IAM allows you to effectively manage access from a bird’s-eye view for all of your critical resources.
Tip: Never, ever, assign someone’s account more permissions than they need. It will make your life easier when you know who explicitly has access to what.
Disclaimer: Policies can be a bit of a pain. Here’s a good link for some help.
Use IAM Roles for Resource Access (EC2)
If you have thing X in AWS that needs to talk to thing Y, do NOT issue them a new set of IAM credentials, and don’t ever use an existing access key / secret combo. Use [IAM roles]()! Assigning a specific IAM role for your resource alleviates the burden that comes with having to handle access keys securely. I promise this makes life easier. Here’s an article to help you get there.
2. Inspect Your Security Groups
Security groups are the best tool for defining access permissions in the cloud. They allow you to restrict access at the port level for every AWS resource through defining allowed ingress (incoming packets) and egress (outgoing packets). Security groups are basically easy to configure firewalls for your entire AWS setup.
Like stale credentials through, security groups can fall victim to neglect. Despite best intentions, developers often leave gaping holes in the security groups due to:
- Misconfiguration / misunderstanding of how they work
- Forgetting they ‘temporarily’ altered one during the course of a setup or debug session
- Not targeting other security groups for ingress/egress
Luckily there are some cool tools out there to help you identify gaps in your setup. One of our favorite ones is Scout2. It’s made by NCC group and does a good job of helping you understand the exposed ingress and egress in your setup.
When you hand out those new IAM Access/Secret Keys we created in step #1, you hope/pray/doubt that they are handled in a secure fashion. Make it easy on the recipients of those credentials and get them set up on AWS-Vault from the folks at 99 Designs.
AWS-Vault helps by forcing a user to enter credentials only once, but enables you to use them whenever needed. It has great support for 2FA and makes rotation a breeze. It really makes life easier on everyone.
4. Turn on Cloud Trail
This is a simple thing to do that will keep a record of all access to your AWS instances. It takes next to no time and will be vital in the event of a breach. A quick start guide can be found here
Once enabled, Cloud Watch will record all incoming requests into your account and deliver them within 15 minutes to an S3 bucket. It will also include API calls made by other high-level services (CloudFormation, OpsWorks, Beanstalk) into your resources.
When you get ‘hacked’, the first thing your triage team will do is look for logs and pray you have extensive ones set up. Enabling this provides: - Who made the API call - When it was made - What was the API call - What resources were acted upon - Where it was made from
5. Set up a bastion host
Having all of your public facing instances accept SSH makes it harder to effectively manage access to your resources. Public facing instances also make it more difficult to retroactively understand how some malicious access came through. A bastion host is a funny term that basically means there is one point of access into your firewall/cloud/DMZ/AWS.
Since every EC2 instance you launch has SSH enabled out of the box, restricting access to one really helps you identify the point of access into your cloud. Your bastion host can just be a normal EC2 instance, but the caveat is that it needs to be the only one that can accept an incoming SSH connection. You can achieve this via security groups (only allowing the bastion host to receive incoming requests on port 22).
Once you have SSH’d into the bastion host, you can SSH directly into other instances using their private IP addresses. Other than SSH’ing, you may want to inspect a database or Redis from the command line. Setting up a bastion host just gives you a safer place to do these things rather than exposing multiple EC2 instances, or even worse, exposing services like RDS to the broader internet.
If you want to go the extra mile, use public and private subnets to restrict which resources can even be allowed to access the internet.
There are some other cool things you can do to beef up your security picture
GitSecrets is a really cool tool for helping you monitor and guard against sensitive passwords being checked into your repos. It’s primarily used as a CI tool, but is great to even run once on your repo to make sure no one has checked any secrets in to the git history by accident… which you know someone probably has ;)
Security Monkey is a really great and interesting project by Netflix. It can attach to your AWS or GCP instance to give you feedback on your current cloud security picture and track it with ongoing monitoring. Another really cool feature they rolled out is a GitHub integration that monitors your organization.
Export your security settings with this script. There is a great talk from AWS re:Invent 2013 on intrusion detection. It covers some of the points in this post, but also some great insight on how to protect against and detect intrusion.