添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爱旅游的手套  ·  Logrotate - Gentoo wiki·  1 月前    · 
无邪的斑马  ·  [SOLVED] logrotate ...·  1 月前    · 
睡不着的电影票  ·  FreePBX 14 RC - log ...·  1 月前    · 
奔放的针织衫  ·  Linux | Tools | ...·  2 月前    · 
仗义的人字拖  ·  Hubbards Food Fair·  1 周前    · 
欢快的花生  ·  home automation diy ...·  4 月前    · 
睿智的熊猫  ·  知乎日报 - 知乎·  4 月前    · 
$ nginx -h nginx version: nginx/1.18.0 ( Ubuntu ) Usage: nginx [ -?hvVtTq ] [ -s signal ] [ -c filename ] [ -p prefix ] [ -g directives ] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit -t : test configuration and exit -T : test configuration, dump it and exit -q : suppress non-error messages during configuration testing -s signal : send signal to a master process: stop, quit, reopen, reload -p prefix : set prefix path ( default: /usr/share/nginx/ ) -c filename : set configuration file ( default: /etc/nginx/nginx.conf ) -g directives : set global directives out of configuration file # 值得一说的就是 -s(发送信号)/-g(从配置文件中设置全局指令) 参数 stop: 快速停止nginx服务 quit: 完整有序的停止nginx服务 reopen: 重新打开日志文件 ( 日志文件mv等操作后会重新生成 ) reload: 修改配置后重新加载生效 # 简述reload命令的执行步骤 1. master进程检查配置文件的正确性,若错误则返回错误信息并终止 ( 采用原配置文件继续工作;因为worker并未受到影响 ) ,若正常则继续后续步骤。 2. 用新的配置文件,启动新的worker进程。 3. nginx将新的请求,分配新的worker进程。 4. 等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程。 5. 重复上面过程,知道全部旧的worker进程都被关闭掉。

1. 缓解 DDoS 的攻击

分布式拒绝服务 ( DDoS )攻击是一种试图使服务(通常是网站服务)无法正常使用,通过多台机器同时对目标产生大量流量从而使其服务器因为资源耗尽而无法正常提供服务。通常,攻击者试图同目标系统建立大量连接和发送大量连接请求,使其无法在接受新的连接或者响应速度变的非常缓慢严重影响使用。

1.1 攻击特征

这里说明的是,应用层( DDos )的攻击特征

