14

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!

Napster_X
  • 3,333
  • 16
  • 20
boris quiroz
  • 1,140
  • 1
  • 7
  • 18

5 Answers5

22

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

Tama
  • 321
  • 2
  • 4
  • 1
    [The quotas for AWS VPCs](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html) are pretty limited so this is only sensible for blocking a *very* small number of IP addresses. – Kenny Evitt Nov 05 '20 at 19:05
2

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

Pete
  • 123
  • 4
2

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

Sebastian Cruz
  • 232
  • 2
  • 6
  • 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 07 '13 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.

Napster_X
  • 3,333
  • 16
  • 20
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

kvz
  • 402
  • 4
  • 14