Rob's web

Apache

Apache

The apache webserver is often part of a LAMP stack.

L = Linux
A = Apache
M = Mysql/MariaDB
P = PHP

Instead of Mysql you can use MariaDB. This had we already installed.

Installation

First we install de basic webserver.

# dnf install httpd

Configuration

# cd /etc/httpd/
# ll
drwxr-xr-x. 2 root root  37 18 nov 14:47 conf
drwxr-xr-x. 2 root root  82 18 nov 14:47 conf.d
drwxr-xr-x. 2 root root 146 18 nov 14:47 conf.modules.d
lrwxrwxrwx. 1 root root  19 18 nov 14:47 logs -> ../../var/log/httpd
lrwxrwxrwx. 1 root root  29 18 nov 14:47 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx. 1 root root  10 18 nov 14:47 run -> /run/httpd
# ll conf
-rw-r--r--. 1 root root 11753 30 sep 15:20 httpd.conf
-rw-r--r--. 1 root root 13064  1 okt 18:52 magic

The configuration is put in the file httpd.conf.

httpd.conf

This is the main configuration file for the server.

We need to change this file so we can use virtual hosts.

# cd /etc/httpd/conf
# cp httpd.conf httpd.conf.org
# vi httpd.conf

# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
ServerRoot "/etc/httpd"

# Listen: Allows you to bind Apache to specific IP addresses and/or
Listen 80

