Apache Web Server

Apache Doku

https://httpd.apache.org/docs/2.4/mod/directives.html

Unter Debian liefern diese Pakete eine vollständige Apache Serverinstallation:

apache2						install
apache2-bin					install
apache2-data					install
apache2-doc					install
apache2-utils					install

Weitere abhängige Pakete (Module) können je nach Laufzeitumgebung (php, perl, java, ruby) und angeschlossener Datenbanken notwendig sein.

Beispiel Konfiguration: WordPress unverschlüsselt betreiben

Hier wird nur der lokale unverschlüsselten Port 80 und das http Protokoll benutzt. Die Datei /etc/apache2/sites-abailabe/000-default ist normalerweise vorinstalliert und braucht diese Syntax. Wichtig ist das DocumentRoot

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/wordpress

	# 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
</VirtualHost>

Beispiel Konfiguration: WordPress verschlüsselt mit lokalem ssl

Hier liegen root Zertifikat, Server Zertifikat und der Zertifikats-Schlüssel lokal auf dem Server. Die Zertifikats-Dateien werden durch den lokalen certbot Service von der letsencrypt Certificate Authority angefordert und vor Ablauf der 90-Tage Gültigkeit automatisch erneuert.

Man muss also zuerst letsencrypt certbot einrichten. Weitere Details siehe

<VirtualHost *:443>
	ServerAdmin webmaster@localhost

	DocumentRoot /var/www/html

	# 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

	#   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

	#   Server Certificate Chain:
	#   Point SSLCertificateChainFile at a file containing the
	#   concatenation of PEM encoded CA certificates which form the
	#   certificate chain for the server certificate. Alternatively
	#   the referenced file can be the same as SSLCertificateFile
	#   when the CA certificates are directly appended to the server
	#   certificate for convinience.
	#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt

	#   Certificate Authority (CA):
	#   Set the CA certificate verification path where to find CA
	#   certificates for client authentication or alternatively one
	#   huge file containing all of them (file must be PEM encoded)
	#   Note: Inside SSLCACertificatePath you need hash symlinks
	#         to point to the certificate files. Use the provided
	#         Makefile to update the hash symlinks after changes.
	#SSLCACertificatePath /etc/ssl/certs/
	#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt

	#   Certificate Revocation Lists (CRL):
	#   Set the CA revocation path where to find CA CRLs for client
	#   authentication or alternatively one huge file containing all
	#   of them (file must be PEM encoded)
	#   Note: Inside SSLCARevocationPath you need hash symlinks
	#         to point to the certificate files. Use the provided
	#         Makefile to update the hash symlinks after changes.
	#SSLCARevocationPath /etc/apache2/ssl.crl/
	#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl

	#   Client Authentication (Type):
	#   Client certificate verification type and depth.  Types are
	#   none, optional, require and optional_no_ca.  Depth is a
	#   number which specifies how deeply to verify the certificate
	#   issuer chain before deciding the certificate is not valid.
	#SSLVerifyClient require
	#SSLVerifyDepth  10

	#   SSL Engine Options:
	#   Set various options for the SSL engine.
	#   o FakeBasicAuth:
	#    Translate the client X.509 into a Basic Authorisation.  This means that
	#    the standard Auth/DBMAuth methods can be used for access control.  The
	#    user name is the `one line' version of the client's X.509 certificate.
	#    Note that no password is obtained from the user. Every entry in the user
	#    file needs this password: `xxj31ZMTZzkVA'.
	#   o ExportCertData:
	#    This exports two additional environment variables: SSL_CLIENT_CERT and
	#    SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
	#    server (always existing) and the client (only existing when client
	#    authentication is used). This can be used to import the certificates
	#    into CGI scripts.
	#   o StdEnvVars:
	#    This exports the standard SSL/TLS related `SSL_*' environment variables.
	#    Per default this exportation is switched off for performance reasons,
	#    because the extraction step is an expensive operation and is usually
	#    useless for serving static content. So one usually enables the
	#    exportation for CGI and SSI requests only.
	#   o OptRenegotiate:
	#    This enables optimized SSL connection renegotiation handling when SSL
	#    directives are used in per-directory context.
	#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
	<FilesMatch "\.(?:cgi|shtml|phtml|php)$">
		SSLOptions +StdEnvVars
	</FilesMatch>
	<Directory /usr/lib/cgi-bin>
		SSLOptions +StdEnvVars
	</Directory>

	#   SSL Protocol Adjustments:
	#   The safe and default but still SSL/TLS standard compliant shutdown
	#   approach is that mod_ssl sends the close notify alert but doesn't wait for
	#   the close notify alert from client. When you need a different shutdown
	#   approach you can use one of the following variables:
	#   o ssl-unclean-shutdown:
	#    This forces an unclean shutdown when the connection is closed, i.e. no
	#    SSL close notify alert is send or allowed to received.  This violates
	#    the SSL/TLS standard but is needed for some brain-dead browsers. Use
	#    this when you receive I/O errors because of the standard approach where
	#    mod_ssl sends the close notify alert.
	#   o ssl-accurate-shutdown:
	#    This forces an accurate shutdown when the connection is closed, i.e. a
	#    SSL close notify alert is send and mod_ssl waits for the close notify
	#    alert of the client. This is 100% SSL/TLS standard compliant, but in
	#    practice often causes hanging connections with brain-dead browsers. Use
	#    this only for browsers where you know that their SSL implementation
	#    works correctly.
	#   Notice: Most problems of broken clients are also related to the HTTP
	#   keep-alive facility, so you usually additionally want to disable
	#   keep-alive for those clients, too. Use variable "nokeepalive" for this.
	#   Similarly, one has to force some clients to use HTTP/1.0 to workaround
	#   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
	#   "force-response-1.0" for this.
	# BrowserMatch "MSIE [2-6]" \
	#	nokeepalive ssl-unclean-shutdown \
	#	downgrade-1.0 force-response-1.0

