OpenSSH-Client – Kurzanleitung

Veröffentlichung 3. August 2018 @ 17:34
Letzte Änderung 29. August 2018 @ 10:58

Überblick

  • Ed25519-Schlüssel für möglichst sicheren Zugang
  • Ed25519-Schlüssel ohne Passphrase, z. B. für unbeaufsichtigtes Backup
  • RSA-Schlüssel für kompatiblen Zugang, z. B. für Eclipse
  • Hostspezifische SSH-Client-Konfiguration

Voraussetzungen

Client client.example.com

  • Benutzerkonto clientuser
  • Client-Schlüssel /home/clientuser/.ssh/id_*
  • Host-Schlüssel /home/clientuser/.ssh/known_hosts
  • Konfiguration /etc/ssh/ssh_config, /root/.ssh/config

Host host.example.com

  • Benutzerkonto hostuser
  • Client-Schlüssel /home/hostuser/.ssh/authorized_keys
  • Host-Schlüssel /etc/ssh/ssh_host_*
  • IP-Adresse x.x.x.x
  • SSH-Port 42022

Software

  • OpenSSH 7.2, OpenSSL 1.0.2g #ssh -V
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ed25519-SSH-Schlüssel mit Passphrase generieren und auf entferntem Host speichern

SSH-Schlüsselpaar mit Authentifizierungs-Algorithmus Ed25519 erzeugen

ssh-keygen -t ed25519 #keine Option -b, da immer 256 bit
  Generating public/private ed25519 key pair.
  Enter file in which to save the key (/home/clientuser/.ssh/id_ed25519): <Enter>
  Enter passphrase (empty for no passphrase): ***
  Enter same passphrase again: ***
  ...

Öffentlichen Schlüssel in Datei authorized_keys auf Host speichern

ssh-copy-id -i /home/clientuser/.ssh/id_ed25519 -p 42022 hostuser@host.example.com #nur bei SSH-Server mit Passwort-Authentifizierung

[Optional] Öffentlichen Schlüssel aus Datei authorized_keys auf Host löschen

ssh -i /home/clientuser/.ssh/id_ed25519 -p 42022 hostuser@host.example.com 'sed --in-place "/^ssh-ed25519.*clientuser@client.example.com$/d" /home/hostuser/.ssh/authorized_keys'

[Optional] Ed25519-SSH-Schlüssel ohne Passphrase generieren

SSH-Schlüsselpaar mit Authentifizierungs-Algorithmus Ed25519 erzeugen

ssh-keygen -C clientuser@client.example.com_ppl -f /home/clientuser/.ssh/id_ed25519_ppl -N '' -t ed25519 #Endung ppl für passphraseless
  Generating public/private ed25519 key pair.
  ...

Öffentlichen Schlüssel in Datei authorized_keys auf Host speichern

ssh-copy-id -i /home/clientuser/.ssh/id_ed25519_ppl -p 42022 hostuser@host.example.com

[Optional] Öffentlichen Schlüssel aus Datei authorized_keys auf Host löschen

ssh -i /home/clientuser/.ssh/id_ed25519_ppl -p 42022 hostuser@host.example.com 'sed --in-place "/^ssh-ed25519.*clientuser@client.example.com_ppl$/d" /home/hostuser/.ssh/authorized_keys'

[Optional] RSA-SSH-Schlüssel mit Passphrase generieren und auf entferntem Host speichern

SSH-Schlüsselpaar mit Authentifizierungs-Algorithmus RSA mit Schlüssellänge 4096 Bits erzeugen

ssh-keygen -b 4096 -t rsa
  Generating public/private rsa key pair.
  Enter file in which to save the key (/home/clientuser/.ssh/id_rsa): <Enter>
  Enter passphrase (empty for no passphrase): ***
  Enter same passphrase again: ***
  ...

Öffentlichen Schlüssel in Datei authorized_keys auf Host speichern

ssh-copy-id -i /home/clientuser/.ssh/id_rsa -p 42022 hostuser@host.example.com

[Optional] Öffentlichen Schlüssel aus Datei authorized_keys auf Host löschen

ssh -i /home/clientuser/.ssh/id_rsa -p 42022 hostuser@host.example.com 'sed --in-place "/^ssh-rsa.*clientuser@client.example.com$/d" /home/hostuser/.ssh/authorized_keys'

SSH-Client für individuellen Zugriff auf entfernte Hosts konfigurieren und testen

Einstellungen in globaler SSH-Client-Konfigurationsdatei auskommentieren

...
#Host *
...
#SendEnv LANG LC_*
#HashKnownHosts yes
#GSSAPIAuthentication yes
#GSSAPIDelegateCredentials no

Öffentliche Host-Schlüssel abfragen

ssh-keyscan -p 42022 host.example.com
  ...
  [host.example.com]:42022 ssh-ed25519 xxx

Benutzerspezifische SSH-Client-Konfigurationsdatei für möglichst sicheren Zugang anlegen und Zugriffsrechte einschränken

#Einstellungen für alle Hosts:
Host *
  #sicherste symmetrische Chiffre mit Authentizierung und Integritätsprüfung gemäß ssh -Q cipher-auth
  #=> kein Eintrag für MACs erforderlich:  
  Ciphers chacha20-poly1305@openssh.com
  #Einträge in known_hosts-Datei als Hashwerte speichern:
  HashKnownHosts yes
  #sicherster Schlüsselaustausch-Algorithmus gemäß ssh -Q kex:
  KexAlgorithms curve25519-sha256@libssh.org
  #keine Passwort-Authentifizierung:
  PasswordAuthentication no
#Einstellungen für Host host.example.com: 
Host example
  #sicherster Host-Authentifizierungs-Algorithmus gemäß ssh-keyscan -p 42022 host.example.com:
  HostKeyAlgorithms ssh-ed25519
  #Name:
  HostName host.example.com
  #Private Schlüsseldatei entsprechend HostKeyAlgorithms:
  IdentityFile ~/.ssh/id_ed25519
  #geänderter Standard-Port für Security through obscurity:
  Port 42022
  #Benutzer:
  User hostuser
chmod 0600 /home/clientuser/.ssh/config

SSH-Zugriff auf Host testen

ssh example
  The authenticity of host '[host.example.com]:42022 ([x.x.x.x]:42022)' can't be established.
  ED25519 key fingerprint is xxx.
  Are you sure you want to continue connecting (yes/no)? yes
  Warning: Permanently added '[host.example.com]:42022,[x.x.x.x]:42022' (ED25519) to the list of known hosts.

