• 【09】Nginx:静态压缩 / 日志切割 / 防盗链 /恶意解析/ 跨域


    写在前面的话

    上一节我们谈了关于 nginx 服务器的一些简单的安全优化问题,能够帮助我们解决一部分线上服务存在的安全隐患。但是想要提升用户体验这是原因不够的,我们还需要从服务的优化方面入手。

    本节更多的还是偏理论的东西,会给出相应的配置。可能有些就无法立即做测试。

    访问优化:静态压缩

    我们知道一个网站总会有一些 CSS/JS 等静态文件需要加载,如果用户每次请求都需要去服务器下载一遍,比如 Jquery 这种根本不会变的。明显会造成带宽的浪费。同时由于用户可能本身网速还不好,就容易给用户带来不好的体验。且不说每次都下载,就是直接以文件形式从服务器下载,传输速度也是问题。

    在 nginx 编译的时候我们增加了模块:http_gzip_static_module

    这个模块的作用在于将静态文件压缩后传输给用户。

    参数说明
    gzip on|off 打开或者关闭 gzip 压缩的功能,默认 off
    gzip_buffers numner|size

    指定 gzip 功能压缩文件时使用的缓存空间的大小。

    number:向服务器申请缓存空间个数。size:每个缓存空间大小。

    默认 number * size 的值为 128,size 一般为 4k 或者 8k

    gzip_comp_level number

    gzip 压缩级别,级别为 1-9,默认为 1。

    级别越高压缩率越高,压缩后文件越小,但越占用 CPU

    gzip_disbale 对不同客户端的请求进行选择性打开 gzip,后面跟浏览器名称
    gzip_http_verson 早期客户端可能因不支持 gzip 而无法解压出现乱码,可根据不同 http 协议版本选择性的打开 gzip
    gzip_min_length 最少压缩的数据包大小,小于此值的数据包将不被压缩,默认 20,建议 1KB,0 则表示全压缩
    gzip_proxine off|any 作为反向代理时有效,设置是否对后端返回的结果进行 gzip 压缩
    gzip_types 根据响应页面的类型选择性打开 gzip
    gzip_vary 是否在头部发送压缩标识告诉客户端,默认 off

    配置模板如下:

    gzip          on;
    gzip_static   on;
    gzip_disable  "MSIE [1-6] .";
    gzip_vary     on;
    gzip_min_length 1k;
    gzip_buffers    4 16k;
    gzip_comp_level 5;
    gzip_types application/x-javascript application/javascript text/javascript text/css application/xml;
    gzip_http_version 1.1;

    但是单纯是这样子配置还不是很完善,我们需要在 location 中配置本地静态文件保存时间:

    location ~* .(ico|jpe?g|gif|png|bmp|swf|flv)$ {
        expires 30d;
        access_log off;
    }
    
    location ~* .(js|css)$ {
        expires 7d;
        access_log off;
    }

    通过 expires 配置保存时间! 

    管理优化:日志切割

    在日常很多服务中是不具备日志切割能力的,所以对待这样的服务,我们一般采用的是系统的 logrotate 进行日志切割。虽然 nginx 没有明显看到关于日志切割的说明,但是我们可以换着方法实现。

    我们添加配置文件:

    server {
        listen       10009;
        server_name  localhost;
    
        if ($time_iso8601 ~ "^(d{4})-(d{2})-(d{2})T(d{2}):(d{2}):(d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
            set $minutes $5;
            set $seconds $6;
        }
    
        access_log  /data/logs/nginx/access-cut-$year-$month-$day-$hour-$minutes.log mylog;
    
        location / {
            root /data/files/share;
        }
    }

    为了测试方便,我们这里使用按照分钟切割,重载访问测试:

    生产环境中建议按照小时或者天切割,这样便于我们排查问题。

    访问优化:防盗链

    在我们的服务上面可能存在一些图片或者其它文件能够被别人拿来放到自己的网站上面显示,这样照成的坏处就是被人的网站占用了我们的带宽,用于居然还不知道这个东西是我们的,等于免费给别人打广告。

    对于这样的问题,专业的名词就叫盗链,就是偷你的链接。

    比如我们配置当前网站的图片静态文件如果不是我们允许的来源的请求都返回 403:

    location ~* .(gif|jpg|png|bmp)$ {
        valid_referers none blocked *.test.com server_names ~.google. ~.baidu.;
        if ($invalid_referer) {
            return 403;
        }
    }

    我们通过判断 referer 的来源判断请求是不是我们限制的域名来源,以此来拒绝其他网站直接请求我们的图片的访问。

    none:代表请求的 refer 为空,也就是直接访问图片地址,这个我们允许的

    blocked:来源不为空,但是里面的值被代理或者防火墙删除了

    server_names:来源包含当前 server_name 的值

    字符串:定义服务器名称,比如 *.test.com 配置后,来源 test.com 都允许

    正则表达式:匹配合法请求来源, 如匹配百度 ~.baidu.

    安全优化:防止恶意域名解析

    域名的公网 IP 我们都可以采取一定的方法获取到,然后我们就可以通过域名解析,将我们的域名解析到那个公网 IP 上面。

    这时候可能还是有些疑问,解析就解析呗,又不影响我们的业务。

    但是这样想,假设有人恶意将一个非法域名解析到你的服务器,然后这个域名被运营商揪了出来,以为是你自己解析的。然后为了所谓的干净的网络环境,把你服务器的端口给你封了。这时候你怎么办。所以防止恶意域名解析还是很有必要的。

    server {
        listen 80 default_server;
        server_name _;
        access_log off;
        return 444;
    }
    
    server {
        listen 443 default_server;
        server_name _;
        ssl on;
        ssl_certificate 随便设置一个ssl证书;
        ssl_certificate_key 随便设置一个ssl证书的key;
        return 444;
    }

    我们只需要添加这样一个配置就能防止没有配置 server_name 的域名解析到我们服务器了。

    访问优化:AJAX 跨域提交

    限制前后端分离成为了市场的大趋势,我们都在尽可能的让服务之间解耦,所以前端有一个域名,后端有一个域名其实是一个很正常的事情了。

    但是就是因为如此,导致我们前端可能在使用 ajax 请求后端的时候报错:

    'Access-Control-Allow-Origin' header is present on the requested resource

    对于此类的问题,我们可以在后端 nginx 配置中增加:

    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    当然,可能由于代码原因,可能这样还不能解决,那么就只能使用最狠的方法:

    在前端的 server 中新增 location 匹配,proxy_pass 后端的访问地址,ajax 直接提交当前域名的 location,就不会跨域了。

    小结

    当然还存在其它的优化项目,我们后续会继续加上去。另外接下来准备添加一个我们这整个分类下来关于 nginx 安装,初始化的一键脚本。

  • 相关阅读:
    近期安卓与IOS招聘面试有感
    java线程池技术(二): 核心ThreadPoolExecutor介绍
    java线程池技术(一):ThreadFactory与BlockingQueue
    Java设计模式之策略模式与状态模式
    java线程间通信:一个小Demo完全搞懂
    Android M 新的运行时权限开发者需要知道的一切
    Java多线程同步问题:一个小Demo完全搞懂
    java多线程之守护线程以及Join方法
    安卓电量优化之JobScheduler使用介绍
    安卓电量优化之WakeLock锁机制全面解析
  • 原文地址:https://www.cnblogs.com/Dy1an/p/11254456.html
Copyright © 2020-2023  润新知