Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

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!

share|improve this question

3 Answers 3

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.

share|improve this answer

If you only need to blacklist a few IPs you could probably use nginx_http_access_module on your web server.

share|improve this answer
    
The main problem with this, is that I need to figure out how to do it "automagically", as all my configurations are managed by Chef. I need something like fail2ban or denyhost to tell some Chef config to block some IP addresses... –  boris quiroz Jan 7 '13 at 11:05

For that, the best solution is, as you said, IPtables at the 3 different machines.

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

set $client_ip $remote_addr;
if ($http_x_forwarded_for) {
  set $client_ip $http_x_forwarded_for;
}

if ($client_ip = "123.123.123.123") {
  return 403;
}

if ($client_ip = "123.123.123.234") {
  return 403;
}

Introducing a variable $client_ip, just so that I could also test this locally, where there is no http_x_forwarded_for available..

Slightly offtopic but posting for convenience, I also added that client ip to my access logs:

log_format main "\$client_ip - \$remote_user [\$time_local] \"\$request\" \$status \$body_bytes_sent \"\$http_referer\" \"\$http_user_agent\"";
access_log /var/log/nginx.access.log main;

It's not pretty, but hope it helps

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.