linux-常用web环境优化
章节目录

1. tomcat 服务调优
1.1. 安全优化
1.2. 性能优化
2. tmpfs 一种基于内存的文件系统
3. nginx 优化
> 防止SQL注入、XSS攻击的实践配置方法
3.1. 版本号隐藏
3.2. 更改nginx默认用户
3.3. 优化wroker进程数
3.4. Nginx 事件模型优化
3.5. Nginx worker 进程最大打开文件数
3.6. Nginx 服务器域名hash表大小
3.7. 开启高效的文件传输模式
3.8. 超时连接优化
   3.8.1. 作用
   3.8.2. 问题
   3.8.3. 建议
   3.8.4. 配置
3.9. 动态参数引擎fastcgi
3.10. gzip
   3.10.1. 优点
   3.10.2. 需要和不需要压缩的对象
   3.10.3. 配置
3.11. nginx expires 缓存
   3.11.1. 优点
   3.11.2. 缺点
   3.11.3. 配置
3.12. nginx 日志
   3.12.1. 切割示例
   3.12.2. 不记录不需要的日志
   3.12.3. 访问日志权限设置
3.13. nginx 站点目录及文件URL控制
   3.13.1. 根据文件扩展名限制程序和文件访问
   3.13.2. 限制网站来源IP访问
   3.13.3. 配置nginx禁止非法域名解析
3.14. 防盗链
   3.14.1. 解决方案
3.15. 错误页面优雅显示
3.16. 站点目录权限优化
3.17. 防爬虫优化
   3.17.1. robots.txt 机器人协议
   3.17.2. nginx 防爬虫优化配置
3.18. nginx 限制http请求方法
3.19. 使用cdn做网站内容加速
3.20. 网站架构优化
   3.20.1. 为网站程序解耦
3.21. nginx 监牢模式
   3.21.1. nginx 服务降权解决方案
3.22. 控制nginx并发连接数
3.23. 控制 nginx请求
4. php 优化
4.1. php 参数调优
   4.1.1. php.ini 参数调优
   4.1.2. php.ini 参数调优
   4.1.3. php.ini 安全优化
   4.1.4. php session 会话保持
4.2. php-fpm 调优
   4.2.1. php-fpm.conf 调优
4.3. mysql 优化


前言

一篇包含tomcat、nginx、php、mysql的相关参数及性能的优化文件,看了很多,但却不能完全记住,整理一篇用于备忘。

1. tomcat 服务调优

1.1. 安全优化

  • 降权启动
    • 新建普通用户,切换到普通用户,启动tomcat
  • telnet管理端口保护
    • 修改配置文件/pathto/tomcat/conf/server.xml,22行左右的<Server port="8005" shutdown="SHUTDOWN"> 8005端口和SHUTDOWN(区分大小写)关键字,防止tomcat被远程关闭
  • ajp 连接端口保护
    • ajp 是apachetomcat相互沟通的一个渠道,如果不使用,需要注释掉。
  • 禁用管理端
    • 一般管理端用于测试使用,如不需要可以删除/pathto/tomcat/webapps/host-manager、manager目录,或者修改/pathto/tomcat/conf/tomcat-users.xml添加管理用户。

1.2. 性能优化

  • 屏蔽dns查询
    • enableLookups="false",69 : /pathto/tomcat/conf/server.xml
  • jvm 调优
    • JAVA_OPTS=根据监控协调参数。

2. tmpfs 一种基于内存的文件系统

可用于挂载临时文件存放目录,挂载后操作目录相当于直接操作内存,umount后挂载目录数据会被直接清空。

mount -t tmpfs -o size=1024M tmpfs /mnt/usb02

3. nginx 优化

记录一篇同僚文章: http://www.z-dig.com/nginx-optimization-25.html

nginx 规则匹配优先级: = > 完整路径 > ^~ > ~|~* > 部分起始路径 > /

防止SQL注入、XSS攻击的实践配置方法

原文接入: https://www.imydl.tech/lnmp/762.html