</VirtualHost>

Beispiel Konfiguration: WordPress hinter einem Reverse Proxy

Hier wird die ssl Verschlüsselung über einen Reverse Proxy zugeliefert und die interne Verbindung vom Reverse Proxy zum Server auf 10.10.10.30:81 ist unverschlüsselt. Das ist die typische Architektur für Web-DIenste in Rechenzentren.

<VirtualHost 10.10.10.30:81>

ServerName xxx.de
ServerAlias aliasxxx.de
ServerAdmin webmaster@xxxde

DocumentRoot /var/www/xxx.de

# rewrite rules
RewriteEngine on

# redirect owncloud requests to new address 
RewriteRule /owncloud/(.*)$ http://yyy.xxx.de/$1 [P,L]

# redirect old www URLs
Redirect 301 www.netzwissen.de/(.*)$ https://yyy.xxx.de/$1

# redirect database admin access 
Redirect 301 /phpmyadmin  https://yyy.xxx.de/phpmyadmin
Redirect 301 /phppgadmin  https://yyy.xxx.de/phppgadmin

# proxy to rspamd web UI on mail
RewriteRule ^/rspamd$ /rspamd/ [R]
ProxyPreserveHost On
ProxyPass /rspamd http://10.10.10.24:11334/
ProxyPassReverse /rspamd http://10.10.10.24:11334/

# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel crit
ErrorLog ${APACHE_LOG_DIR}/xxx-error.log
TransferLog ${APACHE_LOG_DIR}/xxx-access.log

<Directory />
	Options +FollowSymLinks
	AllowOverride None
</Directory>

<Directory /var/www/xxx.de>
	Options +Indexes +FollowSymLinks +MultiViews
	AllowOverride AuthConfig Indexes FileInfo
	Order deny,allow
	allow from all
</Directory>

## matomo settings
Alias /piwik /var/www/matomo
Alias /matomo /var/www/matomo
Alias /analyse /var/www/matomo

<Directory /var/www/matomo>
	DirectoryIndex index.php
	Options FollowSymLinks
	AllowOverride All
	<IfVersion < 2.4>
		Order allow,deny
		Allow from all
	</IfVersion>
	<IfVersion >= 2.4>
		Require all granted
	</IfVersion>
</Directory>

<Files "console">
	Options None
	<IfVersion < 2.4>
		Order allow,deny
		Deny from all
	</IfVersion>
	<IfVersion >= 2.4>
		Require all denied
	</IfVersion>
</Files>

