虚拟化容器,大数据,DBA,中间件,监控。

Nginx 调优

09 11月
作者:admin|分类:应用管理

  • 隐藏 Nginx 版本号
  • 修改 nginx 运行用户-设置 nginx 的 cpu 亲和力
  • 设置 Nginx 每个进程最多可以打开的文件数和事件处理模型
  • ServerName 和 location 匹配及高效传输模式
  • Fastcgi 调优-gzip 压缩网页调优-expires 缓存调优
  • 日志切割优化-目录文件访问控制-来源访问控制
  • 禁止使用 IP 访问网站和 301 优化-防盗链-错误页面的提示-开启认证功能  

  • 修改 nginx 源代码
  • 下载 nginx
  • wget http://nginx.org/download/nginx-1.21.1.tar.gz

  • 隐藏 Nginx 版本号,需要一共修改 3 个源代码文件 nginx.h   ngx_http_header_filter_module.c   ngx_http_special_response.c
  •  tar xf nginx-1.21.1.tar.gz -C /opt/
     cd /opt/nginx-1.21.1/
  • vim src/core/nginx.h
  • 改:
    define NGINX_VERSION "1.21.1"
    define NGINX_VER "nginx/" NGINX_VERSION
    为:
    #define NGINX_VERSION "8.8.8.8" #此行修改的是你想要的版本号。
    #define NGINX_VER "GF/" NGINX_VERSION #此行修改的是你想修改的软件名称。

  •  修改 HTTP 头信息中的 connection 字段,防止回显具体版本号
  • vim src/http/ngx_http_header_filter_module.c
  • 改:static char ngx_http_server_string[] = "Server: nginx" CRLF;
  • 为:static u_char ngx_http_server_string[] = "Server: GF" CRLF;

  • 修改 ngx_http_special_response.c 文件定义了 Nginx 报 404 错误时,不回显版本号。 
  • vim src/http/ngx_http_special_response.c
  • 改 :static u_char ngx_http_error_tail[] =
    "<hr><center>nginx</center>" CRLF
    "</body>" CRLF
    "</html>
  • 为:static u_char ngx_http_error_tail[] =
    "<hr><center>GF</center>" CRLF
    "</body>" CRLF
    "</html>

  • 编译和安装 nginx,安装 nginx 依赖包
  • yum -y install gcc gcc-c++ autoconf automake zlib zlib-devel openssl openssl-devel pcre pcre-devel gd-devel
  • 创建一个 nginx 用户用于后期启动 nginx 进程使用,比直接使用 root 用户启动 nginx 更安全
    useradd -s /sbin/nologin -M nginx 

  • ./configure --prefix=/usr/local/nginx1.21.1 --user=nginx --group=nginx \

    --with-http_ssl_module --with-http_dav_module --with-http_stub_status_module \

    --with-http_addition_module --with-http_sub_module --with-http_flv_module \

    --with-http_mp4_module --with-http_realip_module --with-http_gzip_static_module \

    --with-pcre --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log \

    --http-log-path=/var/log/nginx/access.log --with-debug --with-http_image_filter_module

  • --with-http_dav_module #启用支持(增加 PUT,DELETE,MKCOL:创建集合,COPY 和MOVE 方法)。 默认关闭,需要编译开启
    --with-http_stub_status_module #启用支持(获取 Nginx 上次启动以来的工作状态)。
    --with-http_addition_module #启用支持(作为一个输出过滤器,支持不完全缓冲,分部分相应请求)。
    --with-http_sub_module #启用支持(允许一些其他文本替换 Nginx 相应中的一些文本)。
    --with-http_flv_module #启用支持(提供支持 flv 视频文件支持)。
    --with-http_mp4_module #启用支持(提供支持 mp4 视频文件支持,提供伪流媒体服务端支持)。
    --with-pcre #支持 正则表达式
  • 用#./configure --help 查看帮助。
  • make -j 4 && make install
  • 启动 nginx 服务
    /usr/local/nginx/sbin/nginx

  • nginx systemctl 启动脚本

  • # vim /lib/systemd/system/nginx.service
    [Unit]
    Description=nginx
    After=network.target
    [Service]
    Type=forking
    ExecStart=/usr/local/nginx1.21.1/sbin/nginx
    ExecReload=/usr/local/nginx1.21.1/sbin/nginx -s reload
    ExecStop=/usr/local/nginx1.21.1/sbin/nginx -s quit
    PrivateTmp=true
    [Install]
    WantedBy=multi-user.target
  • # systemctl daemon-reload
    # systemctl enable nginx.service --now
    # systemctl is-enabled nginx

    enabled

  •  测试 :查看在 http 协议中是否隐藏了版本和软件名

  • 测试 :当访问时,出现 404 及其它错误时也会返回已经隐藏的版本信息

  • 测试 :当访问时,出现 403 错误也会返回已经隐藏的版本信息

  • 修改 Nginx 运行用户
  • vim /etc/nginx/nginx.conf
  • 改为:user  nginx;
     
  • 不重启 nginx 服务加载配置文件
  • /usr/local/nginx1.21.1/sbin/nginx -s reload   

  • 这个是以 nginx 身份运行的 worker process 是 nginx 的工作进程,work 进程才为用户提供服务
  • 设置 Nginx 运行进程个数,一般设置为 CPU 核心数或者核心数的2倍,或者设置为 auto 自动识别

  • vim /etc/nginx/nginx.conf
    worker_processes  auto;

  • 查看 nginx 管理进程和 4 个 work 进程的父子关系

  • pstree -p |grep nginx

  • pstree 属于 psmisc 包
  • yum -y install psmisc
  •  设置 Nginx 运行 CPU 的亲和力
    CPU 的亲和力,就是把 nginx 每个进程绑定到固定的 cpu 上,从而减少 cpu 上下文切换导致的额外的开销。
    比如服务器是 4 核 4 线程的 cpu,配置如下:
    vim /etc/nginx/nginx.conf
    worker_processes auto;     #在此行下添加
    worker_cpu_affinity 0001 0010 0100 1000; 
  •  如果服务器是 8 核 8 线程的 cpu,应该配置为如下:
  • worker_processes 8;
  • worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
  • 查看

    # /usr/local/nginx1.21.1/sbin/nginx -s reload
    # pstree -p |grep nginx
               |-nginx(86539)-+-nginx(103390)
               |              |-nginx(103391)
               |              |-nginx(103393)
               |              `-nginx(103395)
    # taskset -cp 103390 

  • list: 0      #表示 nginx PID 103390,只能在第一个 cpu 运行,以此类推

  • 设置 Nginx 每个进程最多可以打开的文件数和事件处理模型

  • Nginx 最多可以打开文件数
  • worker_rlimit_nofile 655350; 
    这个指令是指当一个 Nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与 nginx 进程数相除,即:(ulimit -n)/ worker_processes ,但是 nginx 分配请求并不是那么均匀,所以最好与 ulimit -n 的值保持一致。
  • 修改 ulimit -n 的值
  • ulimit -n 655350

  •  Nginx 事件处理模型
    # vim /usr/local/nginx/conf/nginx.conf
    events {
    use epoll; #添加这一行,使用 epoll 模式
    worker_connections 655350;

  • Nginx 事件处理模型对比

select,poll,epoll 都是 nginx 下的 IO 多路复用的机制。I/O 多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
Epoll 在 Linux2.6 内核中正式引入,和 select 和 poll 相似,其实都是 I/O 多路复用技术。

  • epoll 优势:

Epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于 2048, 一般来说这个数目和系统内存关系很大,具体数目可以 cat /proc/sys/fs/file-max 察看。
# cat /proc/sys/fs/file-max
808855
效率提升,Epoll 最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll 的效率就会远远高于 select 和 poll。
Epoll 在这点上使用了“共享内存”,更省内存,效率更高。

  • 单个进程允许客户端最大并发连接数 
    # 1  html  vim /etc/nginx/nginx.conf
    改:worker_connections 1024; 
    为:worker_connections 655350; 
  •  worker_connections:这个属性是指单个工作进程可以允许同时建立外部连接的数量。无论这个连接是外部主动建立的,还是内部建立的。一个工作进程建立一个连接后,进程将打开一个文件副本。所以这个数量还受限于,操作系统 ulimit -n 设定的值和 nginx 的 worker_connections 的值。一般情况下系统 ulimit -n、worker_rlimit_nofile 、worker_connections 三者的值设定一致。 
  • nginx 服务器实际最大并发值就是:worker_processes*worker_connections 的乘积。
  • # top -u nginx               #Nginx 每个进程使用的内存大小。
  •    PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                  
    104020 nginx     20   0  348828 275636   3148 S   0.0  3.4   0:00.37 nginx                                                                                                                    
    104021 nginx     20   0  348828 275632   3144 S   0.0  3.4   0:00.35 nginx                                                                                                                    
    104024 nginx     20   0  348828 275636   3148 S   0.0  3.4   0:00.36 nginx                                                                                                                    
    104025 nginx     20   0  348828 275632   3144 S   0.0  3.4   0:00.36 nginx 
  • 注:通过查看 RES 列,可以看到刚启动的 nginx 进程占用内存大概 275M 左右。

  • ServerName 和 location 匹配及高效传输模式 

  • ServerName 匹配
  • ServerName 匹配方式
    (1)、精确匹配:www.aa.com
    (2)、左侧通配符匹配:*.aa.com
    (3)、右侧通配符匹配:www.*
    (4)、正则表达式:~ ^.*\.aa\.com$
    (5)、default_server
    (5)、服务 IP 地址
  • 修改 server_name 值为实际的域名
    # vim /etc/nginx/nginx.conf
    改:server_name localhost;
    为:server_name  gf-beyond.com; 
    注:nginx 配置文件中,每个参数都是以分号;结束
  • -t #检测 nginx 配置文件是否正确

  • location 匹配如下:
    = 绝对匹配。
    ^~ URL 前半部分匹配,不检查正则。~ 正则匹配,区分大小写。
    ~* 正则匹配,不区分大小写。
    \ 转义。
    * 配置任意个任意字符。
    $ 以什么结尾。
    例:匹配出以.php 结尾的文件且配置时不区分大小写。 
  • location ~ \.php$ {..}  #~ \.php$ 表示 url 中以.php 结尾的文件且区分大小写,都按{...}中的方法进行处理 。 这个就可以完成我们的需求。
  • 例:匹配出以.txt 结尾的文件且配置时不区分大小写
     location ~* \.txt$ {
    root file;
    }
  • 开启高效传输模式

  • 在 http 模块内配置
  • http {
    Include mime.types;                                #媒体类型。
    default_type application/octet-stream;    #默认媒体类型 足够。
    sendfile on;           #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成 off。
    tcp_nopush on;必须在 sendfile 开启模式才有效,防止网络阻塞,积极的减少网络报文段的数量。
  • 连接超时时间
    主要目的是保护服务器资源,CPU,内存,控制连接数,因为建立连接也是需要消耗资源的,TCP 的三次握手四次挥手等,我们一般断掉的是那些建立连接但是不做事儿,也就是我建立了链接开始,但是后续的握手过程没有进行,那么我们的链接处于等待状态的,全部断掉!
    同时我们也希望 php 建议短链接,消耗资源少。
  • keepalive_timeout 65;       #在此行下加入如下
    tcp_nodelay on;
    client_header_timeout 15;
    client_body_timeout 15;
    send_timeout 15;
  • keepalived_timeout 客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接。
    tcp_nodelay;也是防止网络阻塞,不过要包涵在 keepalived 参数才有效。client_header_timeout 客户端请求头读取超时时间,如果超过设个时间没有发送任何数据,nginx将返回 request time out 的错误。
    client_body_timeout 客户端求主体超时时间,超过这个时间没有发送任何数据,和上面一样的错误提示。
    send_timeout 响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx 关闭连接。
  • 文件上传大小限制  , PHP 可以修改上传文件大小限制,nginx 也可以修改。
  • client_max_body_size 10m;
  • Fastcgi 调优-gzip 压缩网页调优-expires 缓存调优
  • 使用 gzip 压缩功能,可能为我们节约带宽,加快传输速度,有更好的体验,节约成本,所以说这是一个重点。
    Nginx 启用压缩功能需要 ngx_http_gzip_module 模块,apache 使用的是 mod_deflate
    一般需要压缩的内容有:文本,js,html,css,对于图片,视频,flash 什么的不压缩,同时也要注意,使用 gzip 的功能需要消耗 CPU 
  •     gzip on;
        gzip_min_length 1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml font/ttf font/otf
        gzip_vary on;
        gzip_proxied expired no-cache no-store private auth;
        gzip_disable "MSIE [1-6]\.";
  • gzip on; #开启压缩功能。
    gzip_min_length 1k; #设置允许压缩的页面最小字节数,页面字节数从 header 头的Content-Length(内容长度)中获取,默认值是 0,不管页面多大都进行压缩,建议设置成大于 1K,如果小与 1K 可能会越压越大。
    gzip_buffers 4 32k; #压缩缓冲区大小,表示申请 4 个单位为 32K 的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储 gzip 压缩结果。
    gzip_http_version 1.1; #压缩版本(默认 1.1,前端为 squid2.5 时使用 1.0)用于设置识别 HTTP协议版本,默认是 1.1,目前大部分浏览器已经支持 GZIP 解压,使用默认即可。
    gzip_comp_level 9; #压缩比例,用来指定 GZIP 压缩比,1 压缩比最小,处理速度最快,9 压缩比最大,传输速度快,但是处理慢,也比较消耗 CPU 资源。
    gzip_types text/css text/xml application/javascript; #用来指定压缩的类型,‘text/html’类型总是会被压缩。
    gzip_vary on; #vary header 支持,该选项可以让前端的缓存服务器缓存经过 GZIP 压缩的页面,
    例如用 Squid 缓存经过 nginx 压缩的数据。
  • Fastcgi 相关概念
    FastCGI 是一种协议,规定了 FastCGI 应用和支持 FastCGI 的 Web 服务器之间的接口。Fastcgi 是静态服务和动态服务的一个接口 FastCGI 是二进制连续传递的。
    Fastcgi 相关的个概念如下:
    Cache:写入缓存区
    Buffer:读取缓存区
    Fastcgi 是静态服务和动态服务的一个接口
  •     fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_path /var/run/nginx-tmp-cache;
        fastcgi_temp_file_write_size 128k;
        fastcgi_cache_path /var/run/nginx-cache levels=1:2
        keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g;
  • }
  • 在 server 标签添加如下:
  • server {
  • .......
  •         location ~ .*\.(php|php5)?$ {
             root           /usr/local/nginx1.21.1/html;
             fastcgi_pass 127.0.0.1:9000;
             fastcgi_index index.php;
             fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
             include        fastcgi_params;
             include        fastcgi.conf;
             fastcgi_cache ngx_fcgi_cache;
             fastcgi_cache_valid 200 302 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;
            }
    .......
    }
  • fastcgi cache 资料 官方文档:

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache

配置详解:
HTTP 字段:
fastcgi_connect_timeout 300; #指定链接到后端 FastCGI 的超时时间。
fastcgi_send_timeout 300; # Nginx 允许 FastCGI 服务器返回数据的超时时间,即在规定时间内后端服务器必须传完所有的数据,否则 Nginx 将断开这个连接。
fastcgi_read_timeout 300; # Nginx 从 FastCGI 服务器读取响应信息的超时时间,表示连接建立成功后,Nginx 等待后端服务器的响应时间。
fastcgi_buffers 4 64k; #指定缓冲区的数量和大小,如果一个 PHP 脚本返回的页面大小为 256K,则分配为 4 个 64K 的缓冲区来缓存,大于缓冲区大小的应答结果将被写入 temp_file 临时文件中。推荐该值为你的站点 php 脚本返回的页面大小的平均进行设置,尽量不需要使缓存文件写入磁
盘,也不要设置太大导致内存资源浪费。
fastcgi_temp_path /var/run/nginx-tmp-cache; #指定临时目录
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=ngx_fcgi_cache:512m 
inactive=1d max_size=40g; #定义缓存的路径、大小、缓存时间。
上条命令详解:(参数过长拆分详解)
fastcgi_cache_path 创建缓存路径,如果指定其他路径需注意上层目录是否创建。
levels:指定了该缓存空间有两层 hash 目录,设置缓存目录层数,levels=1:2,表示创建两层目录缓存,最多创建三层。第一层目录名取 fastcgi_cache_key md5 的最后一个字符,第二层目录名取倒数2-3 字符,如:fastcgi_cache_key md5 为 b7f54b2df7773722d382f4809d65029c,则:
注:levels 虽然可以设置 3 层但是数值请勿大于 2.如果设置 1:2:3 则报错。1:2:2 则正常。
levels=2:2 为/var/run/nginx-cache/9c/02/b7f54b2df7773722d382f4809d65029c
levels=1:2 为/var/run/nginx-cache/c/29/b7f54b2df7773722d382f4809d65029c
keys_zone 为这个缓存区起名为 zone_name
512m 指缓存空间最一开始为 512MB;
inactive=1d 代表如果缓存文件一天内没有被访问,则删除;
max_size=40g 代表缓存最大为 40G,建议根据自己的磁盘剩余空间来写大小,不能超过剩余缓存的 80%;

Server 字段中配置详解:
include fastcgi.conf; #引用 fastcgi 默认配置文件
fastcgi_cache ngx_fcgi_cache; #指定缓存名称,由 http 字段中 fastcgi_cache_path
创建。
fastcgi_cache_valid 200 302 1h; #设置 200、302 状态的 URL 缓存 1 小时
fastcgi_cache_valid 301 1d; #设置 301 状态的 URL 缓存 1 天。
fastcgi_cache_valid any 1m; #将其他应答缓存为 1 分钟。
fastcgi_cache_min_uses 1; #设置请求 1 次就会被缓存。
fastcgi_cache_use_stale error timeout invalid_header http_500; #设置 500 状态码
不进行缓存。500 状态码意思是:内部服务器错误
fastcgi_cache_key http://$host$request_uri; #该指令用来设置 Web 缓存的 Key 值,Nginx
根据 Key 值 MD5 缓存。一般根据 host(域名),request_uri(请求的路径)等变量组合成
fastcgi_cache_key。MD5 值将作为缓存文件名。

  • expires 缓存调优
    缓存,主要针对于图片,css,js 等元素更改机会比较少的情况下使用,特别是图片,占用带宽大,完全可以设置图片在浏览器本地缓存 365d,css,js,html 可以缓存个 10 来天,这样用户第一次打开加载慢一点,第二次,就非常快了!缓存的时候,我们需要将需要缓存的拓展名列出来!
  • Expires 缓存配置在 server 字段里面:
  •         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
                    expires 365d;
            }
            
            location ~ .*\.(js|css)?$ {
                    expires 30d;
            }

            location ~ ^/(images|javascript|js|css|flash|media|static)/ {
                    expires 360d;
            }

            location ~(robots.txt) {
                    expires 7d;
                    break;
            }

  • }

  • expire 功能缺点:
    被缓存的页面或数据更新了,用户看到的可能还是旧的内容,反而影响用户体验。
    解决办法:
    第一个 缩短缓存时间,例如:1 天,不彻底,除非更新频率大于 1 天。
    第二个 对缓存的对象改名。
    a.图片,附件一般不会被用户修改,如果用户修改了,实际上也是更改文件名重新传了而已。
    b.网站升级对于 js,css 元素,一般可以改名,把 css,js,推送到 CDN。
    网站不希望被缓存的内容:
    1)广告图片
    2)网站流量统计工具
    3)更新频繁的文件(google 的 logo)
  • 查看缓存目录

  • 将缓存文件挂载至内存
  • # vim /etc/fstab #添加一行
    tmpfs /var/run/nginx-cache tmpfs defaults,size=512M 0 0
    mount -a
    df -Th

  • 注:fastcgi_cache 缓存是先写在 fastcgi_temp_path 再移到 fastcgi_cache_path,所以如果不选择将缓存目录挂载至内存,建议 tmp_path 和 cache_path 在同一分区中,同分区文件复制不会占用过高的 IO 资源。
  •  浏览器 F12 查看缓存情况 

  • ​​​日志切割优化-目录文件访问控制-来源访问控制

  • 日志优化的目的,是为了一天日志一压缩,按天存放,超过 10 天的删除。


  • # vim /usr/local/nginx1.21.1/logs/cut_nginx_log.sh         #每天日志分割脚本。

  • #!/bin/bash
    date=$(date +%F -d -1day)
    cd /var/log/nginx/
    if [ ! -d cut ] ; then mkdir cut
    fi
    mv access.log cut/access_$(date +%F -d -1day).log
    mv error.log cut/error_$(date +%F -d -1day).log
    /usr/local/nginx1.21.1/sbin/nginx -s reload
    tar -JcPf cut/$date.tar.xz cut/*
    mv cut/$date.tar.xz /var/log/nginx/
    rm -f cut/access* && rm -f cut/error*
    if [[ -z `egrep -v "00 00 * * * /bin/bash /usr/local/nginx1.21.1/logs/cut_nginx_log.sh &> /dev/null" /var/spool/cron/root` ]]; then
    echo "00 00 * * * /bin/bash /usr/local/nginx1.21.1/logs/cut_nginx_log.sh &> /dev/null" >> /var/spool/cron/root
    fi
    find /var/log/nginx/cut/ -type f -mtime +10 | xargs rm -rf

  • chmod +x cut_nginx_log.sh

  • ./cut_nginx_log.sh

  • 健康检查的日志,不用输入到 log 中,因为这些日志没有意义,我们分析的话只需要分析访问日志,看看一些页面链接,如 200,301,404 的状态码,在 SEO 中很重要,而且我们统计 PV 是页面计算,这些都没有意义,反而消耗了磁盘 IO,降低了服务器性能,可以屏蔽这些如图片,js,css 这些不宜变化的内容。
    # vim /etc/nginx/nginx.conf
  • server {
  • ......
           location ~ .*\.(js|jpg|jpeg|JPG|JPEG|css|bmp|gif|GIF)$ {
                    access_log off;
            }
  • ........
  •  }
  • 测试读取日志文件 

  • 日志目录权限优化:只允许root用户有更改权限
  • chown -R root. /var/log/nginx/
  • 日志格式优化

  • 注意不能写在 server 字段 否则会报一个类似:nginx: [emerg] “log_format” directive is not allowed here in的错误
  • log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for ' '"$upstream_addr" "$upstream_status" "$upstream_response_time" "$request_time"';
    其中,各个字段的含义如下:
     1. $remote_addr 与$http_x_forwarded_for 用以记录客户端的 ip 地址;
     2. $remote_user :用来记录客户端用户名称;
     3. $time_local : 用来记录访问时间与时区;
     4. request : 用来记录请求的 url 与 http 协议;
     5. status : 用来记录请求状态,功是 200;
     6. body_bytes_s ent :记录发送给客户端文件主体内容大小;
     7. http_referer :用来记录从哪个页面链接访问过来的;
     8. http_user_agent :记录客户端浏览器的相关信息;

  • 目录文件访问控制
    主要用在禁止目录下指定文件被访问,当然也可以禁止所有文件被访问!一般什么情况下用?比如是有存储共享,这些文件本来都只是一些下载资源文件,那么这些资源文件就不允许被执行,如 sh,py,pl,php等等。
    例如:禁止访问 images 下面的 php 程序文件 
  • 在 server 字段添加
  • server {
  • ......
  •         location ~ ^/images/(jpg|png)/.*\.(php|php5|.sh|.py|.py)$ {
                     deny all;
            }
  • }
  • echo "<?php phpinfo(); ?>" > /usr/local/nginx1.21.1/html/images/test.php
  • chown root. /usr/local/nginx1.21.1/html/images/test.php
  • chmod 600 /usr/local/nginx1.21.1/html/images/test.php

  •  其他文件访问正常

  •  images 下的其他目录下的 PHP 文件

  •  配置 nginx 禁止访问*.txt 文件
  • server {
  • .................
  •         location ~* \.(txt|doc)$ {
                    if ( -f $request_filename) {
                    root /usr/local/nginx1.21.1/html;
                    break;
                    }
                    deny all;
            }
  • ....................
  • }

  •  其他目录

  •  也可以重定向到某一个 URL
  • server {
  • ..........
    location ~* \.(txt|doc)$ {

                if ( -f $request_filename) {
                root /usr/local/nginx1.21.1/html;
                rewrite ^/(.*)$ http://www.gf-beyond.com last;
                break;
                }
                #deny all;
        }
......
}


 

  •  对目录进行限制的方法
  • server {
    ........

            location ~ ^/(upload)/ {
                    deny all;
            }

            location ~ ^/(test)/ {
                    deny all;
            }

    ........
    }

  • 来源访问控制
    需要 ngx_http_access_module 模块支持
  • server {
    .......
            location / {
                root   /usr/local/nginx1.21.1/html;
                index  index.html index.htm;
                    allow 192.168.1.0/24;
                    deny all;
            }
    .........
    }
  •  这里为了测试改成 1.0 网段,本地使用 2.0 网段

  •  禁止使用 IP 访问网站和 301 优化-防盗链-错误页面的提示开启认证功能

  • 有时候,访问网站的时候,使用 IP 也可以,把这一层给屏蔽掉,让其直接反馈给 403,也可以做跳转。
  • 禁止 IP 直接访问,跳转到首页
  • server {
    ...............

            listen       80;
            server_name  www.gf-beyond.com gf-beyond.com;

            if ( $host = '192.168.2.40' ) {
                     rewrite ^/(.*)$ http://www.gf-beyond.com/$1 permanent;
            }

    ......................

    }

  • 查看日志 304 跳转

  •  域名跳转的做法:
  •     server {
            listen       80;
            server_name  gf-beyond.com;

            rewrite ^ http://www.baidu.com$request_uri?;
    ........
    }

  •  访问 http://www.gf-beyond.com 会直接跳转到  baidu.com
  • 403 反馈的做法
    server {
     listen 80 default_server;
     server_name _;
     return 403;
    ........
    }

  • 访问 gf-beyond.com 会跳转到  http://www.gf-beyond.com

  •  防盗链

  • 防止别人直接从你网站引用图片等链接,消耗了你的资源和网络流量,那么我们的解决办法由几种:
    1:水印,品牌宣传,你的带宽,服务器足够
    2:防火墙,直接控制,前提是你知道 IP 来源
    3:防盗链策略
    下面的方法是直接给予 404 的错误提示:
  • server {
    .......
            location ~* \.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
                    valid_referers none blocked *.gf-beyond.com gf-beyond.com;
                    if ($invalid_referer) {
                    return 404;
                    }
            }
    ........
    }

  •  在图片上右键 --- 在新标签页打开图片

  • 同时,我们也可以设置一个独有的,图片比较小的,来做 rewrite 跳转
    server {
    .........
    location ~* \.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
     valid_referers none blocked *.beyond.com beyond.com;
     if ($invalid_referer) {
     rewrite ^/ http://www.gf-beyond.com/images/nolink.png;
     }
    }
    ....
    }

  • 错误页面的提示

  • 对于自定义的错误页面,我们只需要将 errorpage 写入到配置文件。
  • server {
    ........
    error_page 404 /404.html;
    ...............
    }

  •  开启认证功能
  • server {
    .............
    location ~ /test/ {
     auth_basic "gf";
     auth_basic_user_file /usr/local/nginx1.21.1/passwd;
     }
    ........................
  • htpasswd -cb /usr/local/nginx1.21.1/passwd gf 123456
    chmod 400 /usr/local/nginx1.21.1/passwd 
    chown nginx. /usr/local/nginx1.21.1/passwd
    nginx -s reload

 

  • 防止 DDOS 攻击
    通过使用 limit_conn_zone 进行控制单个 IP 或者域名的访问次数。
  • vim /etc/nginx/nginx.conf
  • http {
    .......
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    ........

    server {
    ...................
    location / {
                root   /usr/local/nginx1.21.1/html;
                index  index.html index.htm;
                    allow 192.168.2.0/24;
                    deny all;
                    limit_conn addr 1;
            }
    ...................
    }
  • 测试
  • 在另外一台机器上 
  • ab -n 2 -c 2 -t 1 http://192.168.2.40/test/11.html
  • 测试  -n 发出 2个 在 -t 1秒内并发 -c 2个请求

  • 查看 192.168.2.40 的访问日志

  • 加大测试次数
  • ab -n 200 -c 200 -t 1 http://192.168.2.40/1.html

  •  查看日志

  •  server {
    .......
           location / {
                root   /usr/local/nginx1.21.1/html;
                index  index.html index.htm;
                    allow 192.168.2.0/24;
                    deny all;
                    limit_conn addr 1;
                    set $no_cache 0;
                            if ($request_method = POST) {
                                    set $no_cache 1;
                            }
                            if ($query_string != "") {
                                    set $no_cache 1;
                            }
                            if ($request_uri ~* "(/zb_system/)") {
                                    set $no_cache 1;
                            }
                            fastcgi_cache_bypass $no_cache;
                            fastcgi_no_cache $no_cache;

            }
    .........

    }
  • 再次测试


  • 完整 配置文件内容

  • grep -Ev "^$|^#|^[[:space:]].*#.*$" /etc/nginx/nginx.conf
    user  nginx;
    worker_processes  auto;
    worker_cpu_affinity 0001 0010 0100 1000;
    worker_rlimit_nofile 655350;
    events {
        use epoll;
        worker_connections  655350;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile       on;
        tcp_nopush     on;
        keepalive_timeout  65;
        tcp_nodelay on;
        client_header_timeout 15;
        client_body_timeout 15;
        send_timeout 15;
        client_max_body_size 10m;
        gzip on;
        gzip_min_length 1k;
        gzip_buffers 4 16k;
        gzip_http_version 1.1;
        gzip_comp_level 9;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml font/ttf font/otf application/x-httpd-php image/jpeg image/gif image/png; 
        gzip_vary on;
        gzip_proxied expired no-cache no-store private auth;
        gzip_disable "MSIE [1-6]\.";
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffers 4 64k;
        fastcgi_busy_buffers_size 128k;
        fastcgi_temp_path /var/run/nginx-tmp-cache;
        fastcgi_temp_file_write_size 128k;
        fastcgi_cache_path /var/run/nginx-cache levels=1:2 
        keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g;
        log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for ' '"$upstream_addr" "$upstream_status" "$upstream_response_time" "$request_time"';
        limit_conn_zone $binary_remote_addr zone=addr:10m;
        server {
            listen       80;
            server_name  www.gf-beyond.com gf-beyond.com;
            charset utf-8;
         if ( $host = 'gf-beyond.com' ) {
             rewrite ^/(.*)$ http://www.gf-beyond.com/$1 permanent;
         }
         if ( $host = '192.168.2.40' ) {
             rewrite ^/(.*)$ http://www.gf-beyond.com/$1 permanent;
         }
        location ~* .*\.(js|css|jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar|mp4|rm|rmvb|mkv|gz)$ {
            expires 360d;
            valid_referers none blocked *.gf-beyond.com gf-beyond.com;
                        if ($invalid_referer) {
                            rewrite ^/ http://www.gf-beyond.com/images/nolink.png;
                        }
         }
        location ~* ^/(images|fonts|javascript|css|js|flash|media|static|assets)/ {
            expires 360d;
         }
        location ~(robots.txt) {
            expires 7d;
             break;
         }
        location ~ .*\.(js|jpg|jpeg|JPG|JPEG|css|bmp|gif|GIF)$ {
            access_log off;
        }
            location / {
                root   /usr/local/nginx1.21.1/html;
                index  index.html index.htm;
            allow 192.168.2.0/24;
            deny all;
            limit_conn addr 1;
            set $no_cache 0;
                 if ($request_method = POST) {
                     set $no_cache 1;
                 }
                if ($query_string != "") {
                    set $no_cache 1;
                }
                if ($request_uri ~* "(/)") {
                    set $no_cache 1;
                }
                fastcgi_cache_bypass $no_cache;
                fastcgi_no_cache $no_cache;
            }
         location ~* ^/images/(jpg|png)/.*\.(php|php5|.sh|.py|.pl)$ {
             deny all;
             }    
        location ~* \.(txt|doc)$ {
            if ( -f $request_filename) {
            root /usr/local/nginx1.21.1/html;
            rewrite ^/(.*)$ http://www.gf-beyond.com last;
             break;
             }
            }
            error_page  404              /404.html;
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        location ~ .*\.(php|php5)?$ {
         root        /usr/local/nginx1.21.1/html;
          fastcgi_pass 127.0.0.1:9000;
         fastcgi_index index.php;
             fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
             include        fastcgi_params;
         include     fastcgi.conf;
         fastcgi_cache ngx_fcgi_cache;
         fastcgi_cache_valid 200 302 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;
            }
        location ~ /test/ {
            auth_basic "gf";
            auth_basic_user_file /usr/local/nginx1.21.1/passwd;
            }
        }
    }
  • 切割日志脚本
  • cut_nginx_log.sh 
    #!/bin/bash
    #
    if [[ `id -u` != "0" ]]; then
        echo "Must by root !";
        exit 1;
    fi

    date=$(date +%F -d -1day)
    logdir=/var/log/nginx

    if [[ ! -d $logdir ]]; then
        echo "Log Dir is not found !"
        exit 2;
    elif [[ ! -d $logdir/cut ]] ; then 
        mkdir $logdir/cut &> /dev/null
    fi

    cd $logdir
    mv access.log cut/access_$date.log
    mv error.log cut/error_$date.log

    /usr/local/nginx1.21.1/sbin/nginx -s reload

    if [[ -n $logdir/cut/$date.tar.xz ]]; then
    tar -JcPf $logdir/$date.tar.xz cut/*
    fi

    rm -f cut/*.log

    if [[ -z `egrep -v "00 00 * * * /bin/bash /usr/local/nginx1.21.1/logs/cut_nginx_log.sh &> /dev/null" /var/spool/cron/root` ]]; then
    echo "00 00 * * * /bin/bash /usr/local/nginx1.21.1/logs/cut_nginx_log.sh &> /dev/null" >> /var/spool/cron/root
    fi

    find $logdir -type f -mtime +7 | xargs rm -rf {}

浏览394 评论0
返回
目录
返回
首页
Mycat 实现 Mysql 集群读写分离 apache 调优