Synopsis: httpd `server match` and `alias match` are broken.
Category: system
Environment:
System : OpenBSD 6.8
Details : OpenBSD 6.8 (GENERIC.MP) #5: Mon Feb 22 04:36:10 MST 2021
[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
Architecture: OpenBSD.amd64
Machine : amd64
Description:
If using `server match` or `alias match` in `httpd.conf`, the first
`server` in an interface/port combo that uses a match entry will become
the "default" server for that interface/port combo. It doesn't seem to
simply be a `greedy` match situation -- because earlier-defined servers
don't get pulled in by the match -- only defaults and all subsequently
defined servers.
How-To-Repeat:
Create `/etc/hosts` entries for hostnames `abc`, `def`, `ghi`, and
`jkl`.
Run `httpd` with this config. Note: to simplify this config, I
configured each host to return a different http status code for each
server. The same works for returned files, though (I originally
encountered this when I tried using a server match for the
second-to-last-defined server entry, and then noticed that the wrong
files were served from the last-defined server entry).
```
server "abc" {
listen on * port 80
block return 405
}
server "def" {
# This will perform similarly when patterned as "^def$", "^def", etc.
Also, works the same if it's done as `server match` instead.
# Commented out this line to run once how it "should" work; uncomment
the below to "break" it.
#alias match "^$"
listen on * port 80
block return 406
}
server "ghi" {
listen on * port 80
block return 407
}
```
`curl http://abc` -- returns 405
`curl http://def` -- returns 406
`curl http://ghi` -- returns 407
`curl http://jkl` -- returns 405
--- the above works as expected ---
If you uncomment the `alias match` line above, and reload httpd, then:
`curl http://abc` -- returns 405
`curl http://def` -- returns 406
`curl http://ghi` -- returns 406
`curl http://jkl` -- returns 406
Fix:
Stop using `server match` or `alias match` entries, and enumerate all
the individual entries.