Home Blog Certs Knowledge Base About

LPIC-2 208.1 โ€” Basic Apache Configuration

Exam topic 208.1 โ€” Basic Apache Configuration (weight: 4). Covers Apache httpd installation, configuration structure, modules, MPM, access control, virtual hosts, and basic performance tuning.


Apache Overview

Apache HTTP Server (httpd) is the most widely deployed web server in the world. It handles HTTP/HTTPS requests and supports a rich module ecosystem.

Default port: 80 (HTTP), 443 (HTTPS)

Configuration file locations:

DistributionMain configAdditional
RHEL / CentOS/etc/httpd/conf/httpd.conf/etc/httpd/conf.d/*.conf
Debian / Ubuntu/etc/apache2/apache2.confSplit into multiple directories

Debian/Ubuntu directory structure:

/etc/apache2/
โ”œโ”€โ”€ apache2.conf          # Main config
โ”œโ”€โ”€ ports.conf            # Listen directives
โ”œโ”€โ”€ sites-available/      # All virtual host configs
โ”œโ”€โ”€ sites-enabled/        # Symlinks to active sites
โ”œโ”€โ”€ mods-available/       # All module configs (.load + .conf)
โ”œโ”€โ”€ mods-enabled/         # Symlinks to active modules
โ””โ”€โ”€ conf-available/       # Additional config snippets
    conf-enabled/         # Symlinks to active snippets

Managing Apache

apache2ctl / apachectl

apache2ctl start           # start Apache
apache2ctl stop            # stop Apache
apache2ctl restart         # restart (drops connections)
apache2ctl graceful        # graceful restart (waits for requests to finish)
apache2ctl graceful-stop   # graceful stop
apache2ctl configtest      # test configuration (-t shorthand)
apache2ctl status          # show server status (requires mod_status)
apache2ctl -M              # list loaded modules
apache2ctl -S              # list virtual hosts
apache2ctl -l              # list statically compiled modules (httpd -l)

Debian helper tools:

a2enmod  rewrite           # enable module
a2dismod rewrite           # disable module
a2ensite 000-default       # enable virtual host
a2dissite 000-default      # disable virtual host
a2enconf security          # enable config snippet
a2disconf security         # disable config snippet

Apache Modules

Static vs DSO modules

TypeHow loadedDetection
StaticCompiled into binaryhttpd -l (built-in list)
DSOLoaded at runtime via LoadModulehttpd -M or apache2ctl -M

DSO (Dynamic Shared Object) requires mod_so to be compiled in.

LoadModule syntax:

LoadModule rewrite_module modules/mod_rewrite.so
LoadModule php7_module      /usr/lib/apache2/modules/libphp7.so

Module files location:

  • RHEL: /etc/httpd/modules/ โ†’ symlink to /usr/lib64/httpd/modules/
  • Debian: /usr/lib/apache2/modules/

Building modules with apxs:

apxs -c -i -a mod_example.c
# -c  compile
# -i  install into modules directory
# -a  enable in httpd.conf (adds LoadModule)

MPM โ€” Multi-Processing Module

Apache can use one of several MPM backends:

Prefork MPM (default for mod_php compatibility)

Each request handled by a separate process (no threads). Safer with non-thread-safe libraries.

<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxRequestWorkers   150
    MaxConnectionsPerChild 0
</IfModule>
DirectiveDefaultDescription
StartServers5Initial child processes
MinSpareServers5Minimum idle processes
MaxSpareServers10Maximum idle processes
MaxRequestWorkers150Max simultaneous connections
MaxConnectionsPerChild0Max requests per child (0 = unlimited)

Worker MPM

Hybrid: multiple processes, each with multiple threads. More efficient but requires thread-safe code.

<IfModule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadsPerChild      25
    MaxRequestWorkers   150
    MaxConnectionsPerChild 0
</IfModule>

MaxRequestWorkers protects available RAM from being exhausted under high load.


Logging

Access log

Default location: /var/log/apache2/access.log (Debian) or /var/log/httpd/access_log (RHEL)

Common Log Format (CLF):

%h %l %u %t "%r" %>s %b
TokenMeaning
%hRemote hostname/IP
%lIdentity (from identd, usually -)
%uAuthenticated user (or -)
%tTime of request
%rFirst line of request (GET /path HTTP/1.1)
%>sFinal HTTP status code
%bBytes sent (excluding headers; - if zero)

Combined format adds:

%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"

Defining log formats:

LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

CustomLog /var/log/apache2/access.log combined

Error log

ErrorLog  /var/log/apache2/error.log
LogLevel  warn

LogLevel values (least โ†’ most verbose):

emerg โ†’ alert โ†’ crit โ†’ error โ†’ warn โ†’ notice โ†’ info โ†’ debug โ†’ trace1 โ†’ trace8

Per-module or per-directory LogLevel (Apache 2.3.6+):

LogLevel info ssl:warn
LogLevel warn
<Directory /var/www/debug>
    LogLevel debug
</Directory>

Access Control

Two types:

TypeMechanismDescription
DAC (Authentication)authn_file, htpasswdBased on username/password
MAC (Authorization)authz_host, IP rulesBased on IP address or hostname

Apache 2.2 syntax (legacy):

Order Deny,Allow
Deny from all
Allow from 192.168.1.0/24

Order Allow,Deny
Allow from all
Deny from 10.0.0.0/8

Satisfy Any โ€” access if EITHER authentication OR IP passes.

Apache 2.4 syntax (current):

# Allow by IP:
Require ip 192.168.1.0/24

# Allow localhost:
Require local

# Allow authenticated users:
Require valid-user

# Allow specific user:
Require user alice

# Allow group:
Require group admins

# Combine (all must match):
<RequireAll>
    Require valid-user
    Require ip 192.168.1.0/24
</RequireAll>

# Combine (any must match):
<RequireAny>
    Require ip 10.0.0.0/8
    Require valid-user
</RequireAny>

# Deny specific, allow rest:
<RequireNone>
    Require ip 1.2.3.4
</RequireNone>

Password Authentication

htpasswd

htpasswd -cB /etc/apache2/.htpasswd alice    # create file + add user (bcrypt)
htpasswd -B  /etc/apache2/.htpasswd bob      # add user to existing file
htpasswd     /etc/apache2/.htpasswd alice    # update password (MD5 default)
htpasswd -D  /etc/apache2/.htpasswd alice    # delete user

Security: The password file MUST be stored outside the DocumentRoot.

htpasswd options:

OptionDescription
-cCreate new file (overwrites if exists)
-BUse bcrypt (recommended)
-mUse MD5 (default on most systems)
-sUse SHA-1
-DDelete user

Basic Auth configuration:

<Directory /var/www/html/private>
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /etc/apache2/.htpasswd
    AuthGroupFile /etc/apache2/.htgroups
    Require valid-user
</Directory>

.htaccess files

Per-directory overrides (no server restart needed):

# In httpd.conf or VirtualHost:
<Directory /var/www/html>
    AllowOverride All     # allow .htaccess to override everything
    # AllowOverride None  # disable .htaccess (more secure)
</Directory>

mod_perl

Embeds a Perl interpreter inside Apache โ€” scripts persist in memory between requests (fast).

LoadModule perl_module modules/mod_perl.so
AddModule  mod_perl.c

PerlModule Apache::Registry

Alias /perl /var/www/perl
<Directory /var/www/perl>
    SetHandler perl-script
    PerlHandler Apache::Registry
    Options +ExecCGI
    PerlSendHeader On
</Directory>

mod_php

Embeds PHP interpreter inside Apache.

Two modes:

ModeDescriptionPerformance
CGIPHP as external processSlow (new process per request)
DSOPHP as Apache moduleFast (in-process)

DSO configuration:

LoadModule php7_module /usr/lib/apache2/modules/libphp7.so

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

# Alternatively:
AddType application/x-httpd-php .php .phtml

PHP settings in Apache config:

php_value  upload_max_filesize 10M
php_flag   display_errors      Off

PHP settings in .htaccess require AllowOverride Options.


Virtual Hosting

Multiple sites on a single IP, distinguished by the Host: header.

# Debian: Listen is usually in ports.conf
Listen 80

<VirtualHost *:80>
    ServerName   www.example.com
    ServerAlias  example.com
    DocumentRoot /var/www/example
    ErrorLog     /var/log/apache2/example-error.log
    CustomLog    /var/log/apache2/example-access.log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName   www.other.com
    DocumentRoot /var/www/other
</VirtualHost>

Note: NameVirtualHost directive is obsolete in Apache 2.4 โ€” it is now the default behavior when using *:80.

First VirtualHost that matches the IP/port is the default if no Host: header matches.

IP-based virtual hosting

Each site uses a different IP address:

<VirtualHost 192.168.1.10:80>
    ServerName site1.example.com
    DocumentRoot /var/www/site1
</VirtualHost>

<VirtualHost 192.168.1.20:80>
    ServerName site2.example.com
    DocumentRoot /var/www/site2
</VirtualHost>

Listing configured virtual hosts:

apache2ctl -S
httpd -S

Redirects

mod_alias:

Redirect permanent /old    https://example.com/new     # 301
Redirect temp     /promo   https://example.com/sale    # 302 (default)
Redirect seeother /moved   https://example.com/here    # 303
Redirect gone     /removed                              # 410

RedirectMatch permanent ^/blog/(.*)$ /articles/$1      # regex redirect

mod_rewrite:

RewriteEngine On
RewriteCond   %{HTTP_HOST} ^old\.example\.com$
RewriteRule   ^(.*)$       https://new.example.com$1 [R=301,L]

# Force HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$    https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Monitoring and Performance

MRTG โ†’ RRDtool โ†’ Cricket

Evolution of network/server graphing tools:

ToolDescription
MRTGMulti Router Traffic Grapher โ€” original SNMP-based grapher
RRDtoolRound Robin Database โ€” storage + graphing engine, successor
CricketConfiguration-driven monitoring system built on RRDtool

mod_status

<Location /server-status>
    SetHandler server-status
    Require ip 127.0.0.1
</Location>
apache2ctl status          # requires mod_status + lynx

Key performance directive:

# Prefork: limits total simultaneous connections
MaxRequestWorkers 150

# Tune based on: RAM / (RAM per process)
# e.g., 2GB / 20MB per process = ~100 workers

Key Configuration Directives Reference

ServerRoot      /etc/httpd                  # base for relative paths
ServerName      www.example.com:80          # server's hostname
DocumentRoot    /var/www/html               # default document root
Listen          80                          # port to listen on
User            apache                      # run as this user
Group           apache                      # run as this group
DirectoryIndex  index.html index.php        # default files

# Performance:
KeepAlive        On                         # persistent connections
MaxKeepAliveRequests 100
KeepAliveTimeout 5

# Security:
ServerTokens     Prod                       # minimal version in headers
ServerSignature  Off                        # no version in error pages

Exam Cheat Sheet

Files and Paths

/etc/httpd/conf/httpd.conf         # RHEL main config
/etc/apache2/apache2.conf          # Debian main config
/etc/apache2/sites-available/      # virtual host configs
/etc/apache2/sites-enabled/        # active virtual hosts (symlinks)
/etc/apache2/mods-available/       # available modules
/etc/apache2/mods-enabled/         # active modules (symlinks)
/var/log/apache2/access.log        # access log (Debian)
/var/log/apache2/error.log         # error log (Debian)
/var/log/httpd/access_log          # access log (RHEL)

Commands

apache2ctl configtest             # test config (-t)
apache2ctl -M                     # list loaded modules (DSO + static)
apache2ctl -S                     # list virtual hosts
httpd -l                          # list static (compiled-in) modules only
a2enmod rewrite && apache2ctl graceful
htpasswd -cB /etc/apache2/.htpasswd user   # create file + bcrypt
htpasswd -D  /etc/apache2/.htpasswd user   # delete user
apxs -c -i -a mod_example.c               # compile + install + enable module

MPM Comparison

MPMModelBest for
Prefork1 process per requestmod_php (non-thread-safe)
WorkerThreads per processHigh-concurrency, thread-safe
EventAsync keep-aliveModern high-traffic sites

Access Control: 2.2 vs 2.4

Apache 2.2Apache 2.4 equivalent
Order Allow,Deny + Allow from allRequire all granted
Order Deny,Allow + Deny from allRequire all denied
Allow from 192.168.1.0/24Require ip 192.168.1.0/24
Satisfy Any<RequireAny>

Logging Format Tokens

TokenMeaning
%hClient IP
%uAuth user
%tTimestamp
%rRequest line
%>sStatus code
%bBytes sent
%{Referer}iReferer header
%{User-Agent}iUser-Agent header

Virtual Host Rules

RuleNote
First matching VirtualHostbecomes the default
NameVirtualHostobsolete in Apache 2.4
Listen directiverequired (usually in ports.conf on Debian)
ServerAliasadditional names for same VirtualHost