Home

 

Server::Apache

Index 
1.  Webserver Installeren
    Webserver componenten
    Apache installeren
       Verhuis Webroot naar bindmount /store/live
       Permissies Website Root
    MariaDB Database Server installeren
       MariaDB beveiligen
       Maak gebruikers aan voor import Piwigo en Wordpress
       Verhuis MariaDB data naar bindmount /store/live
    PHP and PHP Extensions installeren
       Edit PHP.ini
       Test met phpinfo()
       PHP extension Imagick
       phpMyAdmin installeren
       Wijzig poort phpMyAdmin van 80/443 naar 81
2.  Apache Configureren
    Apache2.conf
          Volgorde van directives
    Modules
    Sites - VirtualHosts
          HTTP 000-mysite80.conf
          HTTPS 001-mysite443.conf
          HTTP 002-mysite81.conf
    Global Configuration Snippets
          Mydirectives.conf
          Myerror-pages.conf
    Gebruik van .htaccess vermijden
    Piwigo.Conf
         Toegangscontrole /var/www/html/archief met Cookie
         Piwigo Cookie zetten
         Login en toegangscontrole../archief/ via Piwigo
         SameSite extra cookie security
    Wordpress.Conf
         Dynamische integratie van .htaccess
3.  HTTPS en Certificatie
    SSL Encryptie flowchart
    Webserver SSL activeren
    HTTPS Virtual Host
          Gebruiker aanvaart risico Selfsigned Certificaat
    Let's Encrypt Free SSL Certificates
          Certbot voor Apache2 installeren
          Let's Encrypt Certificaat aanvragen
          Certificaat geïntegreerd in Virtual Host 443
4.  Error Messaging
    Layout ErrorDocuments
    HTTP_UNAUTHORIZED.html.var
    Personalisatie Layout
    Tekst Correcties
5.  Awstats en Access-logs
    Access-Logbestanden
       Geef Awstats user www-data toegang tot de accesslogs
       Logrotate en ACL (Access Control List)
    Installatie
    Apache2 Configuratie
    Awstats Sites Configuratie
    Data updaten en opslaan
    Statistieken bekijken in de browser
6.  Crawlers en Robots.txt

Naar index

Webserver Installeren

Webserver componenten

De distributie van Ubuntu Server is op 05/12/2024: Ubuntu Server 24.04.1 LTS (Noble Numbat)
(# less /etc/os-release)

De snelste methode om LAMP op te starten is het installeren met 'tasksel'. Tasksel is een Debian/Ubuntu tool dat meervoudige gerelateerde packages op het systeem installeert als een gecoördineerde 'taak'.
een nadeel van deze benadering is dat de applicatiebestanden niet op een standaard manier in het systeem geplaatst worden, wat het lastig maakt de applicatie terug te vinden.
Tevens is de default database bij Ubuntu Server MySQL terwijl al mijn gegevens op de huidige server opgeslagen zijn op MariaDb.
Daarom is er voor gekozen de LAMP server te installeren als losse componenten zoals omschreven in 'How to Install LAMP Server on Ubuntu'

We installeren de laatst beschikbare versies in de Ubuntu repository:

  1. Apache 2.4.58-1ubuntu8.5
  2. MariaDB 10.11.8
  3. PHP 8.3.6

Naar index

Apache installeren

root@testserver:~# apt update

root@testserver:~# apt install apache2
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
apache2 is already the newest version (2.4.58-1ubuntu8.5).     

Stel Apache service in voor het automatisch starten als daemon service

root@testserver:~# systemctl enable –now apache2
root@testserver:~# systemctl status apache2
 apache2.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Wed 2024-12-04 14:57:15 CET; 1 day 2h ago
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 126388 (apache2)   

Sta Apache verkeer toe door de firewall:
Zie ook Server::Firewall > Maak rules Homeserver

Open poort 80 voor HTTP:

root@testserver:~# ufw allow http
Rule added
Rule added (v6)

Open poort 443 voor HTTPS:

root@testserver:~# ufw allow https
Rule added
Rule added (v6)

 

root@testserver:~# ufw status
Status: activest

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
...

...
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)    

Browse naar het server IP-adres, om te verifiëren dat de Webserver vanaf een browser bereikbaar is.
De Apache welkomspagina wordt getoond.

Naar index

Verhuis Webroot naar bindmount /store/live

Zoals beschreven in Server::Gebruikersdata Opslag > Standaard Partitionering slaan we op de Server de data op, op een fysiek van het OS gescheiden schijf /store/live
Zie ook de Backup Flowchart

Voor het verhuizen van website data naar de centrale opslag hebben we te doen met één locatie waar alle Apache2 data opgeslagen worden: var/www/html.

Maak de bindmount directory

# mkdir /store/live/webroot

Verzamel informatie van de bron directory

[root@testserver ~]# ls -la /var/www/html |head -n2
total 52
drwxr-xr-x  5 www-data lanshare 4096 Dec  4 11:30 .

Voer de commando's uit om de permissies van bron naar doel te synchroniseren

# chown --reference /var/www/html /store/live/webroot
# chmod --reference /var/www/html /store/live/webroot

Naar index

Valideer resultaat:

[root@testserver ~]# ls -al /store/live/webroot |head -n2
total 0
drwxrwx--- 2 www-data lanshare   6 Oct 19 16:50 .

Stop nu elke service die momenteel de bron directory mogelijk gebruikt.

# systemctl stop smb
# systemctl stop apache2
# systemctl stop backuppc
# systemctl stop mariadb 

Verhuis de data naar de nieuwe locatie:

[root@testserver ~]# rsync -av --delete /var/www/html/* /store/live/webroot/.

Verifiëer dat de informatie op de nieuwe locatie is:

[root@testserver ~]# ls -l /store/live/webroot
total 44
-rw-rw-r--  1 www-data lanshare  367 Jan 27  2014 clearphpcache.php
drwxr-xr-x 15 www-data lanshare 4096 Dec  4 10:48 exploringlinux
-rw-rw-r--  1 www-data lanshare 7405 Dec  4 11:29 index.html
-rw-r--r--  1 www-data lanshare 7050 Apr  6  2022 index-normaal.html
-rw-r--r--  1 www-data lanshare   69 Oct 31 17:02 klamzweet
drwxr-xr-x  4 www-data lanshare 4096 Dec  4 11:31 mainmenu
drwxr-xr-x  9 www-data lanshare 4096 Dec  4 11:00 nbp
-rw-r--r--  1 www-data lanshare   24 Dec 11  2015 phpinfo.php
-rw-rw-r--  1 www-data lanshare   82 Jun 22  2017 robots.txt

Naar index

Verwijder de data uit de oude locatie:

[root@testserver ~]# rm -rf /var/www/html/*
[root@testserver ~]# ls -l /var/www/html
total 0

Maak de bindmount aan in /etc/fstab door een nieuwe lijn toe te voegen:

/store/live/webroot  /var/www/html none bind,rw 0 0

Mount de toegevoegde device en verifiëer de bindmount :

[root@testserver ~]# mount -a

[root@testserver ~]# ls -l /var/www/html
total 44
-rw-rw-r--  1 www-data lanshare  367 Jan 27  2014 clearphpcache.php
drwxr-xr-x 15 www-data lanshare 4096 Dec  4 10:48 exploringlinux
-rw-rw-r--  1 www-data lanshare 7405 Dec  4 11:29 index.html
-rw-r--r--  1 www-data lanshare 7050 Apr  6  2022 index-normaal.html
-rw-r--r--  1 www-data lanshare   69 Oct 31 17:02 klamzweet
drwxr-xr-x  4 www-data lanshare 4096 Dec  4 11:31 mainmenu
drwxr-xr-x  9 www-data lanshare 4096 Dec  4 11:00 nbp
-rw-r--r--  1 www-data lanshare   24 Dec 11  2015 phpinfo.php
-rw-rw-r--  1 www-data lanshare   82 Jun 22  2017 robots.txt

Start de eventuele services die gestopt waren:

# systemctl start smb
# systemctl start httpd
# systemctl start backuppc
# systemctl start mariadb

Naar index

Permissies Website Root

In de Virtual Host bestanden '/etc/apache2/sites-enabled/000-mysite80.conf en 001-mysite443.conf' wordt de root van de website vastgelegd op '/var/www/html'.
Door middel van Samba wordt de website voorzien van bestanden met als eigenaar 'www-data' en groep 'lanshare'.
De permissies voor directories zijn 755 en bestanden 644. Hiermee heeft Apache2 in groep 'www-data' voldoende rechten.
Zie ook sectie Samba: Samba Acces naar Webserver

Reset Permissies en Owners van Websites
Bij updates van websites van bijv. Wordpress en Piwigo worden soms onbedoeld permissies en/of ownerships gewijzigd.
Van alle submappen van /var/www/html moeten de permissies (terug)gezet worden naar 755 voor mappen en 644 voor bestanden.
Hiervoor heb ik het script reset-perm-users-websites gemaakt:

##########################################################################################
# Script voor het recursief re-setten van permissies en owners van map /var/www/html,    #
# (alle websites). Alles www-data:lanshare, mappen 755 en files 644                      #
# Ben Makkink 20-december-2024                                                           #
##########################################################################################
#!/bin/sh
chown -R www-data:lanshare /var/www/;
chmod -R 755 /var/www/;
find /var/www/html -type f -name '*' -exec chmod 644 '{}' \;

Naar index

MariaDB Database Server installeren

Het volgende component van de LAMP stack is de MySQL database server. Wij kiezen in plaats daarvan MariaDB vanwege de hoge prestaties en overvloed aan opties en functionaliteit
Zie ook How-to-install-lamp-server

Geef voor de installatie van MariaDB het volgende commando:

root@tesserver:~# apt install mariadb-server
The following NEW packages will be installed:
galera-4 libcgi-fast-perl libcgi-pm-perl libconfig-inifiles-perl
libdbd-mysql-perl libdbi-perl libfcgi-bin libfcgi-perl
libfcgi0t64 libhtml-template-perl libmariadb3 libsnappy1v5
mariadb-client mariadb-client-core mariadb-common
mariadb-plugin-provider-bzip2 mariadb-plugin-provider-lz4
mariadb-plugin-provider-lzma mariadb-plugin-provider-lzo
mariadb-plugin-provider-snappy
mariadb-server mariadb-server-core pv socat

Net zoals de Apache service start MariaDB service automatisch zodra MariaDB geïnstalleerd is.
Geef om dit te confirmeren het volgende commando:

root@testserver:~# systemctl status mariadb
 mariadb.service - MariaDB 10.11.8 database server
     Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: enabled)
     Active: active (running) since Tue 2024-11-26 12:51:00 CET; 5min ago

root@testserver:~# mariadb --version
mariadb  Ver 15.1 Distrib 10.11.8-MariaDB, for debian-linux-gnu (x86_64) using  EditLine wrapper

Naar index

