nginx使用入门的笔记

本文于2016年4月底完成,发布在个人博客网站。
考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来。


从源码安装nginx

下载软件

编译nginx,必备pcrezlib,由于jackie打算研究HTTPS,所以还需要openssl

wget https://www.openssl.org/source/openssl-1.0.2g.tar.gz
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.38.tar.gz
wget http://zlib.net/zlib-1.2.8.tar.gz
wget http://nginx.org/download/nginx-1.9.15.tar.gz

当前openssl的最新版本为1.1.0-pre5,但是在编译时发现会报错,所以还是使用了1.0.2g版本。

编译和安装

软件上传至/home/jackie/installer,然后执行如下命令

  1. 解压软件包

     cd /home/jackie/installer
     tar vxfz openssl-1.0.2g.tar.gz
     tar vxfz pcre-8.38.tar.gz
     tar vxfz zlib-1.2.8.tar.gz
     tar vxfz nginx-1.9.15.tar.gz
    
  2. 准备编译脚本

     cd nginx-1.9.15
     test -f Makefile && make clean
     ./configure --prefix=/home/jackie/software/nginx \ 
     	--with-http_ssl_module --with-openssl=/home/jackie/installer/openssl-1.0.2g \
     	--with-pcre=/home/jackie/installer/pcre-8.38 \
     	--with-zlib=/home/jackie/installer/zlib-1.2.8
    
  3. 编译,利用多核CPU的优势,提升效率。如无意外,这一步一般都会成功。

     make -j4 
    
  4. 执行安装

     make install  
    

基本使用

  • nginx -v,查看当前版本

      #./nginx -v
      nginx version: nginx/1.9.15
    
  • nginx -c filename,使用指定的配置文件启动nginx进程。

  • nginx -s stop,立即关闭nginx,直接退出运行。

  • nginx -s quit,正常关闭,完成响应之后退出运行。

  • nginx -s reload,使用新的配置启动新的工作进程,正常关闭旧的工作进程。

  • nginx -s reopen,重新打开日志文件。

  • nginx -t,测试配置文件的内容是否正确。

使用上述命令,可以简单验证下刚才编译得到的nginx是否可以使用。

nginx的目录结构

安装路径下包含如下目录:

  • conf
  • html
  • logs
  • sbin

conf

存放nginx在运行时需要的配置文件,默认情况下有如下文件:

  • 字符集转换映射表

    • koi-utf
    • koi-win
    • win-utf

    模块ngx_http_charset_module的文档中提到了如上的三个文件,以及使用说明。

    Full conversion tables from koi8-r to windows-1251, and from koi8-r and windows-1251 to utf-8 are provided in the distribution files conf/koi-win, conf/koi-utf, and conf/win-utf.

    如下是使用样例:

    include conf/koi-win;

    charset windows-1251;

    source_charset koi8-r;

  • 文件扩展名与文件类型的映射表

    • mime.types
    • mime.types.default

    nginx根据映射表中定义的映射关系,设置HTTP响应头的Content-Type值。当在映射表中没有找到文件对应的Content-Type时,nginx将使用default-type指令指定的默认值。

    比如在nginx.conf有如下配置,则Content-Type默认值为application/octet-stream

      include       mime.types;
      default_type  application/octet-stream;
    
  • cgi参数传递的配置

    • fastcgi.conf
    • fastcgi.conf.default
    • fastcgi.params
    • fastcgi.params.default
    • scgi_params
    • scgi_params.default
    • uwsgi_params
    • uwsgi_params.default

    由于Jackie没有用到cgi形式的调用,因此对于这类配置文件没有做专门的了解。

  • nginx的主要配置文件,啰嗦了这么多,终于到了nginx最重要的配置文件,具体指令的说明在后面逐步介绍。

    • nginx.conf
    • nginx.conf.dfault

html

默认情况下有如下两个文件:

  • index.html,nginx的欢迎主页。
  • 50x.html,50x错误时的页面。

logs

默认情况下日志文件的输出目录。

sbin

默认情况下,nginx程序的安装目录。

nginx的配置

配置说明

基本配置

指定nginx工作者进程运行时的用户,例如如下指令指定使用用户nobody来运行nginx工作者进程。

user nobody;

指定保存nginx主进程ID的文件

pid logs/nginx.pid;

隐藏nginx的版本号

server_tokens   off;

禁止非必要的HTTP方法

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return    444;
}

禁止访问隐藏文件

location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
}

禁止访问WEB-INF目录

location ~ ^/WEB-INF/ {
     deny  all;
}

错误日志

指定错误日志保存文件名。

error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;

访问日志

关闭访问日志

access_log off;

指定访问日志输出路径

access_log logs/access.log;

指定日志输出路径,同时指定只保存部分内容

log_format apache
    '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_cookie"';
access_log logs/access.log apache;

输出全部日志到access-full.log中

log_format full
    '$remote_addr $remote_user [$time_local] '
    '"$host"->$proxy_host->$upstream_addr '
    '"$request" $status($upstream_status) '
    '$bytes_sent/$gzip_ratio($sent_http_content_type) '
    '$request_time($upstream_response_time)';	
access_log logs/access-full.log full;

TCP传输配置

启用sendfile特性,提高I/O效率。

sendfile                on;
tcp_nodelay             off;
tcp_nopush              on;
keepalive_requests      100;

超时的定义

client_header_timeout   30;
client_body_timeout     60;
send_timeout            60;
keepalive_timeout       65 20;

缓存相关参数的定义

client_header_buffer_size   1k;
client_body_buffer_size     128k;
large_client_header_buffers 4 4k;
client_max_body_size        10m;
client_body_temp_path       temp/client/;
output_buffers              1 32k;
postpone_output             1460;