if ($request_method !~* GET|POST) { return 444; } #使用444错误代码可以更加减轻服务器负载压力。 #防止SQL注入 if ($query_string ~* (\$|'|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[\<|%3c]script[\>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm\(|innerhtml|innertext)(.*)$) { return 555; } if ($uri ~* (/~).*) { return 501; } if ($uri ~* (\\x.)) { return 501; } #防止SQL注入 if ($query_string ~* "[;'<>].*") { return 509; } if ($request_uri ~ " ") { return 509; } if ($request_uri ~ (\/\.+)) { return 509; } if ($request_uri ~ (\.+\/)) { return 509; } #if ($uri ~* (insert|select|delete|update|count|master|truncate|declare|exec|\*|\')(.*)$ ) { return 503; } #防止SQL注入 if ($request_uri ~* "(cost\()|(concat\()") { return 504; } if ($request_uri ~* "[+|(%20)]union[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]and[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]select[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]or[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]delete[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]update[+|(%20)]") { return 504; } if ($request_uri ~* "[+|(%20)]insert[+|(%20)]") { return 504; } if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { return 505; } if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { return 505; } if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { return 505; } if ($query_string ~ "proc/self/environ") { return 505; } if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { return 505; } if ($query_string ~ "base64_(en|de)code\(.*\)") { return 505; } if ($query_string ~ "[a-zA-Z0-9_]=http://") { return 506; } if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { return 506; } if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { return 506; } if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { return 507; } if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") {return 507; } if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { return 507; } if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { return 507; } #这里大家根据自己情况添加删减上述判断参数,cURL、wget这类的屏蔽有点儿极端了,但要“宁可错杀一千,不可放过一个”。 if ($http_user_agent ~* YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000|github|wget|curl|Java|python) { return 508; } #同上,大家根据自己站点实际情况来添加删减下面的屏蔽拦截参数。 if ($http_user_agent ~* "Go-Ahead-Got-It") { return 508; } if ($http_user_agent ~* "GetWeb!") { return 508; } if ($http_user_agent ~* "Go!Zilla") { return 508; } if ($http_user_agent ~* "Download Demon") { return 508; } if ($http_user_agent ~* "Indy Library") { return 508; } if ($http_user_agent ~* "libwww-perl") { return 508; } if ($http_user_agent ~* "Nmap Scripting Engine") { return 508; } if ($http_user_agent ~* "~17ce.com") { return 508; } if ($http_user_agent ~* "WebBench*") { return 508; } if ($http_user_agent ~* "spider") { return 508; } #这个会影响国内某些搜索引擎爬虫,比如:搜狗 #拦截各恶意请求的UA,可以通过分析站点日志文件或者waf日志作为参考配置。 if ($http_referer ~* 17ce.com) { return 509; } #拦截17ce.com站点测速节点的请求,所以明月一直都说这些测速网站的数据仅供参考不能当真的。 if ($http_referer ~* WebBench*") { return 509; } #拦截WebBench或者类似压力测试工具,其他工具只需要更换名称即可。

3.1. 版本号隐藏

  1. 修改文件: 修改nginx.conf,在http标签中添加server_tokens off;参数,然后reload
  2. 编译修改:
    • 修改nginx源码文件/pathto/nginx-x.xx.x/src/core/nginx.h,nginx版本号参数NGINX_VERSION,软件名称 NGINX_VAR
    • 修改nginx源码文件49: /pathto/nginx-x.xx.x/src/http/ngx_http_header_filter_module.c ,值 Server: xxxx(curl 显示的页面)
    • 修改nginx源码文件36: /pathto/nginx-x.xx.x/src/ngx_http_special_response.c,值 <hr><center>xxxx</center>(错误页面:例如502)
    • 正常编译安装

3.2. 更改nginx默认用户

  1. 修改配置文件: /pathto/nginx/conf/nginx.conf,值 user nobodyuser <user> <group>;
  2. 编译时指定默认用户: --user=<user> --group=<group>

3.3. 优化wroker进程数

# main worker_processes 8; worker_cpu_affinity 0001 0010 0100 1000 0001 0010 0100 1000; # 掩码形式 分别代表1-8核

3.4. Nginx 事件模型优化

nginx是异步的网络io模型,epoll 工作模型是高性能高并发的设置。

  1. 修改配置文件: /pathto/nginx/conf/nginx.conf
# main events { use epoll; worker_connections 65535; # 单个worker的连接数(并发等于 worker_connections * worker_processes ) }

