防止PHP-FPM在轻负载下崩溃

我在我主持的wordpress网站上发生DoS攻击。

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)" 

我在我的nginx访问日志中获得了大约140个这样的日志(大概需要10秒,所以〜14次/秒),然后他们切换到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)" 

此时,必须重新启动PHP-FPM才能恢复站点。

所以,我的问题是: 有什么我可以做的,以防止一个单一的攻击者崩溃PHP-FPM

我的(有限的)经验大部分是与Apache,所以任何意见将不胜感激。

我试图设定一切合理的限制。 服务器有足够的内存负载,所以这似乎不是问题。 我刚刚添加了一个速率限制器,从以下教程: https : //www.howtoforge.com/rate-limiting-with-nginx ,虽然这似乎延迟的痛苦,它仍然最终崩溃PHP-FPM

/var/log/php5-fpm.log似乎没有显示任何有趣或有用的东西,除了我忘记在configuration文件中添加前导/后引入的几个错误,以及一些成功行重新启动:

 [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/example.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; } } 

** 更新 **

我已经更新了标题以更好地反映我的问题,希望能够吸引一些关于PHP-FPM调优的高质量讨论。

作为第二个问题,可能比我的第一个问题更重要,我想知道: 如何调整/强化PHP-FPM以利用我所有可用的服务器资源而不首先崩溃。

Apache / PHP可能没有那么高效,但是在服务器瘫痪之前它并没有停止服务请求,然后当攻击结束时,该站点已经恢复。 手动重启稍微过度的服务看起来相当不愉快。 (14瑞奇/秒是真的没什么)

我同意使用fail2ban来缓解DoS攻击的想法,但是我真正担心的是如果/当正常stream量达到15次/秒时会发生什么?

基本上你有以下select:

  • 使用包filter阻塞
  • 使用nginx阻塞就好

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

  • pm.max_children增加到一个等于cpu核心的数目x 2,5的方式太低 – 可能是在增加之后才能够每秒处理14个请求,实际上并不是那么大的数字。 此外,您正在使用nginx limit_req指令来限制请求率,我build议您添加另一个区域,并使用较低的突发大小或nodelay