Based on the Linux Master 1 exam syllabusReport an error
DocumentRoot (file location) · <Directory> (access permissions) · <VirtualHost> (per-site branching).User apache, turn off Options Indexes in production, and use Apache 2.4's Require syntax (2.2 uses Order/Allow).httpd -t and then restart. The virtual host list is httpd -S, modules are httpd -M.httpd (the Debian family uses apache2).# Install
yum install httpd
# Daemon control
systemctl start httpd
systemctl enable httpd # Auto-start at boot
systemctl status httpd
# Config syntax check (a must before restarting!)
httpd -t # Confirm Syntax OK
apachectl configtest # Same
# Check the list of applied virtual hosts
httpd -S| Path | Role |
|---|---|
/etc/httpd/conf/httpd.conf | Main configuration file |
/etc/httpd/conf.d/ | Directory for keeping additional config (virtual hosts, etc.) separate |
/etc/httpd/conf.modules.d/ | Module loading configuration |
/var/www/html/ | Default DocumentRoot (web document root) |
/var/log/httpd/ | access_log, error_log |
Thanks to Include conf.d/*.conf inside httpd.conf, virtual hosts and extra config can be split into files in conf.d/ instead of being crammed into the main file. Keep the main config clean and put per-site config in separate files — this is the structure recommended in production. If you changed the configuration, you must check the syntax with httpd -t before restarting, so that a single typo does not bring down the whole server.
ServerRoot "/etc/httpd" # Base directory of the Apache installation
Listen 80 # Listening port (443 is HTTPS)
ServerName www.example.com:80 # The server's canonical name and port
DocumentRoot "/var/www/html" # Top-level directory where web documents are placed
DirectoryIndex index.html index.php # Default file to show on a directory request
ServerAdmin admin@example.com # Admin email shown on error pages
User apache # User the daemon runs as
Group apache # Group the daemon runs as
ErrorLog "logs/error_log" # Error log path
CustomLog "logs/access_log" combined # Access log path and format
LogLevel warn # Log verbosity level| Directive | Role |
|---|---|
Listen | Port Apache waits on (default 80, HTTPS 443) |
ServerName | The server's canonical hostname. Used for virtual host matching |
DocumentRoot | Actual file path corresponding to the URL root (/) |
DirectoryIndex | Default document to show when only a directory is requested |
ServerRoot | Base path for configuration, logs, and modules |
User / Group | Run as a dedicated non-root account for security |
LogLevel | Log detail level (debug/info/warn/error, etc.) |
Apache starts with root privileges and opens port 80 (only root can bind ports below 1024), then drops down to the low-privilege apache account (privilege drop) to handle the actual requests. That is why the User apache/Group apache settings are the heart of security — even if the web application is breached, it only runs as a restricted non-root account, so the damage scope shrinks. Leaving User root is a serious security mistake.
<Directory> block.<Directory "/var/www/html">
Options Indexes FollowSymLinks # Directory feature options
AllowOverride None # Scope allowed for .htaccess
Require all granted # Allow access (2.4 syntax)
</Directory>| Directive | Role |
|---|---|
Options Indexes | Automatically show a file listing when there is no index file |
Options FollowSymLinks | Allow following symbolic links |
AllowOverride | Scope in which .htaccess files may override configuration in that directory |
Require all granted | Allow all access (Apache 2.4) |
Require all denied | Block all access |
⚠️ Trap: Apache 2.2 and 2.4 have different access-control syntax. 2.2 uses
Order allow,deny/Allow from/Deny from, while 2.4 usesRequire all granted/Require ip .... Also, leavingOptions Indexeson creates a security problem in which the file list of a directory without index.html is exposed as-is — on production servers it is usually turned off. Another trap is that withAllowOverride None, .htaccess is ignored entirely.
site-a.com and site-b.com at the same time from a single physical server, use virtual hosts. There are two methods.| Method | Distinguishing criterion | IPs needed | Use |
|---|---|---|---|
| Name-based | The request's Host header (domain name) | 1 IP for many sites | Most common |
| IP-based | The IP address connected to | 1 IP per site | Some HTTPS cases / when isolation is needed |
Name-based virtual hosts — distinguished by domain name on a single IP:
<VirtualHost *:80>
ServerName www.site-a.com
DocumentRoot "/var/www/site-a"
ErrorLog "logs/site-a-error_log"
</VirtualHost>
<VirtualHost *:80>
ServerName www.site-b.com
DocumentRoot "/var/www/site-b"
ErrorLog "logs/site-b-error_log"
</VirtualHost>*:80 (port 80 on all IPs).ServerName the domain name in the HTTP Host header sent by the client matches.IP-based virtual hosts — give the server several IPs and distinguish by IP:
<VirtualHost 192.168.1.10:80>
ServerName www.site-a.com
DocumentRoot "/var/www/site-a"
</VirtualHost>
<VirtualHost 192.168.1.20:80>
ServerName www.site-b.com
DocumentRoot "/var/www/site-b"
</VirtualHost>Name-based virtual hosts are possible because, from HTTP/1.1, the Host header became mandatory in requests, so even when requests arrive on the same IP, "which domain is wanted" is carried inside the request. Thanks to this, hundreds of sites can run on one IP. If a request arrives unrelated to any domain (no matching ServerName), the first defined VirtualHost handles it by default.
In the early web (HTTP/1.0) there was no Host header, so running different sites on the same server meant buying a separate public IP for each site (IP-based). As IPv4 addresses began to run out, this was a big waste, and HTTP/1.1 made the Host header mandatory, making name-based virtual hosts the standard. That today's cloud can run countless sites without buying an IP per domain is a result of this change.
LoadModule rewrite_module modules/mod_rewrite.so # URL rewriting
LoadModule ssl_module modules/mod_ssl.so # HTTPS# Check loaded modules
httpd -M| Module | Role |
|---|---|
mod_ssl | HTTPS (TLS) support |
mod_rewrite | URL rewriting and redirects |
mod_proxy | Reverse proxy and load balancing |
mod_dir | DirectoryIndex handling |
Apache's operating model is determined by the MPM (Multi-Processing Module). prefork spawns a process per request, which is stable but uses a lot of memory (the traditional PHP environment), while worker/event use threads and are efficient for concurrent connections. If a server has many concurrent connections and runs short of memory, choosing the MPM and tuning limits such as MaxRequestWorkers is the starting point of tuning.
# Access log: who requested what
tail -f /var/log/httpd/access_log
# Example: 192.168.1.5 - - [05/Jun/2026:10:00:00] "GET /index.html HTTP/1.1" 200 1024
# Error log: what went wrong
tail -f /var/log/httpd/error_logcombined format contains the client IP, time, request line, response status code, bytes sent, referrer, and browser info.⚠️ Trap:
CustomLog(or access_log) records every request, andErrorLogrecords errors and diagnostic messages. A choice that mixes them up, such as "a 404 is left only in error_log, not access_log", is wrong — response codes like 404 are left in access_log as status codes, while configuration errors, module failures, and the like are left in error_log.
# 1. Create a default page
echo "<h1>Hello Apache</h1>" > /var/www/html/index.html
# 2. Check syntax, then start
httpd -t
systemctl restart httpd
# 3. Check the response locally
curl http://localhost/
curl -I http://localhost/ # Headers only (check the status code)
# 4. Check virtual host matching
httpd -S # List of defined VirtualHosts
# 5. Watch the log in real time
tail -f /var/log/httpd/access_logHTTP/1.1 200 OK returned by curl -I, it is working.curl -H "Host: www.site-a.com" http://localhost/, to see which site responds.Tomorrow we move on to Nginx, another powerhouse web server, covering its event-driven architecture, the reverse proxy, and a comparison with Apache.
/) actually points to. The default is /var/www/html.Include conf.d/*.conf : A structure that splits per-site configuration into separate files to keep the main configuration clean.apache account to handle requests. Set by User/Group.Options Indexes : An option that exposes the directory listing as-is when there is no index file. Usually turned off in production.AllowOverride : The scope in which .htaccess can override configuration in that directory. With None, .htaccess is ignored.Require all granted / denied : Apache 2.4's allow / block access syntax. It replaced 2.2's Order and Allow from.prefork is process-based, while worker and event are thread-based.Click a choice to reveal the answer and explanation.
Question 1
In Apache httpd.conf, which directive specifies the top-level directory where web documents are placed (the actual path corresponding to the URL root /)?
Question 2
When serving several domains from a single IP address, what criterion does Apache use to decide which site to send a request to?
Question 3
Which command checks for syntax errors after modifying the Apache configuration and before restarting?
Question 4
What behavior occurs when Options Indexes is left on in a <Directory> block?
Question 5
Which of the following is correct about the difference between IP-based and name-based virtual hosts?
Question 6
Which directive specifies that Apache starts as root and opens the port, then drops to a low-privilege account to handle actual requests?
Question 7
In Apache 2.4, which directive allows all access to a specific directory?