3.5. Nginx worker 进程最大打开文件数

  1. main标签下设置worker_rlimit_nofile 65535 ,值可为系统优化后设置的ulimit -HSn的结果 。

3.6. Nginx 服务器域名hash表大小

: main

  1. 参数1: server_names_hash_max_size 512; 设置存放域名(server_names)的最大hash表大小
  2. 参数2: server_names_hash_bucket_size 128; 此设置与server_names_hash_max_size共同控制保存服务器域名的hash表.

3.7. 开启高效的文件传输模式

; http/server/location/if in location

  1. sendfile on;, 作用于两个文件描述符之间的数据拷贝函数,这个拷贝操作是在内核中的。
  2. tcp_nopush on;,允许把http response header和文件的开始放在一个文件里面发布,积极的作用是减少网络报文段的数量。
  3. tcp_nodelay on;, 提升io性能,默认情况下数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高I/O性能,但是,每次只发送很少字节的业务场景,使用tcp_nodelay功能,等待时间会比较长.(高并发建议使用)

3.8. 超时连接优化

3.8.1. 作用

  1. 设置将无用的连接尽快超时,可以保护服务器的系统资源(cpu、内存、磁盘)
  2. 当连接很多时,及时断掉那些已经建立好但又长时间不做事的连接, 以减少其占用的服务器资源,应为服务器维护连接也是要消耗资源的。
  3. 有时黑客或恶意用户攻击网站,就会不断的和服务器建立多个连接,消耗连接数,但啥也不干,只是持续建立连接,这就会大量消耗服务器的资源,此时就应该及时断掉这些恶意占用资源的连接。
  4. LNMP环境中,如果用户请求了动态服务,则Nginx就会建立连接请求fastcgi服务以及mysql服务,此时这个Nginx连接就要设定一个超时时间,在用户容忍的是就按内反回数据,或者在多等一会后端服务器返回数据,具体的策略要具体业务分析。

3.8.2. 问题

  1. 超时时间若设置太短,并发很大的时候,就会导致服务器无法瞬间响应用户请求,导致体验下降 。

3.8.3. 建议

  1. php 网站建议短连接,php程序建立连接消耗的资源和时间少
  2. java网站建议长连接,java程序建立连接消耗的资源和时间多(连接重用,连接池..)

3.8.4. 配置

# http/server keepalive_timeout 60; # 默认60秒 # keepalive_time 可以使客户端到服务器端已经建立的连接一直工作而不退出,当服务器有持续请求的时候,keep-alive会使用正在建立的连接提供服务,从而避免服务器重新建立新的连接处理请求。 此参数生效需激活tcp_nodelay选项 client_header_timeout 15; # 用于设置读取客户端请求头数据的超时时间,此处的数值15单位是秒,为经验参考值。如果超过此事件客户端还没有发送完整的header数据,服务端将返回 408错误 ,指定一个时间可以防止客户端利用http协议进行攻击 。 client_body_timeout 15; # 用于设置读取客户端请求主体的超时时间,这个超时仅仅为两次成功的读取操作之间的一个超时,非请求整个主体数据的超时时间,如果在这个超时时间内,客户端没有发送任何数据,则服务端返回 408 。 send_timeout 25; # 设置服务器端传送http响应信息到客户端的超时时间(服务端发给客户端),这个超时时间仅仅为两次成功握手后的一个超时,非请求整个响应数据的超时时间,如果这个超时时间内,客户端没有接受任何数据,连接将会被关闭。 # 上传文件大小 client_max_body_size 8m; # 上传文件大小,超过设置值反会413错误.

3.9. 动态参数引擎fastcgi

