Apache Web Server

These notes address installing, running, and configuring an Apache web server for local access in the safety of a home network. They do not consider hardening and security practices for servers facing the cold, cruel world.

Install & run

Apache runs as the httpd service (package httpd):

-> yum install httpd httpd-tools httpd-manual
⋮
-> systemctl start httpd.service
-> systemctl enable httpd.service
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'

The base URL is http://localhost, which looks to the document root /var/www/html for content. Until this directory gets a proper home page, Apache displays the "Fedora Test Page" (cf. conf.d/welcome.conf).

The error and access logs reside under /var/log/httpd.

Optional package httpd-manual installs documentation to /usr/share/httpd/manual as HTML files. The manual can be browsed through URL http://localhost/manual (cf. conf.d/manual.conf).

To enable access to the web server from other machines on the home network, adjust the firewall on Apache's host to accept TCP connections on port 80 (HTTP service). There's an underlying assumption here that Apache's host sits behind a router restricting connections to trusted supplicants.

To see the list of modules:

-> httpd -M
Loaded Modules:
 core_module (static)
⋮

Apache loads modules as instructed by the configuration files in directory conf.modules.d. It looks to directory conf.d for modules' run-time configuration.

To add support for running PHP, install package php and restart Apache. Installation adds configuration file conf.modules.d/10-php.conf that tells Apache to load the PHP-handling module, and it also adds file conf.d/php.conf that tells Apache to use the module when it encounters a PHP page. The modules resides under /usr/lib64/httpd/modules.

To optionally test or inspect, create file /var/www/html/phpinfo.php like this:

-> echo '<?php phpinfo(); ?>' > /var/www/html/phpinfo.php

Then open URL http://localhost/phpinfo.php in a browser.

Under Security-Enhanced Linux (SELinux), Apache's httpd process runs under the httpd_t SELinux type:

-> ps -eZ | grep httpd_t
system_u:system_r:httpd_t:s0     5073 ?        00:00:00 /usr/sbin/httpd

system_u:system_r:httpd_t:s0     5999 ?        00:00:00 /usr/sbin/httpd

Security-Enhanced Linux affects Apache; see httpd Selinux Policy documentation.

To have a running Apache server reload its (modified) configuration files:

-> apachectl graceful

The examples below implicitly assume this step.

Configure

Configuration files reside within directory /etc/httpd. The base configuration file is /etc/httpd/conf/httpd.conf; it additionally loads configuration files from directory conf.d.

After you edit a configuration file, let apachectl make sure you did not mess up:

-> apachectl configtest
AH00526: Syntax error on line 119 of /etc/httpd/conf/httpd.conf:
DocumentRoot must be a directory
-> emacs /etc/httpd/conf/httpd.conf
⋮
->  apachectl configtest
Syntax OK

DirectoryIndex determines what file Apache seeks when a client requests a directory (e.g., http://localhost/). By default, Apache looks for file index.html in that directory (e.g., http://localhost/index.html):

-> grep DirectoryIndex /etc/httpd/conf/httpd.conf
    DirectoryIndex index.html

You can adjust DirectoryIndex to suit your tastes. For example, this website uses home.html as a directory's response:

<IfModule dir_module>
    DirectoryIndex home.html
</IfModule>

This next website prefers home.html but lets index.html do the job in the absence of the former:

DirectoryIndex home.html index.html

Order counts here: Apache will seek index.html only if it does not find home.html first.

Apache's root document directory is set by directive DocumentRoot in httpd.conf:

-> grep DocumentRoot /etc/httpd/conf/httpd.conf | grep --invert-match '#'
DocumentRoot "/var/www/html"

You can relocate the document root by editing the new path into httpd.conf. Remember to make the new directory and its contents world-executable (e.g., directories) and world-readable (e.g., directories and files) as appropriate. And under SELinux, you may also need to adjust the security context of the new location (type httpd_sys_content_t).

As an example, here's how to put the document root under /home/www/html (as a safeguard against overwriting /var when installing a new version of Fedora). First, in httpd.conf, replace string /var/www/html with string /home/www/html. Then:

-> cd /home/www
-> mkdir html
-> chcon --type httpd_sys_content_t html
-> ls --context
unconfined_u:object_r:httpd_sys_content_t:s0 html/
-> cd html
-> echo 'Hello World!' > hello.txt
-> ls --context hello.txt 
unconfined_u:object_r:httpd_sys_content_t:s0 hello.txt

After you restart Apache (as root), you can use curl or lynx or similar to make a quick and easy test:

-> curl http://localhost/hello.txt
Hello World!
-> lynx -dump http://localhost/hello.txt
Hello World!

Apache's scripts directory is set by directive ScriptAlias in httpd.conf:

 -> grep ScriptAlias /etc/httpd/conf/httpd.conf | grep --invert-match '#'
    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

You can allow per-user web directories wherein URL http://localhost/~username maps to /home/username/public_html for each user on the system. First, adjust SELinux and file permissions:

-> setsebool -P httpd_enable_homedirs 1
-> chmod 711 /home/*

Next, modify /etc/httpd/conf.d/userdir.conf to enable user directories and to set the source directory:

<IfModule mod_userdir.c>
    UserDir enabled
    UserDir public_html
</IfModule>

Each user's public_html directory must be listable to other, and its (public) contents must be readable to other:

-> cd ~
-> chmod o+x public_html
-> ls -dog public_html
drwxr-xr-x. 2 4096 Aug  3 15:01 public_html/
-> chmod -R o+r public_html

This directory can be added to /etc/skel with the required permissions so that useradd creates it for new accounts.

To have Apache look for file home.html when an URL ends in a directory, add this name to DirectoryIndex in /etc/httpd/conf/httpd.conf. For example:

<IfModule dir_module>
    DirectoryIndex home.html index.html 
</IfModule>

To allow access to directory /home/ray/notebook via URL /notebook, for example, create configuration file /etc/httpd/conf.d/notebook.conf with the following sort of contents:

Alias /notebook /home/ray/notebook
<Directory /home/ray/notebook>
     <RequireAny>
       Require ip 127.0.0.1
       Require ip ::1
       Require ip 192.168.1
     </RequireAny>
</Directory>

The filename is not significant to Apache. The location and extension, however, ensure that the IncludeOptional directive ending httpd.conf loads this file.