Nginx vor Apache - Reverse Proxy mit Froxlor
Im gleichnamigen Artikel von meteor-digitals findet man eine Entscheidungshilfe, warum gerade Nginx zum Einsatz kommen soll und zusätzlich dazu eine genaue Anleitung für die Proxy-Konfiguration. Ich gehe hier in dem Artikel direkt auf einige Schritte speziell für meinen gemieteten virtuellen Server von netcups GmbH ein. Die Änderungen sind dabei als root-User notwendig, also seid bitte vorsichtig bei den Schritten, damit ihr nichts anderes am Server kaputt macht!
Apache Listenport neukonfigurieren
Froxlor läuft als Website im Apache2, lauscht laut Standardkonfiguration auf dem Port 80 für ungesicherte http-Anfragen und falls bereits konfiguriert, auf Port 443 für gesicherte https-Anfragen. Da wir nun aber Nginx als Proxy laufen lassen möchten, muss dieser Webserver stattdessen auf den Ports 80 und 443 lauschen. Deshalb stellen wir in der Apache2-Konfiguration die Ports um. Dazu öffnet man die Datei /etc/apache2/ports.conf und ändert die Einstellungen wie folgt ab:
..
Listen 8888
<IfModule ssl_module>
Listen 8843
</IfModule>
<IfModule mod_gnutls.c>
Listen 8843
</IfModule>
..
Als nächstes ändert man noch die Einstellungen in der Datei /etc/apache2/sites-enabled/000-default.conf wie folgt ab:
..
<VirtualHost *:8888>
..
Hat man eine Konfiguration für SSL, z.B. als Datei /etc/apache2/sites-enabled/000-default-ssl.conf, so ändert man diese ebenfalls ab:
..
<VirtualHost *:8843>
..
Nun muss der Apache2 neugestartet werden:
$ service apache2 restart
Nginx installieren und konfigurieren
Bei der vorinstallierten Debian Version ist der Nginx Webserver in einer recht alten Version verfügbar. Deshalb aktualisieren wir die Paketquellen vom System, um eine möglichst neue Version installieren zu können, damit wir auch gegen Sicherheitslücken geschützt sind. Dazu erweitern wir die Datei /etc/apt/sources.list um die Einträge:
..
# new nginx packages
deb http://nginx.org/packages/mainline/debian/ jessie nginx
deb-src http://nginx.org/packages/mainline/debian/ jessie nginx
Danach müssen wir noch den offiziellen Signing-Key der Paketquellen im System installieren:
$ wget http://nginx.org/packages/keys/nginx_signing.key
$ cat nginx_signing.key | apt-key add -
$ rm nginx_signing.key
Die benötigten Pakete installiert man über den Debian Paketmanager:
$ apt-get update && apt-get install nginx php5-cgi php5-fpm
Als nächstes passt man die Nginx Hauptkonfiguration /etc/nginx/nginx.conf an:
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Nun fügt man die Konfigurationsdatei /etc/nginx/proxy.conf mit dem Inhalt hinzu:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Url-Scheme $scheme;
proxy_set_header X-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy-host $proxy_host;
client_max_body_size 400m;
client_body_buffer_size 128k;
proxy_buffering off;
proxy_connect_timeout 7200;
proxy_send_timeout 7200;
proxy_read_timeout 7200;
proxy_buffers 8 32k;
Danach muss die Script-Datei /etc/init.d/php-fcgi mit folgendem Inhalt angelegt werden:
#!/bin/bash
### BEGIN INIT INFO
# Provides: php-fcgi
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the php-fcgi
# Description: starts php-fcgi using start-stop-daemon
### END INIT INFO
BIND="127.0.0.1:8888"
USER="www-data"
PHP_FCGI_CHILDREN="15"
PHP_FCGI_MAX_REQUESTS="1000"
PHP_CGI="/usr/bin/php-cgi"
PHP_CGI_NAME="$(basename ${PHP_CGI})"
PHP_CGI_ARGS="- USER=${USER} PATH=/usr/bin PHP_FCGI_CHILDREN=${PHP_FCGI_CHILDREN} PHP_FCGI_MAX_REQUESTS=${PHP_FCGI_MAX_REQUESTS} ${PHP_CGI} -
b ${BIND}"
RETVAL="0"
start() {
echo -n "Starting PHP FastCGI: "
start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
RETVAL="$?"
echo "${PHP_CGI_NAME}."
}
stop() {
echo -n "Stopping PHP FastCGI: "
killall -q -w -u ${USER} ${PHP_CGI}
RETVAL="$?"
echo "${PHP_CGI_NAME}."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: php-fastcgi {start|stop|restart}"
exit 1
;;
esac
exit "$RETVAL"
Nachdem man die Dateirechte angepasst hat, kann man dieses Script starten:
$ chmod u+x /etc/init.d/php-fcgi
$ /etc/init.d/php-fcgi restart
Damit es bei einem Server-Neustart automatisch gestartet wird, sollte man es im Autostart mit aufnehmen:
$ insserv -d /etc/init.d/php-fcgi
Außerdem muss noch die Pool-Konfiguration für den PHP Fast Pool Manager /etc/php5/fpm/pool.d/www.conf angepasst werden:
..
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
..
Hier ist ebenfalls ein Restart des Service notwenig:
$ /etc/init.d/php5-fpm restart
Apache aus Autostart entfernen
Falls man den Apache2 nicht mehr als Webserver benötigen sollte, so wie es bei mir der Fall ist, kann man diesen auch aus dem Autostart entfernen. Nginx fungiert dann nicht mehr nur als Proxy, sondern als alleiniger Webserver:
$ update-rc.d -f apache2 remove
Für Nginx konfiguriert man dann alle Websites im Verzeichnis /etc/nginx/sites-enabled/. Hier im Bsp. ist die Konfiguration für froxlor zu finden. Dabei legt man einfach die Datei /etc/nginx/sites-enabled/10_froxlor_ipandport_80.conf mit dem Inhalt an:
# 10_froxlor_ipandport_80.conf
# Created 26.06.2018 18:55
# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.
server {
listen <youripaddress>:80 default_server;
# Froxlor default vhost
server_name <yourservername>;
access_log /var/log/nginx/access.log;
root /var/www/;
index index.php index.html index.htm;
location / {
}
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
try_files $fastcgi_script_name =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
}
Bitte beachte, dass du die Platzhalter <youripaddress> und <yourservername> mit den realen Werten ersetzen musst, welche du von netcup GmbH in der Bereitstellungsmail des virtuellen Servers erhalten hast! Nun musst du nur noch deinen Webserver neustarten:
$ /etc/init.d/nginx restart
Nginx mit fail2ban absichern
Um diverse Attacken aus dem Internet zu verlangsamen, kann man auf das Paket fail2ban zurückgreifen. Es bietet sehr flexible Konfigurationsmöglichkeiten für Services an, welche auf TCP- und UDP-Verbindungen lauschen. Installiert wird es wieder über den Debian Paketmanager:
$ apt-get install fail2ban
Danach legt man einen Filter für Nginx an, indem man die Datei /etc/fail2ban/filter.d/nginx-req-limit.conf mit Inhalt erzeugt:
[Definition]
failregex = limiting requests, excess:.* by zone.*client: <HOST>
Fail2ban benötigt eine grundsätzliche Konfiguration, welche in der Datei /etc/fail2ban/jail.local enthalten ist. Findet man keine solche Datei, dann erstellt man diese aus der vorhandenen /etc/fail2ban/jail.conf:
$ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Am Ende dieser Konfigurationsdatei fügt man Folgendes hinzu:
..
[nginx-req-limit]
enabled = true
filter = nginx-req-limit
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
logpath = /var/log/nginx/*error.log
findtime = 600
bantime = 7200
maxretry = 10
Die Werte von findtime und maxretry sind sehr wichtig, denn mit diesen entscheidet fail2ban, in welcher Frequenz eine IP-Adresse gebannt wird. Als letztes muss der fail2ban Service neugestartet werden:
$ service fail2ban restart
Den Bann-Status des soeben erzeugten Nginx Filters kann man mit folgenden Kommando abfragen:
$ fail2ban-client status nginx-req-limit
Ausblick
Anstatt das veraltete PHP5 zu nutzen, kann man das System auch auf die modernere PHP7 Variante aktualisieren. Wie das im Detail für Debian Jessie funktioniert, findet man in diesem Artikel von HTPC Guides.
Nun sind wir auch schon wieder am Ende dieses Artikels. Ich hoffe, dass dieser euch geholfen hat. Wollt ihr mich unterstützen, damit ich noch viele andere spannende Artikel schreiben kann, dann schaut bitte in meiner Rubrik Crowdfunding vorbei.