HTTPS相关配置

#ssl_stapling           on;
#ssl_stapling_verify    on;
ssl_prefer_server_ciphers on;
ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers             HIGH:!RC4:!3DES:!aDSS:!aNULL:!kPSK:!kSRP:!MD5:@STRENGTH:+SHA1:+kRSA;
ssl_session_cache       shared:TLSSL:16m;
ssl_session_timeout     10m;
ssl_certificate         sslcert/de/<company>/wildcard.crt;
ssl_certificate_key     sslcert/de/<company>/wildcard.key;

HTTP协议的安全头部

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;	

add_header X-Frame-Options SAMEORIGIN always; # frame页面的地址只能为同源域名下的页面
#add_header X-Frame-Options DENY; # 浏览器拒绝当前页面加载任何Frame页面
#add_header X-Frame-Options ALLOW-FROM; # origin为允许frame加载的页面地址

add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options nosniff;

启用gzip传输

gzip                    on;
gzip_static             on;
gzip_disable            "msie6";
#gzip_disable "MSIE [1-6]\.";
gzip_vary               on;
gzip_min_length         1024;
gzip_buffers            128 32k;
gzip_comp_level         6;
#gzip_proxied            any;
gzip_http_version       1.1;
gzip_proxied            expired no-cache no-store private auth;
gzip_types              text/plain text/css text/x-component
                        text/xml application/xml application/xhtml+xml application/json
                        image/x-icon image/bmp image/svg+xml application/atom+xml
                        text/javascript application/javascript application/x-javascript
                        application/pdf application/postscript
                        application/rtf application/msword
                        application/vnd.ms-powerpoint application/vnd.ms-excel
                        application/vnd.ms-fontobject application/vnd.wap.wml
                        application/x-font-ttf application/x-font-opentype;

代理的相关配置

proxy_intercept_errors  on; 
proxy_ignore_client_abort off;
#proxy_redirect          http:// $scheme://;
proxy_pass https://127.0.0.1:18433;

proxy_hide_header       Server;
proxy_hide_header       X-Powered-By;
proxy_set_header        Host              $http_host;
#proxy_set_header        Host              $host;

在设置Host时,有的网友使用的是如下指令。经过实测,对于后端基于tomcat的Web应用如果使用了非标准的端口提供Web服务,在页面重定向后URL中会丢失端口,导致用户无法正常访问站点。

proxy_set_header        Host              $host;

如果后端的应用启用了对referer的验证,为避免代理后的请求被应用屏蔽,需要手工指定Referer。

proxy_set_header 		referer 		  ''; 

指定原始请求的信息

proxy_set_header        X-Forwarded-By    $server_addr:$server_port;
proxy_set_header        X-Forwarded-For   $remote_addr;
proxy_set_header        X-Forwarded-Class $classification;
proxy_set_header        X-Forwarded-Proto $scheme;

### proxy-timeouts ###
proxy_connect_timeout   6;
proxy_send_timeout      60;
proxy_read_timeout      60;

### proxy-buffers ###
proxy_buffering         on;
proxy_buffer_size       8k;
proxy_buffers           256 8k;
proxy_busy_buffers_size    64k;
proxy_temp_file_write_size 64k;
proxy_temp_path         temp/proxy/;

完整样例

nginx作为反向代理

  • 将请求转给后端,后端基于tomcat+jsp开发;
  • nginx启用HTTPS支持;

nginx.conf

#user  nobody;
worker_processes  1;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
    gzip_vary               on;
    gzip_min_length         1024;
    gzip_buffers            128 32k;
    gzip_comp_level         6;
    gzip_http_version       1.1;
    gzip_proxied            expired no-cache no-store private auth;
    gzip_types              text/plain text/css text/xml application/xml application/json text/javascript application/javascript application/x-javascript;

    charset utf-8;
    server {
        listen 8080;
        server_name  192.168.1.102;
        if ($scheme ~ http) {
            return https://192.168.1.102:8443$request_uri;
        }
    }

    server {
        listen       8443 ssl;
        server_name  192.168.1.102;

        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" always;
        add_header X-Frame-Options SAMEORIGIN always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options nosniff;

        location / {
			#root   html;
            index  index.jsp;
            proxy_pass http://192.168.1.102:18080;
            proxy_set_header        referer           '';
            include proxy.conf;
        }

        location ~ .*\.jsp$ {
			#root   html;
            index  index.jsp;
            proxy_pass http://192.168.1.102:18080;
            proxy_set_header        referer           '';
            include proxy.conf;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
    }

}

proxy.conf

proxy_hide_header       Server;
proxy_hide_header       X-Powered-By;
proxy_set_header        Host              $http_host;
proxy_set_header        X-Forwarded-By    $server_addr:$server_port;
proxy_set_header        X-Forwarded-For   $remote_addr;
#proxy_set_header        X-Forwarded-Class $classification;
proxy_set_header        X-Forwarded-Proto $scheme;
proxy_connect_timeout   6;
proxy_send_timeout      60;
proxy_read_timeout      60;
proxy_buffering         on;
proxy_buffer_size       8k;
proxy_buffers           256 8k;
proxy_busy_buffers_size    64k;
proxy_temp_file_write_size 64k;
#proxy_temp_path         temp/proxy/;

参考资料

nginx

nginx wiki

网友的经验和总结

关于HTTPS

关于安全头部

关于gzip

关于sendfile

相关博客

热门相关:朔明   顺明   惹火甜妻:老公大人,宠上瘾!   官策   官策