Nginx Fastcgi参数(http) 说明
fastcgi_connect_timeout 表示Nginx服务器和后端FastCGI服务器连接的超时时间,默认60s,这个参数通常设置不要超过75s,因为建立的连接诶越多消耗的资源就越多。(Nginx请求php服务器多少时间内要拿到数据,否则断开连接502)
fastcgi_send_timeout 设置Nginx允许FastCGI服务端返回数据的超时时间,即在规定时间之内后端服务器必须传完所有数据,否则Nginx将断开这个连接,默认60s(PHP需要在多少时间内将数据全部发送完成给nginx,否则断开)
fastcgi_read_timeout 设置Nginx从FastCGI服务端读取响应信息的超时时间,表示连接成功建立后,Nginx等待后端服务器的响应时间,是Nginx已经进入后端的排队之中等候处理的时间。
fastcgi_buffer_size 这个是Nginx fastcgi的缓冲区大小参数,设定用来读取从fastcgi服务端收到的第一部分响应信息的缓冲区大小,这里的第一部分通常会包含一个小的响应头部,默认情况下大小是由fastcgi_buffers 指定的一个缓冲区的大小
fastcgi_buffers 设定用来读取从Fastcgi服务端收到响应信息的缓冲区大小,已经缓冲区的数量。默认值:fastcg_buffers 8 4|8k; 指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256kb,那么会为其分配4个64kb的缓冲区来缓存;如果页面大小大于256k,那么大于256k的部分会被缓存到fastcgi_temp指定的路径中,但这样不是最好的方法,应为内存中处理的速度肯定是要高于硬盘的,一般这个值设定应该为站点中php脚本所产生的页面大小的中间值。那么可以把这个值设置为16 16k4 64k
fastcgi_busy_buffers_size 用于设置系统很繁忙的时候可以使用的fastcgi_buffers大小,官方推荐的大小为fastcgi_buffers *2,默认值 fastcgi_busy_buffers_size 8k|16k
fastcgi_temp_file_write_size fastcgi临时文件的大小,可设置128-256k
fastcgi_cache xxxx 表示开启fastcgi缓存并为其指定一个名称,开启缓存非常有用,可以有效的降低cpu负载,并且防止502错误的发生,但是开启缓存也有可能会引起其他问题,要根据具体情况来选择。
fastcgi_cache_path 例:fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:521min active=1d max_size=40g ,fastcgi_cache缓存目录,可以设置hash层级,比如2:2会生成256×256个子目录,keys_zone是这个缓存空间的名字,cache是用多少内存(这样热门的内容nginx直接存放内存,提高访问速度),inactive表示默认失效的时间,max_size 表示最多用多少硬盘空间。需要注意的是fastcgi_cache缓存是先写在fastcgi_temp_path,在转移到fastcgi_cache_path,所以这两个目录最好是放在同一分区
fastcgi_cache_valid 例: fastcgi_cache_valid 200 302 1h;当状态码是200、302时候缓存一小时;fastcgi_cache_valid 301 1d; 当状态码是301时缓存一天;fastcgi_cache_valid any 1m; 当状态码是其他的时候缓存1分钟
fastcgi_cache_min_uses 设置请求几次响应被缓存 例: fastcgi_cache_min_uses 1; 表示1次请求即被缓存
fastcgi_cache_use_stale 定义那些情况下使用过期缓存 例:fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_cache_key 例: fastcgi_cache_key $request_method://$host$request_uri; fastcgi_cache_key http://$host$request_uri; 定义fastcgi_cache的key,示例中就以请求的URI作为缓存的key,Nginx回去这个key的md5作为缓存文件,如果设置了缓存hash目录,nginx会从后向前取相应的位数作为目录。注意 一定要加上$request_method 作为cache key,否则如果HEAD类型的先请求会导致后面的GET请求返回为空。

示例配置:

# fastcgi 缓冲区 和 超时时间 (http标签) fastcgi_send_timeout 240; fastcgi_read_timeout 240; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_temp_path /opt/nginxssl/fastcgi_temp/tmp; fastcgi_cache_path /opt/nginxssl/fastcgi_temp/cache levels=2:2 keys_zone=cache:128m inactive=1d max_size=6g; #fastcgi 缓存 (server标签) fastcgi_cache cache; fastcgi_cache_valid 200 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_min_uses 1; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_cache_key http://$host$request_uri;

3.10. gzip

3.10.1. 优点

  • 提升网站用户体验,提升网站用户访问速度
  • 节约网站宽带成本

3.10.2. 需要和不需要压缩的对象

  • 纯文本内容压缩比很高,因此纯文本的内容最好要压缩(例如: html、js、css、xml、shtml等)
  • 被压缩的纯文本必须要大于1kb,否则由于压缩算法的原因,可能导致压缩反而是文件增大
  • 图片、视频(流媒体)等文件尽量不要压缩,因为这些文件大多都是经过压缩的,如果在压缩可能不会减少太多,或者可能增大,而在压缩还会消耗大量的cpu、内存资源

