I've, more or less, following configuration on AWS:
Elastic load balancer with 3 machines o 3 different availability zones. My security group allows 0.0.0.0/0:80 as it's my rails application (nginx, unicorn).
I was wondering if there's any way to deny access to my app to an specific public ip address? I've been reading AWS documentation, but as SG's are "deny all" there's no way to deny just one specific IP address.
Any ideas? iptables on the 3 machines behind load balancer?
Thanks!
A straight forward solution is to use a VPC Network ACL Inbound Rule. This only works if your ELB is in a VPC, but if you've created it in the last few years it should be in the default one.
To ban 1.2.3.4 for example, do the following:
VPC
.Network ACLs
from the left hand menu.Inbound Rules
tab.Edit
and add a new rule with the following attributes:There's a bunch more information about Network ACLs here: http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html
If you only need to blacklist a few IPs you could probably use nginx_http_access_module on your web server.
With an Application Load Balancer, you can stop the traffic via a Listener Rule.
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-update-rules.html
No, There is no option to block IPs with security group.
Security group is essentially a white-list, instead of black-list.
Everything is denied by default and you can selectively open ports according to your need, but you can't block any specific people/ip.
For that, the best solution is, as you said, IPtables at the 3 different machines.
I am sure going forward AWS security groups will have this functionality too, but not as of now.
Actually, that is not a good solution as the remote ip (
$remote_addr
in Nginx) will be from Amazon's loadbalancer. Banning that will result in all traffic forwarded getting banned.You'll have to inspect the packets and find the HTTP
X-Forwarded-For
header, IPtables isn't protocol aware like that.I settled for the following solution to 2 naughty IPs in Nginx
Introducing a variable
$client_ip
, just so that I could also test this locally, where there is nohttp_x_forwarded_for
available..Slightly offtopic but posting for convenience, I also added that client ip to my access logs:
It's not pretty, but hope it helps