This article is all http daemon related which is a very small subset of server config...
I don't want to devolve into all my own tips and then have arguments about fail2ban, but I have one tweak to the TRACE/TRACK note, really there are some silly things people can do with any requests other than POST/GET (also silly things people can do with those, but that's primarily App security).
I disallow OPTIONS, HEAD, TRACE... everything, with this sort of an Apache config:
<LimitExcept POST GET>
Require valid-user
</LimitExcept>
The biggest place this can cause issues is with load balancers using a HEAD command to check the existence of a server.
This is probably over-broad. HEAD is also used by browsers to determine whether or not to re-request cached content; disabling it will still allow pages to load properly, but will waste bandwidth and slow down page loads as browsers re-request unchanged content.
I've found that some of the URL security that people setup only apply to GET/POST, they're unaware of these other methods (TRACK? WTF?). As such, it's nice to have these off by default, and turn them on when needed. I saw a good note some time ago from people essentially stat'ing files they shouldn't have been able to see at all via OPTIONS or HEAD because they were secured against GET and POST only.
There is a nice discussion going below on whether you need these for AJAX, conditional gets, etc. If you need this enabled for AJAX, consider enabling it for the URL or directory where your AJAX interactions occur. I run a large wordpress site and haven't had issues with any of this.
Why would a browser use HEAD instead of conditional GET to re-request cached content? It would require one more round-trip if a refresh is actually required.
HEAD just returns the headers, not the content. So, it is a faster way to see if content has been updated. If it has, then the client can request the content with a GET.
Right, the question was why not use a conditional get, which either returns content if the thing has been modified, or a 304 Not Modified and no content if it hasn't -- this accomplishes the same thing as HEAD with only one request. Above, though, I wasn't sure why one or the other wasn't always used...
I looked it up, though. It looks like you have to have an ETag to do a conditional GET, so browsers use HEAD if the original response (the cached one) didn't include one.
Either Last-Modified or Etag is sufficient. Most servers will add both, though.
Edit: The difference is that Last-Modified allows clients to use a heuristic to determine if the response should be cached for a certain duration (unless explicit Cache-Control or Expires headers are used). The heuristic isn't specified, but a 10% fraction of Date - Last-Modified is suggested, and in fact, that is what e.g. Internet Explorer does.
I don't think browsers do use HEAD to determine whether or not to re-request cached content; they make a conditional GET, ie a GET with an If-Modified-Since header (or one of its relatives).
Are there some situations where browsers use HEAD instead of conditional GET? Or is my understanding wrong?
Still, HEAD seems like it should generally be fairly safe, so not something i'd leap to block.
I don't want to devolve into all my own tips and then have arguments about fail2ban, but I have one tweak to the TRACE/TRACK note, really there are some silly things people can do with any requests other than POST/GET (also silly things people can do with those, but that's primarily App security).
I disallow OPTIONS, HEAD, TRACE... everything, with this sort of an Apache config:
<LimitExcept POST GET> Require valid-user </LimitExcept>
The biggest place this can cause issues is with load balancers using a HEAD command to check the existence of a server.