By Kuyper Hoffman, Amazon Web Services
Just as any host on the Internet, your EC2 instances are vulnerable to attack. While the EC2 firewall is a very powerful tool for securing your instance from unwanted network traffic, if used incorrectly you may still leave your instance vulnerable to attack. These attacks can come in many forms, e.g.:
- Intrusion attempts: exploiting bad passwords on your system
- Port Scanning: detecting what services you are running and then trying to exploit those
- Denial of Service Attacks: inundating your server with junk requests or partial connections
These are some of the most important steps to take in order to mitigate risks.
Note: This is not intended to be an exhaustive security guide nor are there any implicit or explicit guarantees that these steps will ensure absolute system security.
Lock it Down: Close All Unecessary Ports
In our Getting Started guide we discuss the use of the ec2-authorize command. For the purposes of keeping things simple, that particular example suggests opening certain ports, eg ssh (TCP port 22) to the world, thus:
PROMPT> ec2-authorize default -p 22 PERMISSION default ALLOWS tcp 22 22 FROM CIDR 0.0.0.0/0Whilst this makes it easy for you to reach your instance from anywhere in the world, it makes it equally for anyone else to reach your instance. A more prudent approach is to restrict the access to port 22, in particular, to a set of hosts or networks that you trust.
For instance, let's assume that your corporate firewall has the IP address 184.108.40.206 and your corporation has been assigned that network as a /20, ie 220.127.116.11/20 (18.104.22.168-22.214.171.124) you could easily restrict ssh access to hosts only on your corporate network thus:
PROMPT> ec2-authorize default -p 22 -s 126.96.36.199/20 PERMISSION default ALLOWS tcp 22 22 FROM CIDR 188.8.131.52/20making it impossible for anyone on another network to even connect to your ssh server (the ec2-authorize command instructs the firewall (integrated into every EC2 instance) to drop packets not sourced on an approved network.) To make things even more secure, let's say all traffic only comes from your firewall, we could restrict it to just one host:
PROMPT> ec2-revoke default -p 22 -s 184.108.40.206/20 PERMISSION default ALLOWS tcp 22 22 FROM CIDR220.127.116.11/20 PROMPT> ec2-authorize default -p 22 -s 18.104.22.168/32 PERMISSION default ALLOWS tcp 22 22 FROM CIDR 22.214.171.124/32which is even more secure. If your network changes, you can always remove this rule and replace it with the new firewall address.
This technique should be used to secure any service port for TCP, UDP and ICMP traffic. Open only those ports that must be open for your service to operate.
Ditch Those Passwords: Use ssh Keys
In the Get Started guide we also show how to use keys to allow root login without passwords by using the ec2-add-keypair command to generate an RSA key and add it to your key-ring. This key is included when you launch your instance with the "-k" option and ensures that you can log in as root on your new instance.
However, we find that many users are then going on to create additional users for their instances and secure these accounts with passwords. Very often, these passwords are not very secure and are trivially cracked by intruders. They can also be taken with the employee when he or she leaves your organization.
A far better and certainly more secure mechanism is to use ssh keys for all users, in a similar way to the secure root login method described in the guide. Because the bundled commands only work for the root user, we'll now describe some steps for adding ssh keys for all additional user accounts.
We'll work on the assumption that you have access to a UNIX system of some description, although OpenSSH is available on many platforms. In addition, if you do not have a command-line based ssh client, most GUI clients, such as PuTTY work fine and there is a PuTTY Chapter a part of our standard docs.
For generating ssh keys for regular user accounts, we'd recommend that each user in your organization generate their own key. Have them provide their public key to your system administrator who may then add the key of any authorized use to the account(s) for which they need access on your ec2 instances.
Disable Password-based LoginLog in to your instance as root and edit the ssh daemon configuration file:
# vi /etc/ssh/sshd_configFind the line
PasswordAuthentication yesand change it to
Note:Caution: whenever making changes to your sshd.config file, be certain that you have an active shell session in case you've made a fatal syntax error. After restarting sshd, log in from another session to test it before terminating your active terminal sessionSave the file and restart sshd:
# /etc/init.d/sshd restartYou will now only be able to log in with an ssh key. A few other measures could include giving "sudo" access to a select set of Administrative users and removing root login entirely as well as explicitly specifying the only users who may login. Such a list should exclude other "system" accounts that do not need login capabilities. Once logged in with your regular account, you can always su the "su" or "sudo" commands to gain privilege to these accounts:
# vi /etc/ssh/sshd_configFind the line
PermitRootLogin yesand add the AllowUsers entry and change PermitRootLogin to
PermitRootLogin no AllowUsers john sallyAgain, be sure that you have an active login, save the file and restart sshd:
# /etc/init.d/sshd restart
Key Generation and DistributionIn the Getting Started guide we showed how to generate the initial keypair for the root user. This is how to create similar keypairs for all users who need access to your instances.
In the example below (to be run on your local machine, not your EC2 instance) replace "user" with the actual user's login, name or some other unique identifier.
ssh-keygen -b 1024 -f user -t dsaThis will create 2 files:
- user (private key)
- user.pub (public key)
scp -i root *.pub ec2-your-instance-name.compute.amazonaws.com:/tmp
User Account CreationLog in to the instance as root. For each user you are creating, add the user to your instance with the
# useradd -c "firstname lastname" userFor simplicity's sake, use the same "user" name as you did for key generation. Now we need to place the key into their ssh authorized keys file (again, replacing "user" with the username you chose earlier)
# cd ~user # mkdir .ssh # chmod 700 .ssh # chown user:user .ssh # cat /tmp/user.pub >> .ssh/authorized_keys # chmod 600 .ssh/authorized_keys # chown user:user .ssh/authorized_keys
Logging InEnsure that your users all have their appropriate private keys (generated earlier) and that they are in the users' ".ssh" directory of the local machine. Each user can now log in to any instance that has them added as a user and a copy of their public key in the .ssh/authorized_keys file in their home directory on the EC2 instance:
ssh -i ~/.ssh/user -l user ec2-your-instance-name.compute.amazonaws.comFor use with PuTTy, please read this chapter.
Bundle UpNaturally, these keys and user entries now exist on the current running instance and when you have added all your users, you should bundle and register the new AMI as described in Getting Started so that any new instances you launch from the AMI will already have all the appropriate accounts set up. Naturally, this may be tedious for situations with many user accounts or many instances, so you could equally provide a scripted solution that keeps track of active users by synchronizing with a persistent store such as S3.
Cleaning UpRemember to delete keys from the authorized_keys file on your instances when someone leaves your organization or no longer requires access. This can easily be achieved with the
# userdel usercommand. Beware, this will delete all data in the user's home directory.
It's All About Need to Know: Who, Why and What
Operate your system on a strictly "need to know" basis:
- Provide access only to those users who have a business need to be on your systems.
- Give them only as much access and privelege as they need to perform their specific tasks.
- provide temporary escalated priveleges such as sudo for users who need to perform occasional specialty tasks. These commands leave an audit trail.
- Have a procedure to revoke access when it is no longer needed.
Keeping Current: Regular Updates
Because the Linux world is highly dynamic and supported by a large and active community, there are always new versions, patches and upgrades to many components of a system. Many of these upgrades are in response to security vulnerabilities and it is vitally important to always stay current.
Due to the fact that EC2 provides a set of base AMIs that have been created at some time in the past, it's important to integrate the latest changes when initiating a new AMI for the first time as many patches may have been released since the original bundling of the AMI.
When you rebundle this AMI as your own, it will incorporate all the changes, but it's still important to establish a periodic check for all your running instances to collect any new changes.
The easiest tool to maintain your versions is something like the yum tool. Log in to your instance as root and simply run:
# yum update
Other distributions may offer similar tools, eg Debian and Ubuntu may use
# apt-get update
You should also subscribe to security mailing lists such as:
If you are running any specialized applications, you should also subscribe to their development and announcement mailing lists, as they may announce problems even before security lists such as BugTraq.
Other tools such as TripWire are also useful in identifying unauthorized changes to vital files in your environment and can be a crucial indicator of an intrusion.
What's It to Me? Why Security IS Important to You
Aside from the loss of data, disruption to your business and general inconvenience, there are more sinister aspects to an intrusion on your systems.
Many intruders are looking for an anonymous place to conduct their own nefarious business and their actions can have a direct impact on you:
- Legal: If the intruder goes on to conduct illegal activity on or from your server, parties who suffer damage may hold you liable.
- Financial: Bandwith consumed by your instances will be billed to your account. For example, if the intruder were to host a download site for (say) illegal software or music downloads and advertize the address on an underground mailing list, thousands of like minded downloaders may start downloading from your server, running up your usage charges.