[Optional] Host-Schlüssel aus known_hosts löschen

Schlüssel für Host-FQDN entfernen

ssh-keygen -R [host.example.com]:42022
  Host [host.example.com]:42022 found: line 1
  /home/clientuser/.ssh/known_hosts updated.
  Original contents retained as /home/clientuser/.ssh/known_hosts.old

Schlüssel für Host-IP entfernen

ssh-keygen -R [x.x.x.x]:42022
  Host [x.x.x.x]:42022 found: line 1
  /home/clientuser/.ssh/known_hosts updated.
  Original contents retained as /home/clientuser/.ssh/known_hosts.old

Quellen

https://infosec.mozilla.org/guidelines/openssh
https://man.openbsd.org/ssh
https://man.openbsd.org/ssh-keygen
https://man.openbsd.org/ssh-keyscan
http://manpages.ubuntu.com/manpages/xenial/man1/ssh-copy-id.1.html
http://manpages.ubuntu.com/manpages/xenial/man5/ssh_config.5.html
https://stribika.github.io/2015/01/04/secure-secure-shell.html
https://www.openssh.com/manual.html
https://www.openssh.com/specs.html

Logrotate-Konfigurations-Skript – Kurzanleitung

Veröffentlichung 3. August 2018 @ 15:27
Letzte Änderung 29. August 2018 @ 10:58

Überblick

  • Erzeugen von Logrotate-Konfigurationsdateien

Voraussetzungen

Netzwerk

  • Benutzer root

Software

  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Konfiguration /etc/logrotate.d/example
  • Log /root/logs/example.log*
  • Skript /root/scripts/create_logrotate.sh

Bash-Skript zum Anlegen von Logrotate-Konfigurationsdateien erstellen

Logrotate-Skript anlegen

#!/bin/bash
LOGFILE=$1 #Logdatei
CONFIGFILE=$2 #Konfigurationsdatei
CONFIGDIR=/etc/logrotate.d #Konfigurationsverzeichnis
rm --force $CONFIGDIR/$CONFIGFILE
touch $CONFIGDIR/$CONFIGFILE
echo "$LOGFILE {" >> $CONFIGDIR/$CONFIGFILE
echo "  daily" >> $CONFIGDIR/$CONFIGFILE
echo "  missingok" >> $CONFIGDIR/$CONFIGFILE
echo "  nocompress" >> $CONFIGDIR/$CONFIGFILE
echo "  notifempty" >> $CONFIGDIR/$CONFIGFILE
echo "  rotate 7" >> $CONFIGDIR/$CONFIGFILE
echo "}" >> $CONFIGDIR/$CONFIGFILE

Zugriffsrechte anpassen

chmod 0700 /root/scripts/create_logrotate.sh

Beispiel

Logdatei /root/log/example.log rotieren

/root/scripts/create_logrotate.sh /root/logs/example.log example

Quellen

http://manpages.ubuntu.com/manpages/xenial/man8/logrotate.8.html
https://www.gnu.org/software/bash/manual/

Verzeichnis-Backup-Skript – Kurzanleitung

Veröffentlichung 3. August 2018 @ 12:56
Letzte Änderung 6. September 2018 @ 10:10

Überblick

  • Lokale Sicherung von Verzeichnissen
  • Automatisches Löschen alter Backup-Dateien

Voraussetzungen

Netzwerk

  • Benutzer root
  • Verzeichnis /root/example

Software

  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Backup /root/backup/example.tar.gz, /root/backup/example/example*.tar.gz
  • Skript /root/scripts/backup_directory.sh

Bash-Skript zur lokalen Sicherung von Verzeichnissen erstellen

Backup-Skript anlegen

DIRECTORY=$1 #Verzeichnisname
BACKUPNAME=$2 #Backup-Name
BACKUPDIR=$3 #Backup-Hauptverzeichnis
USERGROUP=$4 #Benutzer und Gruppe der Backup-Datei
BACKUPMAXAGE=$5 #maximales Alter der Backup-Dateien in Tagen
DATETIME="$(date +%Y-%m-%d-%H-%M-%S)" #aktuelles Datum und aktuelle Uhrzeit
if [ ! -d "$BACKUPDIR/$BACKUPNAME" ]; then
  mkdir --mode=0700 $BACKUPDIR/$BACKUPNAME
  chown $USERGROUP:$USERGROUP $BACKUPDIR/$BACKUPNAME
fi
find $BACKUPDIR/$BACKUPNAME -mtime +$BACKUPMAXAGE -name "$BACKUPNAME-*.tar.gz" -type f -exec rm {} \;
#Verzeichnis mit allen Unterverzeichnissen, die nicht Datei CACHEDIR.TAG enthalten, sichern
tar --create --directory=/ --exclude-caches --file=$BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.tar.gz --gzip ${DIRECTORY:1}/
ln -fs $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.tar.gz $BACKUPDIR/$BACKUPNAME.tar.gz
chown -h $USERGROUP:$USERGROUP $BACKUPDIR/$BACKUPNAME/$BACKUPNME-$DATETIME.tar.gz $BACKUPDIR/$BACKUPNAME.tar.gz
chmod 0600 $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.tar.gz

Zugriffsrechte anpassen

chmod 0700 /root/scripts/backup_directory.sh

Beispiel

Verzeichnis /root/example sichern

/root/scripts/backup_directory.sh /root/example example /root/backup root 30

Aktuelles Verzeichnis-Backup rücksichern

tar --directory=/ --extract --file=/root/backup/example.tar.gz --gzip

Quellen

http://www.bford.info/cachedir/
https://www.gnu.org/software/bash/manual/
https://www.gnu.org/software/tar/manual/

MySQL-Backup-Skript – Kurzanleitung

Veröffentlichung 3. August 2018 @ 12:28
Letzte Änderung 29. August 2018 @ 10:59

Überblick

  • Lokale Sicherung von MySQL-Datenbanken
  • Automatisches Löschen alter Backup-Dateien

Voraussetzungen

Netzwerk

  • Benutzer root
  • Datenbank example
  • MySQL-Benutzer root

Software

  • MySQL 5.7.22 #mysql –version
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Backup /root/backup/example.sql, /root/backup/example/example*.sql
  • Konfiguration /root/.my.cnf
  • Skript /root/scripts/backup_database.sh

MySQL-Konfigurationsdatei für Skriptausführung ohne Passwortabfrage anlegen

Konfigurationsdatei erstellen

[client]
user=root
password=***

Zugriffsrechte anpassen

chmod 0600 /root/.my.cnf