MariaDB beveiligen

De default MariaDB settings zijn zwak ten aanzien van database-inbraken of inbreuken, de database is erg gevoelig voor aanvallen van buitenaf.
Daarom is nog een extra stap nodig en de database beveiligen door het mysql-secure-installatiescript uit te voeren.

root@testserver:~# mysql_secure_installation

Het script leidt je door een paar prompts.

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): ENTER
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] N
 ... skipping.

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] Y
New password: Zie LastPass homeserver MariaDB
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Naar index

Maak gebruikers aan voor import Piwigo en Wordpress

Alleen in het geval dat deze databases geexporteerd worden van een andere server.
Zie voor de creatie van nieuwe databases Piwigo::Installeren en Wordpress::Installeren

Voordat we de eigen databases kunnen importeren moeten we de gebruikers aanmaken en authoriseren.
Dit kan alleen door tijdelijk de databases Piwigo en Wordpress aan te maken.
Nadat de nieuwe gebruikers geauthoriseerd zijn moeten we de lege databases weer verwijderen.

# mariadb-admin -uroot -p'root-mysqlpassword' CREATE piwigo;
# mariadb piwigo -uroot -p'root-mysqlpassword' -e
   "GRANT ALL PRIVILEGES ON piwigo.*
   TO piwigo@localhost IDENTIFIED BY 'piwigo-mysqlpassword'";
# mariadb-admin -uroot -p'root-mysqlpassword' drop piwigo;

# mariadb-admin -uroot -p'root-mysqlpassword' CREATE wordpress;
# mariadb wordpress -uroot -p'root-mysqlpassword' -e
   "GRANT ALL PRIVILEGES ON wordpress.*
   TO wordpress@localhost IDENTIFIED BY 'wordpress-mysqlpassword'";
# mariadb-admin -uroot -p'root-mysqlpassword' drop wordpress;

Check:

root@testserver:~# mariadb -uroot -p'kn1kk@M!48';
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 246
Server version: 10.11.8-MariaDB-0ubuntu0.24.04.1 Ubuntu 24.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use mysql
Reading table information for completion of table and column names

MariaDB [mysql]> select user, password from user where user = 'piwigo' or user = 'wordpress';
+-----------+-------------------------------------------+
| User      | Password                                  |
+-----------+-------------------------------------------+
| wordpress | *2CA1303E5546D67438BECF09F2C85035FC386BA1 |
| piwigo    | *2CA1303E5546D67438BECF09F2C85035FC386BA1 |
+-----------+-------------------------------------------+
2 rows in set (0.002 sec)

Importeer eigen Database Piwigo en Wordpress bijvoorbeeld opgeslagen in /home/dbase_dump/

# mysql -uroot -p'root-mysqlpassword' < /home/dbase_dump/piwigo-dump.sql
# mysql -uroot -p'root-mysqlpassword' < /home/dbase_dump/wordpress-dump.sql

Naar index

Verhuis MariaDB data naar bindmount /store/live

Zoals beschreven in Server::Gebruikersdata Opslag > Standaard Partitionering slaan we op de Homeserver de data op, op een fysiek van het OS gescheiden schijf /store/live
Zie ook de Backup Flowchart

Voor het verhuizen van MySQL data naar de centrale opslag hebben we te doen met één locatie waar alle MariaDB data opgeslagen worden: var/lib/mysql.

Maak de bindmount directory

root@testserver:~# mkdir /store/live/mysql

Verzamel informatie van de bron directory

root@testserver:~# ls -la /var/lib/mysql/|head -n2
total 123356
drwxr-xr-x  6 mysql mysql      4096 Dec  6 15:16 .

Voer de commando's uit om de permissies van bron naar doel te synchroniseren

root@testserver:~# chown --reference /var/lib/mysql /store/live/mysql
root@testserver:~# chmod --reference /var/lib/mysql /store/live/mysql

Naar index

Valideer resultaat:

root@testserver:~# ls -la /store/live/mysql | head -n2
total 8
drwxr-xr-x 2 mysql mysql 4096 Dec  6 15:44 .

Stop nu elke potentieel aanwezige service die momenteel de brondirectorie mogelijk gebruikt.
Voor /home zou dat bijvoorbeeld Piwigo of Wordpress kunnen zijn waarvan de foto's in een /home subdirectory opgeslagen zijn, Samba die de verschillende /home shares beheert en/of BackupPC.
Voor de zekerheid:

root@testserver:~# systemctl stop smb
root@testserver:~# systemctl stop apache2
root@testserver:~# systemctl stop backuppc
root@testserver:~# systemctl stop mariadb 

Verhuis de data naar de nieuwe locatie:

root@testserver:~# rsync -av --delete /var/lib/mysql/* /store/live/mysql/.

Verifiëer dat de informatie op de nieuwe locatie is:

root@homeserver:~# ls -l /store/live/mysql
total 111036
-rw-rw---- 1 mysql mysql    417792 Dec  6 16:06 aria_log.00000001
-rw-rw---- 1 mysql mysql        52 Dec  6 16:06 aria_log_control
-rw-r--r-- 1 root  root          0 Nov 26 12:50 debian-10.11.flag
-rw-rw---- 1 mysql mysql      1317 Dec  6 16:06 ib_buffer_pool
-rw-rw---- 1 mysql mysql  12582912 Dec  6 16:06 ibdata1
-rw-rw---- 1 mysql mysql 100663296 Dec  6 16:06 ib_logfile0
-rw-rw---- 1 mysql mysql         0 Nov 26 12:51 multi-master.info
drwx------ 2 mysql mysql      4096 Nov 26 12:50 mysql
-rw-r--r-- 1 root  root         15 Nov 26 12:50 mysql_upgrade_info
drwx------ 2 mysql mysql      4096 Nov 26 12:50 performance_schema
drwx------ 2 mysql mysql      4096 Nov 26 15:33 phpmyadmin
drwx------ 2 mysql mysql     12288 Nov 26 12:50 sys

Naar index

Verwijder de data uit de oude locatie:

root@testserver:~# rm -rf /var/lib/mysql/*
root@testserver:~# ls -l /var/lib/mysql
total 0

Maak de bindmount aan in /etc/fstab door een nieuwe lijn toe te voegen:

/store/live/mysql  /var/lib/mysql none bind,rw 0 0

Mount de toegevoegde device en verifiëer de bindmount :

root@testserver:~## mount -a
root@testserver:~# ls -l /var/lib/mysql -rw-rw---- 1 mysql mysql 417792 Feb 5 11:06 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Feb 5 11:06 aria_log_control -rw-r--r-- 1 root root 0 Feb 5 10:37 debian-10.11.flag -rw-rw---- 1 mysql mysql 910 Feb 5 11:06 ib_buffer_pool -rw-rw---- 1 mysql mysql 12582912 Feb 5 10:37 ibdata1 -rw-rw---- 1 mysql mysql 100663296 Feb 5 10:37 ib_logfile0 -rw-rw---- 1 mysql mysql 0 Feb 5 10:37 multi-master.info drwx------ 2 mysql mysql 4096 Feb 5 10:37 mysql -rw-r--r-- 1 root root 15 Feb 5 10:37 mysql_upgrade_info drwx------ 2 mysql mysql 4096 Feb 5 10:37 performance_schema drwx------ 2 mysql mysql 12288 Feb 5 10:37 sys

Start de eventuele services die gestopt waren:

# systemctl start smb
# systemctl start apache2
# systemctl start backuppc
# systemctl start mariadb

Naar index

PHP and PHP Extensions installeren

Zie ook How-to-install-lamp-server

Nu Apache en MariaDB geïnstalleerd is, volgt het installeren van PHP en de vereiste extensies.
PHP is beschikbaar in de standaard Ubuntu repositories.
Php-mysql is ook nodig, een PHP-module waarmee PHP kan communiceren met MySQL-databases. Om Apache PHP-bestanden te laten verwerken, heb je ook libapache2-mod-php nodig.
De afhankelijkheden voor de belangrijkste PHP-pakketten worden automatisch geïnstalleerd.

Voer het volgende commando uit:

root@testserver:~# apt install php libapache2-mod-php php-mysql
  The following additional packages will be installed:
  libapache2-mod-php8.3 php-common php8.3 php8.3-cli php8.3-common
  php8.3-mysql php8.3-opcache php8.3-readline

root@testserver:~# php -v
PHP 8.3.6 (cli) (built: Sep 30 2024 15:17:17) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies

Naar index

Edit PHP.ini

Onderstaande gewijzigde instellingen zijn nodig voor het werken met grotere bestanden zoals het uploaden van foto's in wordpress.
Open het PHP settings bestand '/etc/php/8.3/apache2/php.ini' in een teksteditor en zet de volgende argumenten (in de volgorde zoals ze voorkomen):

root@testserver:~# vi /etc/php/8.3/apache2/php.ini 

memory_limit = 256M
post_max_size = 100M
upload_max_filesize = 100M

Naar index

Test met phpinfo()

Op een server waar PHP actief is kan op eenvoudige wijze achterhaald worden welke versies en modules er op de server actief zijn en wat hun argumenten, variabelen of instellingen zijn.
Dit is mogelijk door de phpinfo functie te gebruiken door de volgende code in een .php bestand (bijvoorbeeld phpinfo.php) te plaatsen en deze via de browser aan te roepen:

<?php
    phpinfo(); 
?>

Naar index

PHP extension Imagick

Imagick is de PHP ImageMagick extension voor het creëren en bewerken van foto's gebruik makend van de ImageMagick Application Programming Interface (API).
Piwigo en Wordpress maken middels Imagick gebruik van de ImageMagick App en elke PHP versie heeft zijn eigen Imagick extension.

  1. Installeer PHP-Imagick.
    root@testserver:~# apt install php-imagick  

  2. Verifiëer.
    root@testeserver:~# apt list --installed *magick*
    Listing... Done
    imagemagick-6-common/noble,now 8:6.9.12.98+dfsg1-5.2build2 all [installed,automatic]
    libmagickcore-6.q16-7t64/noble,now 8:6.9.12.98+dfsg1-5.2build2 amd64 [installed,automatic]
    libmagickwand-6.q16-7t64/noble,now 8:6.9.12.98+dfsg1-5.2build2 amd64 [installed,automatic]
    php-imagick/noble,now 3.7.0-4ubuntu3 amd64 [installed]
    php8.3-imagick/noble,now 3.7.0-4ubuntu3 amd64 [installed,automatic]


  3. Reboot server (niet alleen apache) en verify met phpinfo()

Naar index

phpMyAdmin installeren

phpMyAdmin is een web interface, bedoelt om het beheren van MySQL-/MariaDB-databases over het internet makkelijker te maken.
Veel voorkomende SQL-handelingen, zoals het beheer van databases, tabellen, kolommen, gebruikers, rechten, etc. kunnen vanuit de phpMyAdmin web interface uitgevoerd worden.

root@testserver:~# apt -y update
root@testserver:~# apt -y upgrade
root@testserver:~# apt install phpmyadmin

Je krijgt tijdens het installatieproces een aantal vensters te zien voor de configuratie van phpMyAdmin.
De eerste is welke webserver je gebruikt:

Er zal je nu gevraagd worden om een database aan te maken die gebruikt zal worden door phpMyAdmin.
Zonder deze database zal phpMyAdmin niet werken, kies hier dan ook voor 'Yes'.

Naar index

phpMyAdmin heeft voor de database ook een wachtwoord nodig.
Stel hier een uniek wachtwoord in (zie LastPass 019a-homeserver MariaDB & phpMyAdmin) en klik op 'Enter' om verder te gaan en het wachtwoord nogmaals te bevestigen.

De installatie zelf is nu klaar, maar Apache kan niet direct phpMyAdmin gebruiken.
Hiervoor moet je eerst nog de phpMyAdmin-configuratie /etc/phpmyadmin/apache.conf met een symbolic link toevoegen aan de Apache-configuratie:

root@testserver:~# ln -s /etc/phpmyadmin/apache.conf 
                      /etc/apache2/conf-available/phpmyadmin.conf

Enable phpMyAdmin.conf in Apache2:

root@testserver:~# a2enconf phpmyadmin.conf
root@testserver:~# systemctl reload apache2

Open phpMyAdmin in browser http://homeserver/phpmyadmin.

Note:
Op deze manier heeft elke bezoeker van het web (poort 80 of 443) ook toegang tot phpMyAdmin!
Alleen nog een wachtwoord die het tegenhoud.

Naar index

Wijzig poort phpMyAdmin van 80/443 naar 81

Zie: Change-phpmyadmin-port-from-80/443-to-another-number

Security:
Door voor phpMyAdmin een Virtual Host aan te maken die niet luistert op poort 80 en/of 443 is phpMyAdmin niet meer bereikbaar via het web.

Voer de volgende stappen uit:

  1. Als er al een symbolic link naar /etc/phpmyadmin/apache.conf gemaakt is in /etc/apache2/conf-available en/of /etc/apache2/conf-enabled, verwijder deze dan.
    # a2disconf phpmyadmin
    # rm /etc/apache2/conf-available/phpmyadmin.conf

  2. Maak in /etc/apache2/sites-available een nieuwe Virtual Host in een nieuw bestand 002-mysite81.conf met inhoud:

    Listen 81
    <VirtualHost *:81>
       Include /etc/phpmyadmin/apache.conf

      ErrorLog ${APACHE_LOG_DIR}/phpmyadmin.error.log
      CustomLog ${APACHE_LOG_DIR}/phpmyadmin.access.log combined
    </VirtualHost>


  3. Enable de site 002-mysite81.conf:

    # a2ensite 002-mysite81
    # systemctl restart apache2.service


  4. Voeg firewall rule toe:
    # ufw allow from 192.168.178.0/26 to any port 81
    dwz: open poort 81 inkomend van trusted ip's. Dus alleen toegang voor vertrouwde IP’s in het thuisnetwerk.

  5. phpMyAdmin is nu alleen op het thuisnetwerk beschikbaar met url: http://homeserver:81/phpmyadmin

Naar index

Apache Configureren

Na de installatie van Apache2 moet deze nog nader geconfigureerd worden.
Apache2 wordt geleverd met een 'Virtual-Host-Friendly standaard configuratie.

De Apache2 webserver configuratie in Debian is nogal afwijkend van de door "upstream's" gesuggereerde manier van configureren.
Debian's standaard configuratie probeert het toevoegen en verwijderen van Modules, Virtual Hosts, en extra configuratie directives zo eenvoudig en flexibel mogelijk te houden.

De configuratie is opgedeeld in diverse bestanden in een configuratie hiëarchiein de map /etc/apache2/

# /etc/apache2/
# |-- apache2.conf
# |    `-- ports.conf
# |
# |-- mods-enabled
# |    |-- *.load
# |    `-- *.conf
# |
# |-- conf-enabled
# |    `-- *.conf
# |
# |-- sites-enabled
#      `-- *.conf

Apache2.conf is het hoofd-configuratiebestand. Bij het opstarten van de webserver voegt het alle overige configuratiebestanden toe door een include.

Ports.conf is altijd toegevoegd door de apache2.conf. Het dient voor het vaststellen van de 'listen' poorten voor inkomende verbindingen.

Configuratie bestanden in de mods-enabled/, conf-enabled/ en sites-enabled/ mappen bevatten specifieke configuratie snippets voor respectievelijk het beheer van modules, globale configuraties of Virtual Host configuraties.
Ze worden geactiveerd door het symbolisch linken van de beschikbare configuratiebestanden in de bijbehorende *-available/ mappen.
Dit moet gedaan worden met specifieke commando's:
a2enmod/a2dismod
a2ensite/a2dissite
a2enconf/a2disconf

Naar index

Apache2.conf

Dit bestand laten we ongewijzigd.

De meest relevante directives zijn:

# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>

<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>

<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>

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

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf

Naar index

Volgorde van directives

Bij het opstaren van de webserver voegt het bestand apache2.conf alle overige configuratiebestanden toe door een include.

- Als eerste worden de Modules geladen met IncludeOptional mods-enabled/*. In deze groep is de volgorde alphabetisch.

- Hierna volgen de 'global directives' van het bovenstaande default security model en .ht directives

- Vervolgens worden alle conf-enabled/* bestanden geladen (in alphabetische volgorde)

- En als laatste de sites-enabled/*

Als dus voor een zelfde item verschillende directives gegeven zijn dan gelden de laatst gegeven directive.

Bijvoorbeeld:
Hierboven staat in de Apache2.conf directive:

<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>

Als vervolgens in /conf-enabled/mydirective onderstaande directive staat:

<Directory /usr/share>
AllowOverride None
Require all denied
</Directory>

dan is de eerste directive overschreven door de laatste, dus all denied.

Naar index

Modules

De default al geladen en geactiveerde modules:

root@homeserver:~# apache2ctl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 mime_module (shared)
 mpm_prefork_module (shared)
 negotiation_module (shared)
 php_module (shared)
 reqtimeout_module (shared)
 setenvif_module (shared)
 status_module (shared)

Naar index

Hieronder de listing van modules die nodig zijn voor een goede werking van de Thuisserver

 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 include_module (shared)
 mime_module (shared)
 mpm_prefork_module (shared)
 negotiation_module (shared)
 php_module (shared)
 reqtimeout_module (shared)
 rewrite_module (shared)
 setenvif_module (shared)
 socache_shmcb_module (shared)
 ssl_module (shared)
 status_module (shared)

Voor nu missen we:

  1. authz_groupfile_module
  2. cgi_module
  3. include_module
  4. rewrite_module
  5. socache_shmcb_module
  6. ssl_module

Sommige van bovenstaande modules worden enabled bij de installatie van packages maar als dat (nog) niet gebeurd is activeren we nu deze missende modules.

root@testserver:~# a2enmod authz_groupfile
root@testserver:~#  a2enmod cgi
root@testserver:~#  a2enmod include
root@testserver:~#  a2enmod rewrite
root@testserver:~#  a2enmod socache_shmcb
root@testserver:~#  a2enmod ssl

root@testserver:~#  systemctl reload apache2

De onderstaande geactiveerde modules hebben ook nog een eigen configuratiebestand.
Voor nu zijn er geen wijzigingen nodig:

root@testserver:/etc/apache2/mods-enabled# ls -l *.conf
lrwxrwxrwx 1 root root 28 Oct  2 17:02 alias.conf -> ../mods-available/alias.conf
lrwxrwxrwx 1 root root 32 Oct  2 17:02 autoindex.conf -> ../mods-available/autoindex.conf
lrwxrwxrwx 1 root root 30 Oct  2 17:02 deflate.conf -> ../mods-available/deflate.conf
lrwxrwxrwx 1 root root 26 Oct  2 17:02 dir.conf -> ../mods-available/dir.conf
lrwxrwxrwx 1 root root 27 Oct  2 17:02 mime.conf -> ../mods-available/mime.conf
lrwxrwxrwx 1 root root 34 Nov 26 13:37 mpm_prefork.conf -> ../mods-available/mpm_prefork.conf
lrwxrwxrwx 1 root root 34 Oct  2 17:02 negotiation.conf -> ../mods-available/negotiation.conf
lrwxrwxrwx 1 root root 29 Nov 26 13:37 php8.3.conf -> ../mods-available/php8.3.conf
lrwxrwxrwx 1 root root 33 Oct  2 17:02 reqtimeout.conf -> ../mods-available/reqtimeout.conf
lrwxrwxrwx 1 root root 31 Oct  2 17:02 setenvif.conf -> ../mods-available/setenvif.conf
lrwxrwxrwx 1 root root 26 Dec  3 16:22 ssl.conf -> ../mods-available/ssl.conf
lrwxrwxrwx 1 root root 29 Oct  2 17:02 status.conf -> ../mods-available/status.conf

Naar index

Sites - VirtualHosts

Apache2 wordt geleverd met een enkele standaard virtuele host die kan worden gebruikt als u één site hebt. Als deze ongewijzigd wordt gebruikt, zal de standaard virtuele host als uw standaardsite dienen.
Als je de standaard virtuele host wilt wijzigen, bewerk dan het bestand /etc/apache2/sites-available/000-default.conf.
Beter is echter te werken met een kopie van 000-default.conf die met een eigen naam in dezelfde map geplaatst wordt.
De cijfers als prefix zorgt voor sortering.

Voor HTTP gebruiken we een kopie van 000-default.conf en noemen deze 000-mysite80.conf
Voor HTTPS gebruiken we een kopie van default-ssl.conf en noemen deze 001-mysite443.conf

HTTP
Edit 000-mysite80.conf
Download 000-mysite80.conf

<VirtualHost *:80>
        ServerAdmin ben@makkink.eu
        DocumentRoot /var/www/html
        ServerName makkink.eu
        ServerAlias www.makkink.eu
        
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # Custom Access logs voor Awstats---------------------------------
        CustomLog ${APACHE_LOG_DIR}/piwigo_access.log combined env=piwigo
        CustomLog ${APACHE_LOG_DIR}/blog_access.log combined env=blog
        # Aanvullende SETENVIF's in Awstats.conf---------------------------

        RewriteEngine on
        RewriteCond %{SERVER_NAME} =www.makkink.eu [OR]
        RewriteCond %{SERVER_NAME} =*makkink.eu
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

De Custom Access logs voor Awstats zijn toegevoegd om individuele statistieken voor Piwigo en Wordpress te creëren.
Aanvullende SETENVIF directives moeten in Awstat.conf gemaakt worden.

De Rewrite directives zijn toegevoegd door LetsEncrypt als redirect naar HTTPS voor het domein 'www.makkink.eu'

Enable 000-mysite80.conf

root@testserver:~# a2dissite 000-default.conf
Site 000-default disabled.

root@testserver:~# a2ensite 000-mysite80.conf
Enabling site 000-mysite80.
To activate the new configuration, you need to run:
  systemctl reload apache2
root@homeserver:~# systemctl reload apache2

Naar index

HTTPS
Edit 001-mysite443.conf

Zie ook HTTPS en Certificatie

Download 001-mysite443.conf

<VirtualHost *:443>
        ServerAdmin ben@makkink.eu
        DocumentRoot /var/www/html
        ServerName makkink.eu
        ServerAlias www.makkink.eu

        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # Custom Access logs voor Awstats---------------------------------
        CustomLog ${APACHE_LOG_DIR}/piwigo_access.log combined env=piwigo
        CustomLog ${APACHE_LOG_DIR}/blog_access.log combined env=blog
        # Aanvullende SETENVIF's in Awstats.conf---------------------------

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on

        <FilesMatch "\.(?:cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>

        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>

        SSLCertificateFile      /etc/letsencrypt/live/www.makkink.eu/fullchain.pem
        SSLCertificateKeyFile   /etc/letsencrypt/live/www.makkink.eu/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

De Custom Access logs voor Awstats zijn toegevoegd om individuele statistieken voor Piwigo en Wordpress te creëren.
Aanvullende SETENVIF directives moeten in Awstat.conf gemaakt worden.

De laatste alinea's specificeren de locaties van de LetsEncrypt certificaten

Enable 001-mysite443.conf

root@testserver:~# a2dissite default-ssl.conf
Site 000-default disabled.

root@testserver:~# a2ensite 001-mysite443.conf
Enabling site 001-mysite443.
To activate the new configuration, you need to run:
  systemctl reload apache2
root@testserver:~# systemctl reload apache2

Naar index

002-mysite81
Zie ook: Wijzig poort phpMyAdmin van 80/443 naar 81
        en: Wijzig poort BackupPC van 80/433 naar 81

002-mysite81.conf
Maak in /etc/apache2/sites-available een nieuwe Virtual Host in een nieuw bestand '002-mysite81.conf'

Download 002-mysite81.conf

Listen 81
<VirtualHost *:81>

Include /etc/phpmyadmin/apache.conf

ErrorLog ${APACHE_LOG_DIR}/phpmyadmin.error.log
CustomLog ${APACHE_LOG_DIR}/phpmyadmin.access.log combined

Include /etc/backuppc/apache.conf

</VirtualHost>   

Enable 002-mysite81.conf

root@testserver:~# a2ensite 002-mysite81.conf
Enabling site 002-mysite81.
To activate the new configuration, you need to run:
  systemctl reload apache2
root@testserver:~# systemctl reload apache2

Naar index

Global Configuration Snippets

In de map /etc/apache2/conf-available vinden we de overige configuratie directives
Op dit moment zijn al de navolgende directives geactiveerd in /etc/apache2/conf-enabled:

root@testserver:/etc/apache2/conf-enabled# ls -l
total 0
lrwxrwxrwx 1 root root 30 Oct  2 17:02 charset.conf -> ../conf-available/charset.conf
lrwxrwxrwx 1 root root 40 Nov 26 15:31 javascript-common.conf -> ../conf-available/javascript-common.conf
lrwxrwxrwx 1 root root 35 Nov 30 15:35 mydirectives.conf -> ../conf-available/mydirectives.conf
lrwxrwxrwx 1 root root 36 Dec  3 11:10 myerror-pages.conf -> ../conf-available/myerror-pages.conf
lrwxrwxrwx 1 root root 46 Oct  2 17:02 other-vhosts-access-log.conf -> ../conf-available/other-vhosts-access-log.conf
lrwxrwxrwx 1 root root 31 Oct  2 17:02 security.conf -> ../conf-available/security.conf
lrwxrwxrwx 1 root root 36 Oct  2 17:02 serve-cgi-bin.conf -> ../conf-available/serve-cgi-bin.conf

In de configuratiebestanden zijn geen wijzigingen aangebracht behalve in 'mydirectives.conf' en 'myerror-pages.conf'
Mydirectives.conf bevat eigen aanvullende directives en myerror-pages.conf is een bewerking van de Ubuntu default localized-error-pages.conf

Naar index

Mydirectives.conf

Download bestand

# Blokkeer tonen van directory-index, sta volgen van symbolic links toe
# maar blokkeer uitvoerbare bestanden
<Directory "/var/www/html">
   Options -Indexes +FollowSymLinks -IncludesNOExec
   Require all granted
</Directory>

# Mapping naar bestanden buiten de httpd root.
# Met alias wordt een korte url bewerkstelligd,een soort van symbolic link.
# Met de directive worden nadere instellingen gemaakt:
# a. het tonen van een bestandslisting
# b. het beperken wie toegang heeft, bijv. local LAN only.
Alias /manuals "/usr/share/doc"
<Directory "/usr/share/doc">
        Options Indexes
        AllowOverride None
        Require ip 192.168.178.0/24
        # Require all granted
</Directory>

# Forceer domein www.makkink.eu naar HTTPS
# Alleen voor off-line server
<Directory /var/www/html>
       RewriteEngine On
       RewriteCond %{SERVER_PORT} 80
# Eerstvolgende regel is niet meer nodig, is door LetsEncrypt
# in 000-mysite80.conf geplaatst  
#      RewriteRule ^(.*)$ https://www.makkink.eu/$1 [R,L] 
       RewriteRule ^(.*)$ https://192.168.178.5/$1 [R,L]
</Directory>

Enable mydirectives.conf

root@testserver:~# a2enconf mydirectives.conf
Enabling mydirectives.conf.
To activate the new configuration, you need to run:
  systemctl reload apache2
root@testserver:~# systemctl reload apache2

Naar index

Myerror-pages.conf

ErrorDocuments directives om multilinguale HTTP foutmeldingen weer te geven.

In de errorpages 401, 403 en 404 hebben we wijzigingen aangebracht met de anders weing zeggende default pagina's.
Deze aangepaste bestanden bevinden zich in /usr/share/apache2/error en worden behandeld in de sectie Error Messaging

De directives voor de error documenten zijn opgenomen in /etc/apache2/conf-available/localized-error-pages.conf
We brengen geen wijzigingen aan in dat bestand maar in een kopie genaamd 'myerror-pages.conf'
Download bestand myerror-pages.conf

Edit myerror-pages.conf
Van alle regels met highlight is de uitmarkering verwijderd

# ErrorDocuments directives om multilinguale HTTP foutmeldingen weer te
# geven

# Gebruik Alias /error/ om de locatie aan te geven van de ErrorDocumenten
Alias /error/ "/usr/share/httpd/error/"

# Geef de benodigde permissies en instellingen voor het correct weergeven
<IfModule mod_negotiation.c>
  <IfModule mod_include.c>
    <Directory "/usr/share/httpd/error">
        AllowOverride None
        Options IncludesNoExec
        AddOutputFilter Includes html
        AddHandler type-map var
        Require all granted
        LanguagePriority nl en es de fr
        ForceLanguagePriority Prefer Fallback
    </Directory>

# Verwijder de '#' voor het ErrorDocument waarvoor de uitgebreide optie
# gewenst is
#    ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
    ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
    ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
    ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
#    ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
#    ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
#    ErrorDocument 410 /error/HTTP_GONE.html.var
#    ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
#    ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
#    ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
#    ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
#    ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
#    ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
#    ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
#    ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
#    ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
#    ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
  </IfModule>
</IfModule>

Enable myerror-pages.conf

root@testserver:~# a2disconf localized-error-pages.conf
localized-error-pages.conf disabled.
root@testserver:~# a2enconf myerror-pages.conf
Enabling myerror-pages.conf.
To activate the new configuration, you need to run:
  systemctl reload apache2
root@testserver:~# systemctl reload apache2

Naar index

Gebruik van .htaccess vermijden

Het .htaccess bestand is een high-level website configuratiebestand.
Op Apache2 websites maakt het .htaccess bestand het mogelijk wijzigingen aan te brengen in de websiteconfiguratie zonder dat daarvoor de HTTPD configuratiebestanden bewerkt moeten worden.

Een .htaccessbestand wordt geplaatst in de root van websiteapps zoals Piwigo en Wordpress.
Dit in tegenstelling tot apache2.conf en de 'includes' in mods-enabled/, conf-enabled/ en sites-enabled/ die buiten de webroot geplaatst zijn en dus onbereikbaar voor de webgebruiker.

Omdat een .htaccess bestand in de webroot hackbaar is plaatsen we in apache2.conf voor de webroot onderstaande directive waardoor .htaccess bestanden geblokkeerd zijn:

<Directory /var/www/>
 Options Indexes FollowSymLinks
 AllowOverride None
 Require all granted
</Directory>

Naar index

Tevens wordt het lezen van de .htaccess bestanden geblokkeerd door de volgende directive:

<FilesMatch "^\.ht">
Require all denied
</FilesMatch>

Voorbeeld van een .htaccess bestand
Om in Piwigo een directe url naar originele fotos in ../piwigo/upload te blokkeren wordt een .htaccessbestand geplaatst in de /var/www/html/piwigo/upload met daarin één regel:

Require all denied

Kwetsbaarheid
In ons .htaccess voorbeeld plaatsen we feitelijk een directive binnen de webroot en met wat hackwerk bereikbaar voor webgebruikers.
In theorie is het nu mogelijk middels Piwigo, in plaats van een foto, een .htaccess bestand met eigen directives naar /var/www/html/piwigo/upload te uploaden die daarmee het aanwezige .htaccess bestand vervangt.

Oplossing
Waar mogelijk worden .htaccess bestanden op de Homeserver niet toegepast.
Door in apache2.conf de directive voor de webroot 'AllowOverride None' te laten worden eventuele .htaccess bestanden niet uitgevoerd.

De directives in de .htaccess bestanden zijn echter nodig voor het correct functioneren van apps zoals Piwigo en Wordpress.
Dit lossen we op door als root configuratiebestanden aan te maken in /etc/apache2/conf-available zoals piwigo.conf en wordpress.conf waarin we de directives uit de .htaccess bestanden plaatsen.

Let hierbij op dat het pad van de directive gelijk is aan het pad waar het .htaccess bestand gevonden wordt.
In het voorbeeld van het Piwigo .htaccess bestand met de directe url blokkering vervangen we het .htaccess bestand door onderstaande directive in piwigo.conf

<Directory /var/www/html/piwigo/upload>
 Require all denied
</Directory>

Naar index

Piwigo.conf

Piwigo is een fotogalerijprogramma voor websites. Het programma heeft een GPL-licentie, en is geschreven in PHP en gebruikt een MySQL-database.
Piwigo stond eerder bekend als "PhpWebGallery" maar de oorspronkelijke auteur van de software, Pierrick Le Gall, wijzigde in september 2008 de naam naar de huidige.
Zie de Piwigo pagina's voor installatie en configuratie.

De Piwigo App wordt geinstalleerd in de webroot /var/www/html en heeft in principe geen aanvullende http directives nodig.
Voor bijvoorbeeld security worden extra directives aanbevolen middels het gebruik van .htaccess bestanden.
Zoals beschreven in de sectie .htaccess proberen we .htaccess bestanden te vermijden en wordt op deze server in /etc/apache2/conf-available de 'include' piwigo.conf gebruikt waarin we ook andere http 'customisations' onderbrengen.
Zie voor de laatste ook Piwigo::Beveiliging > Apache Directives voor Piwigo
Download piwigo.conf

#*********************************************************************
#* /etc/apache2/conf-available/piwigo.conf                           *
#* Custom apache2 configuratie   Ben Makkink 13-december-2024        *
#*********************************************************************
# In apache2.conf is AllowOverride naar None gezet
# Indien Piwigo beveiliging mbv .htaccess toch gewenst is dit hier
# toestaan door Override toe te staan
<Directory /var/www/html/piwigo>
#    AllowOverride FileInfo Options AuthConfig Limit
</Directory>

# Voor toegangscontrole voor de  familiewebsite /var/www/html/archief
# en toegang middels Piwigo Cookie

<Directory "/var/www/html/archief">
 Require all denied
   SetEnvIf COOKIE ^GALLERYSID user_logged_in
   Require env user_logged_in
</Directory>

# Blokkeer directe url naar originele fotos in ../piwigo/galleries
# In plaats van .htaccess in /var/www/html/piwigo/galleries
# Maak een uitzondering voor Video-JS voor directe toegang tot mp4
# Voeg tevens toe in ../piwigo/local/config/config.inc.php
# $conf['original_url_protection'] = 'images';

<Directory /var/www/html/piwigo/galleries>
 Order Allow,Deny
 Require all denied
 <FilesMatch "\.(?:mp4|m4v)$">
  Order Deny,Allow
  Require all granted
 </FilesMatch>
</Directory>

# Blokkeer directe url naar originele fotos in ../piwigo/upload
# In plaats van .htaccess in /var/www/html/piwigo/upload

<Directory /var/www/html/piwigo/upload>
  Require all denied
</Directory>

# Blokkeer directe url naar derivaten in ../piwigo/_data/i
# Voeg tevens toe in ../piwigo/local/config/config.inc.php
# $conf['derivative_url_style'] = 2;

<Directory /var/www/html/piwigo/_data/i>
  Require all denied
</Directory>

#************************************************************************
# Zet SameSite support voor Cookies                                     *
# Ben Makkink 26-juni-2020                                              *
#************************************************************************
# Zie https://developer.mozilla.org/nl/docs/Web/HTTP/Headers/Set-Cookie/SameSite
# en https://www.makkink.eu/exploringlinux/server7/html/apache.html#piwigoconf

<ifmodule mod_headers.c>
 # Header always edit Set-Cookie (.*) "$1; SameSite=strict"
 Header always edit Set-Cookie (.*) "$1; SameSite=lax"
</ifmodule>

Naar index

Toegangscontrole /var/www/html/archief via Piwigo Cookie
Voor de directorie /var/www/html/archief/ voegen we in bovenstaand bestand een directive toe met als eerste de 'Require all denied' statement. Hiermee wordt toegang tot '/archief/' volledig geblokkeerd.
Daarna word middels 'SetEnvIf' gecontroleerd of in de clientbrowser een Piwigo Cookie is gezet. Deze Cookie wordt gezet als een client via Piwigo ingelogd en geauthentiseerd is als een geregistreerde gebruiker. Zie hiervoor ook Piwigo::Albums Inrichten > Beveiliging 'Archief' en toegang via Piwigo registratie
Als het Cookie gevonden wordt, wordt de variabele 'env' gezet naar 'user_logged_in' en krijgt de clientbrowser toegang tot '/archief/'.

Onderstaande regels worden hiervoor aan piwigo.conf toegevoegd:

# toegangscontrole via Piwigo Cookie
<Directory "/var/www/html/archief">
Require all denied
   SetEnvIf COOKIE ^GALLERYSID user_logged_in
   Require env user_logged_in
</Directory>

Naar index

Piwigo Cookie zetten
Zie ook Piwigo::Wijzigingen > Hacks > Extra Cookie wanneer gebruiker ingelogd is
Bovenstaande toegangscontrole test of er in de webroot een Cookie met de naam 'GALLERYSID' gezet is door Piwigo.
Piwigo zet weliswaar een Cookie maar dat is slechts een Session Cookie en deze wordt gezet in /piwigo/met de naam 'pwg_id'. Deze Cookie wordt echter ook gezet als er niet op Piwigo ingelogd is en de gebruiker dus 'guest' is. De 'value' van de Piwigo Session Cookie bevat de code waarmee de gebruiker van Piwigo in de MySQL database te herleiden is.
Als de Piwigo Session Cookie al in de webroot zou staan en de bovenstaande 'SetEnvIf' http methode mogelijk ook de inhoud (value) van de Cookie zou kunnen testen, dan kan daar nog steeds verder niets mee gedaan worden zonder toegang tot de Piwigo database.

Het enige alternatief is dat Piwigo een additionele Cookie in de Webroot zet met een unieke naam en dat alleen als er op Piwigo ingelogd is door een geregistreerde gebruiker. Er is een toevoeging nodig in het Piwigo 'index.php' bestand.
Hieronder volgt de benodigde toevoeging direct in het begin na de include calls in het script /var/www/html/piwigo/index.php:

define('PHPWG_ROOT_PATH','./');
include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
include(PHPWG_ROOT_PATH.'include/section_init.inc.php');

//Ben Makkink 26/03/2016
//Toevoeging voor het zetten van extra cookie als gebruiker ingelogd is
//Control Cookie voor toegang tot afgeschermde data

if ($user['status']!=="guest")
{
  setcookie('GALLERYSID',time(),0, '/');
}
else
{
  setcookie('GALLERYSID', ' ', time()-7000000, '/');
}

// Check Access and exit when user status is not ok
check_status(ACCESS_GUEST);

// access authorization check
if (isset($page['category']))

In index.php wordt als eerste de include 'common.inc.php' uitgevoerd. In deze include wordt o.a. het global PHP commando 'session_start()' uitgevoerd. Dit commando start een nieuwe- of vervolgt een bestaande Piwigo Sessie en opent vervolgens de Piwigo Home pagina. Als er niet ingelogd is dan is de userstatus 'guest' en wordt de optie geboden in te loggen.
Door nu de status van $user te testen kunnen we vaststellen wanneer de gebruiker ingelogd is (is niet guest) en in dat geval wordt er een Cookie met de naam 'GALLERSID' gezet. De 'value' is niet belanrijk, maar het veld mag niet leeg zijn, we zetten hier bijvoorbeeld de huidige tijd. De expirydate zetten we naar 'onbepaald' door 0 in te voeren. Voor path van de Cookie zetten we '/', zijnde de webroot.
Als de gebruiker uitlogt dan wordt $user['status'] weer naar 'guest' gezet en verwijderen we de Cookie 'GALLERYSID' door zijn waarde naar 'leeg' te zetten en de expirydate naar een punt in het verre verleden

Naar index

Login en toegangscontrole../archief/ via Piwigo
In de voorgaande sectie is beschreven hoe de site 'archief' afgeschermd is. Alleen als een client ingelogd is als geregistreerde gebruiker op Piwigo zal deze toegang krijgen tot de vertrouwelijke site.
In Piwigo wordt de link met URL naar het archief alleen getoond als een gebruiker ingelogd is. En omdat er dan ingelogd is krijgt de URL toegang tot het archief.
Zie Piwigo::Albums Inrichten > Albums Beheren > Galerij minatuur met link naar externe site 'Archief'

Naar index

SameSite extra cookie security
Medio juni 2020 werd de volgende waarschuwing afgegeven in mijn Firefox Browser Console:

Cookie “pwg_id” will be soon rejected because it has the “sameSite” attribute set to “none” or an invalid value, without the “secure” attribute. To know more about the “sameSite“ attribute, read https://developer.mozilla.org/docs/Web/ … e/SameSite

Mede met de informatie in de blog SameSite cookies in practice heb ik, zonder succes, diverse PHP oplossingen geprobeerd. Dit in een poging Piwigo te laten voldoen aan de nieuwe eisen.

Wat uiteindelijk lukte is met een toevoeging in het Apache Webserver configuratiebestand. Omdat het in mijn situatie alleen voor Piwigo noodzakelijk is, is de code in Piwigo.conf geplaatst.
Middels deze code worden alle cookies die op de server gezet worden bewerkt waardoor ze de vereiste SameSite settings bevatten. Ik heb gekozen voor de 'lax' setting, maar Piwigo werkt ook prima met 'strict'.

#************************************************************************
# Zet SameSite support voor Cookies                                     *
# Ben Makkink 26-juni-2020                                              *
#************************************************************************
# Zie https://developer.mozilla.org/nl/docs/Web/HTTP/Headers/Set-Cookie/SameSite
# en https://www.makkink.eu/exploringlinux/server7/html/apache.html#piwigoconf

<ifmodule mod_headers.c>
 # Header always edit Set-Cookie (.*) "$1; SameSite=strict"
 Header always edit Set-Cookie (.*) "$1; SameSite=lax"
</ifmodule>

Naar index

Wordpress.Conf

Wordpress:

De Wordpress Blog App wordt geinstalleerd in de webroot /var/www/html en heeft enkele aanvullende http directives nodig en deze worden bij de installatie geplaatst in een .htaccess bestand in de wordpress blog root /var/www/html/blog.
De directives in dit .htaccess bestand worden dynamisch gegenereerd door Wordpress en zouden alleen aangepast mogen worden via WordPress filters. Alle wijzigingen aan de richtlijnen worden mogelijk bij een update/upgrade overschreven.

AllowOverride None
Zoals beschreven in de sectie .htaccess proberen we .htaccess bestanden te vermijden en wordt op deze server in /etc/apache2/conf-available de 'include' wordpress.conf gebruikt.
Download wordpress.conf

Kopieer hiervoor de inhoud van het /var/www/html/blog/.htaccess bestand.

# BEGIN WordPress
# De richtlijnen (regels) tussen "BEGIN WordPress" en "END WordPress"
# worden dynamisch gegenereerd en zouden alleen aangepast mogen worden
# via WordPress filters. Alle wijzigingen aan de richtlijnen tussen
# deze markeringen worden overschreven.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress

Naar index

en plaats dat in /etc/httpd/conf.d/wordpress.conf
Zorg er hierbij voor dat het een directive wordt voor de Directory waarin het .htaccess bestand staat, dwz /var/www/html/blog

<Directory /var/www/html/blog>
# BEGIN WordPress
# De richtlijnen (regels) tussen "BEGIN WordPress" en "END WordPress"
# worden dynamisch gegenereerd en zouden alleen aangepast mogen worden
# via WordPress filters. Alle wijzigingen aan de richtlijnen tussen
# deze markeringen worden overschreven.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
</Directory>

Naar index

Dynamische integratie van .htaccess

Het Wordpress .htaccess bestand wordt dynamisch gegenereerd bij de installatie en/of update door Wordpress.
De hierboven voorgestelde integratie van .htaccess in wordpress.conf is echter statisch waarvoor manuele interventie van de admin vereist is.

WP-HTACCESS
Dit process wordt op mijn server min of meer automatisch gemaakt door een dagelijkse crontab die het script wp-htaccess start met een check of er een wijziging in .htaccess geweest is en of deze al dan niet onderdeel is geweest van een Wordpress update:

NOTE:
De crontab NIET op OFF-LINE SERVER!!

Meldingen
Als er wel een Wordpress update plaatsvond maar geen .htaccess codewijziging dan ontvangt Admin onderstaande melding in een mail:

Aan: ServerAdmin

Er is een update/upgrade van de Wordpress uitgevoerd.

Hierbij heeft er zich geen wijziging voorgedaan in het dynamischgegenereerde .htaccess bestand in /var/www/html/blog/.
Er is geen verdere actie nodig.

Zie ook https://www.makkink.eu/exploringlinux/wordpress/html/installeren.html#htaccess

Als er een .htaccess codewijziging plaatsvond tijdens een Wordpress update dan ontvangt Admin onderstaande melding in een mail:

Aan: ServerAdmin

Er is een update van het Wordpress .htaccess bestand geïntegreerd
met webserver conf.bestand /etc/apache2/conf-available/wordpress.conf.

Het nieuwe .htaccess bestand was onderdeel van een Wordpress update of goedgekeurd na manuele interventie.

Zie ook https://www.makkink.eu/exploringlinux/wordpress/html/installeren.html#htaccess

Naar index

Als er echter een .htaccess codewijziging plaatsvond zonder een Wordpress update dan kan het een hack zijn en ontvangt Admin onderstaande melding in een mail:

To: ServerAdmin
Subject: Wordpress .htaccess gehackt?
Er is een wijziging aangebracht in het .htaccess bestand van Wordpress
zonder dat hiervoor een Wordpress update plaatsvond.
Dit is een verdachte situatie en is mogelijk het resultaat van een hack.

De webserver is dusdanig geconfigureerd dat een Override door .htaccess
niet is toegestaan of te wel de code van .htaccess wordt niet uitgevoerd.
Na een legitieme Wordpress version update wordt de dynamische inhoud van
.htaccess gekopieerd naar de webserverconfiguratie /etc/apache/conf-available/wordpress.conf.

POTENTIELE HACK GEBLOKKEERD.
Omdat zojuist de Wordpress ".htaccess" is gewijzigd terwijl er geen version
update plaatsvond is deze als verdacht aangemerkt en geblokkeerd door een
kopie van .htaccess op te slaan als "/var/www/html/blog/hta_fout".

EVALUEREN
Het bestand "/var/www/html/blog/hta_fout" moet eerst geevalueerd worden.

OUDE .HTACCESS TERUGZETTEN
- Als hierbij blijkt dat iets met de code in "hta_fout" inderdaad niet
klopt dan moet de voorlaatste .htaccess teruggezet worden.
Activeer dit door bet bestand "hta_fout" te hernoemen naar "hta_terug".
Door het script "wp-htaccess" uit te voeren wordt de laatste correcte
situatie hersteld (Dit gebeurd ook automatisch als de dagelijkse cron
"wp-htaccess" draait).

INTEGREREN
- Als echter blijkt dat er niets aan de hand is met de code in "hta_fout"
hernoem deze dan naar "hta_ok".
Door het script "wp-htaccess" uit te voeren wordt de nieuwe .htaccess
alsnog gekopieerd en geïntegrrerd in de webserverconfiguratie
/etc/httpd/conf.d/wordpress.conf (Dit gebeurd ook automatisch als de
dagelijkse cron "wp-htaccess" draait).
De webserver wordt opnieuw gestart om het gewijzigde configuratiebestand
"../conf-available/wordpress.conf" te laden.

Zie ook https://www.makkink.eu/exploringlinux/wordpress/html/installeren.html#htaccess

Naar index

De resulterende wordpress.conf zie eruit als volgend voorbeeld:

#************************************************************************
#* /etc/apache2/conf-available/wordpress.conf                           *
#* Custom apache2 configuratie voor Wordpress. Ben Makkink 13-dec-2024  *
#************************************************************************
#* Per default is in apache2.conf AllowOverride naar None gezet.        *
#* Mede om remote toegang via hacks van .htaccess te voorkomen is het   *
#* wenselijk deze Homeserver default instelling te handhaven.           *
#*                                                                      *
#* Wordpress genereerd voor o.a. permalinks en beveiliging wel dynamisch*
#* een .htaccess bestand in de Wordpress root.                          *
#* Deze directives hevelen we over naar dit bestand 'wordpress.conf'    *
#* zodat ze toch uitgevoerd worden.                                     *
#* Elke keer dat er dynamisch een wijziging gemaakt wordt in '.htaccess'*
#* wordt dit bestand 'wordpress.conf' ververst d.m.v. het script        *
#* 'wp-htaccess' welke regelmatig start d.m.v. een cron                 *
#************************************************************************

# Dit bestand vervangt .htaccess, dus reconfirmeer 'AllowOverride None'
<Directory /var/www/html/blog>
  AllowOverride None
</Directory>

# Later toe te voegen custom directives boven deze regel invoegen
#========================================================================
<Directory /var/www/html/blog>
# BEGIN WordPress
# De richtlijnen (regels) tussen "BEGIN WordPress" en "END WordPress"
# worden dynamisch gegenereerd en zouden alleen aangepast mogen worden
# via WordPress filters. Alle wijzigingen aan de richtlijnen tussen deze
# markeringen worden overschreven.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
</Directory>

Naar index

HTTPS en Certificatie

Als er met HTTPS gewerkt wordt wordt gebruik gemaakt van een SSL verbinding.
Een SSL/TLS-verbinding is een gecodeerde verbinding tussen de server en bezoeker.
Naast het slotje bovenin je browser voor de URL kun je een SSL-verbinding ook herkennen aan de https aan het begin van de URL.
Https staat voor Hyper Text Transfer Protocol Secure. De extra S aan het einde van http staat dus voor veilig. Klik je op het slotje, dan kun je de gegevens van het certificaat en de uitgever daarvan controleren.
TLS staat voor Transport Layer Security. Eigenlijk is dit niets anders dan een veiligere versie van SSL. Tegenwoordig wordt er eigenlijk altijd gebruik gemaakt van de TLS-technologie. Toch gebruiken we de term SSL nog altijd omdat dit de meest gebruikte term is.

De gegevensstroom tussen de server en bezoeker is heel makkelijk uit te lezen met zogenaamde netwerk sniffers. Wachtwoorden zijn op deze manier bijvoorbeeld heel makkelijk te achterhalen. Om dat enorme (!) beveiligingsrisico op te vangen, kan men het beste een SSL-verbinding gebruiken. Dan worden deze gegevens namelijk versleuteld verzonden.

SSL Certificaat
SSL beveiligt de verbinding tussen twee computers. Om zo’n beveiligde verbinding plaats te laten vinden heb je een certificaat nodig, een SSL-certificaat. Een certificaat bevat gegevens over de certificaathouder, het domein, de naam van de instantie die het certificaat heeft uitgegeven, het land waarin het certificaat is uitgegeven en de geldigheidsduur. Een SSL-certificaat bestaat altijd uit een public- en een private key die nodig zijn om het bericht versleuteld te versturen en uiteindelijk weer in een leesbare tekst om te zetten.
Deze SSL-certificaten worden door verschillende bedrijven uitgegeven. Via een zoekmachine zijn resellers van deze certificaten eenvoudig te vinden. De prijzen lopen daarbij echter wel uiteen van 15 tot meer dan 1500 euro.

Naar index

SSL Encryptie flowchart

  1. Browser verbind met een webserver (website) beveiligd met SSL (https). Browser verzoekt de server zich te identificeren.
  2. Server zendt een kopie van zijn SSL Certificaat, samen met de public-key van de server
  3. Browser checkt de Certificaat bron (CA) en vergelijkt deze met een lijst van vertrouwde CA's, dat het certificaat niet verlopen is, niet ongeldig verklaard is en dat het geldig is voor de website waarmee het zich verbindt. Als de browser het certificaat vertrouwd, creëert het een symmetrische session-key, versleuteld deze met de ontvangen public-key van de server en zend het naar de server.
  4. Server ontsleutelt de session-key gebruikmakend van zijn private-key en stuurt een bevestiging versleuteld met de nu gedeelde session-key voor het starten van de versleutelde sessie.
  5. Server en Browser versleutelen nu alle verstuurde data met de gezamenlijke session-key

Naar index

Webserver SSL activeren

Zie ook ubuntu.com enable-https-on-my-server

Voor het activeren van HTTPS in Apache moet eerst de Apache2 SSL module geïnstalleerd worden en vervolgens geactiveerd in de Apache2 configuratie.
Verifiëer dat de SSL module geïnstalleerd is ((automatisch geïnstalleerd met de Apache2 installatie):

root@testserver:/etc/apache2/mods-available# ls -l ssl*
-rw-r--r-- 1 root root 3129 Mar 18  2024 ssl.conf
-rw-r--r-- 1 root root   88 Mar 18  2024 ssl.load

Download ssl.conf

Activeer SSL

root@testserver:/etc/apache2/mods-available# a2enmod ssl
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure
SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  systemctl restart apache2
root@testserver:/etc/apache2/mods-available# systemctl restart apache2

Er zijn dus enkele dependencies die ook geactiveerd worden.

Naar index

HTTPS Virtual Host

Bij de installatie van Apache2 ook een Virtual Host voor HTTPS meegeleverd.
Het is het bestand /etc/apache2/sites-available/default-ssl.conf waarin nog de nodige aanvullingen gemaakt moeten worden.
Maar we gaan dit doen in een kopie genaamd 001-mysite443.conf

root@testserver:/etc/apache2/sites-available# cp -a default-ssl.conf 001-mysite443.conf

Zie hier het originele default-ssl.conf

Edit dit nieuwe bestand 0010mysite443.conf.

# vi /etc/apache2/sites-available/001-mysite443.conf

<VirtualHost *:443>
        ServerAdmin ben@makkink.eu
        DocumentRoot /var/www/html
        ServerName makkink.eu
        ServerAlias www.makkink.eu

        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on

        SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key

        <FilesMatch "\.(?:cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>

        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
</VirtualHost>

Naar index

Gebruiker aanvaart risico Selfsigned Certificaat

Vanwege de kostprijs heeft Ubuntu een eigen self-signed SSL-certificaat met de distributie meegegeven.
Deze is automatisch geactiveerd als de HTTPS-site gebruik maakt van /etc/apache2/sites-available/default-ssl.conf

#   Enable/Disable SSL for this virtual host.
    SSLEngine on
#   A self-signed (snakeoil) certificate can be created by installing
#   the ssl-cert package. See
#   /usr/share/doc/apache2/README.Debian.gz for more info.
#   If both key and certificate are stored in the same file, only the
#   SSLCertificateFile directive is needed.
SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key

Dit is een optie waarvan geen enkele webbrowser het certificaat zal (h)erkennen.
Als we hier genoegen meenemen moeten we de https cliënten verzoeken het certificaat van ons domein te vertrouwen en de waarschuwingen van de browser te laten voor wat ze zijn.
Voor kleinschalig gebruik biedt dit voldoende veilige versleuteling.

Hier een voorbeeld van het aanvaarden van het risco en doorgaan in Firefox.

Naar index

Let's Encrypt Free SSL Certificates

Zie ook digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu

Let's Encrypt is een Certificate Authority (CA) die het verkrijgen en installeren gratis TLS/SSL certificates faciliteert en zodoende versleutelde HTTPS op webservers mogelijk maakt.
Het stroomlijnt het proces door te voorzien in een software client, Cerbot, die al de benodigde stappen automatiseert.

Voor de Homeserver gebruiken we Certbot om een gratis SSL certificaat voor Apache en Ubuntu te verkrijgen en deze automatisch te verlengen.

Naar index

Certbot voor Apache2 installeren

Er zijn 2 packages nodig: certbot en python3-certbot-apache. De laatste is a plugin die Certbot met Apache integreert.

Installeer de Certbot software:

root@testserver:~# apt install certbot python3-certbot-apache

Check de Apache Virtual Host Configuratie

Voor het automatisch verkrijgen en configureren van SSL voor de Homeserver, moet Certbot de juiste Virtual Host vinden bij de Apache2 configuratie bestanden.
De server domainnaam wordt opgehaald van de ServerName and ServerAlias directives gedefinieerd in het VirtualHost configuratieblok.

Controleer het HTTPS Virtual Host bestand /etc/apache2/sites-available/001-mysite443.conf en confirmeer de volgende instellingen:

        ServerName makkink.eu
        ServerAlias www.makkink.eu

Firewall

Confirmeer HTTPS port 443 is open voor inkomend verkeer.

On-line

Voor het verkrijgen van de certificaten is het nodig dat Let's Encrypt het doemein www.makkink.eu kan bereiken, dus de Thuisserver moet On-line zijn.

Naar index

Let's Encrypt Certificaat aanvragen

Op de Thuisserver is al een gedeeltelijk Cerificaat aanwezig voor Postfix, standalone en certonly) en kan ook gebruikt kunnen worden voor HTTPS op Apache.
Maar een eenvoudige renew zal resulteren in een error omdat een renewal van dit certificaat gebruik maakt van poort 80 die nu in gebruik is door Apache.

HTTPS Encryptie
Certbot verkrijgt het certificaat door plugins.
Zie https://eff-certbot.readthedocs.io/en/stable/using.html#getting-certificates-and-choosing-plugins
En de Certbot Apache plugin regelt het herconfigureren van Apache en het herladen van deze configuratie.

root@testserver:~# certbot --apache
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: makkink.eu
2: www.makkink.eu
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2

Certificate not yet due for renewal
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/www.makkink.eu.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Attempt to reinstall this existing certificate
2: Renew & replace the certificate (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

Renewing an existing certificate for www.makkink.eu
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/www.makkink.eu/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/www.makkink.eu/privkey.pem

This certificate expires on 2025-07-14.
These files will be updated when the certificate renews.

Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for www.makkink.eu to /etc/apache2/sites-enabled/001-mysite443.conf
Your existing certificate has been successfully renewed, and the new certificate has been installed.

Check expiry date

root@thuisserver:# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: www.makkink.eu
    Serial Number: 69f07fb9129401f143c730fd599f5165499
    Key Type: ECDSA
    Domains: www.makkink.eu
    Expiry Date: 2025-07-14 10:53:12+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/www.makkink.eu/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/www.makkink.eu/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Automatic Renewal
Certbot has set up a scheduled task to automatically renew this certificate in the background

Timer: /usr/lib/systemd/system/certbot.timer

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

Service: /usr/lib/systemd/system/certbot.service

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://certbot.eff.org/docs

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew --no-random-sleep-on-renew
PrivateTmp=true

Configuratie: /etc/letsencrypt/renewal/www.makkink.eu.conf

# renew_before_expiry = 30 days
version = 2.9.0
archive_dir = /etc/letsencrypt/archive/www.makkink.eu
cert = /etc/letsencrypt/live/www.makkink.eu/cert.pem
privkey = /etc/letsencrypt/live/www.makkink.eu/privkey.pem
chain = /etc/letsencrypt/live/www.makkink.eu/chain.pem
fullchain = /etc/letsencrypt/live/www.makkink.eu/fullchain.pem

# Options used in the renewal process
[renewalparams]
account = 430a5bd335673af2f0785a1cc5ca1a11
authenticator = apache
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa
installer = apache

Naar index

Herstart Apache

root@testserver:~# systemctl restart apache2

Renew certificaat (dry-run)

root@thuisserver:# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - -
Processing /etc/letsencrypt/renewal/www.makkink.eu.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - -
Simulating renewal of an existing certificate for www.makkink.eu

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/www.makkink.eu/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -

Naar index

Certificaat geïntegreerd in Virtual Host 443

Het ontvangen Let's Encrypt certificaat wordt door Certbot geïntegreerd in de Virtual Host en het self-signed (snakeoil) certificaat is verwijderd).

001-mysite443.conf

<VirtualHost *:443>
        ServerAdmin ben@makkink.eu
        DocumentRoot /var/www/html
        ServerName makkink.eu
        ServerAlias www.makkink.eu

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on

        <FilesMatch "\.(?:cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>

        SSLCertificateFile      /etc/letsencrypt/live/www.makkink.eu/fullchain.pem
        SSLCertificateKeyFile   /etc/letsencrypt/live/www.makkink.eu/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf

</VirtualHost> 

Naar index

Error Messaging


Apache2 Configuratie

Zie voor volledig verhaal Server::Apache > Myerror-pages.conf

Essentiële code /etc/apache2/conf-available/myerror-pages.conf:

<IfModule mod_negotiation.c>
        <IfModule mod_include.c>
                <IfModule mod_alias.c>
                        Alias /error/ "/usr/share/apache2/error/"

                        <Directory "/usr/share/apache2/error">
                                Options IncludesNoExec
                                AddOutputFilter Includes html
                                AddHandler type-map var
                                Order allow,deny
                                Allow from all
                                LanguagePriority nl en es de fr
                                ForceLanguagePriority Prefer Fallback
                        </Directory>

                        ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
                        ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
                        ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
                </IfModule>
        </IfModule>
</IfModule>

Naar index

Layout ErrorDocuments

Als de Apache2 default instellingen gebruikt worden dan wordt alleen het error-nummer geretourneerd zonder verdere uitleg.
Voor de 3 meest voorkomende errors worden op de Homeserver door de directives in Myerror-pages.conf meer uitgebreide boodschappen weergegeven.
De Error pagina's die nu getoond worden zijn met de module meegeleverd en nog steeds wat basic en bevatten taalfouten.
Maar deze pagina's zijn naar wens verder te personaliseren.
De ErrorDocuments zijn opgeslagen in directory '/usr/share/apache2/error/' en we nemen als voorbeeld 'ErrorDocument 401 /error/ HTTP_UNAUTHORIZED.html.var

Naar index

HTTP_UNAUTHORIZED.html.var

Bekijk hier de inhoud van HTTP_UNAUTHORIZED.html.var en er is een sectie voor elke taal. De taal ingesteld op de clientbrowser bepaald welke taal getoond wordt.

Voor de structuur bekijken we nu de sectie 'Content-language: nl'.

Content-language: nl
Content-type: text/html; charset=UTF-8
Body:----------nl--
<!--#set var="CONTENT_LANGUAGE" value="nl"-->
<!--#set var="TITLE" value="Authenticatie nodig!"-->
<!--#include virtual="include/top.html" -->

    De server kon niet controleren of u gemachtigd bent om toegang te krijgen
    tot de URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
    U hebt zich onvoldoende geauthenticeerd ( vb : verkeerd paswoord ), of
    uw browser is niet in staat de nodige authentificatiegegevens door te geven.

<!--#include virtual="include/spacer.html" -->

    Indien u toch gemachtigd bent toegang te krijgen tot het document,
    controleer uw gebruikersnaam en paswoord en probeer opnieuw.

<!--#include virtual="include/bottom.html" -->
----------nl--

We zien dat het begint met een paar standaard html instellingen waarna de rest volgt en deze wordt opgebouwd met de volgende componenten:

  1. De 'include/top.html' waarin de pagina opgebouwd wordt met o.a de styles met backgroundcolor, background image etc.
  2. Nu wordt de Nederlandse tekst toegevoegd.
  3. Het eerste tekstblok wordt gevolgd door 'include/spacer.html' die exact doet wat het zegt, voegt een lege paragraaf toe. Dit kan naar behoefte groter of kleiner gemaakt worden of worden voorzien van een lijn of afbeelding.
  4. Dit wordt opnieuw gevolgd door een stuk Nederlandse tekst.
  5. De pagina wordt afgesloten met 'include/bottom.html' en deze heeft als eerste ook weer een 'include ../contact.html.var' met de contact gegevens in de taal van de browser (in ons geval NL). Daarna sluit 'include/bottom.html' de error pagina met de Error Code en Apache versie
Alle Error Messages maken in alle talen gebruik van de bestanden 'top.html', 'spacer.html' en 'bottom.html'. Door in deze bestanden de layout te specificeren zullen alle Error Messages dezelfde layout krijgen.

Naar index

Personalisatie Layout

TOP.HTML
Zie hier de code van gewijzigde '/usr/share/apache2/error/include/top.html'

Modificeer top.html
Voeg toe/wijzig style:
body { color: #000000;
      background-color: #D4C1A3;
      background-repeat: no-repeat;
      background-image: url(/../error/errormsg_backgr.jpg);
      }


Note: De Apache root is de website root '/var/www/html', dus de url hierboven begint in '/var/www/html' en gaat dan 1 stap terug naar '/var/www' en gaat van daaruit naar alias '/error/' en haalt daar '/usr/share/apache2/error/errormsg_backgr.jpg'.

BOTTOM.HTML
Zie hier code van gewijzigde '/usr/share/httpd/error/include/bottom.html'

Voeg toe na de regel <a href="/"><  blahblah  var="SERVER_NAME" --></a><br />:
<a href="/"><img src="/../error/logo.png" /></a><br />

Naar index

Tekst Correcties

CONTACT.HTML.VAR
De Nederlandse vertaling in contact.html.var ziet er wat vreemd uit:
Indien u van oordeel bent dat deze server in fout is, gelieve de <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a> te contacteren.
Dit gewijzigd naar:
Indien u van oordeel bent dat het een serverfout is, neem dan a.u.b. contact op met de <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a>

HTTP_UNAUTHORIZED.HTML.VAR
De tekst in HTTP_UNAUTHORIZED.html.var is niet echt zinvol en daarom is:
Indien u toch gemachtigd bent toegang te krijgen tot het document, controleer uw gebruikersnaam en paswoord en probeer opnieuw.
Gewijzigd naar:
Als u toegang wenst tot deze pagina's neem dan contact op met de <a href="mailto:<!--#echo encoding="url" var="SERVER_ADMIN" -->">webmaster</a> voor een gebruikersnaam en paswoord.

In HTTP_FORBIDDEN.html.var en HTTP_NOT_FOUND.html.var zijn geen wijzigingen aangebracht.

Naar index

Awstats en Access-logs

AWStats is een krachtig tool met veel opties voor grafische webserver rapportage. Het rapportageprogramma voor de webserver analyseert uw webserver logbestanden. Deze genereert daarna voor elke (virtuele) website uitgebreide statistieken over bezoek daarvan.

Access Logbestanden

De AWSTATS statistieken zijn per default gebaseerd op de Apache access_logs van de gehele webroot 'var/www/html/'.
Om statistieken te kunnen produceren van specieke websites, zoals de piwigo fotogalerie en de wordpress blog welke zich als subdirectories in de webroot bevinden, zal er eerst gezorgd moeten worden voor access_logs met alleen data voor deze specifieke sites.

In de Virtuele Host configuraties moeten hiervoor directives geplaats worden om de specifieke accesslogs te maken.
In zowel de Virtuele Host configuratie 000-mysite80.conf als 001-mysite443.conf moeten de volgende directives opgenomen worden:

# Custom Access logs voor Awstats---------------------------------
CustomLog ${APACHE_LOG_DIR}/piwigo_access.log combined env=piwigo
CustomLog ${APACHE_LOG_DIR}/blog_access.log combined env=blog
# Aanvullende SETENVIF's in Awstats.conf---------------------------

In combinatie met bovenstaande directives worde in onderstaande Awstat configuratie aanvullende Access log directives geplaatst

# Access_Logs: Zet 'env' voor paden 'piwigo' en 'blog' vanuit
# de webroot en geef deze env's een alias (piwigo en blog)
# --------------------------------------------------------------------
SetEnvIf Request_URI "^/piwigo/" piwigo
CustomLog ${APACHE_LOG_DIR}/piwigo_access.log combined env=piwigo
SetEnvIf Request_URI "^/blog/" blog
CustomLog ${APACHE_LOG_DIR}/blog_access.log combined env=blog

Naar index

Geef Awstats user www-data toegang tot de accesslogs

Van de Apache2 access-logs worden de permissies gezet naar rw-r----- 1 root adm
Dit houdt in dat de Apache2 app Awstats user en groep www-data geen toegang heeft tot de access logs.

Dit is op te lossen door een Access Control List (ACL) voor /var/log/apache2 aan te maken.
Hiermee kunnen we een permissie toevoegen aan de bestaande permissies en geven we de user www-data read access naar alle bestanden in de map /var/log/apache2

# Installeer ACL
root@homeserver:~# apt install acl

# Maak Access Control List voor /var/log/apache2
root@homeserver:~# setfacl -R -m "u:www-data:rx" /var/log/apache2/

root@homeserver:~# getfacl /var/log/apache2
getfacl: Removing leading '/' from absolute path names
# file: var/log/apache2
# owner: root
# group: adm
user::rwx
user:www-data:r-x

Naar index

Logrotate en ACL (Access Control List)

Bij elke logrotate wordt er een nieuw leeg logbestand gemaakt, echter opnieuw met de beperkte permissies voor alleen user root en de admin groep.
Dus hier moet opnieuw een ACL toegevoegd worden.

Hiervoor is een edit nodig in het logrotatebestand /etc/logrotate.d/apache2 en voegen we onder 'postrotate' de SETFACL regel toe:

/var/log/apache2/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then
                        run-parts /etc/logrotate.d/httpd-prerotate
                fi
        endscript
        postrotate
                if pgrep -f ^/usr/sbin/apache2 > /dev/null; then
                        invoke-rc.d apache2 reload 2>&1 | logger -t apache2.logrotate
                fi
                /usr/bin/setfacl -R -m "u:www-data:rx" /var/log/apache2/*.log
        endscript
}

Naar index

Installatie

AWStats wordt in de Ubuntu Server repository meegeleverd.

root@testserver:~# apt update
root@testserver:~# apt upgrade

root@testserver:~# apt-get install awstats
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
awstats is already the newest version (7.9-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 

Naar index

Apache2 Configuratie

Indien nog niet gebeurd, moet nu eerst de CGI/CGID module geactiveerd worden

root@testserver:~# a2enmod cgi
Enabling module cgi.
To activate the new configuration, you need to run:
  systemctl restart apache2
root@testserver:~# systemctl restart apache2

Maak awstats.conf configuratiebestand in /etc/apache2/conf-available met de volgende inhoud:

# Directives to add to your Apache conf file to allow
         use of AWStats as a CGI.
# Note that path "/usr/share/awstats/" must reflect
         your AWStats install path.
#
# AWStats configuration
Alias /awstatsclasses "/usr/share/awstats/lib/"
Alias /awstats-icon "/usr/share/awstats/icon/"
Alias /awstatscss "/usr/share/doc/awstats/examples/css"
ScriptAlias /awstats/ "/usr/lib/cgi-bin/"
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

<Directory “/usr/lib/cgi-bin/”>
    Options None
    AllowOverride None
    <IfModule mod_authz_core.c>
        # Apache 2.4
        Require ip 192.168.178.0/24
    </IfModule>
    <IfModule !mod_authz_core.c>
        # Apache 2.2
        Order allow,deny
        Allow from 192.168.178.0/24
    </IfModule>
</Directory>

# Access_Logs: Zet 'env' voor paden 'piwigo' en 'blog' vanuit
# de webroot en geef deze env's een alias (piwigo en blog)
# --------------------------------------------------------------------
SetEnvIf Request_URI "^/piwigo/" piwigo
CustomLog ${APACHE_LOG_DIR}/piwigo_access.log combined env=piwigo
SetEnvIf Request_URI "^/blog/" blog
CustomLog ${APACHE_LOG_DIR}/blog_access.log combined env=blog

Met de directives in <Directory “/usr/lib/cgi-bin/”> wordt de toegang beperkt tot het thuisnetwerk

Activeer awstats.conf

root@testserver:~# a2enconf awstats

root@testserver:~# systemctl restart apache2 

Naar index

Awstats Sites Configuratie

  1. awstats.makkink.eu.conf
    Voor elke site op de webserver maken we nu een configuratie aan, om te beginnen de gehele webserver.
    Voer volgende commando's uit:
    # cp -a /ect/awstats/awstats-template.conf awstats.makkink.eu.conf

    Edit awstats.makkink.eu.conf en maak de volgende instellingen:
    LogFile="/var/log/apache2/access.log"
    Sitedomain="makkink.eu"
    HostAliases="makkink.eu www.makkink.eu localhost 127.0.0.1"

    Laat de rest zoals het is en voer uit: # systemctl restart apache2

  2. awstats.piwigo.conf
    Statistieken van de webpagina's van 'Piwigo'
    Voer volgende commando's uit:
    cp -a /ect/awstats/awstats-template.conf awstats.piwigo.conf

    Edit awstats.piwigo.conf en maak de volgende instellingen:
    LogFile="/var/log/apache2/piwigo_access.log"
    Sitedomain="piwigo"
    HostAliases="makkink.eu www.makkink.eu localhost 127.0.0.1"

    Laat de rest zoals het is en voer uit: # systemctl restart apache2

  3. awstats.blog.conf
    Statistieken van de webpagina's van 'blog' (Dopheide)
    Voer volgende commando's uit:
    cp -a /ect/awstats/awstats-template.conf awstats.piwigo.conf

    Edit awstats.blog.conf en maak de volgende instellingen:
    LogFile="/var/log/apache2/blog_access.log"
    Sitedomain="blog"
    HostAliases="makkink.eu www.makkink.eu localhost 127.0.0.1"

    Laat de rest zoals het is en voer uit: # systemctl restart apache2

Naar index

Data updaten en opslaan

Bij de installatie met APT plaatst AWSTATS ook een cron in /etc/cron.d/awstats:

MAILTO=root
# elke 10 minuten update
*/10 * * * * www-data [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh

# Generate static reports:
10 03 * * * www-data [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh

Met deze cron maakt Awstats elke 10 minuten een updata voor de statistieken
De data die met de update gecreëerd worden worden in /var/lib/awstats/ toegevoegd aan de bestanden met een naam in het formaat: awstats122015.makkink.eu.txt
Elke maand wordt door de cron van elke site een nieuw bestand aangemaakt. Door het deleten van deze txt bestanden worden de statistieken gereset. Door ze vanuit een backup terug te zetten kunnen historische data getoond worden.

Behalve met de cron, kan een update ook gestart worden aan de prompt door één van onderstaande commando's:

Naar index

Statistieken bekijken in de browser

Om de statistieken in de browser te bekijken voeren we één van onderstaande URL's in:

Naar index

Crawlers en Robots.txt

Het Robots Exclusion Protocol of robots.txt protocol is een conventie om (delen) van een normaal toegankelijke website af te schermen voor bepaalde webspiders en zoekrobots. Dit wordt met name gebruikt om te voorkomen dat (delen van) een website ongevraagd automatisch wordt gekopieerd en bijvoorbeeld daarmee wordt opgenomen in zoekresultaten van zoekmachines.

Het protocol maakt gebruik van het 'robots.txt' bestand, dat in de rootdirectory van een website wordt gezet. Als alternatief voor dit speciale bestand kan in bestaande HTML-bestanden middels HTML-tag Meta het attribuut "robots" worden opgenomen.

Het protocol dient echter alleen ter advies en gaat uit van medewerking van de bezoekende webrobot. Het kan dus niet daadwerkelijk de toegang tot bestanden en mappen ontzeggen en is daarmee ongeschikt om (delen van) een website af te schermen. Het protocol is dan ook voornamelijk bedoeld om gegevens die irrelevant zijn voor bezoekers niet weer te geven in de zoekresultaten van zoekmachines.

Zie ook:
http://nl.wikipedia.org/wiki/Robots_Exclusion_Protocol

Procedure voor mijn testserver:

Naar index