Logging, Access Control & Basic Hardening
Web Servers Fundamentals
Chapter 8 · Logging, Access Control & Basic Hardening
Chapter 5 flagged directory listing as a real, common misconfiguration. This chapter widens that lens: what each server records about every request by default, how to restrict access at the web-server layer itself before a request ever reaches the application, and a handful of other low-cost hardening steps worth knowing about.
Access Logs & Error Logs
Every request handled is normally recorded in an access log — client IP, timestamp, the request line itself, the response status code, and typically the response size — while server-side problems (a misconfiguration, a backend failing to respond) go to a separate error log. Apache uses access.log/error.log, with the exact fields recorded controlled by a configurable LogFormat. Nginx uses its own access_log/error_log directives, similarly format-configurable. IIS records requests in the W3C Extended Log File Format by default, configured through IIS Manager. All three capture broadly the same core information, just formatted and configured differently.
Basic Access Control
Restricting who can reach a given path can happen at the web-server layer itself, before a request ever reaches the application behind it. Apache's Require directive (via mod_authz_host) can restrict access by IP, and .htpasswd-backed Basic Authentication can require a username/password. Nginx uses its own allow/deny directives for IP restriction and auth_basic for password protection. IIS offers the equivalent through its IP Address and Domain Restrictions feature, plus Basic or Windows Authentication configured per site. In every case, a request that fails this check never reaches the application at all — the rejection happens at the web server itself.
Basic Hardening: Hiding Version Information
By default, all three servers reveal their own name and version number in response headers or error pages — Apache's ServerTokens/ServerSignature and Nginx's server_tokens off suppress this; IIS requires an add-on (commonly via URL Rewrite rules) to strip its own version string similarly. The goal is reducing the information an attacker can gather during initial reconnaissance — knowing the exact server version can point directly at known, unpatched vulnerabilities for that specific version.
Revisiting Directory Listing
Chapter 5's own directory-listing warning belongs on this same checklist: confirming it's genuinely disabled (not just left at whatever the default happens to be) is one more low-cost step in the same category as version hiding and access control — each one closes off a small piece of information or access an attacker could otherwise use.
| Apache | Nginx | IIS | |
|---|---|---|---|
| Access/error logs | access.log/error.log, configurable LogFormat | access_log/error_log directives | W3C Extended Log File Format |
| IP-based access control | Require (mod_authz_host) | allow/deny | IP Address and Domain Restrictions |
| Password auth | .htpasswd + Basic Auth | auth_basic | Basic/Windows Authentication |
| Hide version info | ServerTokens/ServerSignature | server_tokens off | Requires an add-on (e.g. URL Rewrite) |
Hands-On Exercises
Write the Nginx configuration that restricts access to a /admin/ path to only the IP address 203.0.113.10, denying everyone else.
📄 View solutionA team disables ServerTokens/server_tokens on their production servers and considers the server "properly secured" as a result, deprioritizing an overdue security patch. Using this chapter's own warning box, explain what's wrong with this reasoning.
📄 View solutionExplain, in your own words, why restricting access to a sensitive path at the web-server layer (via IP restriction or Basic Auth) is meaningfully different from relying on the application itself to check permissions before showing that content.
📄 View solutionChapter 8 Quick Reference
- All three servers log requests by default — Apache/Nginx via configurable plain-text formats, IIS via W3C Extended Log File Format
- Access control at the web-server layer rejects disallowed requests before they ever reach the application
- Hiding version info (ServerTokens/server_tokens off) reduces reconnaissance value but is security through obscurity, not a real fix
- Directory listing (Chapter 5) belongs on this same hardening checklist — confirm it's genuinely disabled, not just defaulted