Bash-Skript zur lokalen Sicherung von MySQL-Datenbanken erstellen

Backup-Skript anlegen

#!/bin/bash
DATABASE=$1 #Datenbankname
BACKUPNAME=$2 #Backup-Name
BACKUPDIR=$3 #Backup-Hauptverzeichnis
OPTIONFILE=$4 #MySQL-Optionsdatei
USERGROUP=$5 #Benutzer und Gruppe der Backup-Datei
BACKUPMAXAGE=$6 #maximales Alter der Backup-Dateien in Tagen
DATETIME="$(date +%Y-%m-%d-%H-%M-%S)"
if [ ! -d "$BACKUPDIR/$BACKUPNAME" ]; then
  mkdir --mode=0700 $BACKUPDIR/$BACKUPNAME
  chown $USERGROUP:$USERGROUP $BACKUPDIR/$BACKUPNAME
fi
find $BACKUPDIR/$BACKUPNAME -mtime +$BACKUPMAXAGE -name "$BACKUPNAME-*.sql" -type f -exec rm {} \;
mysqldump --defaults-extra-file=$OPTIONFILE $DATABASE > $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.sql
ln -fs $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.sql $BACKUPDIR/$BACKUPNAME.sql
chown -h $USERGROUP:$USERGROUP $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.sql $BACKUPDIR/$BACKUPNAME.sql
chmod 0600 $BACKUPDIR/$BACKUPNAME/$BACKUPNAME-$DATETIME.sql

Zugriffsrechte anpassen

chmod 0700 /root/scripts/backup_database.sh

Beispiel

Datenbank example sichern

/root/scripts/backup_database.sh example example /root/backup /root/.my.cnf root 30

Aktuelles Datenbank-Backup rücksichern

mysql --defaults-extra-file=/root/.my.cnf example < /root/backup/example.sql

Quellen

https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
https://dev.mysql.com/doc/refman/5.7/en/option-files.html
https://www.gnu.org/software/bash/manual/

PHP-FPM – Kurzanleitung

Veröffentlichung 31. Juli 2018 @ 16:01
Letzte Änderung 29. August 2018 @ 10:59

Übersicht

  • Apache Multi-Processing-Modul MPM event / worker mit mod_fast_fcgi im Allgemeinen performanter als MPM prefork mit mod_php
  • Individuelle PHP-Einstellungen für einzelne Websites durch unterschiedliche FPM-Pool-Konfigurationen möglich
  • Keine „Nebenwirkungen“ auf Sicherheit durch für andere Websites erforderliche PHP-Einstellungen, die nur global in php.ini gesetzt werden können, z. B. disable_functions

Voraussetzungen

Software

  • Apache 2.4.18 #apache2 -v
  • PHP 7.0.30 #php –version
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Konfiguration /etc/apache2/sites-available/example.conf, /etc/php/7.0/apache2/php.ini, /etc/php/7.0/fpm/pool.d/example.conf
  • Log /var/log/apache2/error.log, /var/log/apache2/error-example.log, /var/log/php7.0-fpm.log
  • Systemd /lib/systemd/system/php7.0-fpm.service

Apache / PHP von Multi-Processing-Modul MPM prefork mit mod_php auf MPM event / worker mit mod_fast_fcgi umstellen

FastCGI Process Manager PHP-FPM und Apache-Modul FastCGI installieren

apt install php7.0-fpm
#systemctl status php7.0-fpm.service
apt install libapache2-mod-fastcgi

Eigene PHP-Einstellungen in Apache-Konfiguration und php.ini-Datei finden

...
php_admin_flag xxx xxx
...
php_admin_value xxx xxx
...
php_flag xxx xxx
...
php_value xxx xxx
...
...
xxx = xxx
...

FPM-Pool-Konfigurationsdatei mit eigenem Socket anlegen, Konfiguration testen und PHP-FPM neustarten

[example]
...
listen = /run/php/php7.0-fpm-example.sock
...
php_admin_flag[xxx] = xxx
...
php_admin_value[xxx] = xxx
...
php_flag[xxx] = xxx
...
php_value[xxx] = xxx
...
php-fpm7.0 --test
systemctl reload php7.0-fpm
#systemctl status php7.0-fpm.service

Apache-Konfigurationsdatei anpassen

...
#PHP-Konfigurationsdirektiven deaktivieren:
#php_admin_flag xxx xxx
...
#php_admin_value xxx xxx
...
#php_flag xxx xxx
...
#php_value xxx xxx
...
#über Reverse-Proxy mit PHP-FPM-Pool verbinden:
<FilesMatch "\.php$">
  <If "-f %{REQUEST_FILENAME}">
    SetHandler "proxy:unix:/run/php/php7.0-fpm-example.sock|fcgi://localhost/"
  </If>
</FilesMatch>
#https://serverfault.com/questions/717481/how-can-i-fix-recurring-php-503-errors-on-my-apache-mod-proxy-fcgi-php-fpm-serve UDS does not currently support connection reuse:
#<Proxy "fcgi://localhost/" enablereuse=on max=10>
<Proxy "fcgi://localhost/">
</Proxy>
...

Apache-Module mpm_prefork und mod_php deaktivieren, mpm_event / mpm_worker, mod_proxy und mod_proxy_fcgi aktivieren

a2dismod mpm_prefork php7.0
a2enmod mpm_event proxy proxy_fcgi
#a2enmod mpm_worker proxy proxy_fcgi

Konfiguration testen und Apache neustarten

apache2ctl configtest
systemctl reload apache2 #nicht systemctl reload apache2, da MPM-Änderung
#systemctl status apache2.service

Logdateien analysieren

...
...
...

Apache / PHP von Multi-Processing-Modul MPM event / worker mit mod_fast_fcgi auf MPM prefork mit mod_php umstellen

Apache-Modul PHP installieren

apt install libapache2-mod-php7.0

Eigene PHP-Einstellungen in FPM-Pool-Konfigurationsdatei finden

...
php_admin_flag[xxx] = xxx
...
php_admin_value[xxx] = xxx
...
php_flag[xxx] = xxx
...
php_value[xxx] = xxx
...

Apache-Konfigurationsdatei anpassen

