Nginx常用配置

2018-04-18|Categories: Cluster, Linux|Tags: |

本文属于Nginx系列的第二篇,第一篇《初识Nginx》已经介绍过的测试环境,例如网卡IP地址、用hosts文件解析测试域名、创建测试web页面等步骤就直接省略,不再赘述。

启用文件缓存

这里缓存的不是文件的内容,而是文件的「元数据」:

  • 文件描述符、文件大小和上次修改时间。
  • 已经打开过的目录结构。
  • 没有找到的或者没有权限操作的文件信息。

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

Windows下的文件描述符和信号量、互斥锁等内核对象一样都记作HANDLE(句柄)。

https://zh.wikipedia.org/wiki/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6

这样,通过读取缓存就减少了对磁盘的操作,提升了性能。

http {
    open_file_cache          max=1000 inactive=20s;
    open_file_cache_valid    30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors   on;
}
  • max:表示在内存中存储元素的最大个数。当达到最大限制数量后,将采用LRU(Least Recently Used)算法从缓存中淘汰最近最少使用的元素。
  • inactive:表示在inactive指定的时间段内没有被访问过的元素将会被淘汰。默认时间为60秒。
  • open_file_cache_min_uses:与open_file_cache中的inactive参数配合使用。如果在inactive指定的时间段内,访问次数超过了open_file_cache_min_uses指定的最小次数,那么将不会被淘汰出缓存。
  • open_file_cache_valid:默认为每60秒检查一次缓存中的元素是否仍有效。

启用gzip压缩

此处需要用到ngx_http_gzip_module模块:

server {
    server_name         c.com www.c.com;
    root                /usr/share/nginx/html/vhost/c/;
    
    gzip                on;
    gzip_min_length     1k;
    gzip_comp_level     5;
    gzip_vary           on;
    gzip_proxied        expired no-cache no-store private auth;
    
    # 压缩类型默认包含`text/html`,不需要重复添加,否则报错
    gzip_types          text/plain text/css application/javascript;
}

压缩注意事项

压缩对象 gzip_types

  • 避免压缩视频、图片等已经压缩过的文件
  • 避免压缩小于1K的文本文件

压缩等级 gzip_comp_level

当传输内容越大,更高的压缩等级可以获得更小的文件,但需要消耗更多CPU资源,下表是不同大小的文本文件压缩前后的对比:

压缩等级 压缩前 KB 压缩后 KB 压缩比
Level 5 27.63 8.45 30.6%
Level 9 27.63 8.42 30.5%
Level 5 254.20 70.12 27.6%
Level 9 254.20 68.85 27.1%

测试注意事项

  • 首选最新版浏览器测试
  • 如果使用curl,命令如下:
    curl c.com -v --compressed >/dev/null
    
    • 不能使用-I选项,因为响应首部内容不足1K,不会被压缩
    • 必须添加--compressed选项,否则web服务器认为客户端不支持压缩
    • 老版本curl需要添加--http1.1选项,因为Nginx的gzip_http_version指令的默认值为1.1

启用HTTPS

创建测试证书

cd /etc/pki/tls/certs/

# 删除证书生成脚本的`-aes128`选项,以后生成私钥时都不需要设置密码,
# 否则每次Nginx启动都需要手工输入私钥密码
sed -i.bak -r 's/(.*) -aes128(.*)/\1\2/' /etc/pki/tls/certs/Makefile

make c.com.crt
# 根据提示输入证书的必要信息
# 生成c.com.crt和c.com.key

# 如果私钥已设置密码,可用以下命令去除
openssl rsa -in c.com.key -out c.com.new.key

mv c.com.* /etc/nginx/conf.d/

配置Nginx

此处需要用到ngx_http_ssl_module模块:

server {
    server_name            c.com www.c.com;
    root                   /usr/share/nginx/html/vhost/c/;
    
    listen                 443 ssl;
    ssl_certificate        /etc/nginx/conf.d/c.com.crt;
    ssl_certificate_key    /etc/nginx/conf.d/c.com.key;
    ssl_session_cache      shared:SSL:10m;
    ssl_session_timeout    10m;
}
# 此时只能通过 https://c.com 访问,普通的 http://c.com 访问将出错

上面的代码仅能用于测试环境,因为证书是自签名的,生产环境必须使用第三方权威机构签发的数字证书,具体做法详见《使用Let’s Encrypt证书把网站升级为HTTPS》

Nginx官方对配置HTTPS的建议

不需要再设置ssl_protocolsssl_ciphers,采用Nginx默认设置即可。

HTTPS最消耗CPU资源的操作是SSL握手,针对单个客户端有两种方式减少SSL握手操作:一、启用HTTP持久连接,二、重复利用SSL会话参数。

http://nginx.org/en/docs/http/configuring_https_servers.html

相同IP地址上提供多个HTTPS网站,并使用不同证书

前提条件

Nginx编译时已加入TLS SNI支持。

SNI = Server Name Indication,服务器名称指示

检测命令:nginx -V

  • 输出必须包含「TLS SNI support enabled」
  • 如果输出是「TLS SNI support disabled」,就需要重新编译Nginx
    • 下载最新稳定版的OpenSSL的源码(0.9.8f版开始支持SNI)并解压
    • 修改Nginx编译参数--with-openssl="path/to/openssl/src/"

配置方法

  • 把多个域名解析到同一个IP
  • 多个server块配置不同的server_name、root、证书

启用URI rewrite

此处需要用到ngx_http_rewrite_module模块:

所有HTTP请求重写为HTTPS请求

server {
        listen          80;
        server_name     c.com www.c.com;
        return          302 https://$server_name$request_uri;
}
server {
        listen          443 ssl;
        server_name     c.com www.c.com;
        root            /usr/share/nginx/html/vhost/c/;
        # ...
}

Nginx官方rewrite示例

https://www.nginx.com/blog/creating-nginx-rewrite-rules/

  • Standardizing the Domain Name
    • Redirecting from a Former Name to the Current Name
    • Redirecting All Traffic to the Correct Domain Name
    • Adding and Removing the www Prefix
  • Forcing all Requests to Use SSL/TLS
  • Enabling Pretty Permalinks for WordPress Websites
  • Dropping Requests for Unsupported File Extensions
  • Configuring Custom Rerouting

启用rewrite规则匹配日志

启用rewrite匹配日志有助于排错:

http {
    # rewrite操作的日志等级是`notice`
    error_log       /var/log/nginx/error.log notice;
    rewrite_log     on;
}

启用防盗链(Anti-leech)

为了防止网站资源——最常见的是图片——被第三方滥用(hotlinking),网站管理员需要做防盗链设置。Nginx可以根据HTTP请求头部的Referer字段来阻止未授权的访问。

referer 实际上是一个拼写错误,正确写法是 referrer。但由于HTTP已经被广泛使用,目前只能将错就错。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer

server {
    server_name         c.com www.c.com;
    root                /usr/share/nginx/html/vhosts/c/;
    
    valid_referers      none blocked server_names 
                        ~\.google\. ~\.baidu\. ~\.bing\.;
    
    if ($invalid_referer) {
            return      403;
    }
}

3 Comments

  1. tester 2018-04-18 at 18:48 - Reply

    Now I know I can use these Markdown syntax: italic, bold, inline code.

    And the heading syntax # Heading 1 can’t be used.

    • tester 2018-04-18 at 18:58 - Reply

      What about the fence code block?

      echo 'Hello world!'
      seq 3 8

      • tester 2018-04-18 at 19:03 - Reply

        OK, the content of a fenced code block was converted to inline code, but the syntax can work.

Leave A Comment