|
Webserver Fragen zum Apache, MySQL-Einrichtung und was sonst noch mit WebServern zu tun hat |
|
Themen-Optionen | Ansicht |
31.05.2012, 17:30 | #1 | |||||||||||
Erfahrener Benutzer
Registriert seit: 04.04.2011
Beitr?ge: 247
Abgegebene Danke: 6
Erhielt 94 Danke für 7 Beiträge
Downloads: 2
Uploads: 0 Nachrichten: 34 Renommee-Modifikator:
1013 |
nginx - Was man wissen sollte
So, bekomme grad Lust was zu schreiben. Vielleicht hilft es dem einen oder anderen Quereinsteiger
Wer es nicht weiß - nginx ist ein robuster, kleiner und performanter Webserver der einem Apache kaum (wenn überhaupt noch) nachsteht. Gerade bei stark frequentierten Seiten, würde ich jedem zu nginx raten, wenn man nicht Unsummen in Hardware stecken möchte, da der Lastunterschied zwischen nginx und Apache doch gravierend ist. Auf meinem Server (im Schnitt etwa 35k Anfragen in der Minute) ging die Serverlast von ~70% runter auf ~22%. Ich denke das spricht für sich, wenn man bedenkt das auch die Verarbeitung der Anfragen und die Seitenauslieferung um einiges schneller vonstatten geht. Jedoch sollte man nginx vor dem Liveeinsatz erst einmal auf einem (lokalen) Testserver kennenlernen. Achtung: Die hier gezeigten Beispiele (außer die Snippets), sollten auch als solche betrachtet werden. Einige Sachen habe ich willkürlich zusammengestellt, damit etwas da steht. Syntaktisch korrekt sind alle, aber ob die Kombination zuträglich ist, vermag ich nicht zu sagen. nginx kompilieren Ich verzichte auf die fertigen Packages, und stelle mir nginx lieber selber zusammen. nginx herunterladen, entpacken und in das Source Verzeichnis wechseln: Code:
wget http://nginx.org/download/nginx-1.2.0.tar.gz
tar xvfz nginx-1.2.0.tar.gz
CD nginx-1.2.0
Code:
./configure --help Beispiel Code:
./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx/nginx.pid --http-proxy-temp-path=/usr/share/nginx/tmp/proxy --http-fastcgi-temp-path=/usr/share/nginx/tmp/fastcgi --http-uwsgi-temp-path=/usr/share/nginx/tmp/uwsgi --http-scgi-temp-path=/usr/share/nginx/tmp/scgi --http-client-body-temp-path=/usr/share/nginx/tmp/client_body --user=www-data --group=www-data --with-sha1-asm --with-sha1=/usr/lib --with-http_realip_module --with-http_ssl_module --with-http_perl_module --with-cpu-opt=amd64 --with-http_flv_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module Dann noch Code:
make && make install init.d Das Startskript wird automatisch erstellt, zu finden unter /etc/init.d. Falls nicht, ich habe mal eins angehangen, ggf. müssen die Pfade angepasst werden. Ändert man während des laufenden Betriebes etwas an den Configs, reicht ein Code:
/etc/init.d/nginx reload Konfig Unter /etc/nginx findet man alle Konfigdateien. Man kann auch selber welche erstellen, die man später per include einbinden kann. Nach alle Änderungen muss ein reload/restart erfolgen. Um Fehler zu vermeiden, kann man vorher ein configtest machen. Ach und wer nach einer optimalen Konfiguration sucht - vergesst es, so etwas gibt es nicht! Es gibt für einige Parameter Richtlinien, die sich an der vorhandenen Hardware und den Zugriffen orientieren. Diese sollte man beherzigen. Die Optimierung muss jedoch im Livebetrieb erfolgen. mime.types Merkt man das ein Inhalt nicht korrekt ausgeliefert wird, sollte man den MIME Typ hier hinzufügen. nginx übernimmt dann den Rest. Der Aufbau ist Content-Type Extension. Beispiel Code:
types { ... image/gif gif; ... } Diese Datei sollte man um globale Parameter erweitern, damit man diese nicht immer extra bei den vHosts einfügen muss. Natürlich können diese auch in einem vHost überschrieben werden. Mittels include kann man die Datei später einbinden. Welche Parameter man festlegen will, ist jedem selber überlassen. Alle Parameter haben in der Regel einen Defaultwert, die man an die Frequentierung seines Servers anpassen sollte. Beispiel Code:
... # PHP only, falls PHP mit --enable-force-cgi-redirect kompiliert wurde fastcgi_param REDIRECT_STATUS 200; # FastCGI Response-Header Puffer fastcgi_buffer_size 256k; # Antworten unter 1MB bleiben im RAM, Rest wird auf die Platte geschrieben | 4k/8k/16k -> getconf PAGESIZE fastcgi_buffers 256 4k; # alle Antworten bleiben im RAM fastcgi_max_temp_file_size 0; # Timeout zum FastCGI Server fastcgi_connect_timeout 60; # Timeout, wenn in der Zeit nichts geschrieben wurde fastcgi_send_timeout 180; # Timeout, wenn in der Zeit nichts gelesen wurde fastcgi_read_timeout 180; # FastCGI Fehler werden von nginx ausgegeben (error_page) fastcgi_intercept_errors on; ... deny.conf Ich weiß gar nicht mehr, ob das überhaupt eine Defaultkonfig ist. Jedenfalls kann man sich eine Datei erstellen, in der man einzelne IPs adden kann, die nginx später blocken soll. Wie jede andere Konfig muss diese später via include eingebunden werden. Ich selber nutze für so etwas lieber iptables, aber jedem das seine. Beispiel Code:
deny 123.123.123.123 deny 90.0.0.2 ... Kann man sehen wie fastcgi_params, nur das es sich hier um die Parameter des Proxymoduls dreht. Wird nur benötigt, wenn man einen Reverse Proxy braucht, oder nginx als solchen nutzen möchte. Hier findet man alle Parameter aufgeschlüsselt. nginx.conf Nun zum eigentlichen Herzstück. Diese Konfig gliedert sich in drei Teile: CoreModule, EventsModule und HttpCoreModule Code:
# CoreModule ... # EventsModule Block events { ... } # HttpCoreModule Block http { ... } Beispiel Code:
# CoreModule # PID File pid /var/run/nginx.pid; # jede Sekunde ein gettimeofday() syscall timer_resolution 1000ms; # verwendeter Nutzer user www-data; # auf einen CPU (Core) kommt ein worker_process worker_processes 4; # maximale Anzahl der gleichzeitig geöffneten Dateien - /etc/security/limits.conf muss ebenfalls angepasst werden, sonst hat diese Einstellung keinen Effekt worker_rlimit_nofile 50000; # jeden worker_process einem CPU (Core) zuweisen worker_cpu_affinity 0001 0010 0100 1000; Beispiel Code:
# EventsModule Block events { # soviele Verbindungen wie möglich akzeptieren multi_accept on; # maximale Anzahl gleichzeitiger Verbindungen (max clients = worker_processes * worker_connections) worker_connections 20000; } Beispiel Code:
# HttpCoreModule Block http { # mime.types inkludieren include /etc/nginx/mime.types; # deny.conf inkludieren include /etc/nginx/deny.conf; # Timeout, wenn der Client nach 5s nichts geschickt hat client_body_timeout 5; # max. 5s auf den Client Request Header warten client_header_timeout 5; # falls zu niedrig kommt der Status 413, z.B. bei einem Uploadformular client_max_body_size 25M; # default mime, wenn in der mime.types nichts anderes definiert ist default_type application/octet-stream; # braucht --with-http_gzip_static_module # gzip Kompression aktivieren gzip on; # gzip für alte IEs deaktivieren gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # alle Antworten für einen Proxy komprimieren gzip_proxied any; # mime types die komprimiert gesendet werden sollen gzip_types text/plain text/html text/css text/xml application/x-javascript application/xml application/xml+rss text/javascript; # aktivieren von Vary im Antwortheader gzip_vary on; # ungültige Headerinformationen werden ignoriert ignore_invalid_headers on; # gleichzeitige Anfragen über keep-alive Verbindung keepalive_requests 4; # keep-alive Verbindung nach 5s schließen | keep-alive header 5s keepalive_timeout 5 5; # nginx Default minimieren, niemand braucht eine so lange URI (falls doch sollte man den Code optimieren) large_client_header_buffers 2 2k; # Client liest nichts in 10s, Verbindung schließen send_timeout 10; # Datentransfer beschleunigen, falls Sendfile() Kernel Primitive existiert sendfile on; # nginx Version auf Fehlerseiten / im Server Header nicht anzeigen server_tokens off; # Antwort in einem Paket schicken, wenn sendfile aktiviert tcp_nopush on; # Pakete schicken, Antwort später verarbeiten tcp_nodelay on; # eigene Konfigdateien einbinden include /etc/nginx/conf.d/*.conf; # vHosts einbinden include /etc/nginx/sites-enabled/*; } vHosts Einen vHost kann man auch in der nginx.conf definieren, indem man einfach alles in den HttpCoreModule Block reinschreibt. Da dies allerdings recht schnell unübersichtlich werden kann, sollte man es doch lieber lassen Zuerst einmal legt man eine Datei my_vHost in /etc/nginx/sites-available an. Um den vHost später auch zu aktivieren, einfach einen Softlink von der Datei in das Verzeichnis /etc/nginx/sites-enabled legen. Den Rest macht dann die Anweisung include /etc/nginx/sites-enabled/*; im HttpCoreModule Block. Beispiel Code:
# vHost Block - http Verbindung server { # Dieser vHost lauscht am Port 80. Man kann auch noch die Server-IP voranstellen: ServerIP:80. Der default_server Parameter wird gleich erläutert. listen 80 default_server; # Der eingehende Request muss an "example.com", eine entsprechende Subdomain, oder an "www.example.com" gerichtet sein. server_name example.com *.example.com # Hat man mehrere vHosts konfiguriert und aktiviert, wird der Host Header des Requests mit allen Servernamen verglichen. # Wird kein Servername gefunden, wird nach dem entsprechendem Port gesucht. # Vorzugsweise wird dann der vHost mit dem "default_server" Parameter genommen. # Ist dieser Parameter nicht gesetzt, wird einfach der zuerst passende vHost genommen um den Request zu verarbeiten. # Man sollte seine vHosts also genau definieren um Quark zu vermeiden. # Pfade der Logdateien access_log /var/log/nginx/meine_seite.de.access.log; error_log /var/log/nginx/meine_seite.de.error.log; # Content-Type Charset setzen charset utf-8; # Fehlerseiten definieren (Status -> Seite) error_page 404 /404.html; error_page 500 502 503 504 /50x.html; # Mittels location können, in Abhängigkeit von der Request-URI, verschiedene Direktiven konfiguriert werden. # Einfach bei den einzelnen Direktiven (der Module) auf "Context: location" achten. # Diese location trifft auf alle URIs zu. Jeder Request landet hier, wenn keine andere location Direktive definiert ist. location / { # Index definieren index index.php index.html index.htm; # Einträge alá "xyz.php not found" werden nicht mehr in die error_log geschrieben log_not_found off; # Access Log deaktivieren access_log off; # usw. (wenn man denn möchte) } # PHP Seiten verarbeiten (URI endet auf .php) location ~* \.php$ { # Zero-day exploit defense # http://forum.nginx.org/read.php?2,88845,page=3 try_files $uri = 404; # SCRIPT_NAME und PATH_INFO Variablen setzen fastcgi_split_path_info ^(.+\.php)(/.+)$; # FastCGI Config laden include fastcgi_params; # SCRIPT_FILENAME definieren fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # FastCGI Server Socket setzen fastcgi_pass unix:/var/run/php5-fpm.socket; # hat bei mir in Extremfällen zum Absturz des FastCGI Servers geführt, wenn es auf off geschalten war fastcgi_ignore_client_abort on; } # Pfad zum www Verzeichnis für diesen vHost root /path/to/www } location Syntax Die location Direktive ist speziell dafür da, um Aufrufe gezielt zu verarbeiten, umzuleiten oder zu blocken. location [=|~|~*|^~|@] uri { … }
Verarbeitungsreihenfolge 1. Direktiven mit = werden zuerst untersucht. Bei einem Treffer wird die Suche gestoppt. 2. Danach folgen Direktiven mit einem String Literal als uri. Nutzt die Direktive ^~ und es gibt einen Treffer, wird die Suche gestoppt. 3. Dauert die Suche an, werden alle RegEx uri's, in der Reihenfolge in der sie definiert wurden, untersucht. 4. Gibt es bei 3. eine Übereinstimmung wird diese genommen und die Suche beendet. Andernfalls wird die bestmögliche Übereinstimmung aus 2. genommen. Hat man viele location Direktiven konfiguriert, sollte man die Anordnung der Verarbeitungsreihenfolge anpassen. Diese Optimierung kann je nach Frequentierung doch einiges ausmachen. Beispiele Code:
server { ... # Request-URI ist "/bla.php" location = /bla.php { # ändere die Fehlerseite für den Status 404, wenn bla.php aufgerufen wird error_page 404 @errorpage; } location @errorpage { # Definiere die Fehlerseite, wenn die named location aufgerufen wird. # OK, das Beispiel ist jetzt ziemlich sinnlos, aber man kann ja auch einen Redirect nehmen, oder andere hübsche Sachen anstellen error_page 404 /404_new.html; } # Request-URI ist /images/hotlink.gif location ^~ /images { # gib einen 403 zurück, wenn die Datei im images Ordner liegt return 403; } # Request-URI ist irgendeine PHP location ~* \.php$ { # mach was, wenn die Request-URI mit ".php" endet } # alle anderen Request-URIs fallen hier rein location / { ... } ... } rewrite Syntax Ab und zu braucht man auch mal eine Umleitung. rewrite regex replacement [flag]
Beispiel Code:
server { # dauerhafte Umleitung von http://www.example.com / http://subdomain.example.com auf http://example.com server_name .example.com; rewrite ^ http://example.com$request_uri? permanent; # oder rewrite ^(.*) http://example.com$1 permanent; } Natürlich war das nur eine Einführung bzw. ein grober Überblick wenn man so will. Für eine optimale Konfiguration kommt man nicht um das nginx Wiki herum. Zum Schluß noch ein paar Snippets, die dem ein oder anderem sicherlich helfen werden Snippets Direktzugriff auf das Verzeichnis LockedFolder sperren Code:
location ^~ /LockedFolder/ { deny all; allow 127.0.0.1; return 403; } Code:
location ^~ /LockedFolder/ { auth_basic "Restricted"; auth_basic_user_file /path/to/.htpasswd; autoindex on; allow all; } Code:
location ~* \.(jpe?g|png|bmp|gif)$ { # prüfen ob der Referer gültig ist, falls nicht gib 404 zurück # blocked = Referer ist maskiert # none = Referer fehlt # server_names = definierte server_names valid_referers blocked none server_names; if ($invalid_referer) { return 404; } } ... # muss unterhalb des Hotlink Schutzes gesetzt werden, da dieser sonst nicht greift root /path/to/www Code:
location ~* \.(css|js)$ { expires max; } Code:
server { listen 80; server_name example.com; rewrite ^/announce.php$ http://example.com:81/announce.php permanent; } Code:
server { listen 443; server_name example.com; ssl on; ssl_certificate /path/to/.crt; ssl_certificate_key /path/to/.key; ssl_client_certificate /path/to/.pem; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; ... } Code:
# kann für jede location extra definiert werden http { ... # Zone "dosprotection" mit 10MB um die Sessions zu verwalten - 30 Requests pro Sekunde sind erlaubt, alles darüber wird geblockt # muss bei einer stark frequentierten Seite ausbalanciert werden, da sonst einige User geblockt werden können limit_req_zone $binary_remote_addr zone=dosprotection:10m rate=30r/s; # ab v1.1.18 limit_conn_zone sonst limit_zone # Zone "slimits" und deren Größe für die Speicherung der Sessions wird definiert limit_conn_zone slimits $binary_remote_addr 10m; # maximale simultane Verbindungen in der Zone "slimits" pro Session - alles darüber bekommt einen 503 limit_conn slimits 20; ... location / { ... # User darf 30 Requests die Sekunde haben, wenn es mal mehr sein soll, dann können es auch maximal 60 sein. # Liegt der erlaubte Requestanzahl mehrere Sekunden lang über 30, wird der Überschuss aufaddiert, bis 60 erreicht ist. # Danach gibt es für den User einen 503er. limit_req zone=dosprotection burst=60; } ... } Code:
server { listen 1.2.3.4:80; server_name example.com; location / { proxy_pass http://5.6.7.8:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host 5.6.7.8; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ... } } Code:
# IPv4 & IPv6 listen [::]:80; # nur IPv6 listen [::]:80 ipv6only=on; Ge?ndert von bl0bb (01.06.2012 um 08:30 Uhr) |
|||||||||||
Folgende 16 Benutzer sagen Danke zu bl0bb für den nützlichen Beitrag: | $iMpLy (31.05.2012), Cerberus (01.06.2012), DoLo (31.05.2012), Eltacom (01.06.2012), Entity (31.05.2012), gotthummer (31.05.2012), haudenLukas (31.05.2012), hawk (01.06.2012), ike (31.05.2012), kaitokid (21.12.2014), Lex (01.06.2012), robby (31.05.2012), Sponge (31.05.2012), tantetoni2 (31.05.2012), Thunder™ (31.05.2012), Zero111 (31.05.2012) |
31.05.2012, 19:12 | #2 | |||||||||||
König
Registriert seit: 15.10.2008
Beitr?ge: 1.923
Abgegebene Danke: 23
Erhielt 571 Danke für 38 Beiträge
Downloads: 8
Uploads: 0 Nachrichten: 4155 Renommee-Modifikator:
7257 |
fein fein
__________________
|
|||||||||||
31.05.2012, 19:30 | #3 | |||||||||||
Erfahrener Benutzer
Registriert seit: 04.04.2011
Beitr?ge: 247
Abgegebene Danke: 6
Erhielt 94 Danke für 7 Beiträge
Themenstarter
Downloads: 2
Uploads: 0 Nachrichten: 34 Renommee-Modifikator:
1013 |
Ich seh grad, in dem rewrite Beispiel, da muss
rewrite ^(.*) http://example.com$1 permanent; hin. Das $1 fehlt, k.A. warum. Wenn ich auf Ändern gehe, wird es angezeigt. |
|||||||||||
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, G?ste: 1) | |
Themen-Optionen | |
Ansicht | |
|
|