3.10.3. 配置

参数 作用
gzip on 开启gzip压缩功能
gzip_min_length 1k 设置允许压缩页面的最小字节数,页面字节数从header头的Content-Length中获取,默认0,表示不管页面多大都进行压缩
gzip_buffers 4 16k 压缩区缓冲区大小,表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
gzip_http_version 1.1 压缩版本,默认1.1,比如说前端访问的并不一定是用户,可能是cdn,这个时候就需要加一个版本,先大部分都支持gzip解压,设置默认即可
gzip_comp_level 2; 用来指定压缩比例,1 压缩最小,处理速度最快;9压缩比例最大,传输快,但处理速度慢,也比较消耗cpu资源
gzip_types text/plan application/x-javascript 指定需要压缩的文件类型
gzip_vary on; vary header 支持,该选项可以让前端的缓存服务器缓存gzip压缩的页面,(让缓存服务器继续缓存,而不是解压,只有在浏览器的时候在解压)

3.11. nginx expires 缓存

3.11.1. 优点

  • expires 可以降低网站的宽带,节约成本
  • 加快用户访问网站的速度,提升用户体验
  • 减少服务器访问量,降低服务器压力,节约服务器成本

3.11.2. 缺点

  • 当网站被缓存的页面存在更新时,用户看到的可能还是旧的数据
    • 解决方案:
      1. 缩短经常修改页面的缓存时间
      2. 对于经常修改的页面文件名进行添加,或加上版本号,这样前端cdn以及用户端需要重新更新缓存内容

3.11.3. 配置

如果配置后导致前端无法正常访问,有可能是因为server标签中没有指定root目录有关
示例:

# server / http location ~ .*\.(gif|jpg|jpeg|png|bmp|swf){ expires 6d; }

3.12. nginx 日志

3.12.1. 切割示例

#!/bin/bash # 40 23 * * * /bin/bash /opt/sh/cut_nginx_all.sh >> /dev/null 2>&1 time=`date +"%Y-%m-%d"` log_path="/opt/nginxssl/logs" pid_path="/opt/nginxssl/logs/nginx.pid" new_dir="/opt/logs/nginxlogs" # nginx web 日志 (www.log) ,以空格隔开,无需后缀 logs_names=(www www1) cd $new_dir num=${#logs_names[@]} for((i=0;i<num ;i++));do mv ${log_path}/${logs_names[i]}.log ${new_dir}/${logs_names[i]}_${time}.log tar czf ${logs_names[i]}_${time}.tar.gz ${logs_names[i]}_${time}.log rm ${logs_names[i]}_${time}.log done /opt/nginxssl/sbin/nginx -s reopen

3.12.2. 不记录不需要的日志

  1. 在实际工作中,对于负载均衡器的健康检查节点或某些特定文件(如图片、js、css等)的日志,一般不需要记录下来,因为在PV时是按照页面计算的。而且日志写入太频繁会大量消耗磁盘IO,降低服务器性能.
    • 网络流量度量术语
      1. 独立(公网)ip数: 指的是不同IP地址的计算机访问网站时被计算的总次数。独立IP书是衡量网站流量的一个重要指标。一般一天内相同IP地址的客户端访问网站页面只被计算为一次,记录独立IP的时间可以为一天或一个月,目前通常标准为一天;
      2. PV 访问量: 即Page View 页面浏览,即页面浏览量或点击量,不管客户端是不是相同,也不管ip是不是相同,用户每次访问一个网站页面都会被计算一个PV。具体度量方法就是从客户浏览器发出一个对web服务器的请求,web服务器接到这个请求后,将该请求对应的一个网页发给浏览器,就产生了一个pv。但是只要这个请求发送给了浏览器,无论这个页面是否完全打开(或下载完成),那么都会被(服务器日志)计数为一个PV,一般为了防止用户快速刷PV,都是把PV的统计程序放在页面的最下面。
      3. UV 独立访客数: 同一个客户端(PC或移动端) 访问网站被计算为一个访客,一天内相同的客户端访问同一个网站只计算一次UV,UV一般是以客户端Cookie等计算作为统计依据,实际统计会有误差。一台客户端可能忽悠多人使用的情况,因此,UV实际上并不一定是独立的自然人访问。
  2. 配置方法:
    这里的location标签匹配不记录日志的元素扩展名,然后关掉了日志。
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ { access_log off; }

