The problem with the 2 balancer solution is that either of them will indiscriminately accept any Host
header and forward the request to the server. There's nothing at all wrong with pointing multiple balancers to the same server, but this configuration trivially bypasses your security group settings if a malicious user is aware of a.example.com
-- they simply connect to the a.example.com balancer and inject Host: b.example.com
in their request, and the instance cannot tell the difference.
ALBs add an HTTP header X-Forwarded-For
to each incoming request. The rightmost value in this header represents the actual IP address of the connecting client, and cannot be forged. Any addresses to the left of the rightmost value was supplied by the client (usually a proxy or a script kiddie) and for your purposes are untrustworthy and meaningless. But the one on the right will be accurate.
The simplest configuration would be to use a single ALB,
and for whatever is accepting the HTTP connections on the instance (e.g. Nginx, Apache) to simply deny HTTP requests when the Host
header contains b.example.com but X-Forwarded-For
does not end with the trusted IP, e.g. 203.0.113.50. The error could be 403 Forbidden
but perhaps better might be 503 Service Unavailable
.
With the two balancer setup, and one balancer restricted by security groups or NACLs, either your instance or the balancer needs to block requests for b.example.com
via the a.example.com
balancer. The instance can't, because identifying which balancer sent the request is not practical. When they scale or fail (and recover), their internal addresses change.
It is possible to blackhole specific requests through an ALB, either by Host
header or path pattern matching as I discussed here on SF, by creating a dummy target group with no instances assigned to it... so the a.example.com balancer could blackhole requests for b.example.com using such a configuration.
Or you can use Amazon Web Application Firewall (WAF) in conjunction with ALB to block any unexpected requests. This is a good option if you are planning on using WAF, anyway.
However... If you do use WAF, then you don't need two balancers... you could use a single balancer for both sites, and add rules on WAF to block requests for Host: b.example.com
unless the client IP matches the allowed list. The only caveat with WAF is that since it is checked for every request this means an outage in WAF would result in an outage for your sites... so WAF was designed to fail open. A WAF failure means all traffic is allowed, however unlikely such a failure may be. WAF is fully managed, so there is nothing for you to have to maintain.