LFCE 51 ๐ง Apache โ Basic Configuration
Apache HTTP Server, commonly called httpd, is the other major web server in the Linux ecosystem. The previous chapter covered installation and the default “It works!” page. This chapter covers the configuration that replaces the default with a working site: the ServerName and DocumentRoot directives, the <Directory> block that controls access to the filesystem, the DirectoryIndex that determines which file is served for a directory request, and the validation command that prevents a syntax error from becoming an outage. Apache’s configuration is directive-based, and the directives live inside containers like <Directory> and <VirtualHost>. The main configuration file differs by distribution: /etc/apache2/apache2.conf on Debian and Ubuntu, and /etc/httpd/conf/httpd.conf on RHEL and its derivatives .
Key point: The DocumentRoot directive tells Apache where the site’s files live. The <Directory> block for that path controls which features are allowed and who can access the files. The ServerName directive identifies the hostname the server uses for self-referential URLs. Always run apache2ctl configtest (Debian) or httpd -t (RHEL) before reloading; a configuration error prevents the new configuration from being applied.
Why basic configuration requires understanding the container model
The directory-permission problem.
Apache serves files from the filesystem, and the <Directory> block is the mechanism that grants or denies access to a specific path. The default configuration on many distributions includes a <Directory /var/www/> block with Require all granted, which allows access to the web root. If the DocumentRoot is changed to a path that is not covered by a permissive <Directory> block, the server returns a 403 Forbidden response even though the files exist and the path is correct . The <Directory> block is not optional decoration; it is the access control layer that sits between the filesystem and the HTTP response.
The ServerName problem.
Apache uses the ServerName directive to construct self-referential URLs, such as redirects when a client requests a directory without a trailing slash. If ServerName is not set, Apache attempts to determine the hostname from the system’s DNS configuration, which may be slow or incorrect. A warning during startup indicates that ServerName is not configured . The directive should be set explicitly to the hostname that clients use to reach the server.
The DirectoryIndex problem.
A request for a directory, such as http://example.com/, does not specify a file. The DirectoryIndex directive tells Apache which file to serve when the request resolves to a directory. The default is index.html, but applications often need index.php or a list of candidates. If the DirectoryIndex does not include the file that exists in the directory, Apache returns a 403 or a directory listing, depending on the Options setting .
a. The ServerName and DocumentRoot directives
The ServerName directive identifies the hostname, and the DocumentRoot directive sets the filesystem path for the site. Both belong in the main server configuration or in a virtual host block.
# /etc/apache2/apache2.conf (Debian) or /etc/httpd/conf/httpd.conf (RHEL)
ServerName example.com
DocumentRoot /var/www/example
<Directory /var/www/example>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
The ServerName is the hostname that Apache uses when it needs to construct a URL that refers to itself. The DocumentRoot is the base path for all requests. The <Directory> block grants access to that path and sets the options for the directory .
The Options directive controls which features are enabled in the directory. FollowSymLinks allows symbolic links to be followed. Indexes allows directory listings when no index file exists; it should be removed or negated (-Indexes) to prevent listing the contents of directories that lack an index file . The AllowOverride directive controls whether .htaccess files can override the configuration; None disables them, which is the recommended setting when the application does not require them.
b. The DirectoryIndex and access control
The DirectoryIndex directive specifies the files that Apache tries when a request resolves to a directory. The first file that exists is served.
# Serve index.html or index.php for directory requests
DirectoryIndex index.html index.php
The order matters. Apache tries each file in the order listed and serves the first one that exists. If the application uses PHP, index.php should be in the list. If the site is static, index.html is sufficient .
The access control is provided by the Require directive inside the <Directory> block. The Require all granted directive allows access from all clients. The Require all denied directive denies access from all clients. A more restrictive configuration can require authentication or restrict access to specific IP addresses.
<Directory /var/www/example>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
# Deny access to sensitive files
<Files ".env">
Require all denied
</Files>
The <Files> block applies the access control to a specific filename pattern, regardless of which directory it is in. The Require all denied directive for .env prevents the file from being served, even if it is inside the DocumentRoot .
c. Validating and reloading the configuration
The validation command parses the configuration and reports syntax errors before the reload. On Debian and Ubuntu, the command is apache2ctl configtest. On RHEL and its derivatives, the command is httpd -t .
# Debian / Ubuntu
sudo apache2ctl configtest
# Output: Syntax OK
# RHEL / Rocky
sudo httpd -t
# Output: Syntax OK
If the validation succeeds, the configuration can be reloaded without dropping active connections. The reload command differs by distribution: systemctl reload apache2 on Debian, systemctl reload httpd on RHEL .
# Debian
sudo systemctl reload apache2
# RHEL
sudo systemctl reload httpd
After the reload, the site can be tested with curl from the local host or from a remote client. The curl -I http://localhost command retrieves the HTTP headers and confirms that the server returns a response. A browser request to the server’s IP address or hostname returns the content from the DocumentRoot.
Complete Example Session
# ============================================
# PART 1: CREATE THE SITE DIRECTORY
# ============================================
sudo mkdir -p /var/www/example
echo "<h1>Example Site</h1>" | sudo tee /var/www/example/index.html
# ============================================
# PART 2: SET OWNERSHIP AND PERMISSIONS
# ============================================
# Debian: www-data; RHEL: apache
sudo chown -R www-data:www-data /var/www/example
sudo chmod -R 755 /var/www/example
# ============================================
# PART 3: EDIT THE MAIN CONFIGURATION
# ============================================
# Debian: /etc/apache2/apache2.conf
# RHEL: /etc/httpd/conf/httpd.conf
# Add or modify:
# ServerName example.com
# DocumentRoot /var/www/example
# <Directory /var/www/example>
# Options -Indexes +FollowSymLinks
# AllowOverride None
# Require all granted
# </Directory>
# DirectoryIndex index.html index.php
# ============================================
# PART 4: VALIDATE THE CONFIGURATION
# ============================================
sudo apache2ctl configtest # Debian
# or
sudo httpd -t # RHEL
# Output: Syntax OK
# ============================================
# PART 5: RELOAD APACHE
# ============================================
sudo systemctl reload apache2 # Debian
# or
sudo systemctl reload httpd # RHEL
# ============================================
# PART 6: TEST LOCALLY
# ============================================
curl -I http://localhost
# Output: HTTP/1.1 200 OK
# ============================================
# PART 7: TEST FROM A REMOTE CLIENT
# ============================================
# From another machine:
# curl http://<server-ip>
# Output: <h1>Example Site</h1>
# ============================================
# PART 8: VERIFY DIRECTORY LISTING IS DISABLED
# ============================================
curl -I http://localhost/nonexistent/
# Output: HTTP/1.1 403 Forbidden (or 404)
# The -Indexes option prevents the listing
# ============================================
# PART 9: CHECK THE ERROR LOG
# ============================================
sudo tail -5 /var/log/apache2/error.log # Debian
# or
sudo tail -5 /var/log/httpd/error_log # RHEL
# Output shows any warnings or errors from the reload
# ============================================
# PART 10: VERIFY THE SERVER NAME
# ============================================
sudo apache2ctl -S # Debian
# or
sudo httpd -S # RHEL
# Output shows the server name and the virtual host configuration
The ten parts demonstrate the complete basic configuration workflow: create content, set permissions, edit the configuration, validate, reload, test locally, test remotely, verify directory listing is disabled, check the error log, and verify the server name. The critical steps are Part 4 (validation before reload) and Part 10 (confirming that ServerName is recognized).
Quick Reference
Basic Configuration Directives
| Directive | Purpose | Example |
|---|---|---|
ServerName | Hostname for self-referential URLs | ServerName example.com |
DocumentRoot | Filesystem path for the site | DocumentRoot /var/www/example |
<Directory> | Access control for a path | <Directory /var/www/example> |
Options | Features enabled in the directory | Options -Indexes +FollowSymLinks |
AllowOverride | Whether .htaccess can override | AllowOverride None |
Require | Access control | Require all granted |
DirectoryIndex | Default file for directory requests | DirectoryIndex index.html |
<Files> | Access control for a filename pattern | <Files ".env"> |
Validation and Control Commands
| Command | Distribution | Purpose |
|---|---|---|
apache2ctl configtest | Debian | Validate configuration syntax |
httpd -t | RHEL | Validate configuration syntax |
systemctl reload apache2 | Debian | Reload without dropping connections |
systemctl reload httpd | RHEL | Reload without dropping connections |
apache2ctl -S / httpd -S | Both | Show server name and virtual hosts |
Common Options
| Option | Meaning |
|---|---|
Indexes | Allow directory listings |
-Indexes | Disable directory listings |
FollowSymLinks | Allow symbolic links |
+FollowSymLinks | Enable symbolic links (additive) |
None | Disable all options |
Best Practices
โ Do This:
# Set ServerName explicitly
ServerName example.com # โ
# Use -Indexes to prevent directory listings
Options -Indexes +FollowSymLinks # โ
# Grant access explicitly to the DocumentRoot
<Directory /var/www/example>
Require all granted
</Directory> # โ
# Deny access to sensitive files
<Files ".env">
Require all denied
</Files> # โ
# Set DirectoryIndex to include the application's entry file
DirectoryIndex index.html index.php # โ
# Validate before reloading
apache2ctl configtest # or httpd -t # โ
โ Don’t Do This:
# Forget the <Directory> block for the DocumentRoot
DocumentRoot /var/www/example # 403 without the block # โ
# Leave Indexes enabled on a directory with no index file
Options Indexes # Lists the directory contents # โ
# Use a permissive <Directory> for the entire filesystem
<Directory />
Require all granted
</Directory> # Grants access to /etc, /root, etc. # โ
# Omit DirectoryIndex for PHP applications
DirectoryIndex index.html # index.php is not served # โ
# Reload without validation
systemctl reload apache2 # A syntax error is rejected # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| 403 Forbidden on the site | No <Directory> block or wrong permissions | Add the block; chown to the web user |
| 404 but the file exists | DocumentRoot path is wrong | Verify the path and the file location |
| Directory listing appears | Options Indexes is enabled | Use Options -Indexes |
ServerName warning at startup | ServerName not set | Add ServerName example.com |
| PHP file is not served | DirectoryIndex does not include index.php | Add it to the list |
| Configuration error after edit | Missing directive or typo | apache2ctl configtest reports the line |
Real-World Examples
1. Set ServerName
ServerName example.com
2. Set DocumentRoot
DocumentRoot /var/www/example
3. Grant access to the DocumentRoot
<Directory /var/www/example>
Require all granted
</Directory>
4. Disable directory listing
Options -Indexes +FollowSymLinks
5. Disable .htaccess overrides
AllowOverride None
6. Set DirectoryIndex
DirectoryIndex index.html index.php
7. Deny access to sensitive files
<Files ".env">
Require all denied
</Files>
8. Validate configuration
apache2ctl configtest # Debian
httpd -t # RHEL
9. Reload Apache
systemctl reload apache2 # Debian
systemctl reload httpd # RHEL
10. Show server configuration
apache2ctl -S # Debian
httpd -S # RHEL
Visual
The Configuration Container Model
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ APACHE CONFIGURATION IS DIRECTIVES INSIDE CONTAINERS โ
โ โ
โ ServerName example.com โ Global directive โ
โ DocumentRoot /var/www/example โ Global directive โ
โ โ
โ <Directory /var/www/example> โ Container โ
โ Options -Indexes โ
โ Require all granted โ Directive inside container โ
โ </Directory> โ
โ โ
โ <Files ".env"> โ Container โ
โ Require all denied โ
โ </Files> โ
โ โ
โ The container determines where the directives apply. โ
โ <Directory> applies to a filesystem path. โ
โ <Files> applies to a filename pattern. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Access Control Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE <Directory> BLOCK GRANTS OR DENIES ACCESS โ
โ โ
โ Request: GET /index.html โ
โ โ โ
โ โผ โ
โ DocumentRoot = /var/www/example โ
โ Filesystem path = /var/www/example/index.html โ
โ โ โ
โ โผ โ
โ Is there a <Directory> block for /var/www/example? โ
โ โ โ
โ โโโ No โ 403 Forbidden โ
โ โ โ
โ โโโ Yes โ Check Require directive โ
โ โ โ
โ โโโ Require all denied โ 403 Forbidden โ
โ โ โ
โ โโโ Require all granted โ Serve the file โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Validation and Reload Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ VALIDATE BEFORE RELOADING โ
โ โ
โ Edit configuration โ
โ โ โ
โ โผ โ
โ apache2ctl configtest (Debian) / httpd -t (RHEL) โ
โ โ โ
โ โโโ Error โ Fix file, repeat โ
โ โ โ
โ โโโ Syntax OK โ systemctl reload apache2 / httpd โ
โ โ โ
โ โผ โ
โ New configuration active โ
โ Active connections preserved โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Debian main config | /etc/apache2/apache2.conf |
| RHEL main config | /etc/httpd/conf/httpd.conf |
| Server hostname | ServerName directive |
| Document root | DocumentRoot directive |
| Access control | <Directory> + Require |
| Directory listing | Options Indexes / -Indexes |
| Default index file | DirectoryIndex directive |
| Sensitive file denial | <Files> + Require all denied |
| Validation (Debian) | apache2ctl configtest |
| Validation (RHEL) | httpd -t |
| Reload (Debian) | systemctl reload apache2 |
| Reload (RHEL) | systemctl reload httpd |
Key takeaways:
- The
<Directory>block is the access control layer. Without it, Apache returns 403 Forbidden even when the files exist and the path is correct. The block grants access withRequire all grantedand sets the options for the directory . ServerNameshould be set explicitly. Apache uses it to construct self-referential URLs. Without it, the server may produce incorrect redirects or a warning at startup .DirectoryIndexdetermines the default file. A request for a directory serves the first file in the list that exists. For PHP applications,index.phpmust be in the list .Options -Indexesprevents directory listings. Without it, a request for a directory with no index file produces a listing of its contents, which can expose files that should not be visible .- The
<Files>block denies access to specific filenames. A<Files ".env">block withRequire all deniedprevents the file from being served even if it is inside theDocumentRoot. - Validate before reloading.
apache2ctl configteston Debian andhttpd -ton RHEL catch syntax errors before the configuration is applied. A configuration error prevents the reload, and the running configuration remains in effect .
Remember: Apache configuration is built from directives inside containers. The ServerName and DocumentRoot directives set the identity and the filesystem path. The <Directory> block grants access and controls the features for that path. The DirectoryIndex determines which file is served for a directory request. The <Files> block denies access to sensitive filenames. Validate with configtest or -t, reload with systemctl reload, and test with curl. A configuration that parses is not necessarily a configuration that serves the right site; the test confirms both.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!