Verhindern, dass PHP-FPM bei geringer Belastung abstürzt

Verhindern, dass PHP-FPM bei geringer Belastung abstürzt

Ich werde Opfer eines DoS-Angriffs auf eine WordPress-Site, die ich hoste.

173.192.109.118 - - [30/Sep/2015:22:31:36 +0000] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"

Ich erhalte ungefähr 140 dieser Protokolle in meinem nginxZugriffsprotokoll (dauerte ungefähr 10 Sekunden, also ~14 Anforderungen/Sekunde) und dann wechseln sie zu 502:

173.192.109.118 - - [30/Sep/2015:22:31:46 +0000] "POST /xmlrpc.php HTTP/1.0" 502 537 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"

An diesem Punkt PHP-FPMmuss ein Neustart durchgeführt werden, um die Site wiederherzustellen.

Meine Frage ist also:Kann ich irgendetwas tun, um einen einzelnen Angreifer am Absturz zu hindern PHP-FPM?

Die meisten meiner (begrenzten) Erfahrungen habe ich mit Apache gemacht, daher wäre jeder Ratschlagsehrgeschätzt.

Ich habe versucht, für alles vernünftige Grenzen zu setzen. Der Server hat bei Belastung genügend RAM, das scheint also nicht das Problem zu sein. Ich habe einfach einen Rate-Limiter aus dem folgenden Tutorial hinzugefügt:https://www.howtoforge.com/rate-limiting-mit-nginx, und obwohl das den Schmerz scheinbar hinauszögert, stürzt es am Ende trotzdem ab PHP-FPM.

Es /var/log/php5-fpm.logscheint nichts Interessantes oder Nützliches anzuzeigen, außer ein paar Fehlern, die entstanden sind, als ich vergessen habe, in der Konfigurationsdatei ein / einzuführen, und ein paar Erfolgszeilen vom Neustart:

[30-Sep-2015 23:03:51] ERROR: Unable to create or open slowlog(/usr/log/www.log.slow): No such file or directory (2)
[30-Sep-2015 23:03:51] ERROR: failed to post process the configuration
[30-Sep-2015 23:03:51] ERROR: FPM initialization failed
[30-Sep-2015 23:05:47] NOTICE: configuration file /etc/php5/fpm/php-fpm.conf test is successful

/etc/php5/fpm/pool.d/www.conf

[www]
user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.status_path = /status
ping.path = /ping
ping.response = pong
slowlog = /var/log/php-fpm_$pool.slow.log
request_slowlog_timeout = 30
request_terminate_timeout = 30
chdir = /

/etc/nginx/nginx.conf

user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
    worker_connections 768;
}
http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    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/x-javascript text/xml application/xml application/xml+rss text/javascript;

    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

/etc/nginx/sites-enabled/beispiel.com

server {
  server_name localhost www.example.com;
  return 301 http://example.com$request_uri;
}
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    root /var/www/html;
    index index.php index.html index.htm;
    server_name example.com;

    client_max_body_size 500M;

    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    error_page 404 /404.html;

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/html;
    }

    location ~*  \.(jpg|jpeg|png|gif|ico|css|js|woff)$ {
            expires 365d;
    }
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            limit_req zone=one burst=5;
        }

    location /status {
        fastcgi_pass php;
    }

    location /ping {
        fastcgi_pass php;
    }

    location ~ /\. {
        deny all;
    }
}

**AKTUALISIEREN**

Ich habe den Titel aktualisiert, damit er meine Frage etwas besser widerspiegelt, in der Hoffnung, dass ich damit eine qualitativ hochwertige Diskussion zum Thema PHP-FPMTuning anstoßen kann.

Eine zweite Frage, die möglicherweise wichtiger ist als meine erste Frage, ist: Wie kann ich PHP-FPM optimieren/härten, um alle meine verfügbaren Serverressourcen zu nutzen, ohne vorher abzustürzen?

Apache/PHP war vielleicht nicht so effizient, aber es hat nicht aufgehört, Anfragen zu bearbeiten, bis der Server in die Knie gezwungen wurde, und als der Angriff vorbei war, war die Site wieder online. Es scheint ziemlich unangenehm, einen Dienst, der leicht überlastet war, manuell neu starten zu müssen. (14 Anfragen/Sekunde sind wirklich nichts)

Ich stimme den Ideen zu, die fail2banzur Abwehr von DoS-Angriffen eingesetzt werden können, aber was mich wirklich beunruhigt, ist, was passieren wird, wennregulärDer Verkehr erreicht 15 Anforderungen/Sekunde?

Antwort1

Grundsätzlich stehen Ihnen folgende Möglichkeiten zur Verfügung:

  • Paketfilterblockierung verwenden
  • Verwenden Sie Nginx-Blockierung wie

location / { deny xx.xx.xx.xx; allow all; }

  • pm.max_childrenauf eine Zahl erhöhen , dieCPU-Kerne x 2, 5 ist viel zu niedrig – vielleicht kann es nach der Erhöhung nur 14 Anfragen pro Sekunde verarbeiten, was eigentlich keine so große Zahl ist. Darüber hinaus verwenden Sie die Nginx- limit_reqDirektive, um die Anfragerate zu begrenzen. Ich würde vorschlagen, dass Sie eine weitere Zone hinzufügen und sie mit einer niedrigeren Burst-Größe oder konfigurieren nodelay.

verwandte Informationen