3.12.3. 访问日志权限设置

  • 限制用户及组为root , 修改目录权限 600 ,nginx访问日志的权限即使是root,nginx也是可以读取的

3.13. nginx 站点目录及文件URL控制

3.13.1. 根据文件扩展名限制程序和文件访问

  • 示例:
location ~ ^/image/.*\.(php|php5|sh|pl|py)${ deny all; } location ~ ^/static/.*\.(php|php5|sh|pl|py)${ deny all; } location ~ ^/data/(attachment|avatar)/.*\.(php|php5)${ deny all; }

3.13.2. 限制网站来源IP访问

location ~ ^/oldboy/{ allow xx.xx.xx.xx; allow xx.xx.xx.xx/xx; # deny xx.xx.xx.xx; deny all; }

使用if来限制客户端ip

if ($remote_addr = 10.0.0.7 ) { return 403; } if ($remote_addr = xx.xx.xx.xx ) { set $allow_access_root 'true'; }

3.13.3. 配置nginx禁止非法域名解析

  1. 问题: 如何防止用户IP访问网站(恶意域名解析,也相当于ip访问网站)
    解决:让使用ip访问网站的用户,或者恶意解析域名的用户,收到501错误。(需要放到所有server之前)
server { listen 80 default_server; server_name _; return 501; }

3.14. 防盗链

3.14.1. 解决方案

  1. 根据http_referer实现防盗链 示例:
# server location ~* ^.+\.(jpg|png|swf|flv)$ { valid_referers none bloked *.example.com; if ($invalid_referer) { #rewrite ^/ https://www.example.com/daolian.png; return 403; } }
  1. 根据cookie防盗链

3.15. 错误页面优雅显示

示例:

# error_page 可以多行,每行对应一个状态码 error_page 500 502 503 504 404 /50x_error.html; # 若集群,建议选择域名跳转,统一分配 # error_page 500 502 503 504 404 http://www.example.com/erro_page;

fastcgi_intercept_errors on; 默认 off ,这个指令指定的是是否传递 4xx5xx信息到客户端,或允许nginx 使用error_page处理错误信息。

3.16. 站点目录权限优化

目录权限755,文件权限644,用户及组root,用户上传目录nginx服务用户.(减少文件上传目录权限)

3.17. 防爬虫优化

3.17.1. robots.txt 机器人协议

网站通过robots(网站根目录存放robots.txt)协议告诉搜索引擎哪些页面可以抓取,那些页面不能抓取。 示例:

User-agent: * Disallow: / Sitemap: https://www.example.com/sitemap.xml

3.17.2. nginx 防爬虫优化配置

示例:

# server|location if ($http_user_agent ~* "LWP::Simple|BBBike|wget") { return 403; }

3.18. nginx 限制http请求方法

示例:

# 屏蔽非GET|HEAD|POST的请求方法 # server|location if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 501; }

3.19. 使用cdn做网站内容加速

cdn全国或全球的分布式缓存集群

3.20. 网站架构优化

3.20.1. 为网站程序解耦

指的是把一堆程序代码按照业务用途分开,然后提供服务。例如: 注册登陆、上传、下载、浏览列表、商品内容页面、订单支付等都应该是独立的程序服务。

3.21. nginx 监牢模式

3.21.1. nginx 服务降权解决方案

解决方案:

  • nginx 服务降权,用普通用户(假设普通用户为www )跑nginx 服务,给开发和运维设置普通用户帐号,将开发和运维的帐号设置为与www 同组即可管理nginx,该方案解决了nginx管理问题,防止root分配权限过大。
  • 开发人员使用普通用户即可管理nginx 服务及站点下的程序和日志。
  • 采取项目负责制度,即谁负责的项目维护出了问题就是谁负责。

3.22. 控制nginx并发连接数

示例:

# 定义 # http limit_conn_zone $binary_remote_addr zone=addr:10m; #使用(seerver/location) limit_conn addr 1;

3.23. 控制 nginx请求

# 定义 # http limit_req_zone $binary_remote_addr zone=one;10m rate=1r/s; #使用(seerver/location) limit_req zone=one burst=5;

4. php 优化

4.1. php 参数调优

php.ini-developmentphp.ini-production的区别是日志的开启与隐藏

4.1.1. php.ini 安全参数调优

; 打开安全模式(防止system()函数可调用系统命令),5.5以上已无该参数 safe_mode = On ; safe_mode 打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且同组的用户也能狗对文件进行访问。设置off进行关闭,5.5以上已无该参数 safe_mode_gid = Off ; 关闭危险函数(phpinfo,passthru,exec,shell_exec,system,popen,proc_open,proc_get_status,chroot,scandir,chgrp,chown,readdir,ls_dir,ini_set,ini_alter,ini_restore,dl,pfsockopen,fsocket,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,rmdir,chmod,closedir,opendir,dir,fileperms,copy,delfile),默认无限制 disable_functions = phpinfo ; 关闭php版本信息(默认On) expose_php = Off ; 关闭注册全局变量,5.5以上已无该参数 register_globals = Off ; 防止sql注入(打开后自动把用户体检对sql的查询进行转换,例如把'转换为\),默认Off,5.5以上已无该参数 magic_quotes_gpc = On ; 错误信息输出控制,默认On ; 建议在关闭display_errors后能够把错误信息记录下来,便于查找服务器运行的原因: ; log_errors = On ; error_log = /var/log/php_error.log display_errors = Off

4.1.2. php.ini 优化参数调优

; 每个脚本最大允许执行时间(s),0 表示没有限制 max_execution_time = 30 ; 每个脚本使用的最大内存,要能够使用该指令编译时必须启用 --enable-memory-limit 选项 memory_limit = 128M ; 每个脚本等待输入数据的最长时间 ,-1 表示不限制 max_input_time = 60 ; 上传文件的最大许可 upload_max_filesize = 2M ; 最大上传的文件数量(可同时上传多少个文件),默认20 max_file_uploads = 20 ; http post 数据的大小 (请求包的大小),默认8M post_max_size = 8M

4.1.3. php.ini 安全优化

; 禁止打开远程地址,默认On allow_url_fopen = Off ; 防止nginx文件类型错误解析漏洞,默认1 cgi.fix_pathinfo = 0

4.1.4. php session 会话保持

集群环境,一般会将session存放于memcache中,多个集群节点连接同一个memcache,保证用户session处于在线状态
php.ini 修改

; 调整php session 信息存放类型,默认文件 files session.save_handler = memcache ; session 保存位置,默认tmp session.save_path = "tcp://10.0.0.18:11211"

4.2. php-fpm 调优

4.2.1. php-fpm.conf 调优

; 打开进程pid pid = run/php-fpm.pid ; 打开php-fpm 进程错误日志 error_log = log/php-fpm.log ; 错误日志级别 , 默认notice log_level = error ; 最大的php-fpm进程数量(静态),默认128 process.max = 128 ; 文件描述符,默认1024 rlimit_files = 10240 ; 表示在emergency_restart_interval时间内,出现SIGEGV或者SIGBUS错误的php-cgi进程数如果超过了 ; emergency_restart_threshold个,则php-cgi就会优雅重启 emergency_restart_interval = 60s emergency_restart_threshold = 60 ; ; 池定义 ; 与nginx用户一样 [www] user = www group = www ; 监听 listen = 127.0.0.1:9000 ; 控制允许访问的客户端 listen.allowed_clients = 127.0.0.1 ; 进程模式,默认动态,开启后需配合pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers参数进行设置 pm = dynamic ; 同一时间,最大可创建的子进程的数量(静态模式下由此参数固定进程数) pm.max_children = 300 ; 设置启动时创建的子进程数目 pm.start_servers = 20 ; pm.*_spare_servers 设置空闲服务进程的最低/最大数目 pm.min_spare_servers = 20 pm.max_spare_servers = 300 ; 进程的超时时间,当进程不提供服务后,多少秒关闭,默认10s pm.process_idle_timeout = 10s ; 一个子进程处理多少个请求后退出,默认 0 pm.max_requests = 10240

4.3. mysql 优化

等我看完在更新