zoukankan      html  css  js  c++  java
  • Nginx_安全1

    Nginx 安全

    nginx隐藏版本号

    # 在Nginx的配置文件中进行修改,增加下面这个。
    server_tokens on;

     

    nginx对IP和目录限速

    # Nginx可以通过HTTPLimitZoneModule和HTTPCoreModule两个目录来限速。


    # 示例:
    limit_zone one $binary_remote_addr 10m;  
    location / {  
          limit_conn one 1;  
          limit_rate 100k;  
    }


    # 说明:
    - limit_zone,是针对每个IP定义一个存储session状态的容器。这个示例中定义了一个10m的容器,按照32bytes/session,可以处理320000个session。
    - 然后针对目录进行设定。
    - limit_conn one 1;  # 是限制每个IP只能发起一个连接。
    - limit_rate 100k;   # 是对每个连接限速100k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate x 2。

     

    nginx禁止ip访问, 只能通过域名访问

    # 背景
    - 我的一个地方站曾经遇到过被无故断网的事情,阿里云给的原因是绑定了未备案的域名。归结到技术层面,原因是如果网站允许ip直接访问,那么即使没有在nginx配置中解析恶意的未备案域名,这个域名也是可以访问到你的网站。相关部门进行核查时,会以为你为未备案域名提供主机服务,后果就是封掉的ip。所以,你需要禁止ip访问,只允许你自己配置的server模块的server_name访问。这样即使未备案域名绑定了你的ip,也访问不了你的网站。有必要说明一下,本站用的阿里云的虚拟主机,软件环境是:linux+nginx+mysql+php。因为本文是说明怎么在nginx服务器配置禁止ip访问。

    # 实施方案
    - 增加server模块,第一句 listen 80 default 就禁掉了ip访问,第二句标示如果通过ip访问或者nginx未解析的域名访问 则返回500错误。
    server {
              listen 80 default;
              return 500;
    }
    - 如果把ip访问和未解析域名访问转到你自己的域名,从而带来一些额外流量,则如下配置(logo条纹挡住的词是:permanent):
    server {
              listen 80 default;
              rwrite ^(.*) http://www..1111.com permanent;
    }
    - 加上以上配置之后会带来一个问题,通过cxzaixian.com不能访问了,www.cxzaixian.com没有问题,配置改为如下即可解决:
    server {
              listen 80 default;
              server_name _;
              rewrite ^(.*) http://www..1111.com permanent;
    }

     

    nginx拒绝指定IP访问

    # 背景
    闲来无事,登陆服务器,发现有个IP不断的猜测路径、试图往服务器上传文件(木马)。于是查看了之前的日志,无奈鄙站被攻击者盯上了,不断的有不同的IP试图上传木马。看来坏人还是有的。由于不想让鄙站沦为肉鸡,所以就想写个简单的脚本,来阻止攻击者的IP访问。

    # 以下是举例说明,具体情况要看自己服务器的的实际情况,进行操作。

    # 查看自己的服务器的访问日志
     # 攻击者
    195.154.216.165 - - [28/Nov/2015:23:10:40 +0800] "POST /wp-content/themes/twentyten/404.php HTTP/1.1" 404 27 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:40 +0800] "POST /wp-content/themes/twentythirteen/404.php HTTP/1.1" 404 27 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:40 +0800] "POST /wp-content/themes/twentytwelve/404.php HTTP/1.1" 404 27 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:40 +0800] "POST /wp-content/uploads/phptest.php HTTP/1.1" 404 27 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:41 +0800] "POST /xyr/confings.asp HTTP/1.1" 404 1569 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:41 +0800] "POST /xz.asp;.jpg HTTP/1.1" 404 564 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:41 +0800] "POST /yanyu/?q={${eval%28$_POST[u]%29}} HTTP/1.1" 404 1569 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"

    195.154.216.165 - - [28/Nov/2015:23:10:42 +0800] "POST /ztxxw/Images/images.asp HTTP/1.1" 404 1569 "http://www.z-dig.com/11m.php" "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)" "-"



     # 日志查看,过滤IP(注意有些是蜘蛛,如果公司是需要蜘蛛爬取的,要注意查看,或者服务器配置了CDN也要注意。)
    - 过滤在日志中查看到的不正常的IP访问;
    grep '195.154.216.165' 2015-11-28.access.log|wc -l
    289
    - curl ipinfo.io/195.154.216.165;echo''
    {
    "ip": "195.154.216.165",
    "hostname": "fr.07.gs",
    "city": "",
    "region": "",
    "country": "FR",
    "loc": "48.8600,2.3500",
    "org": "AS12876 ONLINE S.A.S."
    }
     # 网站跑在 Nginx 上,所以可以使用 Nginx 的 Deny 来拒绝攻击者的IP访问。那么思路就出来了,定期(五分钟或十分钟)获取攻击者的IP,将IP放入到黑名单(Nginx 配置文件),并 reload 使其生效。由于前期规划的比较好,网站的访问日志放在了一个指定的目录,Nginx 的错误日志也放在了一个指定的目录。网站的访问日志每日进行切割。Nginx 的错误日志没有进行切割。
     
     
     # 思路和操作步骤:
    - 通过 Nginx 的错误日志(为什么不使用访问日志)来获取攻击者的IP。之前没有对 Nginx 的错误日志进行定时切割,为了方便统计攻击者的IP所以,编写脚本并加入定时任务,使错误日志每小时切割一次,并且每小时对黑名单文件进行清空。

    # 错误日志切割、清空黑名单脚本:
    #!/bin/bash
    # Rotate nginx error logs and clean block ip 's configure file
    # Nginx pid file : /application/nginx/logs/nginx.pid
    # Nginx error logs directory : /data/logs/nginx
    # Block Ip 's configure file : /application/nginx/conf/website/blockip.conf
    # Default log name : error.log
    # Author : Mr.Zhou
    # E-mail : zhou@z-dig.com

    NGX_PID=/application/nginx/logs/nginx.pid
    NGINX_CMD=/application/nginx/sbin/nginx
    LOGS_DIR=/data/logs/nginx
    LOG_NAME=error.log
    BLOCK_IP_FILE=/application/nginx/conf/website/blockip.conf
    cd $LOGS_DIR &&
    /usr/bin/rename $LOG_NAME $(/bin/date +%F-%H -d "last hour").$LOG_NAME $LOG_NAME && /bin/kill -USR1 $(cat $NGX_PID)
    > $BLOCK_IP_FILE && $($NGINX_CMD -s reload)


    # 获取攻击者IP脚本:
    - 该脚本从 Nginx 的错误日志中统计出超过20次试图猜测路径或上传文件的IP,并将这些IP加入到 Nginx 的配置文件。若有新增加的IP则 reload Nginx 使配置文件生效,若没有新增IP则不进行reload。

    # 脚本:
    cat block-ip.sh
    #!/bin/bash
    # block ip

    ERR_LOG=/data/logs/nginx/error.log
    BLOCK_IP_FILE=/application/nginx/conf/website/blockip.conf
    BLOCKED_IP=/dev/shm/blocked-ip.txt
    BLOCK_IP=/dev/shm/block-ip.txt
    NGINX_CMD=/application/nginx/sbin/nginx
    /bin/cp $BLOCK_IP_FILE $BLOCKED_IP &&
    /bin/sed -nr 's#.*[^0-9](([0-9]+.){3}[0-9]+).*#1#p' $ERR_LOG |/bin/awk '{IP[$1]++}END{for (i in IP) print IP[i],i}'|/bin/awk '{if($1>20)print "deny "$2";"}' >$BLOCK_IP &&
    /bin/grep -v -f $BLOCK_IP_FILE $BLOCK_IP >>$BLOCK_IP_FILE && $($NGINX_CMD -s reload)

    # 将拒绝指定IP访问的配置文件(黑名单)单独存放,并在 nginx 主配置文件中 include 进去。
    # grep blockip.conf nginx.conf
    include website/blockip.conf;

    #blockip.conf 文件格式如下:
    cat blockip.conf
    deny 195.154.211.220;
    deny 195.154.188.28;
    deny 195.154.188.186;
    deny 180.97.106.161;
    deny 180.97.106.162;
    deny 180.97.106.36;
    deny 195.154.180.69;
    deny 195.154.211.26;
    deny 221.229.166.247;
    deny 180.97.106.37;
    deny 195.154.216.164;
    deny 195.154.216.165;

    # 将脚本放入定时任务执行:
    - 每小时对 Nginx 的错误日志进行切割并且清空一次被拒绝访问IP的配置文件,若不清空的话,此IP将终生不能访问,若它再次攻击则会再次进入黑名单,>_<。 清空命令放在了切割脚本的尾部。
    - 可以自己决定统计频率,根据指定的频率执行脚本,获取攻击者的IP,若此IP已经在黑名单中,则会忽略掉(由于错误日志一小时切割一次,所以在一小时内会出现重复的IP)。然后把剩下的新攻击者的IP追加到黑名单。并 reload Nginx 。若没有新增的攻击者IP则什么都不做。

    crontab -l
    # rotate nginx log everyday
    00 00 * * * /bin/bash /application/scripts/rotate-nginx-logs.sh &>/dev/null
    # rotate nginx error log every hour and clean the block ip file
    00 */1 * * * /bin/bash /application/scripts/rotate-nginx-error-logs.sh &>/dev/null
    # check hacker's ip every ten minutes
    */10 * * * * /bin/bash /application/scripts/block-ip.sh &>/dev/null


    # 测试结果:
           
    # 以下是脚本运行一段时间的攻击者IP
    cat /application/nginx/conf/website/blockip.conf
    deny 195.154.211.220;
    deny 195.154.188.28;
    deny 195.154.188.186;
    deny 180.97.106.161;
    deny 180.97.106.162;
    deny 180.97.106.36;
    deny 195.154.180.69;
    deny 195.154.211.26;
    deny 221.229.166.247;
    deny 180.97.106.37;
    deny 195.154.216.164;
    deny 195.154.216.165;

    # 过段时间,再列出一份黑名单IP,看是否有变化。
    # cat /application/nginx/conf/website/blockip.conf
    deny 195.154.188.224;
    # curl ipinfo.io/195.154.188.224;echo ''
    {
    "ip": "195.154.188.224",
    "hostname": "195-154-188-224.rev.poneytelecom.eu",
    "city": "",
    "region": "",
    "country": "FR",
    "loc": "48.8600,2.3500",
    "org": "AS12876 ONLINE S.A.S."
    }
    # grep '195.154.188.224' /data/logs/nginx/error.log |wc -l
    102
    # grep '195.154.188.224' /data/logs/nginx/error.log |grep -v 'access forbidden' |wc -l
    24
    # tail -n 1 /data/logs/nginx/error.log
    2015/11/30 10:47:53 [error] 30754#0: *37828 access forbidden by rule, client: 195.154.188.224, server: www.z- dig.com, request: "GET / HTTP/1.1", host: "www.z-dig.com",     referrer: "http://www.z-dig.com"

     

     

    坚持这种真诚,那么总归能遇到良人。
  • 相关阅读:
    百度Hi之CSRF蠕虫攻击
    Portlet之讲解
    try-catch语句讲解
    unset之讲解
    MySQL bin-log 日志清理方式
    php数组array_push()和array_pop()以及array_shift()函数
    php中的func_num_args、func_get_arg与func_get_args函数
    PHP is_callable 方法
    如何实现php异步处理
    Mysql并发时经典常见的死锁原因及解决方法
  • 原文地址:https://www.cnblogs.com/jiaxiaozia/p/12156940.html
Copyright © 2011-2022 走看看