...
#PHP-Konfigurationsdirektiven (re)aktivieren:
php_admin_flag xxx xxx
...
php_admin_value xxx xxx
...
php_flag xxx xxx
...
php_value xxx xxx
...
#Verbinden mit PHP-FPM-Pool über Reverse-Proxy deaktivieren:
#<FilesMatch "\.php$">
#  <If "-f %{REQUEST_FILENAME}">
#    SetHandler "proxy:unix:/run/php/php7.0-fpm-example.sock|fcgi://localhost/"
#  </If>
#</FilesMatch>
##https://serverfault.com/questions/717481/how-can-i-fix-recurring-php-503-errors-on-my-apache-mod-proxy-fcgi-php-fpm-serve UDS does not currently support connection reuse:
##<Proxy "fcgi://localhost/" enablereuse=on max=10>
#<Proxy "fcgi://localhost/">
#</Proxy>
...

Apache-Module mpm_event / mpm_worker, mod_proxy und mod_proxy_fcgi deaktivieren, mpm_prefork und mod_php aktivieren

a2dismod mpm_event proxy proxy_fcgi
#a2dismod mpm_worker proxy proxy_fcgi
a2enmod mpm_prefork php7.0 

Konfiguration testen und Apache neustarten

apache2ctl configtest
systemctl reload apache2 #nicht systemctl reload apache2, da MPM-Änderung
#systemctl status apache2.service

Logdateien analysieren

...
...

Quellen

https://httpd.apache.org/
https://httpd.apache.org/docs/2.4/mod/event.html
https://httpd.apache.org/docs/2.4/mod/mpm_common.html
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
https://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html
https://httpd.apache.org/docs/2.4/mod/prefork.html
https://httpd.apache.org/docs/2.4/mod/worker.html
http://manpages.ubuntu.com/manpages/xenial/man8/php-fpm7.0.8.html
https://secure.php.net/manual/de/configuration.changes.modes.php
https://secure.php.net/manual/de/install.fpm.php
https://serverfault.com/questions/717481/how-can-i-fix-recurring-php-503-errors-on-my-apache-mod-proxy-fcgi-php-fpm-serve
https://wiki.apache.org/httpd/PHP-FPM

Apache – child pid exit signal Segmentation fault – Kurzanleitung

Veröffentlichung 16. Juli 2018 @ 17:38
Letzte Änderung 29. August 2018 @ 10:59

Überblick

  • Fehlermeldung in /var/log/apache2/error.log: [xxx] [core:notice] [pid xxx] AH00051: child pid xxx exit signal Segmentation fault (11), possible coredump in /etc/apache2
  • Fehlersuche in Core Dump mit GNU Project Debugger GDB
  • Kernel-Konfiguration für core_pattern in /proc/sys/kernel/core_pattern entspricht sysctl-Parameter kernel.core_pattern

Voraussetzungen

Software

  • Apache 2.4.18 #apache2 -v
  • GNU Project Debugger GDB 7.11.1 #gdb –version
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Konfiguration /etc/apache2/apache2.conf, /etc/init.d/apache2, /etc/sysctl.conf, /proc/sys/kernel/core_pattern
  • Log /tmp, /var/log/apache2/error.log

Verzeichnis für Core Dumps in Apache-Konfiguration hinterlegen

...
CoreDumpDirectory /tmp

Größenbegrenzung für Core Dumps vor Apache-Start aufheben

Apache-SysVinit-Skript ergänzen

...
do_start()
{
  ulimit -c unlimited #Größenbegrenzung für Core Dumps aufheben
...

systemd-Konfigurationsdateien neu laden und Units neu starten

systemctl daemon-reload

Aufbau der Core-Dump-Dateinamen festlegen

Format core-Programm-Hostname-PID-UID-GID-Zeitstempel

Temporär bis zum nächsten Neustart

echo "/tmp/core-%e-%h-%p-%u-%g-%t" > /proc/sys/kernel/core_pattern

Dauerhaft bei jedem Systemstart

...
kernel.core_pattern=/tmp/core-%e-%h-%p-%u-%g-%t
sysctl --load=/etc/sysctl.conf

Konfiguration testen, Apache neustarten und Status abfragen

apache2ctl configtest
systemctl restart apache2
systemctl status apache2.service

GNU Project Debugger GDB installieren

apt install gdb

Core Dump analysieren

gdb /usr/sbin/apache2 /tmp/core-xxx-xxx-xxx-xxx-xxx-xxx
  ...
  (gdb) bt full
  ...

Aufhebung der Größenbegrenzung für Core Dumps vor Apache-Start rückgängig machen und Apache neu starten

...
do_start()
{
  #ulimit -c unlimited #Größenbegrenzung für Core Dumps aufheben
...
systemctl daemon-reload
systemctl restart apache2

[Optional] Core-Dump-Dateien löschen

rm /tmp/core-*

Quellen

/usr/share/doc/apache2/README.backtrace
https://httpd.apache.org/
https://httpd.apache.org/dev/debugging.html#crashes
http://manpages.ubuntu.com/manpages/xenial/man5/core.5.html
http://manpages.ubuntu.com/manpages/xenial/man1/gdb.1.html
http://manpages.ubuntu.com/manpages/xenial/man8/sysctl.8.html
http://manpages.ubuntu.com/manpages/xenial/man5/sysctl.conf.5.html
https://support.plesk.com/hc/en-us/articles/213366549-How-to-trace-Apache-segmentation-fault-
https://www.gnu.org/software/gdb/

sessionclean – arithmetic expression: expecting primary: „/60“ – Kurzanleitung

Veröffentlichung 16. Juli 2018 @ 9:02
Letzte Änderung 29. August 2018 @ 10:59

Überblick

  • Fehlermeldung (per E-Mail) von Cron Daemon beim Aufruf von [ -x /usr/lib/php/sessionclean ] && /usr/lib/php/sessionclean: /usr/lib/php/sessionclean: 37: /usr/lib/php/sessionclean: arithmetic expression: expecting primary: "/60"
  • Fehler kann z. B. nach Ubuntu-Versionsupgrade oder bei Änderung der PHP-Session-Einstellungen auftreten

Voraussetzungen

Software

  • PHP 7.0.30 #php –version
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Konfiguration /usr/lib/php/sessionclean

sh-Skript sessionclean anpassen

...
if [ "$session_config" ]; then #bei Fehler /usr/lib/php/sessionclean: 37: /usr/lib/php/sessionclean: arithmetic expression: expecting primary: "/60"
  save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
  save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p')
  gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))

  if [ "$save_handler" = "files" -a -d "$save_path" ]; then
    proc_names="$proc_names $(echo "$proc_name" | sed -e "s,@VERSION@,$version,")";
    printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
  fi
fi #bei Fehler /usr/lib/php/sessionclean: 37: /usr/lib/php/sessionclean: arithmetic expression: expecting primary: "/60"
...

Quellen

https://alioth-lists-archive.debian.net/pipermail/pkg-php-maint/2015-April/014252.html

