语法： sendfile on | off; 默认值： sendfile off; 上下文： http，server，location，if in location }指定是否使用sendfile系统调用来传输文件。sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)，从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝，操作效率很高，被称之为零拷贝。参考文章：https://www.jianshu.com/p/70e1c396c320Syntax: tcp_nopush on | off; Default: tcp_nopush off; Context: http, server, locationTCP_NOPUSH 是 FreeBSD 的一个 socket 选项，对应 Linux 的 TCP_CORK，Nginx 里统一用 tcp_nopush 来控制它，并且只有在启用了 sendfile 之后才生效。启用它之后，数据包会累计到一定大小之后才会发送，减小了额外开销，提高网络效率。Syntax: tcp_nodelay on | off; Default: tcp_nodelay on; Context: http, server, locationTCP_NODELAY 也是一个 socket 选项，启用后会禁用 Nagle 算法，尽快发送数据，某些情况下可以节约 200ms（Nagle 算法原理是：在发出去的数据还未被确认之前，新生成的小数据先存起来，凑满一个 MSS 或者等到收到确认后再发送）。Nginx 只会针对处于 keep-alive 状态的 TCP 连接才会启用 tcp_nodelay。当连接转换为keep-alive状态时，启用该选项。此外，它在SSL连接上启用，用于无缓冲代理和WebSocket代理。可以看到 TCP_NOPUSH 是要等数据包累积到一定大小才发送，TCP_NODELAY 是要尽快发送，二者相互矛盾。实际上，它们确实可以一起用，最终的效果是先填满包，再尽快发送。官方文档参考：http://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelaySyntax: keepalive_timeout timeout [header_timeout]; Default: keepalive_timeout 75s; Context: http, server, location第一个参数设置一个超时，在这个超时期间，保持活动的客户端连接将在服务器端保持打开。0值禁用保持连接的客户端连接。第二个可选参数在Keep-Alive: timeout=time响应报头字段中设置一个值。两个参数可能不同。Keep-Alive: timeout=time报头字段被Mozilla和Konqueror识别。MSIE会在大约60秒内自行关闭保持连接。keepalive_timeout 60;fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on;fastcgi模块参数gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\.";开启gzip压缩server_tokens off;启用或禁用在错误页面和服务器响应报头字段中发出nginx版本。build参数(1.11.10)允许随nginx版本一起发出build名称。此外，作为我们商业订阅的一部分，从版本1.9.13开始，错误页面上的签名和服务器响应头字段值可以使用变量字符串显式设置。空字符串禁止发送Server字段。map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; }过CDN，获取真实客户端IP，$clientRealIp====其它待补充
nginx 配置 PHP 的时候出现 File not found 疑难问题解决方法
环境 centos8，编译方式安装的nginx/1.20.1, php 是dnf安装的php/7.2.24nginx 执行用户、php 执行用户、文件权限都检查了，确定没有问题nginx 的php配置也确定没有问题，但就是访问php页面出现 File not found查看nginx报错内容，看到如下错误："Primary script unknown"2021/07/07 20:40:02 [error] 8853#0: *164 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.1.95, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/www.sock:", host: "192.168.1.69"最终解决的方法：#/www/wwwroot/phpwebdir/是我的网站根目录 chcon -R -t httpd_sys_content_t /www/wwwroot/phpwebdir/ chcon -R -t httpd_sys_content_t /www/server/nginx/sbin/nginx /www/server/nginx/sbin/nginx -s reload原因是selinux 在作祟，如上命令是配置 网站目录和nginx执行文件的 selinux 上下文具体selinux这个安全机制至今还没有搞明白咋玩用以下命令可以查看文件或目录的上下文ll -dZ /www/wwwroot/phpwebdir/修改之前是drwxrw-rw-. 7 www www unconfined_u:object_r:admin_home_t:s0 4096 Jul 7 20:28 /www/wwwroot/phpwebdir/修改之后是drwxrw-rw-. 7 www www unconfined_u:object_r:httpd_sys_content_t:s0 4096 Jul 7 20:28 /www/wwwroot/phpwebdir/或者干脆关闭selinux（需要重启服务器）/etc/selinux/config ：SELINUX=disabled
现在被恶意请求了，把恶意请求单独打到一个日志文件，然后提取客户端IP，去重，然后封掉这些IP创建文件vim filterIp.sh文件内容#! /bin/bash sed 's/src:\([0-9\.]\+\).*/\1/g' $1 | sort -n | uniq用这个脚本处理日志文件, 提取到客户端IP，这些IP是排序，去重了的chmod a+x filterIp.sh ./filterIp.sh xxx.log我的 xxx.log 的日志格式是这样的，如果保存日志不一样，则需要改一下 filterIp.sh 中的sed处理规则src:60.173.147.155 cdn:58.215.115.71 - [16/Jun/2021:10:02:01 +0800] "GET /xx.html?xx3 HTTP/1.1" 403 564 "xx" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
http {} 中：map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; } log_format main 'src:$clientRealIp cdn:$remote_addr $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; access_log logs/access.log main;
samba 集成DEV开发环境 php 监控某目录下文件变动，自动执行某些命令操作 重启nginx ，nginx 实现动态域名，动态配置加载
测试环境：centos 7系统，预先安装好bt 宝塔系统，安装好samba，宝塔里面安装好 lnmp软件，php设置 取消 exec 函数限制：将www用户添加到dev组usermod -G dev wwwphp 写了一个脚本，实现监控目录下文件的变量，然后重启nginx的例子：<?php class NginxRewrite { public $dir = "/www/wwwroot/"; private $files = []; public function __construct() { $this->files = $this->readDir(); } public function run() { $oldFiles = $this->files; while (true) { $_files = $this->readDir(); foreach ($_files as $f=>$t) { if (!isset($oldFiles[$f]) || $oldFiles[$f]!=$t) { $oldFiles = $_files; @exec("nginx -t", $out, $status); if ($status === 0) { echo "rewrite change, nginx reload\n"; @exec("nginx -s reload"); } break; } } sleep(10); } } //目录目标目录 private function readDir($dir = null) { $dir = $dir ? $dir : $this->dir; $files = scandir($dir); $deep = count(explode(DIRECTORY_SEPARATOR, $this->dir)); //var_dump($deep); $res = []; foreach ($files as $file) { if ($file == '..' || $file == '.') continue; $_path = rtrim($dir, '\\/') . DIRECTORY_SEPARATOR . $file; $_deep = count(explode(DIRECTORY_SEPARATOR, $_path)); if (is_dir($_path) && $_deep - $deep < 2) { //var_dump($_deep - $deep, $_path); $res = array_merge($res, $this->readDir($_path)); } elseif (is_file($_path) && preg_match("/nginx\.htaccess$/", $file)) { $res[$_path] = filemtime($_path); } } return $res; } } $mod = new NginxRewrite(); $mod->run(); nginx 实现了动态域名，动态加载用户的匹配文件的方法/root/nginx_config_tpl/www.nginx.tplserver { listen 80; server_name ~^(\w+)\.USER_NAME\.tell520\.com$; set $www $1; index index.php index.html index.htm default.php default.htm default.html; root /www/wwwroot/USER_NAME/$www; #SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则 #error_page 404/404.html; #SSL-END #ERROR-PAGE-START 错误页配置，可以注释、删除或修改 #error_page 404 /404.html; #error_page 502 /502.html; #ERROR-PAGE-END #PHP-INFO-START PHP引用配置，可以注释或修改 include enable-php-71.conf; #PHP-INFO-END #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效 location / { include /www/wwwroot/USER_NAME/*/nginx.htaccess; access_log /www/wwwroot/USER_NAME/nginx.log; } #REWRITE-END #禁止访问的文件或目录 location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md) { return 404; } #一键申请SSL证书验证目录相关设置 location ~ \.well-known{ allow all; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; error_log off; access_log /dev/null; } location ~ .*\.(js|css)?$ { expires 12h; error_log off; access_log /dev/null; } }自动创建samba用户，并创建用户的网站目录和默认的例子文件脚本：#! /bin/bash if [ $# -ne 1 ]; then echo -e "use: ./create_dev_user.sh username" exit 1 fi useradd $1 -g dev echo -e "123456\n123456\n" | smbpasswd -a $1 mkdir /www/wwwroot/$1 mkdir /www/wwwroot/$1/test touch /www/wwwroot/$1/test/index.php cat>/www/wwwroot/$1/test/index.php<<EOF <?php echo " "; echo "hello world!\n"; var_export(\$_GET); echo " "; EOF touch /www/wwwroot/$1/test/nginx.htaccess cat>/www/wwwroot/$1/test/nginx.htaccess<<EOF rewrite ^([^\.]*)/(\w+)/(\w+).html\$ \$1/index.php?r=\$2/\$3 last; rewrite ^([^\.]*)$ \$1/index.php?r=index/index last; if (!-e \$request_filename) { rewrite ^(.*)\$ /index.php/\$1 last; } EOF chown $1:dev /www/wwwroot/$1/ -R chmod 776 /www/wwwroot/$1/ -R sed "s/USER_NAME/$1/" /root/nginx_config_tpl/www.nginx.tpl > /www/server/nginx/conf/vhost/$1.conf echo -e "\033[34mAdd hosts to browse the example site : 192.168.2.164 test.$1.tell520.com\033[0m" echo -e "\033[34mAdd network drive : \\\\192.168.2.164\dev\033[0m" echo -e "\033[34mUser AND Password : $1, 123456\033[0m" nginx -t && nginx -s reload samba配置文件:# See smb.conf.example for a more detailed config file or # read the smb.conf manpage. # Run 'testparm' to verify the config is correct after # you modified it. [global] server string = dev Servera Version %v interfaces = ens192 192.168.2.164/24 workgroup = SAMBA security = user passdb backend = tdbsam printing = cups printcap name = cups load printers = yes cups options = raw [dev] comment = dev dir path = /www/wwwroot/yxb browseable = Yes writable = Yes available = Yes valid users = @dev public = No [homes] comment = Home Directories valid users = %S, %D%w%S browseable = Yes read only = No inherit acls = Yes [printers] comment = All Printers path = /var/tmp printable = Yes create mask = 0600 browseable = No [print$] comment = Printer Drivers path = /var/lib/samba/drivers write list = @printadmin root force group = @printadmin create mask = 0664 directory mask = 0775
在 Nginx 中将爬虫过来的请求转到指定的后端服务
一般识别爬虫的方法是通过 UserAgent，这种办法最直接，但也很容易伪造，先不管这个了。实现在 Nginx 中使用 map 指令来匹配一个变量：map $http_user_agent $is_bot { default 0; ~[a-z]bot[^a-z] 1; ~[sS]pider[^a-z] 1; 'Yahoo! Slurp China' 1; 'Mediapartners-Google' 1; }在这里我们生成了一个名为 $is_bot 的变量，该变量默认值是 0 ，如果匹配到上述 4 种正则表达式的情况后，值就变成1。你可以继续往 map 中添加新的表达式规则。然后在 location 中使用该变量：location / { error_page 418 =200 @bots; if ($is_bot) { return 418; } proxy_pass http://tomcat_for_normal_visitors; }@bots 的定义：location @bots { proxy_pass http://tomcat_for_bot; }当判断当前请求是爬虫的时候，返回 418 错误码。通过 error_page 将 418 错误码改为 200 （正常请求响应码），然后进入 @bots 这个 location 进行下一步处理。@bots 中将请求反向代理到你指定的后端应用。如此便可将正常的用户访问和爬虫访问独立开来，使二者不会互相影响。
可能的情况：1、服务器磁盘满了，查看磁盘https://blog.csdn.net/dujianxiong/article/details/84288658df -h2、nginx的fastcgi_temp目录没有读写权限，查看nginx的error日志，会发现：2010/03/13 02:52:19 [crit] 3396#0: *10 open() "/usr/local/nginx/fastcgi_temp/2/00/0000000002" failed (13: Permission denied)处理方法，给目录增加权限或者修改所有者为nginx worker的运行用户chown www:www /usr/local/nginx/fastcgi_temp -R分析 fastcgi_temp 错误以及 Nginx 的 Buffer 机制: https://blog.csdn.net/crx05/article/details/70210323
文章来源：https://blog.csdn.net/revitalizing/article/details/55505853必要工具库一、libgd的安装 export LD_LIBRARY_PATH=/Path/to/libgd.so:$LD_LIBRARY_PATH当然也还有更简单的方法，直接yum安装也行，自己配置好yum源，然后：yum install gd-devel pcre-devel libcurl-devel因为libcurl也是需要的一部分，所以一起安装。二、nginx with-http_image_filter_module模块安装编辑安装nginx的时候需要加上这些参数--with-http_image_filter_module --with-pcre=../pcre-8.36使用：一般情况下，nginx一般都需要用到正则表达式，所以对于图片处理器pcre就更不能少了，如果有pcre，我们的配置就可以写成下面这样： #图片处理，固定返回最大长边尺寸 location ~* /(.+)\.(jpg|gif|png)$ { access_log off; expires 30d; #根据给定的长宽生成缩略图 image_filter resize 800 800; #原图最大2M，要裁剪的图片超过2M返回415错误，需要调节参数image_filter_buffer image_filter_buffer 8M; image_filter_interlace on; image_filter_jpeg_quality 95; image_filter_sharpen 100; image_filter_transparency on; #error_page 415 /images/notfound.jpg; try_files /$1.$2 /notfound.jpg; } #图片处理，支持_1x1.jpg这样的自定义尺寸 location ~* /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ { access_log off; expires 30d; set $w $2; set $h $3; if ($h = "0") { rewrite /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ /$1 last; } if ($w = "0") { rewrite /(.+)_(\d+)x(\d+)\.(jpg|gif|png)$ /$1 last; } #根据给定的长宽生成缩略图 image_filter resize $w $h; #原图最大2M，要裁剪的图片超过2M返回415错误，需要调节参数image_filter_buffer image_filter_buffer 8M; image_filter_interlace on; image_filter_jpeg_quality 95; image_filter_sharpen 100; image_filter_transparency on; #error_page 415 /images/notfound.jpg; try_files /$1 /notfound.jpg; }访问处理后的图片：http://xxxx.xxx.xxx/test.jpg >> http://xxxx.xxx.xxx/test.jpg_500x200.jpg各参数的注释：image_filter off; #关闭模块 image_filter test; #确保图片是jpeg gif png否则返415错误 image_filter size; #输出有关图像的json格式：如下显示{ "img" : { "width": 100, "height": 100, "type": "gif" } } 出错显示：{} image_filter rotate 90|180|270; #旋转指定度数的图像，参数可以包括变量，单独或一起与resize crop一起使用。 image_filter resize width height; #按比例减少图像到指定大小，公减少一个可以另一个用"-"来表示,出错415，参数值可包含变量，可以与rotate一起使用，则两个一起生效。 image_filter crop width height; #按比例减少图像比较大的侧面积和另一侧多余的载翦边缘，其它和rotate一样。没太理解 image_filter_buffer 10M; #设置读取图像缓冲的最大大小，超过则415错误。 image_filter_interlace on; #如果启用，最终的图像将被交错。对于JPEG，最终的图像将在“渐进式JPEG”格式。 image_filter_jpeg_quality 95; #设置变换的JPEG图像的期望质量。可接受的值是从1到100的范围内。较小的值通常意味着既降低图像质量，减少传输数据，推荐的最大值为95。参数值可以包含变量。 image_filter_sharpen 100; #增加了最终图像的清晰度。锐度百分比可以超过100。零值将禁用锐化。参数值可以包含变量。 image_filter_transparency on; #定义是否应该透明转换的GIF图像或PNG图像与调色板中指定的颜色时，可以保留。透明度的损失将导致更好的图像质量。在PNG的Alpha通道总是保留透明度。Nginx图片处理的优缺点优点操作简单。通过简单配置，省去了后端裁剪程序的复杂性。实时裁剪。可以实时访问在线裁剪图片。灵活性强。后端程序裁剪图片时需要知道裁剪图片的尺寸和质量，使用nginx裁剪可以实时裁剪任意尺寸的图片。不占用硬盘空间。缺点消耗CPU和内存，访问量大的时候就会给服务器带来很大的负担。(可以通过使用Nginx缓存和缓存服务器来解决)功能不是很强大，支持的处理图片类型只包括JPEG, GIF, PNG, or WebPPC：宝塔用户nginx是安装了以上模块的，所以可以直接增加配置代码就可以使用了
在nginx的安装目录下面,新建屏蔽ip文件，命名为blockips.conf。 加入如下内容#deny 1.2.3.4; #deny 91.212.45.0/24; deny 115.239.212.0/24; deny 180.97.106.0/24; deny 115.239.212.0/24; deny 220.243.135.0/24; deny 180.97.106.0/24;保存一下。3.在nginx的配置文件nginx.conf中加入如下配置，可以放到http, server, location, limit_except语句块，需要注意相对路径，本例当中nginx.conf，blockips.conf在同一个目录中。include blockips.conf;
方法一：将下面的内容保存到nginx.conf同级目录，比如：deny1.conf# 针对单个ip的形式 deny 171.94.171.205; deny 115.29.166.101; deny 182.247.251.48; deny 61.147.89.17; # 针对网段的形式 deny 66.249.227.0/24;然后在nginx.conf 的 http 段 引入这个文件，重启生效(注意这个是整体全部的网站配置的禁止这些IP访问了，谨慎使用)：include deny1.conf; 方法二：有针对性的阻止，比如有些人工的发起请求，或许其他的你不想要的访问，通常是异常的客户端UA，可以这么做：将下面的内容也保存到一个文件，也是nginx.conf同级目录，比如：deny2.conf#禁止常用工具的抓取 if ($http_user_agent ~* "Scrapy|Curl|HttpClient|Java") { return 403; } #禁止指定UA及UA为空的访问 if ($http_user_agent ~* "Baidu-YunGuanCe|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" ) { return 403; } 这里注意需要把里面的正则表达式修改成你需要的正则表达式，以免达不到你要的效果然后在nginx.conf 的 server 段（也就是某个网站的配置而不是http段） 引入这个文件，重启生效：http{ ... server { ... include deny2.conf; ... } ... }先测试有没有配置错误nginx -t再重启服务nginx -s reload