I have a couple of web servers behind an Amazon ELB Network Load Balancer. The load balancer replaces the source IP address of a client packet with it's own source IP address.
In example, a client with an IP of 203.0.113.1
connects to my load balancer. The load balancer forwards the client traffic to a webserver with a source IP of 172.16.1.1
instead. This makes it difficult to selectively block client IPs.
There are two solutions for this in the Amazon Network Load Balancer:
- IP Preservation preserves IPv4 IPs through the load balancer transparently, but it does not support IPv6 natively, as IPv6 addresses are still translated to
172.16.1.1
- Proxy Protocol V2 can be enabled on the load balancer, which prepends a header to the
TCP DATA
field that contains addressing information. This supports IPv4 and IPv6, and is supported by my Apache webservers. The source IP address in the IP packet is still172.16.1.1
, but the true source IPv4/6 address is in the TCP data field inside the Proxy Protocol V2 header.
Typically, my server's firewall logs are read by Fail2Ban, which blocks misbehaving addresses. My problem is that I do not know how to block misbehaving traffic encapsulated with Proxy Protocol V2, as it does not seem that IPTables can directly inspect the Proxy Protocol V2 header, otherwise I would have used Fail2Ban and IPtables for this purpose.
My next solution is to send the IP addresses to a Lambda script to block IPs at my VPC's Network ACL or route table, but this would add some initial complexity, as this is seems to be the only way to block traffic to a Network Load Balancer.
Is there any easy way for Apache, IPTables or another tool to dynamically block traffic according to the IP value found in the Proxy Protocol V2 header?
iptables -D fail2ban-<name> -p tcp --dport 80 -m string --algo bm --string 'PROXY TCP4 <ip>' -j DROP
will work for IPv4 on the Proxy Protocol V2 at least. I will stress test it and see if it messes things up. Then I will probably look at doing it properly with a network ACL too, but those are limited at 20 rules per ACL. One could just abuse this to bypass firewalls by sending requests from false IPs until the limit is reached. Perhaps I could use multiple ACLs if that's even possible.