phpMyAdmin – Kurzanleitung

Veröffentlichung 15. Juli 2018 @ 19:30
Letzte Änderung 29. August 2018 @ 10:59

Überblick

  • Weboberfläche für MySQL-Datenbanken
  • Anpassung der php.ini-Datei für mod_php und der Default-Pool-Konfigurationsdatei für FPM
  • Version aus Januar 2016
  • Security through obscurity durch komplizierten Hostnamen und abweichenden HTTPS-Port
  • Wildcard-Zertifikat, damit Hostname nicht extern bekannt wird
  • (Zusätzliche) Absicherung über Apache-Basis-Authentifizierung mit kompliziertem Benutzernamen

Voraussetzungen

Netzwerk

  • Host GVkGRtuRO78oB75zxGT5.example.com
  • htpasswd-Benutzer X26gL3z71CeFOcUkd9Zm
  • MySQL-Datenbank phpmyadmin
  • MySQL-Benutzer pma
  • HTTPS-Port 42443

Software

  • Apache 2.4.18 #apache2 -v
  • MySQL 5.7.22 #mysql –version
  • PHP 7.0.30 #php –version
  • phpMyAdmin 4.5.4.1 #https://GVkGRtuRO78oB75zxGT5.example.com:42443
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Installation /usr/share/phpmyadmin, /var/lib/phpmyadmin
  • Konfiguration /etc/apache2/sites-available/phpmyadmin.conf, /etc/php/7.0/apache2/php.ini, /etc/php/7.0/fpm/pool.d/default.conf.disabled, /etc/php/7.0/fpm/pool.d/phpmyadmin.conf, /etc/phpmyadmin/
  • Log /var/log/apache2/access-phpmyadmin.log, /var/log/apache2/error-phpmyadmin.log, /var/log/php7.0-fpm.log
  • Zertifikate und Schlüssel /etc/letsencrypt/live/example.com/*.pem

phpMyAdmin installieren, Setup-Dateien löschen und Zugriffsrechte setzen

apt install phpmyadmin
  Webserver, die automatisch konfiguriert werden sollen: keiner
  Konfigurieren der Datenbank für phpmyadmin mit dbconfig-common? No
rm --recursive /usr/share/phpmyadmin/setup
chown --recursive www-data:www-data /usr/share/phpmyadmin

Konfigurationsspeicher einrichten

mysql --password --user=root
source /usr/share/phpmyadmin/sql/create_tables.sql
GRANT SELECT, INSERT, UPDATE, DELETE ON phpmyadmin.* TO 'pma'@'localhost' IDENTIFIED BY '***';

Virtuellen Host mit Basis-Authentifizierung einrichten

Hostnamen mit Passwortgenerator z. B. KeePass generieren

GVkGRtuRO78oB75zxGT5

Benutzerdatei für Basis-Authentifizierung geschützter Website-Bereiche anlegen / ergänzen

Benutzernamen mit Passwortgenerator z. B. KeePass generieren

X26gL3z71CeFOcUkd9Zm

Benutzerdatei mit bcrypt-Passwort-Hash neu erstellen / ergänzen

htpasswd -B -c /etc/apache2/.htpasswd X26gL3z71CeFOcUkd9Zm
#htpasswd -B /etc/apache2/.htpasswd X26gL3z71CeFOcUkd9Zm

Apache-Konfigurationsdatei anlegen

<VirtualHost *:42443>
  CustomLog ${APACHE_LOG_DIR}/access-phpmyadmin.log vhost_combined
  DocumentRoot /usr/share/phpmyadmin
  ErrorLog ${APACHE_LOG_DIR}/error-phpmyadmin.log
  #Firefox Web-Entwickler:
  Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
  ServerAdmin webmaster@example.com
  ServerName GVkGRtuRO78oB75zxGT5.example.com
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
  SSLEngine on
  <Directory /usr/share/phpmyadmin>
    AuthBasicProvider file
    AuthName "phpMyAdmin"
    AuthType Basic
    AuthUserFile /etc/apache2/.htpasswd
    #/var/log/apache2/error-phpmyadmin.log:
    Options FollowSymLinks
    #/var/log/apache2/error-phpmyadmin.log + GVkGRtuRO78oB75zxGT5.example.com:
    php_admin_value open_basedir /etc/phpmyadmin/:/usr/share/doc/phpmyadmin/:/usr/share/php/:/usr/share/phpmyadmin/:/var/lib/php/sessions/:/var/lib/phpmyadmin/
    Require valid-user
  </Directory>
</VirtualHost>

Konfiguration aktivieren

a2ensite phpmyadmin.conf

[Optional] FPM-Pool-Konfiguration aus Default-Konfiguration erstellen und virtuellen Host anpassen

FPM-Konfigurationsdatei anlegen

cp /etc/php/7.0/fpm/pool.d/default.conf.disabled /etc/php/7.0/fpm/pool.d/phpmyadmin.conf
;[default]
[phpmyadmin]
...
;listen = /run/php/php7.0-fpm-default.sock
listen = /run/php/php7.0-fpm-phpmyadmin.sock
...
;/var/log/apache2/error-phpmyadmin.log + GVkGRtuRO78oB75zxGT5.example.com:
;php_admin_value[open_basedir] = nonexistent
php_admin_value[open_basedir] = /etc/phpmyadmin/:/usr/share/doc/phpmyadmin/:/usr/share/php/:/usr/share/phpmyadmin/:/var/lib/php/sessions/:/var/lib/phpmyadmin/
...

Konfiguration testen und PHP-FPM neustarten

php-fpm7.0 --test
systemctl reload php7.0-fpm
#systemctl status php7.0-fpm.service

Apache-Konfigurationsdatei modifizieren

<VirtualHost *:42443>
  ...
  <Directory /usr/share/phpmyadmin>
    ...
    #php_admin_value open_basedir /etc/phpmyadmin/:/usr/share/doc/phpmyadmin/:/usr/share/php/:/usr/share/phpmyadmin/:/var/lib/php/sessions/:/var/lib/phpmyadmin
    ...
  </Directory>
  <FilesMatch "\.php$">
    <If "-f %{REQUEST_FILENAME}">
      SetHandler "proxy:unix:/run/php/php7.0-fpm-phpmyadmin.sock|fcgi://localhost/"
    </If>
  </FilesMatch>
  <Proxy "fcgi://localhost/" enablereuse=on max=10>
  </Proxy>
</VirtualHost>

PHP-Funktion php_uname freischalten

php.ini-Datei ändern

...
;phpMyAdmin nutzt php_uname
;disable_functions = ${disable_functions}openlog,php_uname,
disable_functions = ${disable_functions}openlog,
...

[Optional] FPM-Pool-Konfiguration ändern, Konfiguration testen und PHP-FPM neustarten

...
;phpMyAdmin nutzt php_uname
;php_admin_value[disable_functions] = openlog,php_uname,
php_admin_value[disable_functions] = openlog,
...
php-fpm7.0 --test
systemctl reload php7.0-fpm
#systemctl status php7.0-fpm.service

Konfiguration testen, Apache neustarten und Status abfragen

apache2ctl configtest
systemctl reload apache2
systemctl status apache2.service

[Optional] Zur Sicherheit Konfiguration deaktivieren und Apache neustarten

a2dissite phpmyadmin.conf
systemctl reload apache2

Quellen

https://docs.phpmyadmin.net/en/latest/setup.html
https://httpd.apache.org/
https://httpd.apache.org/docs/2.4/howto/auth.html
https://keepass.info/
http://manpages.ubuntu.com/manpages/xenial/man8/php-fpm7.0.8.html
https://secure.php.net/manual/de/install.fpm.php
https://wiki.apache.org/httpd/PHP-FPM
https://www.phpmyadmin.net

PhpSecInfo – Kurzanleitung

Veröffentlichung 15. Juli 2018 @ 14:12
Letzte Änderung 22. September 2018 @ 18:07

Überblick

  • Test der Ordnerzugriffsrechte, der aktivierten PHP-Funktionen, der PHP-Kern-Konfiguration und der Session-Einstellungen
  • Anpassung der php.ini-Datei für mod_php und der Default-Pool-Konfigurationsdatei für FPM
  • „Aktuelle“ Version aus Dezember 2016
  • Security through obscurity durch komplizierten Hostnamen und abweichenden HTTPS-Port
  • Wildcard-Zertifikat, damit Hostname nicht extern bekannt wird
  • (Zusätzliche) Absicherung über Apache-Basis-Authentifizierung mit kompliziertem Benutzernamen

Voraussetzungen

Netzwerk

  • Host GoqL6YYNukBQQnLHZmb1.example.com
  • htpasswd-Benutzer eByKKQBFhboZWZD68DAh
  • HTTPS-Port 42443

Software

  • Apache 2.4.18 #apache2 -v
  • Git 2.7.4 #git –version
  • PHP 7.0.30 #php –version
  • PhpSecInfo 2.0.2 #https://GoqL6YYNukBQQnLHZmb1.example.com:42443
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Installation /usr/share/phpsecinfo
  • Konfiguration /etc/apache2/sites-available/phpsecinfo.conf, /etc/php/7.0/apache2/php.ini, /etc/php/7.0/fpm/pool.d/default.conf.disabled, /etc/php/7.0/fpm/pool.d/phpsecinfo.conf
  • Log /var/log/apache2/access-phpsecinfo.log, /var/log/apache2/error-phpsecinfo.log, /var/log/php7.0-fpm.log
  • Zertifikate und Schlüssel /etc/letsencrypt/live/example.com/*.pem

Git installieren

apt install git

PhpSecInfo in Verzeichnis /usr/share/phpsecinfo herunterladen / aktualisieren und Zugriffsrechte setzen

git clone https://github.com/bigdeej/PhpSecInfo.git /usr/share/phpsecinfo
#git -C /usr/share/phpsecinfo pull origin master #Update
chown --recursive www-data:www-data /usr/share/phpsecinfo

Virtuellen Host mit Basis-Authentifizierung einrichten

Hostnamen mit Passwortgenerator z. B. KeePass generieren

GoqL6YYNukBQQnLHZmb1

Benutzerdatei für Basis-Authentifizierung geschützter Website-Bereiche anlegen / ergänzen

Benutzernamen mit Passwortgenerator z. B. KeePass generieren

eByKKQBFhboZWZD68DAh

Benutzerdatei mit bcrypt-Passwort-Hash neu erstellen / ergänzen

htpasswd -B -c /etc/apache2/.htpasswd eByKKQBFhboZWZD68DAh
#htpasswd -B /etc/apache2/.htpasswd eByKKQBFhboZWZD68DAh

Apache-Konfigurationsdatei anlegen

<VirtualHost *:42443>
  CustomLog ${APACHE_LOG_DIR}/access-phpsecinfo.log vhost_combined
  DocumentRoot /usr/share/phpsecinfo
  ErrorLog ${APACHE_LOG_DIR}/error-phpsecinfo.log
  #Firefox Web-Entwickler:
  Header always set Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'"
  ServerAdmin webmaster@example.com
  ServerName GoqL6YYNukBQQnLHZmb1.example.com
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
  SSLEngine on
  <Directory /usr/share/phpsecinfo>
    AuthBasicProvider file
    AuthName "PhpSecInfo"
    AuthType Basic
    AuthUserFile /etc/apache2/.htpasswd
    php_admin_value open_basedir /usr/share/phpsecinfo/
    Require valid-user
  </Directory>
</VirtualHost>

Konfiguration aktivieren

a2ensite phpsecinfo.conf

[Optional] FPM-Pool-Konfiguration aus Default-Konfiguration erstellen und virtuellen Host anpassen

FPM-Konfigurationsdatei anlegen

cp /etc/php/7.0/fpm/pool.d/default.conf.disabled /etc/php/7.0/fpm/pool.d/phpsecinfo.conf
;[default]
[phpsecinfo]
...
;listen = /run/php/php7.0-fpm-default.sock
listen = /run/php/php7.0-fpm-phpsecinfo.sock
...
;php_admin_value[open_basedir] = nonexistent
php_admin_value[open_basedir] = /usr/share/phpsecinfo/
...

Konfiguration testen und PHP-FPM neustarten

php-fpm7.0 --test
systemctl reload php7.0-fpm
#systemctl status php7.0-fpm.service

Apache-Konfigurationsdatei modifizieren

<VirtualHost *:42443>
  ...
  <Directory /usr/share/phpsecinfo>
    ...
    #php_admin_value open_basedir /usr/share/phpsecinfo/
    ...
  </Directory>
  <FilesMatch "\.php$">
    <If "-f %{REQUEST_FILENAME}">
      SetHandler "proxy:unix:/run/php/php7.0-fpm-phpsecinfo.sock|fcgi://localhost/"
    </If>
  </FilesMatch>
  <Proxy "fcgi://localhost/" enablereuse=on max=10>
  </Proxy>
</VirtualHost>

Konfiguration testen, Apache neustarten und Status abfragen

apache2ctl configtest
systemctl reload apache2
systemctl status apache2.service

PHP-Einstellungen (ggf. mehrfach) prüfen und anpassen

PhpSecInfo aufrufen

https://GoqL6YYNukBQQnLHZmb1.example.com:42443
  ...

php.ini-Datei ändern

...
;;;PhpSecInfo
disable_functions = ${disable_functions}apache_setenv,
disable_functions = ${disable_functions}escapeshellarg,escapeshellcmd,
disable_functions = ${disable_functions}ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,
disable_functions = ${disable_functions}highlight_file,
disable_functions = ${disable_functions}ini_alter,ini_get_all,ini_restore,
disable_functions = ${disable_functions}openlog,php_uname,
disable_functions = ${disable_functions}posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_uname,
disable_functions = ${disable_functions}proc_close,proc_get_status,proc_nice,proc_terminate,
disable_functions = ${disable_functions}syslog,  

[Optional] FPM-Pool-Konfiguration ändern, Konfiguration testen und PHP-FPM neustarten

...
;;;PhpSecInfo
php_admin_value[disable_functions] = apache_setenv,
php_admin_value[disable_functions] = escapeshellarg,escapeshellcmd,
php_admin_value[disable_functions] = ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,
php_admin_value[disable_functions] = highlight_file,
php_admin_value[disable_functions] = ini_alter,ini_get_all,ini_restore,
php_admin_value[disable_functions] = openlog,php_uname,
php_admin_value[disable_functions] = posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_uname,
php_admin_value[disable_functions] = proc_close,proc_get_status,proc_nice,proc_terminate,
php_admin_value[disable_functions] = syslog,
php-fpm7.0 --test
systemctl reload php7.0-fpm
#systemctl status php7.0-fpm.service 

[Optional] Default-FPM-Pool-Konfiguration ändern

...
;;;PhpSecInfo
php_admin_value[disable_functions] = apache_setenv,
php_admin_value[disable_functions] = escapeshellarg,escapeshellcmd,
php_admin_value[disable_functions] = ftp_connect,ftp_exec,ftp_get,ftp_login,ftp_nb_fput,ftp_put,ftp_raw,ftp_rawlist,
php_admin_value[disable_functions] = highlight_file,
php_admin_value[disable_functions] = ini_alter,ini_get_all,ini_restore,
php_admin_value[disable_functions] = openlog,php_uname,
php_admin_value[disable_functions] = posix_getpwuid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_uname,
php_admin_value[disable_functions] = proc_close,proc_get_status,proc_nice,proc_terminate,
php_admin_value[disable_functions] = syslog,

Apache neustarten

systemctl reload apache2

Zur Sicherheit Konfiguration deaktivieren und Apache neustarten

a2dissite phpsecinfo.conf
systemctl reload apache2

Quellen

https://git-scm.com/docs
https://github.com/bigdeej/PhpSecInfo
https://httpd.apache.org/
https://httpd.apache.org/docs/2.4/howto/auth.html
https://keepass.info/
http://manpages.ubuntu.com/manpages/xenial/man8/php-fpm7.0.8.html
https://secure.php.net/manual/de/install.fpm.php
https://wiki.apache.org/httpd/PHP-FPM

PHP – Kurzanleitung

Veröffentlichung 10. Juli 2018 @ 18:03
Letzte Änderung 20. September 2018 @ 17:10

Übersicht

  • Konfigurationen für mod_php und FPM
  • Absicherung mit Scanner for PHP.ini Iniscan und PHP Secure Configuration Checker
  • Anlage einer Default-Pool-Konfigurationsdatei statt Anpassung der php.ini für FPM für mehr Flexibilität

Voraussetzungen

Software

  • Apache 2.4.18 #apache2 -v
  • Composer 1.0.0-beta2 #composer –version
  • Git 2.7.4 #git –version
  • PHP 7.0.30 #php –version
  • Ubuntu Server 16.04.04 LTS #lsb_release -a

Ordner und Dateien

  • Installation /usr/share/iniscan, /usr/share/pcc
  • Konfiguration /etc/php/7.0/apache2/php.ini, /etc/php/7.0/cli/php.ini, /etc/php/7.0/fpm/php.ini, /etc/php/7.0/fpm/pool.d/default.conf (/etc/php/7.0/fpm/pool.d/default.conf.disabled)
  • Log /var/log/php7.0-fpm.log
  • Systemd /lib/systemd/system/php7.0-fpm.service

PHP und Module FPM und MySQL installieren

apt install php7.0 php7.0-fpm php7.0-mysql
#systemctl status php7.0-fpm.service

Zeitzone festlegen

Apache

...
date.timezone = "Europe/Berlin"

Kommandozeile

...
date.timezone = "Europe/Berlin"

FPM

...
date.timezone = "Europe/Berlin"

Default-FPM-Pool-Konfigurationsdatei in Anlehnung an www.conf anlegen

[default]
group = www-data
listen = /run/php/php7.0-fpm-default.sock
listen.group = www-data
listen.owner = www-data
pm = dynamic
pm.max_children = 5
pm.max_spare_servers = 3
pm.min_spare_servers = 1
pm.start_servers = 2
user = www-data

PHP mit Scanner for PHP.ini Iniscan absichern

Composer installieren

apt install composer

Scanner for PHP.ini Iniscan in Verzeichnis /usr/share/iniscan herunterladen / aktualisieren

mkdir /usr/share/iniscan
cd /usr/share/iniscan && composer require psecio/iniscan
#cd /usr/share/iniscan && composer update psecio/iniscan #Update

php.ini-Datei für mod_php prüfen und anpassen

/usr/share/iniscan/vendor/bin/iniscan scan --path=/etc/php/7.0/apache2/php.ini
  ...
...
;;;Scanner for PHP.ini Iniscan
;Zugriff auf Remote-Dateien unterbinden, bei Bedarf in Apache-Website-Konfiguration freischalten
allow_url_fopen = 0
;sicherheitskritische PHP-Funktionen durch Erweiterung der ursprünglichen Liste ${disable_functions} deaktivieren, bei mod_php nur in php.ini möglich
disable_functions = ${disable_functions}curl_exec,curl_multi_exec,exec,passthru,popen,proc_open,shell_exec,system,
;PHP-Zugriff auf bestimmte(s) Verzeichniss(e) beschränken, durch "nonexistent" Fehlermeldung provozieren, in Apache-Website-Konfiguration definieren  
open_basedir = nonexistent
;wie in Voreinstellung Server-Hostname als Cookie-Domain verwenden, bei Bedarf in PHP oder Apache-Website-Konfiguration ändern
;session.cookie_domain =
;Session-Cookies ausschließlich über HTTP-Protokoll zugänglich machen 
session.cookie_httponly = 1
;Session-Cookies ausschließlich über sichere Verbindungen senden
session.cookie_secure = 1
;wie in Voreinstellung keinen Prüfsummen-Algorithmus zur Erzeugung der Session-ID festlegen, da ab PHP 7.1.0 nicht mehr verfügbar
;session.hash_function =
;wie in Voreinstellung "PHPSESSID" für Session-Cookie-Name "session.name" verwenden, bei Bedarf in PHP oder Apache-Website-Konfiguration ändern
;session.name = PHPSESSID
;ausschließlich Session-IDs akzeptieren, die initialisiert sind 
session.use_strict_mode = 1

php.ini-Datei für FPM prüfen und Default-FPM-Pool-Konfigurationdatei anpassen

/usr/share/iniscan/vendor/bin/iniscan scan --path=/etc/php/7.0/fpm/php.ini
  ...
...
;;;Scanner for PHP.ini Iniscan
;Zugriff auf Remote-Dateien unterbinden, bei Bedarf in separater FPM-Pool-Konfiguration freischalten
php_admin_value[allow_url_fopen] = 0
;sicherheitskritische PHP-Funktionen durch Erweiterung der ursprünglichen Liste disable_functions deaktivieren
php_admin_value[disable_functions] = curl_exec,curl_multi_exec,exec,passthru,popen,proc_open,shell_exec,system,
;PHP-Zugriff auf bestimmte(s) Verzeichniss(e) beschränken, durch "nonexistent" Fehlermeldung provozieren, in separater FPM-Pool-Konfiguration definieren
php_admin_value[open_basedir] = nonexistent
;wie in Voreinstellung Server-Hostname als Cookie-Domain verwenden, bei Bedarf in PHP oder separater FPM-Pool-Konfiguration ändern
;php_value[session.cookie_domain] =
;Session-Cookies ausschließlich über HTTP-Protokoll zugänglich machen 
php_admin_value[session.cookie_httponly] = 1
;Session-Cookies ausschließlich über sichere Verbindungen senden
php_admin_value[session.cookie_secure] = 1
;wie in Voreinstellung keinen Prüfsummen-Algorithmus zur Erzeugung der Session-ID festlegen, da ab PHP 7.1.0 nicht mehr verfügbar
;php_admin_value[session.hash_function] =
;wie in Voreinstellung "PHPSESSID" für Session-Cookie-Name verwenden, bei Bedarf in PHP oder separater FPM-Pool-Konfiguration ändern
;php_value[session.name] = PHPSESSID
;ausschließlich Session-IDs akzeptieren, die initialisiert sind
php_admin_value[session.use_strict_mode] = 1

PHP zusätzlich mit PHP Secure Configuration Checker absichern

Git installieren

apt install git

PHP Secure Configuration Checker in Verzeichnis /usr/share/pcc herunterladen / aktualisieren

git clone https://github.com/sektioneins/pcc.git /usr/share/pcc
#git -C /usr/share/pcc pull origin master #Update

php.ini-Datei für mod_php prüfen und anpassen

php -c /etc/php/7.0/apache2/php.ini /usr/share/pcc/phpconfigcheck.php
  ...
...
;;;PHP Secure Configuration Checker
;assert()-Auswertung deaktivieren
assert.active = 0
;sicherheitskritische PHP-Klassen durch Erweiterung der ursprünglichen Liste ${disable_classes} deaktivieren, todo
disable_classes = ${disable_classes}
;Datei-Uploads unterbinden, bei Bedarf in Apache-Website-Konfiguration freischalten
file_uploads = 0
;E-Mail-Header 'X-PHP-Originating-Script' unterdrücken
mail.add_x_header = 0
;wie in Voreinstellung maximale Laufzeit für PHP-Skript auf 30 s festlegen, Fehlalarm wegen "This directive is hardcoded to 0 for the CLI SAPI" in php.ini
max_execution_time = 30
;Upload-Verzeichnis festlegen, durch "nonexistent" Fehlermeldung provozieren, bei Bedarf in Apache-Website-Konfiguration definieren   
upload_tmp_dir = nonexistent

php.ini-Datei für FPM prüfen und Default-FPM-Pool-Konfigurationdatei anpassen

php -c /etc/php/7.0/fpm/php.ini /usr/share/pcc/phpconfigcheck.php
  ...
...
;;;PHP Secure Configuration Checker
;assert()-Auswertung deaktivieren
php_admin_value[assert.active] = 0
;sicherheitskritische PHP-Klassen durch Erweiterung der ursprünglichen Liste disable_classes deaktivieren, todo
php_admin_value[disable_classes] =
;Datei-Uploads unterbinden, bei Bedarf in separater FPM-Pool-Konfiguration freischalten
php_admin_value[file_uploads] = 0
;E-Mail-Header 'X-PHP-Originating-Script' unterdrücken
php_admin_value[mail.add_x_header] = 0
;wie in Voreinstellung maximale Laufzeit für PHP-Skript auf 30 s festlegen, Fehlalarm wegen "This directive is hardcoded to 0 for the CLI SAPI" in php.ini
php_admin_value[max_execution_time] = 30 
;Upload-Verzeichnis festlegen, durch "nonexistent" Fehlermeldung provozieren, bei Bedarf in separater FPM-Pool-Konfiguration definieren   
php_admin_value[upload_tmp_dir] = nonexistent

PHP-FPM und Apache neustarten

PHP-FPM-Konfiguration testen, PHP-FPM neustarten und Status abfragen

php-fpm7.0 --test
systemctl reload php7.0-fpm
systemctl status php7.0-fpm.service

Apache neustarten und Status abfragen

systemctl reload apache2
systemctl status apache2.service

[Optional] Default-FPM-Pool-Konfigurationdatei deaktivieren und PHP-FPM neustarten

mv /etc/php/7.0/fpm/pool.d/default.conf /etc/php/7.0/fpm/pool.d/default.conf.disabled
systemctl reload php7.0-fpm

Quellen

https://getcomposer.org/
https://git-scm.com/docs
https://github.com/psecio/iniscan
https://github.com/sektioneins/pcc
http://manpages.ubuntu.com/manpages/xenial/man8/php-fpm7.0.8.html
https://secure.php.net/manual/de/ini.php
https://secure.php.net/manual/de/install.fpm.php