Hi Tim,

On Fri, Apr 27, 2018 at 12:16:15AM +0200, Tim Düsterhus wrote:
> The solution I got from "Holger Just" was:
> 
> >     http-request   set-header X-CHECKSNI %[req.hdr(host)]==%[ssl_fc_sni] if 
> > { ssl_fc_has_sni }
> >     http-request   deny                  if { ssl_fc_has_sni } ! { 
> > hdr(X-CHECKSNI) -m reg -i ^(?<host>.+)==\1$ }
> >     http-request   del-header X-CHECKSNI
> 
> which works well, but is not intuitive and requires PCRE.
> 
> I have contemplated to add a patch with a `ssl_sni_http_host_mismatch`
> fetch, but I wasn't quite sure where to place it (it requires both http
> and ssl and thus is misplaced in both) and what parameters to pass
> (meaning SMP_USE_HRQHV et al). And thus I gave up.

I'd proceed differently I think. Just like we do have arithmetic operators
support variables as arguments, we could have string operators like strcmp()
which would support a variable as well. Then you could simply put your SNI
into a variable, and compare the host field with this variable.

In practice I've long wanted to have a stack-based sample expression
evaluation but while many of us think it will eventually appear, I think
that a few operators like strcmp() and concat() should be implemented to
cover the short-term needs.

> Not having this validation opens up possible security issues (validation
> of client certificates is based on SNI, routing is possibly based on the
> Host header).

For this specific case I agree.

> Personally I require SNI for everything and select the
> backends based on SNI and not the Host header.

This is dangerous because it's not what the backend servers will do,
so you need to keep this in mind to ensure you never switch to the
wrong place. Also as Lukas explained, when some certs overlap, you'll
only have the SNI matching the first Host. Apparently in your case it's
not an issue since you exactly compare them. Normally the reliable way
of doing it would be to ensure that SNI is valid (eg when you have to
check a client cert) but still rely on Host for routing.

> If you could give me some pointers on where to put such a fetch and what
> parameters to set I'd appreciate it. Or tell me that such a fetch is
> stupid, because it mixes information from different layers.

It's not stupid, it's just that I'm pretty sure that immediately after
being committed, someone will want to adjust its behaviour (ignore case,
stop on colon, etc). For this strcmp() will allow you to normalize each
party and then to compare the results.

Regards,
Willy

Reply via email to