应用层(通常为第 7 层的 HTTP 服务)的 DDoS 攻击是由软件程序发动的,并且可以根据具体的系统漏洞发动最佳的攻击。例如,对于无法处理大量并发连接的系统,只需要建立大量的连接并定期发送少量流量保持连接的存活,这样就可以耗尽系统的资源。其他的攻击都可以通过发送大量或超大量的请求来完成。因为发动这些攻击不是真实用户而是机器人,所以攻击者可以很轻松的产生大量的连接并非常快速的发送连接请求。

  • 流量通常来源于一组用于攻击的 IP 地址,其结果就是每一个 IP 地址都请求建立大量远超正常用户的需求连接。
  • 因为流量是由机器人产生的,且其目标就是让服务器瘫痪,所以产生流量的速度远超正常用户可能产生的速度。
  • 通常头部 User-Agent 字段通常为非标准值。
  • 通常头部 Referer 字段有时会设置为与攻击相关的值。
  • 了解 DDoS 攻击的特征(不意味这是一份完整的特征列表)可以帮助缓解受到危害。但是这里非常注意的是,不要认为这种流量模式就一定代表是 DDoS 攻击。使用代理转发也可能产生这种流量,因为代理会为其用户产生大量真实的连接请求。然而,来自代理的连接请求数通常也比来自 DDoS 攻击的少很多。

    1.2 识别攻击

    企业收费版,已经做了很多相关的服务了!

    到目前为止,我们主要关注了如何配置 NGINX NGINX Plus 缓解 DDoS 攻击带来的影响。但是如何使用 NGINX NGINX Plus 帮助发现 DDoS 攻击呢? NGINX Plus 状态模块 提供了详细的指标描述了当前链路的负载均衡状况,可以使用这个模块帮助发现不寻常的流量模式。 NGINX Plus 也提供了一个展示状态仪表盘的网页,可以实时的描述当前 NGINX Plus 系统的运行状态(演示地址: demo.nginx.com )。同样的指标也可以通过 API 进行读取,使用自定义的或第三方监控系统都可以获取到这些指标,之后可以自己根据数据分析历史趋势并发现异常流量进行报警。

    NGINX NGINX Plus 可以作为缓解 DDoS 攻击方案的重要组成部分,其中 NGINX Plus 提供了更多的功能帮助识别并抵御 DDoS 攻击。

    1.3 缓解对策

    通过调节 传入流量 和控制来自 代理或后端服务器的流量 来处理

    NGINX NGINX Plus 含有一些功能,对照上述 DDoS 攻击特征,可以缓解 DDoS 攻击。这些功能通过调节 传入流量 和控制来自 代理或后端服务器的流量 来处理 DDoS 攻击。

  • [1] 限制请求的速率
  • 可以通过 NGINX NGINX Plus 设置将来自真实用户的请求速率限制在一个正常值内。例如,你可能认为一个真实用户进入登录页面至少会每两秒产生一次请求。这样你就可以设置 NGINX NGINX Plus 要求一个客户端的 IP 每隔两秒才能产生一次登录请求(相当于每分钟 30 次)。

    # 本例中为客户端IP地址为$binary_remote_addr变量
    # limit_req_zone指令配置一个共享内存区域称为one且大小为10m,用于存储请求指定项的状态
    # limit_req指令指定location为/login.html的页面使用这块共享内存区域
    limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
    server {
        ...
        location /login.html {
            limit_req zone=one;
        ...
    
  • [2] 限制请求的连接数
  • 可以限制来自单独客户端IP的连接数为一个正常用户适用的值。例如,允许每个客户端IP跟网站的/store区域同时最多建立10个连接。

    # 本例中为客户端IP地址为$binary_remote_addr变量
    # limit_conn_zone指令配置一个共享内存区域称为addr且大小为10m,用于存储请求指定项的状态
    # limit_conn指令指定location为/store的页面使用这块共享内存区域,并且限制每个客户端IP的最大连接数为10个
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        ...
        location /store/ {
            limit_conn addr 10;
            ...
    
  • [3] 关闭慢速连接
  • 可以关闭那些请求数据非常稀少的连接,这些连接通常试图保持尽可能长的时间以消耗服务器资源。Slowloris攻击就是这种类型。client_body_timeout指令控制NGINX在两次用户体写之间等待多长时间,client_header_timeout指令控制NGINX在两次用户头部写之间等待多长时间。这两个指令默认值均为60秒。下面为示例配置NGINX在两次用户体或头部写之间最多等待 5 秒。

    server {
        client_body_timeout 5s;
        client_header_timeout 5s;
        ...
    
  • [4] 设置 IP 地址黑名单
  • 如果你可以识别出用于攻击的IP地址,就可以使用deny指令将其加入黑名单中,这样NGINXNGINX Plus会拒绝来着这个IP的任何连接或请求。例如,如果你确定攻击来自地址123.123.123.1~123.123.123.16

    location / {
        deny 123.123.123.0/28;
        ...
    

    又或者你确定攻击来自地址123.123.123.3123.123.123.5123.123.123.7

    location / {
        deny 123.123.123.3;
        deny 123.123.123.5;
        deny 123.123.123.7;
        ...
    
  • [5] IP 地址白名单
  • 如果网站或应用只允许来自指定IP地址的连接,则可以同时使用allowdeny指令来设置只允许指定IP访问网站或应用。例如,限制只允许来自本地网络的连接。这里的  deny all指令禁止所有来自allow指定范围之外IP的连接。

    location / {
        allow 192.168.1.0/24;
        deny all;
        ...
    
  • [6] 使用缓存来平滑流量峰值
  • 可以配置NGINXNGINX Plus使其承受更多来自攻击产生的流量峰值,通过启用缓存并配置相关参数使其暂存后续的请求。下面是一些有用的配置:

  • proxy_cache_use_stale 指令的 updating 参数告诉 NGINX 当它需要获取一个过期缓存对象的更新时,它应当发送一个更新请求,并在此期间使用更新前的对象继续服务于请求的用户。如果攻击就是在不停的重复请求某个文件,这样可以大大减小对后端服务器的请求数量。

  • proxy_cache_key 指令定义的内置变量(默认关键字有三个,$scheme$proxy_host$request_uri)。如果包含 $query_string 变量,那么攻击者可以发送大量随机的请求字符串从而导致缓存更新过渡频繁。不建议在关键字中包含 $query_string 变量除非你有什么特别的理由。

    proxy_cache_use_stale
    proxy_cache_key
    
  • [7] 设置阻塞请求
  • # 可以配置NGINX和NGINX Plus阻塞多种请求
    1. 极具指向性针对指定URL的请求
    2. 请求头部中的User-Agent字段为非正常值
    3. 请求头部中的Referer字段为与攻击相关的值
    4. 请求头部中其他字段含有与攻击相关的值
    

    例如,如果确定DDoS攻击的目标URL/foo.php,则可以设置阻塞所有对于该页面的请求。或者发现来自DDoS攻击的请求头部User-Agent字段值为foobar,则可以设置阻塞这些请求。

    location / {
        if ($http_user_agent ~* foo|bar) {
            return 403;
        ...
    
  • [8] 限制后端服务器的连接
  • NGINXNGINX Plus由于负载均衡,所以经常同时处理比后端服务器更大量的连接。对于NGINX Plus可以限制每个后端服务器的连接数。例如,如果希望NGINX Plus限制每个网站upstream组内后端服务器最多建立200个连接。

    # max_conns参数为每个服务器指定最大连接数
    # queue指令设置当upstream组内后端服务器达到了最大连接数时请求队列的长度
    # timeout参数设置请求队列中每项的保留时间
    upstream website {
        server 192.168.100.1:80 max_conns=200;
        server 192.168.100.2:80 max_conns=200;
        queue 10 timeout=30s;
    
  • [9] 处理基于 Range 字段的攻击
  • 攻击的另一种方法就是通过发送一个头部中Range字段具有非常大的数值,从而导致服务器的溢出。具体关于如何配置  NGINXNGINX Plus缓解这种攻击可以参见一个案例,如何配置NGINXNGINX Plus抵御CVE-2015-1635

  • [10] 处理高负荷
  • DDoS攻击通常都会导致高负荷。关于如何调整NGINXNGINX Plus以及操作系统处理高负荷可以参见调整NGINX性能。

    2. 日志文件的切割

    日志转存主要是分为,手动脚本处理和借助第三方工具配置处理!

    随着Nginx服务的服务时间越来越长,其日志大小也就越来越大,所有有必要对其进行自动化的切割,以便于之后按天统计访问量神马的功能做准备。

    2.1 脚本切割

    手动脚本处理:可以通过 crontab 定时执行实现日志切割功能

    #!/bin/sh
    # set file path
    NGINX_ACCESS_LOG=/opt/logs/nginx/access/log.pipe
    NGINX_ERROR_LOG=/opt/logs/nginx/error/log
    NGINX_STATIS_LOG=/opt/logs/nginx/statis/log
    # rename log
    mv $NGINX_ACCESS_LOG $NGINX_ACCESS_LOG.`date -d yesterday +%Y%m%d`
    mv $NGINX_ERROR_LOG $NGINX_ERROR_LOG.`date -d yesterday +%Y%m%d`
    mv $NGINX_STATIS_LOG $NGINX_STATIS_LOG.`date -d yesterday +%Y%m%d`
    touch $NGINX_ACCESS_LOG
    touch $NGINX_STATIS_LOG
    touch $NGINX_ERROR_LOG
    # restart nginx(都可以)
    /etc/init.d/nginx reload
    /etc/init.d/nginx reopen
    

    2.2 服务支持

    借助第三方工具配置处理:只要安装 logrotate 软件即可实现功能

  • logrotate 介绍

  • logrotatelinux系统日志的管理工具,可以对单个文件或目录下的文件按时间/大小进行切割
  • logrotate服务程序支持压缩存储、指定日志备份数量、还可以在切割之前后运行自定义命令等
  • logrotate是基于crontab定时任务运行,具体时间点可以查询crontab的配置文件/etc/anacrontab
  • logrotate 服务

  • logrotate的默认配置文件是/etc/logrotate.conf
  • logrotate后面跟配置文件就可以直接执行,如/usr/sbin/logrotate -f /etc/logrotate.d/nginx
  • logrotate 命令服务

  • -f:强制执行
  • -v:显示指令执行过程
  • -s <状态文件>:使用指定的状态文件
  • -d:详细显示指令执行过程,便于排错或了解程序执行的情况
  • logrotate 配置参数

    prerotate if [ -d /etc/logrotate.d/httpd-prerotate ]; then \ run-parts /etc/logrotate.d/httpd-prerotate; \ endscript postrotate invoke-rc.d nginx rotate >/dev/null 2>&1 endscript
    # 1.如何测试logrotate程序执行的情况?
    /usr/sbin/logrotate -d /etc/logrotate.d/nginx
    
    # 2.怎么查看log文件的具体执行情况?
    cat /var/lib/logrotate/status
    
    # 3.使用-v或-d参数时,显示log does not need rotating问题?
    logrotate在对status未记录的文件进行转储时,会在status添加一条该文件的记录,并将操作时间设为当天。
    之后程序再次对此文件进行转储时发现这个文件今天已经操作过,就不再进行相关操作。
    # 解决方法
    1. 编辑/var/lib/logrotate/status文件更改相对应的文件操作日期
    2. 使用-s指定状态文件
    
    # 4.分割日志时报错没有权限
    error: skipping "/var/log/nginx/test.access.log" because parent directory has insecure
    permissions (It is world writable or writable by group which is not "root") Set "su"
    directive in config file to tell logrotate which user/group should be used for rotation.
    # 添加“su root list”文件中即可
    $ sudo vim /etc/logrotate.d/nginx
    /var/log/nginx/*.log {
        su root list
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        postrotate
            [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
    

    3. 获取用户真实 IP 地址

    获取用户真实 IP 地址,可以应对工具、进行溯源等诸多好处!

    如果你的 Web 服务器前端有代理服务器或 CDN 时,在日志中的 $remote_addr 可能就不是客户端的真实 IP 了。比较常用的解决方法有以下三几种,这里我们将主要介绍如何使用 Nginx 自带 realip 模块来解决这一问题。可以参考,我之前写的一篇 Nginx 服务变量传递

  • 使用 CDN 自定义 IP 头来获取
  • 通过 HTTP_X_FORWARDED_FOR 获取 IP 地址
  • 使用 Nginx 自带模块 realip 获取用户 IP 地址
  • 3.1 模块介绍

    介绍 ngx_realip 模块的用途!

    ngx_realip 模块究竟有什么实际用途呢?为什么我们需要去改写请求的来源地址呢?答案就是,当 Nginx 处理的请求经过了某个 HTTP 代理服务器的转发时,这个模块就变得特别有用。

    当原始的用户请求经过转发之后,Nginx 接收到的请求的来源地址无一例外地变成了该代理服务器的 IP 地址,于是 Nginx 以及 Nginx 背后的应用就无法知道原始请求的真实来源。

    所以,一般我们会在 Nginx 之前的代理服务器中把请求的原始来源地址编码进某个特殊的 HTTP 请求头中,然后再在 Nginx 中把这个请求头中编码的地址恢复出来。这样 Nginx 中的后续处理阶段(包括 Nginx 背后的各种后端应用)就会认为这些请求直接来自那些原始的地址,代理服务器就仿佛不存在一样。ngx_realip 模块正是用来处理这个需求的。

    3.2 安装配置

    最好是直接参考官方安装文档,比这里的更新!

    realipNginx 内置模块,需要在编译 Nginx 时加上 --with-http_realip_module 参数来启用它。

  • 常用的编译参数:
  • $ ./configure
        --prefix=/etc/nginx
        --sbin-path=/usr/sbin/nginx
        --conf-path=/etc/nginx/nginx.conf
        --error-log-path=/var/log/nginx/error.log
        --http-log-path=/var/log/nginx/access.log
        --pid-path=/var/run/nginx.pid
        --lock-path=/var/run/nginx.lock
        --http-client-body-temp-path=/var/cache/nginx/client_temp
        --http-proxy-temp-path=/var/cache/nginx/proxy_temp
        --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
        --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
        --http-scgi-temp-path=/var/cache/nginx/scgi_temp
        --user=nginx --group=nginx
        --with-http_ssl_module
        --with-http_realip_module
        --with-http_addition_module
        --with-http_sub_module
        --with-http_dav_module
        --with-http_flv_module
        --with-http_mp4_module
        --with-http_gunzip_module
        --with-http_gzip_static_module
        --with-http_random_index_module
        --with-http_secure_link_module
        --with-http_stub_status_module
        --with-http_auth_request_module
        --with-threads
        --with-stream
        --with-stream_ssl_module
        --with-mail
        --with-mail_ssl_module
        --with-file-aio
        --with-ipv6
        --with-http_spdy_module
        --with-cc-opt='-O2 -g'
    $ make
    $ make install
    
    # 真实服务器上一级代理的IP地址或者IP段,可以写多行
    set_real_ip_from 192.168.1.0/24;
    set_real_ip_from 192.168.2.1;
    # 从哪个header头检索出要的IP地址
    real_ip_header X-Forwarded-For;
    # 递归的去除所配置中的可信IP地址
    real_ip_recursive on;
    
    server {
        listen       80;
        server_name  www.wseacape.site;
        access_log  /var/log/nginx/www.wseacape.site.access.log  main;
        index index.php index.html index.html;
        root /var/www/www.wseacape.site;
        location /
            root /var/www/www.wseacape.site;
            set_real_ip_from  192.168.2.0/24;
            set_real_ip_from  128.22.189.11;
            real_ip_header    X-Forwarded-For;
            real_ip_recursive on;
    
  • 这里详细讲下 real_ip_recursive 的用途:递归的去除所配置中的可信 IP,排除 set_real_ip_from 里面出现的 IP。如果出现了未出现这些 IP 段的 IP,那么这个 IP 将被认为是用户的 IP 地址。以上配置为例,服务器获取到以下的 IP 地址:
  • 128.22.189.11
    192.168.2.100
    222.11.158.67
    
  • real_ip_recursive on 的情况下,128.22.189.11192.168.2.100 都出现在 set_real_ip_from 中,仅仅 222.11.158.67 没出现,那么这个 IP 就被认为是用户的 IP 地址,并且赋值到 remote_addr 变量。在 real_ip_recursive off 或者不设置的情况下,192.168.2.100 出现在了 set_real_ip_from 中会被排除掉,其它的 IP 地址便认为是用户的 IP 地址。
  • 4. 配置服务高可用负载

    服务 5 求之后,客户端响应超时,并非必现场景!

  • [问题起因] 之前为了能够做到服务的高可用或者主备,需要使用 KeepAlive 的服务进行后端服务的心跳健康检查,或者使用 Nginx·Plus 企业版本,配置起来还是非常麻烦的。
  • Syntax:    proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
    Default: proxy_next_upstream error timeout;
    Context:    http, server, location
    
  • [解决方法] 现在已经可以借助 proxy_next_upstream 来配置高可用服务。
  •