# Dynamic Shared Object (DSO) Support
Include conf.modules.d/*.conf

User apache
Group apache

Remove the main server. We wil create a new one later.

We then add and before <IfModule mime_module>:

# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
<Directory />
    AllowOverride none
    Require all denied
</Directory>

# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<Files ".ht*">
    Require all denied
</Files>

# Global errors
# ErrorLog: The location of the error log file.
ErrorLog "/var/log/httpd/error_log"

LogLevel info

# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
#
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common

Add before # Load config files in the "/etc/httpd/conf.d" directory, if any.

# Hide server version on error pages
ServerSignature Off

# Only return Apache in server header
ServerTokens Prod

# Set http protocols
Protocols h2 http/1.1

# Header settings
Header always append X-Frame-Options SAMEORIGIN
Header always set X-Content-Type-Options nosniff
Header always set Referrer-Policy "same-origin"
Header always set X-Permitted-Cross-Domain-Policies: none

The file must end with:

# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf

# Load virtual hosts
Include conf/default.conf
IncludeOptional conf/vhosts.d/*.conf

Testing configfiles

After every step of the installation test te configuration. Also when you made changes.

# httpd -t

If there are errors in the configfiles correct them first. Remember there are no virtualhosts at this point.

Configure name-based virtual hosts

We need to create a defaulthost since we removed it out of httpd.conf

Defaulthost

The first host that is started is the default server. This is the host that replies to all calls that are not handeld by vhosts.

There is no need for encryption if you do not use TLS. If you have TLS vhosts you need the vhosts.con template.

# cd /etc/httpd/conf/
# vi default.conf

<VirtualHost *:80>
ServerName server1.example.com

CustomLog /var/log/httpd/server1-access_log combined
ErrorLog /var/log/httpd/server1-error_log
DirectoryIndex index.html index.php

DocumentRoot /srv/www/default/httpsdocs
<Directory "/srv/www/default/httpsdocs">
	Options +Indexes
	AllowOverride All
	Require all granted
</Directory>
</VirtualHost>

Setting up directories for the default server

# cd /srv
# mkdir www
# chcon -t httpd_sys_content_t: www/
# cd www
# mkdir -p default/httpdocs
# cd default
# chown -R root:users httpdocs
# httpd -t

Check if the server is added to the zone file.

# nslookup server1.example.com

To access the default server enter the URL in the browser:

http://server1.example.com

Homepage default server

For the server to send useable information you have to make a homepage.

# cd /srv/www/default/httpdocs
# vi index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=iso-8859-1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="author" content="Rob Kalmeijer" />
<title>Wrong URL</title>
<link rel="stylesheet" href="/include/style.css" type="text/css" media="screen" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
</head>

<body>
<div id="inhoud">
<h1>Enter a valid URL</h1>

<p>You did enter a invalid URL, did not use a subdomain like www or used a IP address.</p>

<p>If you have enterd a valid URL than the server is in maintenance and please try later.</p>

</div>
</body>
</html>

Starting

We have now a server available so we can start apache.

# httpd -t
# systemctl start httpd
# systemctl enable httpd
# systemctl status httpd

Firewall

We open all http ports:

# firewall-cmd --zone=public --permanent --add-port=80/tcp
# firewall-cmd --zone=public --permanent --add-port=443/tcp
# firewall-cmd --reload

SELinux

The default context is httpd_sys_content_t, which tells SELinux that the Apache process can only read files created in this directory.

If you need that a CMS can write to its files use httpd_sys_rw_content_t.

# cd /srv/www/vhosts/www.example.com/
# chcon -R -t httpd_sys_rw_content_t httpsdocs

SELinux booleans

For an overview and the settings of SELinux boleaans voor httpd enter:

# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
.....

Set:

# setsebool -P httpd_can_network_connect 1
# setsebool -P httpd_can_sendmail 1
# setsebool -P httpd_enable_homedirs 0

Testing the basic server

To list the active virtual hosts enter:

# httpd -S

This command will display all of the host's network addresses, so you will get back a few IP addresses separated by spaces. You can try each in your web browser to see if they work.

# hostname -I

We can now test if the server is working. Enter server1.example.com in the browser URL-address.

This is the only host that is accessable with HTTP. We will add HTTPS for the defaulthost later.

HTTPS

Modern websites need to be secured by use of SSL-certificates.

When you want to run several subdomains and other services you need a wildcard certificate.

We begin now with adding TLS support for the webserver.

Setting up a secure connection

If you want a wildcard certificate you have to buy one.

You can use the free service from Let's encrypt For a single subdomain a good option. The website you want to secure with lets-encrypt must be running in HTTP mode.

Lets encrypt can generate wildcard certificates. So now is the time to do so.

Creating HTTPS for the default server

You need a SSL (wildcard)certificate for this server. It must be installed.

If you want to use lets-encrypt for the default-server that is also an option.

# cd /etc/httpd/conf
# mv default.conf default.conf.http
# cp vhosts.d/vhosts.con default.conf
  1. Open default.conf and remove the first and second VirtualHost sections.
  2. Change example.com to your domain. That also mean the SSL certificates.
  3. The hostname should be like server1.<your-domain>.
  4. If you don't want logs remove them. I would keep it.
  5. Remove the cgi-bin section.
# httpd -t
# systemctl restart httpd

Checking TLS access

Before we can test this we need a virtualhost that listen on port 443.

Testing TLSv1.2

# openssl s_client -tls1_2 -connect server1.example.com:443
CONNECTED(00000003)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN
.....
---
read R BLOCK
closed
#

Testing TLSv1.3

# openssl s_client -tls1_3 -connect server1.example.com:443
CONNECTED(00000003)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN
.....
---
read R BLOCK
closed
#

Testing with lynx text browser

Lynx is a customizable text-based web browser for use on cursor-addressable character cell terminals. As of 2024, it is the oldest web browser still being maintained, having started in 1992.

# dnf install lynx
# lynx <hostname>
.....
q
#

PHP

When the apache server works with the default server we can install php scripting.

Content Management Systems require PHP and MySQL/Mariadb.

See here.

Virtual hosts

After the default server setup we can begin with the virtual hosts. These are the real websites.

The defaulthost is not to be used for websites. It catch all wrong traffic. This is also for https, so it needs an 443 section.

We start with making templates.

See vhosts.

Setting up a Tor-service

You can setup a tor (.onion) link to your website. You don't need a https link to it because there are multiple secure layers.

See tor.

Links