<Directory /var/www/matomo/misc/user>
	Options None
	<IfVersion < 2.4>
		Order allow,deny
		Allow from all
	</IfVersion>
	<IfVersion >= 2.4>
		Require all granted
	</IfVersion>
</Directory>

<Directory /var/www/matomo/misc>
	Options None
	<IfVersion < 2.4>
		Order allow,deny
		Deny from all
	</IfVersion>
	<IfVersion >= 2.4>
		Require all denied
	</IfVersion>
</Directory>

<Directory /var/www/matomo/vendor>
	Options None
	<IfVersion < 2.4>
		Order allow,deny
		Deny from all
	</IfVersion>
	<IfVersion >= 2.4>
		Require all denied
	</IfVersion>
</Directory>

Alias /webmail /var/www/roundcube
<Directory /var/www/roundcube>
       DirectoryIndex index.php
       AllowOverride all
</Directory>

</VirtualHost>

Apache Rewrite rules

https forcieren

Redirect "/" "[https://www.miteinander-esslingen.de/](https://www.miteinander-esslingen.de/)"

canonical subdomain rewrite

Rewrite Engine on RewriteCond %{HTTP*HOST} !^www.* [NC] RewriteCond %{HTTP*HOST} ^owncloud.miteinander-esslingen.de$ RewriteRule ^(.*) [https://www.miteinander-esslingen.de/owncloud/](https://www.miteinander-esslingen.de/owncloud/) [L,QSA]

Header merging Content Security Policy

Mit mod_header

# CSP header merge for Conten-Security-Policy to allow embedding of OC contecnt 
        # into @netzwissen.de content
        # Reference: https://central.owncloud.org/t/iframe-embedding-problem-with-calendar-2-x/39489/8
        Header merge Content-Security-Policy "frame-ancestors 'self' https://netzwissen.de"
        Header edit* Content-Security-Policy , ;

Passt den CSP Header so an, dass das Einbetten von content aus ownCloud (cloud.netzwissen.de) in das CMS auf @netzwissen.de erlaubt ist: frame-ancestors ‚self‘ https://netzwissen.de

vorher

curl -I https://cloud.netzwissen.de/index.php/apps/calendar/embed/UG6ZAHSQ3FQCDAHI | grep content-security-policy

content-security-policy: default-src 'none';manifest-src 'self';script-src 'self' * 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self';

nachher

curl -I https://cloud.netzwissen.de/index.php/apps/calendar/embed/UG6ZAHSQ3FQCDAHI | grep content-security-policy

content-security-policy: default-src 'none';manifest-src 'self';script-src 'self' * 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'; frame-ancestors 'self' https://netzwissen.de'

Apache Benchmark Testing

Das Benchmark Tool ist Teil von apache2-utils

ab -n 100 -c 10 http://www.netzwissen.de/ '

Mit Authentikation:

ab2 -A auth-username:passwort -c 10 -n 100 http://www.netzwissen.de/gallery/main.php/v/thg82/

Apache Server Tuning

Quelle: http://www.woktron.com/secure/knowledgebase/133/How-to-optimize-Apache-performance.html

Apache.conf

To start, open the Apache configuration file and locate the directives section: If you are using nano, vi or vim: once you open the file, you can find the directives by scrolling through the file. Using VI or VIM you can also search by typing forward-slash ‘/’ and typing the exact string that you are looking for (search is case specific).

Timeout

The Timeout setting is the number of seconds before data „sends“ or „receives“ (to or from the client) time out. Having this set to a high number forces site visitors to „wait in line“ which adds extra load to the server. Lowering the ‘Timeout’ value too much will cause a long running script to terminate earlier than expected.

A reasonable value is 100 for Virtual Private Servers, or heavily loaded dedicated servers. For Dedicated Servers under normal load the default value of 300 is sufficient.

KeepAlive

KeepAlive enables persistent connections on the web server. This setting should be On unless the server is getting requests from hundreds of IPs at once. High volume and/or load balanced servers should have this setting disabled Off to increase connection throughput.

MaxKeepAliveRequests

This setting limits the number of requests allowed per persistent connection when KeepAlive is on. If it is set to 0, unlimited requests will be allowed. When using DirectAdmin, this directive can be found in: /etc/httpd/conf/extra/httpd-default.conf

It is recommended to keep this value at 100 for virtualized accounts like VPS accounts. On dedicated servers it is recommended that this value be modified to 150.

KeepAliveTimeout

The number of seconds Apache will wait for another request before closing the connection. Setting this to a high value may cause performance problems in heavily loaded servers. The higher the timeout, the more server processes will be kept occupied waiting on connections with idle clients. When using DirectAdmin, this directive can be found in: /etc/httpd/conf/extra/httpd-default.conf

The default value of 10 seconds is a good value for average server performance. This value should be kept low as the socket will be idle for extended periods otherwise.It is recommended that this value be lowered to 5 on servers under heavy load.

StartServers

sets the number of child server processes created on startup. As the number of processes is dynamically controlled depending on the load there is usually little reason to adjust this parameter. This value should mirror what is set in MinSpareServers.

MinSpareServers

Sets the desired minimum number of idle child server processes. An idle process is one which is not handling a request. If there are fewer spareservers idle then specified by this value, then the parent process creates new children at a maximum rate of 1 per second. Setting this parameter to a large number is almost always a bad idea.

Virtual Private Server 5 Dedicated server with 1-2GB RAM 10 Dedicated server with 2-4GB RAM 20 Dedicated server with 4+ GB RAM 25 `` MaxSpareServers

sets the desired maximum number of idle child server processes. An idle process is one which is not handling a request. If there are more than MaxSpareServers idle, then the parent process will kill off the excess processes.

ServerLimit

is only used if you need to set MaxClients higher than 256 (default). Do not set the value of this directive any higher than what you might want to set MaxClients to.

MaxClients

sets the limit on the number of simultaneous requests that will be served. Any connection attempts over the MaxClients limit will normally be queued, up to a number based on the ListenBacklog directive. Once a child process is freed at the end of a different request, the connection will then be serviced.

For non-threaded servers (i.e., prefork), MaxClients translates into the maximum number of child processes that will be launched to serve requests. The default value is 256; to increase it, you must also raise ServerLimit. this and ServerLimit should be the same or very close with MaxClients never exceeding ServerLimit. For servers under high load this value should be increased. See below for more information on how to define the maxclients directive.

How to define the MaxClients directive

A simple calculation for MaxClients would be: (Total Memory – Critical Services Memory) / Size Per Apache process. I define Critical Services as services such as mySQL, Plesk, DirectAdmin; any service that is required for proper operation of your server.

I’ve used the following commands via shell to determine values for Total Memory, OS Memory, MySQL Memory, and Apache Process Size

TOTAL MEMORY [root@vps httpd]# free -m total used free shared buffers cached Mem: 1002 599 402 0 28 337 -/+ buffers/cache: 233 769 Swap: 2047 124 1922 `` MYSQL MEMORY [root@vps httpd]# ps aux | grep ‘mysql’ | awk ‘{print $6}’ 408 21440 704 `` APACHE PROCESS SIZE [root@vps httpd]# ps aux | grep ‘httpd’ | awk ‘{print $6}’ 22468 11552 41492 40868 41120 41696 39488 41704 15552 16076 16084 728

In this case the server has 1002Mb of memory allocated, xx used by the OS itself, 21Mb used by mySQL, and each Apache thread averages about 30Mb. MaxClients = (1002 – 21) / 30 therefore MaxClients = 32.7

MaxConnectionsPerChild

MaxConnectionsPerChild sets the limit on the number of connections that an individual child server process will handle. After MaxConnectionsPerChild connections, the child process will die. If MaxConnectionsPerChild is 0, then the process will never expire.

Setting MaxConnectionsPerChild to a non-zero value limits the amount of memory that process can consume by (accidental) memory leakage. See below for more information.

How to define the MaxConnectionsPerChild directive

A good calculation for MaxConnectionsPerChild would be: (total amount of daily requests / total number of daily processes)

Determining these values is a bit more complex as it requires some type of statistics package or thorough knowledge of interpreting Apache access logs.

As this does not adversely effect memory usage, only cpu time to cycle the process if you are unable to determine this information the standard 1000 should be used.

Thus a good configuration for this server would be:

StartServers 2 MinSpareServers 3 MaxSpareServers 3 ServerLimit 30 MaxClients 30 MaxRequestsPerChild 1000

Zuletzt bearbeitet von @admin 2025-08-31T06:39:25Z