18

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!

5 Answers 5

28

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:

  1. Login to AWS.
  2. Navigate to VPC.
  3. Choose Network ACLs from the left hand menu.
  4. Choose the ACL associated with the VPC your ELB is in.
  5. Choose the Inbound Rules tab.
  6. Choose Edit and add a new rule with the following attributes:
    • Rule #: 50 (any number as long as it's less than the rule that ALLOWs from ALL)
    • Type: ALL Traffic
    • Protocol: ALL
    • Port Range: ALL
    • Source: 1.2.3.4/32
    • Allow / Deny: DENY

There's a bunch more information about Network ACLs here: http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html

1
4

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

alb listener rule web interface

2

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

1
  • 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... Jan 7, 2013 at 11:05
1

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.

1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .