Server::Apache
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:
- Apache 2.4.58-1ubuntu8.5
- MariaDB 10.11.8
- PHP 8.3.6
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.
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
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
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
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 '{}' \;
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
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!
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
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
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
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
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
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
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(); ?>
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.
- Installeer PHP-Imagick.
root@testserver:~# apt install php-imagick
- 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]
- Reboot server (niet alleen apache) en verify met phpinfo()
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'.
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.
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:
- 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
- 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>
- Enable de site 002-mysite81.conf:
# a2ensite 002-mysite81
# systemctl restart apache2.service
- 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.
- phpMyAdmin is nu alleen op het thuisnetwerk beschikbaar met url: http://homeserver:81/phpmyadmin
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
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
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.
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)
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:
- authz_groupfile_module
- cgi_module
- include_module
- rewrite_module
- socache_shmcb_module
- 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
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
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
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
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
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
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
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>
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:
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>
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>
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>
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
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'
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>
Wordpress.Conf
Wordpress:
- is vrije weblog-software, die onder de voorwaarden van de GNU General Public License (GPL) wordt gepubliceerd.
- is ontwikkeld door Matthew Mullenweg, maar het wordt door een flinke groep ontwikkelaars ondersteund.
- is het meest gebruikte contentmanagementsysteem.
- maakt gebruik van de programmeertaal PHP. Alle content wordt opgeslagen in een MySQL-database.
- is een contentmanagementsysteem (CMS) waardoor de gebruiker op een relatief eenvoudige wijze de inhoud (content) kan wijzigen en/of aanvullen zonder dat daar technische kennis voor vereist is.
Zie de Wordpress pagina's voor installatie en configuratie.
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
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>
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:
- Als de wijziging samenging met een Wordpress update wordt de code van de gewijzigde .htacces vertrouwd en geintegreerd in /etc/apache2/conf-available/wordpress.conf
- Als er echter geen Wordpress update plaatsvond dan wordt de gewijzigde .htaccess code aangemerkt als een potentiële hack en moet Admin het .htaccess bestand eerst evalueren.
Admin ontvangt een e-mail met daarin de te volgen stappen. - Na evaluatie kan Admin de code accepteren door het laten integreren of weigeren waarna het nwe .htaccess vervangen wordt door het oude oorspronkelijke .htaccess bestand.
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
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
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>
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.
SSL Encryptie flowchart
- Browser verbind met een webserver (website) beveiligd met SSL (https). Browser verzoekt de server zich te identificeren.
- Server zendt een kopie van zijn SSL Certificaat, samen met de public-key van de server
- 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.
- 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.
- Server en Browser versleutelen nu alle verstuurde data met de gezamenlijke session-key
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.
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>
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.
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.
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.
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
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) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -
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>
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>
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
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:
- De 'include/top.html' waarin de pagina opgebouwd wordt met o.a de styles met backgroundcolor, background image etc.
- Nu wordt de Nederlandse tekst toegevoegd.
- 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.
- Dit wordt opnieuw gevolgd door een stuk Nederlandse tekst.
- 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
Personalisatie Layout
TOP.HTML
Zie hier de code van gewijzigde '/usr/share/apache2/error/include/top.html'
- Prepareer een achtergrond image naar wens van +/- 1700 x 1100 px en +/- 100-200 kB
Sla deze op op server in '/usr/share/apache2/error' met naam 'errormsg_backgr.jpg'
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'
- Prepareer een logo +/- 100 x 100 px 5-10 kB
Sla deze op op server in '/var/www/error' met naam 'logo.png'
<a href="/"><img src="/../error/logo.png" /></a><br />
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.
Awstats en Access-logs
![]() |
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
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
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 }
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.
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
Awstats Sites Configuratie
- 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
- 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
- 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
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:
- # /usr/lib/cgi-bin/awstats.pl -update -config=makkink.eu
- # /usr/lib/cgi-bin/awstats.pl -update -config=piwigo
- # /usr/lib/cgi-bin/awstats.pl -update -config=blog
Statistieken bekijken in de browser
Om de statistieken in de browser te bekijken voeren we één van onderstaande URL's in:
- https://homeserver/awstats/awstats.pl?config=makkink.eu
- https://homeserver/awstats/awstats.pl?config=piwigo
- https://homeserver/awstats/awstats.pl?config=blog
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:
- CD naar webroot /var/www/html
- maak tekstbestand robots.txt
- inhoud robots.txt:
User-agent:* # match all bots
Disallow: /archief/ # keep them out
Disallow: /piwigo/
Disallow: /manuals/
Allow: /