Rocky www
Zur Navigation springen
Zur Suche springen
Installation
DATEN
| Parameter | Wert | Erläuterung |
|---|---|---|
| VM Name | www | Name der VM |
| Disk | 20GB | Vorgabe übernehmen |
| CPU | 4 Cores | Kerne |
| Ram | 4 GB | Speicher |
| Netzwerk (NIC) | DMZ | Interface-Zuweisung in VirtualBox |
| Admin | root | Passwort: radler |
| User | kit | Passwort: kit |
| IP | 10.88.2XX.11/24 | Statische IP |
| CIDR | 24 | Classless Inter-Domain Routing Präfixlänge |
| GW | 10.88.2XX.1 | GATEWAY |
| NS | 10.88.2XX.21 | Resolver |
| FQDN | www.it2XX.int | Fully Qualified Domain Name |
| DOM | it2XX.int | Domain Name |
Hostname
- hostnamectl set-hostname FQDN
Netzwerk
- nmcli con mod enp0s3 ipv4.addresses IP/CIDR
- nmcli con mod enp0s3 ipv4.gateway GW
- nmcli con mod enp0s3 ipv4.dns NS
- nmcli con mod enp0s3 ipv4.method manual
- nmcli con mod enp0s3 ipv4.dns-search DOM
- nmcli con mod enp0s3 connection.autoconnect yes
- nmcli con up enp0s3
Hintergrund
- Die Verbindungen findet ihr hier
- DIR: /etc/NetworkManager/system-connections/
- In unserem Fall
- cat /etc/NetworkManager/system-connections/enp0s3.nmconnection
[connection] id=enp0s3 uuid=40ff96e5-0c0d-31de-9bf0-f75da265425b type=ethernet autoconnect-priority=-999 interface-name=enp0s3 timestamp=1784278716 [ethernet] [ipv4] address1=192.168.3.127/24 dns=192.168.20.1; dns-search=it.int; gateway=192.168.3.254 method=manual [ipv6] addr-gen-mode=eui64 method=auto [proxy]
Apache Webserver auf Rocky Linux
Der Webserver läuft in der DMZ und stellt Webinhalte über HTTP und HTTPS bereit. HTTP-Anfragen werden automatisch auf HTTPS umgeleitet. Das Zertifikat kommt von web.samogo.de und liegt unter /etc/ssl/.
Installation
- dnf install -y httpd mod_ssl
Zertifikat holen
- get-cert.sh
PHP installieren
- PHP wird über das dnf-Modul installiert – so lässt sich später auch eine andere Version aktivieren
- dnf install -y php php-fpm php-mysqlnd php-json php-mbstring
- PHP-FPM starten – httpd übergibt PHP-Anfragen an diesen Prozess
- systemctl enable --now php-fpm
ℹ️ Hinweis:
- mod_php
- Läuft als Apache-Modul direkt im httpd-Prozess – jeder Apache-Worker hat einen eigenen PHP-Interpreter im Speicher, was bei prefork/MPM viel RAM frisst und PHP fest an Apache bindet.
- PHP-FPM
- Läuft als eigenständiger Prozess-Pool außerhalb von httpd, der über FastCGI (Unix-Socket oder TCP) angesprochen wird – dadurch kann Apache mit dem schlankeren event/worker-MPM laufen, PHP-Prozesse lassen sich unabhängig skalieren/neustarten, und derselbe FPM-Pool ist auch von nginx oder mehreren vhosts mit unterschiedlichen PHP-Versionen nutzbar.
VirtualHost konfigurieren
- Die mitgelieferte ssl.conf wird ersetzt mit dem notwendigsten
- echo Listen 443 https > /etc/httpd/conf.d/ssl.conf
- Die Welcome Seite wir vaborisiert
- rm /etc/httpd/conf.d/welcome.conf
- Wir legen unsere Seite an
- vi /etc/httpd/conf.d/www.conf
# HTTPS VirtualHost
<VirtualHost *:443>
ServerName www.it2XX.int
DocumentRoot /var/repo
SSLEngine on
SSLCertificateFile /etc/ssl/own.crt
SSLCertificateKeyFile /etc/ssl/own.key
<Directory /var/repo>
Options +Indexes
AllowOverride None
Require all granted
</Directory>
# PHP über FPM
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
ErrorLog /var/log/httpd/www.it2XX.int_error.log
CustomLog /var/log/httpd/www.it2XX.int_access.log combined
</VirtualHost>
Beispielseite
- Eine einfache PHP-Seite die den Hostnamen und die aktuelle Zeit anzeigt. /var/www/html ist die Standard-DocumentRoot von httpd – existiert bereits, kein eigenes Verzeichnis und kein eigener SELinux-Kontext nötig
- vi /var/repo/index.php
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Willkommen auf <?= gethostname() ?></title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 4em auto; }
h1 { color: #c0392b; }
p { color: #333; }
</style>
</head>
<body>
<h1>Willkommen auf <?= gethostname() ?></h1>
<p>Server: <strong><?= $_SERVER['SERVER_NAME'] ?></strong></p>
<p>Zeit: <strong><?= date('d.m.Y H:i:s') ?></strong></p>
<p>PHP: <strong><?= phpversion() ?></strong></p>
</body>
</html>
Konfiguration prüfen
- Syntaxfehler erkennen bevor httpd neu gestartet wird
- apachectl configtest
Syntax OK
Dienst Testweise starten
- systemctl restart httpd
SELinux
- SELinux läuft auf Rocky standardmäßig im enforcing-Modus. /var/www/html ist bereits korrekt mit httpd_sys_content_t gelabelt – nur die Zertifikate unter /etc/ssl brauchen einen eigenen Kontext
Fehleranalyse
- Falls der Zugriff trotzdem fehlschlägt – SELinux-Blockaden anzeigen
- ausearch -m avc -ts recent
Kontext setzen
- semanage fcontext -a -t httpd_sys_content_t "/etc/ssl/own\.(crt|key)"
- restorecon -Rv /etc/ssl/
- Kontext prüfen
- ls -Z /etc/ssl/own.crt /etc/ssl/own.key
Firewall
- HTTP und HTTPS auf dem www-Server freigeben
- firewall-cmd --permanent --zone=public --add-service=http
- firewall-cmd --permanent --zone=public --add-service=https
- firewall-cmd --reload
Test
- Im Browser aufrufen
Wir bekommen ein Forbidden
You don't have the permission to access this resource
Wieder zu Ausearch
- ausearch -m avc -ts recent
time->Tue Jul 7 23:59:32 2026
type=PROCTITLE msg=audit(1783461572.080:196): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
type=SYSCALL msg=audit(1783461572.080:196): arch=c000003e syscall=262 success=no exit=-13 a0=ffffff9c a1=7fb4c400bd08 a2=7fb4d1de37c0 a3=100 items=0 ppid=3347 pid=3350 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1783461572.080:196): avc: denied { getattr } for pid=3350 comm="httpd" path="/var/repo/index.html" dev="dm-0" ino=67781042 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0
- semanage fcontext -a -t httpd_sys_content_t "/var/repo(/.*)?"
- restorecon -Rv /var/repo
- Erklärung der Regex "/var/repo(/.*)?"
| Teil | Bedeutung |
|---|---|
/var/repo |
literaler, fester Text – muss genau so vorkommen |
( ) |
Gruppierung – fasst den eingeschlossenen Ausdruck zusammen |
/ |
literales Zeichen – ein fester Slash |
. |
beliebiges einzelnes Zeichen (Wildcard) |
* |
0 bis unendlich Wiederholungen des davorstehenden Elements (hier: .)
|
.* |
zusammen: beliebig viele beliebige Zeichen (auch keins) |
(/.*) |
Gruppe: ein / gefolgt von beliebig vielem Inhalt
|
? |
macht die davorstehende Gruppe optional (0 oder 1 mal) |
(/.*)? |
die ganze Gruppe "/ + beliebiger Inhalt" ist optional |
Matched:
/var/repo/var/repo//var/repo/index.html/var/repo/sub/dir/datei.txt(beliebige Tiefe)
Matched nicht:
/var/repository/var/repo2
Test
- Im Browser aufrufen
- Jetzt klappt es
Logs
- journalctl -fu httpd
- tail -f /var/log/httpd/www.it2XX.int_error.log
- tail -f /var/log/httpd/www.it2XX.int_access.log
- Zertifikat prüfen
- openssl s_client -connect www.it2XX.int:443 -showcerts