If you are looking to improve security on your AWS Amazon Linux AMI Instance, iptables can be a good start. iptables is a kernel-based firewall service, very fast and free. Note that Inbound Security is handled by AWS Security Groups, so iptables is not strictly necessary to control Inbound packets. But if you turn iptables on, you will need to allow Inbound packets in addition to the SG rules.
Where iptables can help is with Outbound Security. If someone were to somehow get access to your servers, their main priority will be escalating privileges to root. Normally to do this you would need to download a ‘hacker pack’. You can prevent this with iptables. If, however, an attacker has root permissions on your box, iptables is useless because it can just be turned off.
Here is a simple starter script to be run on the AWS Instance. This assumes that you don’t do any Outbound Connecting from Apache via PHP (eg curl), but that you do connect to an RDS Instance. You will need to ‘sudo su’ before running the script, or run the script with sudo.
#!/bin/bash # setup basic chains and allow all or we might get locked out while the rules are running... iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # clear rules iptables -F # allow HTTP inbound and replies iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT # allow HTTPS inbound and replies iptables -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT # limit ssh connects to 10 every 10 seconds # change the port 22 if ssh is listening on a different port (which it should be) # in the instance's AWS Security Group, you should limit SSH access to just your IP # however, this will severely impede a password crack attempt should the SG rule be misconfigured iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP # allow SSH inbound and replies # change the port 22 if ssh is listening on a different port (which it should be) iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT # root can initiate HTTP outbound (for yum) iptables -A OUTPUT -p tcp --dport 80 -m owner --uid-owner root -m state --state NEW,ESTABLISHED -j ACCEPT # anyone can receive replies (ok since connections can't be initiated) iptables -A INPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT # root can do DNS searches (if your Subnet is 10.0.0.0/24 AWS DNS seems to be on 10.0.0.2) # if your subnet is different, change 10.0.0.2 to your value (eg a 172.31.1.0/24 Subnet would be 172.31.1.2) # see http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-dns.html # DNS = start subnet range "plus two" iptables -A OUTPUT -p udp --dport 53 -m owner --uid-owner root -d 10.0.0.2/32 -j ACCEPT iptables -A INPUT -p udp --sport 53 -s 10.0.0.2/32 -j ACCEPT # apache user can talk to rds server on 10.0.0.200:3306 iptables -A OUTPUT -p tcp --dport 3306 -m owner --uid-owner apache -d 10.0.0.200 -j ACCEPT iptables -A INPUT -p tcp --sport 3306 -s 10.0.0.200 -j ACCEPT # now drop everything else iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # save config /sbin/service iptables save
You need to be really careful with the SSH rules – if you get them wrong, you will be locked out of your box, permanently, no fix available. Also, if you are not using SSL (or SSL is terminated on your ELB), you should remove the 2 SSL rules.
DNS access is worth a mention. To determine your DNS servers, “add 2” to your Subnet, eg 10.0.0.0/24 would be 10.0.0.2/32. Another option is to type ‘nslookup’ on the server and then something like ‘google.com’ – the first line outputted will be the DNS IP address.
If you need to open up connectivity between servers in the Cloud VPC, here are some example rules, Inbound and Outbound:
# allow inbound access from 10.0.0.10 to port 2182 # change the IP and port as required iptables -A INPUT -p tcp --dport 2182 -m state --state NEW,ESTABLISHED -s 10.0.0.10 -j ACCEPT iptables -A OUTPUT -p tcp --sport 2182 -m state --state ESTABLISHED -j ACCEPT # allow outbound access to 10.0.0.10 port 514 (eg for rsyslog) # change the IP and port as required iptables -A OUTPUT -p tcp --dport 514 -d 10.0.0.10 -j ACCEPT iptables -A INPUT -p tcp --sport 514 -s 10.0.0.10 -j ACCEPT # for something like rsyslog, which runs as root, we can be more restrictive # allow outbound access ONLY TO root to 10.0.0.10:514 (eg for rsyslog) # not the addition of '-m owner --uid-owner root' # change the IP and port as required iptables -A OUTPUT -p tcp --dport 514 -m owner --uid-owner root -d 10.0.0.10 -j ACCEPT iptables -A INPUT -p tcp --sport 514 -s 10.0.0.10 -j ACCEPT
Here are some handy iptables commands (all need to be run as root, so do a ‘sudo su’ or prefix with ‘sudo’):
# stop iptables service iptables stop # start iptables service iptables start # cool stuff watch 'iptables -nvL'
Note that a major problem with iptables is that domain names are resolved when the rule is added and not for every packet. This is probably a good thing because it would mean a lot of DNS lookups… However, if in the rules above you use a domain name (eg an instance DNS name rather than an IP) be aware that if the underlying IP changes, iptables will fail. This applies particularly to RDS services – you can’t fix the IP of an RDS Instance and Amazon recommend connecting via the DNS name, but iptables will resolve the DNS to an IP and if it changes connectivity will be lost. Bear this in mind if you loose database connectivity – to fix, rerun the iptables script.
Frankly, unless you really know what you are doing, I don’t recommend using iptables. The DNS problem mentioned above means your site could experience massive failure if any DNS/IP pairs change. It’s also very unforgiving and I have on several occasions had to terminate and rebuild servers because of a misconfiguration – so MAKE SURE you back everything up before you start playing around with iptables! But, for a simple server which doesn’t communicate much outbound, or only does so to fixed IP addresses, iptables can add very strong extra security.