阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx知识点全面总结

108次阅读
没有评论

共计 27375 个字符,预计需要花费 69 分钟才能阅读完成。

本文目录:
1. nginx 简介
2. nginx 处理请求的过程简单说明
3. nginx 命令
4. nginx 模块及 http 功能速览
5. nginx 配置文件简单说明
5.1 main 和 events 段
5.2 http 段
5.2.1 配置文件概览
5.2.2 root 指令和 alias 指令
5.2.3 location 容器
5.2.4 error_page 指令
5.2.5 allow 和 deny
5.2.6 add_header 添加相应首部字段
5.3 虚拟主机和 server_name 指令
5.4 虚拟主机的匹配规则
5.5 stub_status 指令获取 nginx 状态信息
6. 访问日志 access_log
6.1 log_format 指令
6.2 access_log 指令
6.3 日志文件的分割
7. 配置 web 身份认证
8. 配置 https


 

1. nginx 简介

nginx 是一个优秀的 web 服务程序、反向代理程序。它采用非阻塞异步的套接字,使用 epoll 方式实现事件驱动,同时采用 一个 master+ N 个 worker 进程 (默认) 的方式处理请求,这种架构使得它在并发的处理能力上极其出色,可以比较轻松地解决 C10K 问题。

 

2. nginx 处理请求的过程简单说明

master 进程用于管理 worker 进程,例如接收外界信号、向 worker 进程发送信号、销毁 worker 进程、启动 worker 进程等等。

nginx 之所以性能良好,完全是由它的架构决定的。每个 worker 进程是业务处理进程,负责监听套接字、处理请求、响应请求、代理请求至后端服务器等。

作为 web server 处理静态资源时每个 worker 进程的大致流程:

(1). 监听套接字。
(2). 与客户端建立连接。
(3). 处理监听到的连接请求(加载静态文件)。
(4). 响应数据。
(5). 断开连接。

这几个过程是每个 web server 都具备的能力,但对于 nginx 来说,由于它的异步非阻塞,每个过程都不会阻塞(有些小过程必须阻塞的时候还是会阻塞),使得并发处理能力很好。

从监听套接字开始说。每个 worker 进程都是平等的,它们都可以去监听套接字,正常情况下不可避免地会造成争抢和 ” 惊群问题 ”,而 nginx 采用 ” 争抢 ”accept 互斥锁的方式,只有持有 accept 互斥锁的 worker 进程才有资格将连接请求接到自己的队列中并完成 TCP 连接的建立。但每个进程是相互独立而平等的,谁有资格去 ” 争抢 ” 互斥锁且有更大几率争抢成功?只要 worker 进程当前建立的连接数小于 worker_connections 指令指定的值 (实际上源码中设置的是该值的 7 /8),就允许争抢互斥锁,因为连接数超过了该值的 7 / 8 表示已经非常繁忙。除了繁忙程度限制资格,还有 epoll_wait 的 timeout 的指标,等待越久的 worker 进程争抢能力越强。 总之,在某一时刻,一定只有一个 worker 进程监听并 accept 新的连接请求

当已经监听到连接请求时,worker 进程与它进行三次握手,并最终 accpet 到自己的内存池中,并和客户端交互数据,处理客户端发送的 http 请求并响应数据给客户端。但是,nginx 的高效就在于它的异步非阻塞,无论是在 TCP 连接进入 ESTABLISHED 之前,还是等待客户端发送请求,亦或者是等待加载本地静态资源的 I /O,以及响应数据给客户端的任意一个过程中,nginx 都是非阻塞的,在任意等待发生时都可以去处理其它事情。当等待的某个资源已经准备成功时将产生事件通知 worker 进程,worker 进程可随后去处理。在此过程中,由于 worker 进程绑定在一个 CPU 核心上(推荐如此做),所有的连接都放在内存池中,这使得上下文切换时是极其轻量的,极大地减轻了 CPU 消耗。从理论上来说,当每个 worker 绑定了一个 CPU 核心时,它的并发处理能力主要依赖于内存的大小。

实际上 apache httpd 的 event MPM 也是异步非阻塞的,也可以采用 epoll,但它采用的是多线程方式,虽然异步,但它的异步似乎不体现在并发能力上,而仅仅只是一些具有特殊状态的连接 (如长连接) 的异步处理,在处理过程中 cpu 还是不断地需要在各线程之间大量切换,并发能力并不比 worker MPM 强多少,相比 nginx 更是远远不如。

 

3. nginx 命令

[root@xuexi nginx]# nginx -h
nginx version: nginx/1.12.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : 输出版本号
  -V            : 输出版本号以及编译选项
  -t            : 检查配置文件的语法
  -T            : 检查配置文件的语法并输出配置的内容
  -q            : 静默模式,不输出任何信息
  -s signal     : 向主进程发送信号:stop, quit, reopen, reload
  -p prefix     : 设置 nginx 的 basedir(默认为编译时的 prefix)
  -c filename   : 指定配置文件
  -g directives : 提前设置全局指令

-V选项输出编译选项。

[root@xuexi nginx]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.12.0 --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/subsys/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre

(1). 使用默认配置文件直接启动 nginx 和指定配置文件启动 nginx

nginx -c /usr/local/nginx/conf/nginx.conf

(2). 运行时重载配置文件。当 nginx 主进程接收到重载配置文件的命令后,它会先检查新配置文件语法,然后载入该配置文件到内存中并解析。然后,主进程 fork 一系列新的 worker 进程,并发送 QUIT 信号给旧的 worker 进程(graceful stop)。旧的工作进程接收到 QUIT 信号后,会停止接受新的连接请求,并继续处理旧的连接直到请求处理完成后才退出。

nginx -s reload

(3). 运行时快速关闭 nginx。

nginx -s stop

(4). 运行时优雅关闭 nginx。所有的工作进程会停止接受新的连接,并继续服务旧的连接请求直到所有的请求完成后才退出。

nginx -s quit

(5). 运行时重新打开日志文件。

ngnix -s reopen

 

4. nginx 模块及 http 功能速览

Nginx 的代码由一个核心和一系列的模块组成。

核心 (core functionality) 主要用于提供全局应用的基本功能,创建必要的运行时环境及确保不同模块之间平滑地进行交互等,对应于配置文件的 main 段和 event 段。核心涉及的指令官方文档:http://nginx.org/en/docs/ngx_core_module.html

还有很多功能都通过模块实现,nginx 是高度模块化程序。如 web 相关的功能模块有 ”ngx_http_*_module”,和 mail 相关的功能模块有 ”ngx_mail_*_module”,和 tcp 代理、负载均衡相关的功能模块有 ”ngx_stream_*_module”,这些类别的模块中又分为很多类别的模块,如 http 类别的模块中有基本核心模块、事件类模块、缓存类模块、SSL 相关模块、负载均衡类模块 upstream 等等。

以下是 http 功能模块类中常见的模块。

http 类模块名 模块功能说明
ngx_http_core_module http 核心模块,对应配置文件中的 http 段,包含很多指令,如 location 指令
ngx_http_access_module 访问控制模块,控制网站用户对 nginx 的访问,对应于配置文件中的 allow 和 deny 等指令
ngx_http_auth_basic_module 通过用户名和密码认证的访问控制,如访问站点时需要数据用户名和密码,指令包括 auth_basic 和 auth_basic_user_file
ngx_http_charset_module 设置网页显示字符集。指令之一为 charset,如 charset utf-8
ngx_http_fastcgi_module fastcgi 模块,和动态应用相关。该模块下有非常多的子模块。
ngx_http_flv_module 支持 flv 视频流的模块,如边下边播
ngx_http_mp4_module 同 flv 模块
ngx_http_gzip_module 压缩模块,用来压缩 nginx 返回的响应报文。一般只压缩纯文本内容,因为压缩比例非常大,而图片等不会去压缩
ngx_http_image_filter_module 和图片裁剪、缩略图相关模块,需要安装 gd-devel 才能编译该模块
ngx_http_index_module 定义将要被作为默认主页的文件,对应指令为 index。”index index.html,index.php”
ngx_http_autoindex_module 当 index 指令指定的主页文件不存在时,交给 autoindex 指令,将自动列出目录中的文件 autoindex {on/off}  
ngx_http_log_module 和访问日志相关的模块,指令包括 log_format 和 access_log
ngx_http_memcached_module 和 memcached 相关的模块,用于从 memcached 服务器中获取相应响应数据
ngx_http_proxy_module 和代理相关,允许传送请求到其它服务器
ngx_http_realip_module 当 nginx 在反向代理的后端提供服务时,获取到真正的客户端地址,否则获取的是反向代理的 IP 地址
ngx_http_referer_module 实现防盗链功能的模块
ngx_http_rewrite_module 和 URL 地址重写相关的模块,需要安装 pcre-devel 才能编译安装该模块
ngx_http_scgi_module simple cgi,是 cgi 的替代品,和 fastcgi 类似,但更简单
ngx_http_ssl_module 提供 ssl 功能的模块,即实现 HTTPS
ngx_http_stub_status_module 获取 nginx 运行状态信息
ngx_http_upstream 和负载均衡相关模块

这些模块共同组成了 nginx 的 http 功能。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-10/147744p2.htm

5. nginx 配置文件简单说明

nginx 的配置文件有很多个,如下。其中主配置文件为 nginx.conf,其他配置文件在需要的时候使用 include 指令将其包含到主配置文件中。

[root@xuexi ~]# ls /usr/local/nginx/conf/
fastcgi.conf  fastcgi_params  koi-utf  mime.types  nginx.conf  scgi_params  uwsgi_params  win-utf
fastcgi.conf.default  fastcgi_params.default  koi-win  mime.types.default  nginx.conf.default  scgi_params.default  uwsgi_params.default

其中 ”.default” 后缀的是对应前缀配置文件的备份配置文件,”.params” 是对应前缀的参数文件。如 fastcgi.conf 是和 fastcgi 相关参数的配置文件,fastcgi.params 是 fastcgi 的参数文件,fastcgi.conf.default 是 fastcgi.conf 的备份文件。

关于主配置文件 nginx.conf,由于 Nginx 高度模块化,所以它是分段配置的,核心模块为 core,对应配置文件中的 Main 和 Events 段。此外还有其他一些模块。配置文件中每一个指令必须以分号 ”;” 结束,否则语法错误。

 

5.1 main 和 events 段

Main 用于配置错误日志、进程及权限等相关的参数,Events 用于配置 IO 模型,如 epoll、kqueue、select 或 poll 等,它们是必备模块。如下配置:

#user  nobody;        # worker 进程身份, 默认使用编译时指定值. 语法为 "user user_name [group_name]"
worker_processes  4;  # worker 进程数量, 该指令值依赖因素较多,例如是否 CPU 密集型、是否 IO 密集型。
                      # 在初始时设置为 cpu 的总核数是一个不错的选择。

#error_log logs/error.log;         # 错误日志文件,禁用错误日志 "error_log /dev/null LEVEL;"
#error_log logs/error.log notice;  # 级别:debug|info|notice|warn|error|crit|alert|emerg,默认为 error
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;
#lock_file  logs/nginx.lock;

events {worker_connections  1024;   # 每个 worker 进程的最大连接数
    multi_accept on;            # 是否一次性将监听到的连接全接收进来,默认为 off,关闭时一次接收一条连接
    accept_mutex on             # 默认为 on,开启时表示以串行方式接入新连接,否则将通报给所有 worker。
                                # 这可能会浪费资源并产生不可预计的后果,例如惊群问题
}

如果某个文件采用了相对路径,则其相对的基准为 basedir。例如编译时 –prefix 指定为 /usr/local/nginx,则指定 pid 为 logs/nginx.pid 时,其实际路径为 /usr/local/nginx/logs/nginx.pid。

worker_processes 的值和 work_connections 的值决定了最大并发数量。例如上面的配置中,每个 worker 进程最大允许 1024 个连接,配置了 4 个 worker 进程,所以并发数量为 1024*4=4096。但在反向代理场景中计算方法不同,因为 nginx 既要维持和客户端的连接,又要维持和后端服务器的连接,因此处理一次连接要占用 2 个连接,所以最大并发数计算方式为:worker_processes*worker_connections/2。此外还需注意,除了和客户端的连接、与后端服务器的连接,nginx 可能还会打开其他的连接,这些都会占用文件描述符,从而影响并发数量的计算。最后还需注意,最大并发数量还受 ” 允许打开的最大文件描述符数量 ” 限制,可以使用 ”worker_rlimit_nofile” 指令修改或直接修改操作系统的对应内核参数。

可以在 main 段使用 worker_cpu_affinity 指令绑定 CPU 核心。nginx 通过位数识别 CPU 核心以及核心数,指定位数上占位符为 1 表示使用该核心,占位符为 0 表示不使用该核心。例如 2 核 cpu 的位数分别为 01 和 10,4 核的位数分别为 1000,0100,0010 以及 0001,同理 8 核和 16 核。在结合 worker_processes 指令一起使用时,要注意 worker 进程和核心的对应方式,例如:

# 每个 worker 分别对应 cpu0/cpu1/cpu2/cpu3
worker_processes    4;
worker_cpu_affinity 0001 0010 0100 1000;

# 有 4 核心,但只有两 worker,第一个 worker 对应 cpu0/cpu2,第二个 worker 对应 cpu1/cpu3
worker_processes    2;
worker_cpu_affinity 0101 1010;

在 events 段,可以使用 ”use” 指令可以指定使用哪种 I / O 模型,Linux 上默认是 epoll,通常可以不用手动去设置,因为 nginx 默认会采用最佳配置。

以下是 main 段和 events 段的配置示例,大多数采用的默认值,需要修改的大致就是 worker 数量、每个 worker 最大连接数以及进程绑定 cpu。

worker_processes  4;
events {worker_connections  1024;
}

 

5.2 http 段

 

5.2.1 配置文件概览

http 段是由 http 相关模块支持的。以下是默认配置项。注意,http 根段下使用相对路径是相对 conf 目录的,如 ”include extra/.conf” 表示的是 conf/extra/.conf;非根段内的相对路径如 server 段内使用相对路径是相对于的。

http {include       mime.types;    # nginx 支持的媒体文件类型。相对路径为同目录 conf 下的其他文件
    default_type  application/octet-stream;      # 默认的媒体类型

    #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;   # 启用 sendfile 传输模式,此模式是 "零拷贝"
    #tcp_nopush     on;   # 只在 sendfile on 时有效。让数据包挤满到一定程度才发送出去,挤满之前被阻塞

    #keepalive_timeout  0;   # keepalive 的超时时间
    keepalive_timeout  65;

    #gzip  on;               # 是否启用 gzip 压缩响应报文

    server {# 定义虚拟主机
        listen       80;        # 定义监听套接字
        server_name  localhost; # 定义主机名加域名,即网站地址

        #charset koi8-r;        # 默认字符集

        #access_log  logs/host.access.log  main;         # 访问日志路径

        location / {# location 容器,即 URI 的根
            root   html;                    # 站点根目录,即 DocumentRoot,相对路径时为 <prefix>/html
            index  index.html index.htm;    # 站点主页文件
        }

        #error_page  404    /404.html;      # 出现 404 page not fount 错误时,使用 /404.html 页响应客户端

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;      # 出现 50x 错误时,使用 /50x.html 页返回给客户端
        location = /50x.html {# 定义手动输入包含 /50x.html 时的 location
            root   html;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }
    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
}

 

5.2.2 root 指令和 alias 指令

root 指令设置站点根目录,即 httpd 的 documentroot,但又有所不同,因为 nginx 可以在多个上��文位置处使用 root 指令,例如 Location 容器中。

如果配置如下:

location /i/ {root /data/w3;
}

那么 nginx 将使用文件 /data/w3/i/top.gif 响应请求 ”/i/top.gif”。

root 指令仅仅只是将匹配的 URI 追加在 root 路径后,如果要改变 URI,应该使用 alias 指令,它会对 URI 进行替换。例如:

location /i/ {alias /data/w3/images/;
}

那么 nginx 将使用文件 /data/w3/images/top.gif 响应请求 /i/top.gif。因此,如果 alias 指令的路径最后一部分包含了 URI,则最好使用 root 指令,而非 alias 指令,虽然它们都能成功响应。

location /images/ {alias /data/w3/images/;
}

location /images/ {root /data/w3/;
}

它们都能使用相对路径,相对的是 prefix。例如编译路径为 /usr/local/nginx,则 ”root html” 指的是 ”/usr/local/nginx/html”。

与 root 和 alias 指令相关的变量为 $document_root、$readpath_root。其中 $document_root 的值即是 root 指令、alias 指令的值,而 $realpath_root 的值是对 root、alias 指令进行绝对路径换算后的值

 

5.2.3 location 容器

该指令对规范化后的 URI 进行匹配,并对匹配的路径封装一系列指令。语法:

location [= | ~ | ~* | ^~] uri {...}

其中:location /uri/ {}:表示对 /uri/ 目录及其子目录下的所有文件都匹配。所以 ”location / {}” 的匹配范围是最大的。
location = /uri/ {}:表示只对目录或文件进行匹配,不对目录中的文件和子目录进行匹配。所以一般只用来做文件匹配
location ~ /uri/ {}:表示区分大小写的正则匹配。
location *~ /uri/ {}:表示不区分大小写的正则匹配。
location ^~ /uri/ {}:表示禁用正则匹配,即精确字符串匹配,此时正则中的元字符被解释成普通字符。

它们的匹配优先级规则为:nginx 先检查 URI 的前缀路径,在这些路径中找到最精确匹配请求 URI 的路径。然后 nginx 按在配置文件中的出现顺序检查正则表达式路径,匹配上某个路径后即停止匹配并使用该路径的配置,否则使用最大前缀匹配的路径的配置

使用 ”=” 前缀可以定义 URI 和路径的精确匹配。如果发现匹配,则终止路径查找。例如请求 ”/” 很频繁,定义 ”location = /” 可以提高这些请求的处理速度,因为查找过程在第一次比较以后即结束。

以下是一个优先级的示例。

location = / {[ configuration A]
}

location / {[ configuration B]
}

location /documents/ {[ configuration C]
}

location ^~ /images/ {[ configuration D]
}

location ~* \.(gif|jpg|jpeg)$ {[ configuration E] 
}

请求 ”/” 能匹配 A 和 B,但最精确匹配为 A。
请求 ”/index.html” 的前缀 ”/” 能匹配 A 和 B,但 A 只能匹配 ”/” 自身,因此最终匹配配置 B。(前缀也能匹配 E,但文件名无法匹配)
请求 ”/documents/document.html” 的前缀能匹配 B 和 C,但 C 更精确,因此匹配配置 C。(前缀也能匹配 E,但文件名无法匹配)
请求 ”/images/1.gif” 的前缀能匹配 B、D 和 E,且 D 和 E 都是最长路径匹配,但 ^~ 优先级更高,因此匹配配置 D。
请求 ”/documents/1.jpg” 的前缀能匹配 B、C,同样也能匹配 E,且 E 比 B 的匹配更精确,因此最终匹配配置 E。

大致可以将规则简化为如下优先级:

(location = uri) > (location ^~ uri) > (location *~|~ uri) > (location uri)

等号优先级最高,非正则匹配次之,再之后是正在匹配,它们之间有位置的先后顺序,优先级最低的是没有使用任何符号的匹配

由此也可以知道,”location / {}” 这种方式是一种特殊的 uri 匹配,无论什么 uri 路径,都能往这里面装,可以认为它是默认匹配,当其它 location 都匹配不上时就会匹配它。

 

5.2.4 error_page 指令

当出现对应状态码的错误时,指定返回的 URI 路径。语法为:

error_page code ... [=[response]] uri;

配置文件中的 error_page 部分默认为:

location / {root   html;
    index  index.html index.htm;
}
#error_page  404              /404.html;
error_page   500 502 503 504  /50x.html;
location = /50x.html {root   html;
}

上面的配置文件中,假如取消了 404 错误的 error_page 行注释,当出现 404 错误时,其 uri 为 /404.html,然后会对其进行 location 的匹配,由于只有 ”location / {}” 能匹配到,所以它的目录为 /html/,即 404.html 文件路径为 /html/404.html。对于 50x 的 error_page,其 uri 为 ”/50x.html”,所以会对其进行 location 匹配,发现可以精确匹配到 ”location = /50x.html {}”,当然 ”location / {}” 也能匹配到,但是它的优先级更低,所以当出现 50x 错误时,将从 /html 目录下寻找 50x.html,这里正好和 ”location / {}” 重复了,但它们的匹配过程是不一样的。假如改为如下配置:

location / {root   html;                     
    index  index.html index.htm;     
}
#error_page  404              /404.html;
error_page   500 502 503 504  /50x.html;
location = /50x.html {root   /www/a.com/;
}

出现 50x 错误时,将返回 /www/a.com/50x.html 文件,而不再是 /html/50x.html。

 

5.2.5 allow 和 deny

这两个指令由 ngx_http_access_module 模块提供,用于允许或限制某些 IP 地址的客户端访问。nginx 中的 allow 和 deny 规则很简单,从上向下匹配,只要匹配到就停止。例如:

allow 10.0.0.8
allow 192.168.100.0/24
deny all

允许 10.0.0.8 和 192.168.100 网段的访问,其他的都拒绝。

 

5.2.6 add_header 添加相应首部字段

用于在响应首部中添加字段。例如:

server {add_header RealPath $realpath_root;
}

将添加一个名为 RealPath 的字段,值为变量 realpath_root 的值。

[root@xuexi ~]# curl -I http://localhost/
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Tue, 17 Oct 2017 08:10:14 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 17 Oct 2017 03:20:10 GMT
Connection: keep-alive
ETag: "59e576ea-264"
RealPath: /usr/local/nginx-1.12.1/html   # 此为自定义添加字段
Accept-Ranges: bytes

 

5.3 虚拟主机和 server_name 指令

nginx 使用 server 容器定义一个虚拟主机。在 nginx 中,没有严格区分基于 IP 和基于名称的虚拟主机,它们通过 listen 指令和 server_name 指令结合起来形成不同的虚拟主机。

例如:

# 基于 IP 地址的虚拟主机
server {listen 80;
        server_name 192.168.100.25;
        location / {root /www/longshuai/;
                index index.html index.htm;
        }
}
server {listen 80;
        server_name 192.168.100.26;
        location / {root /www/xiaofang/;
                index index.html index.htm;
        }
}

# 基于名称的虚拟主机
server {listen 80;
        server_name www.longshuai.com;
        location / {root /www/longshuai/;
                index index.html index.htm;
        }
}
server {listen 80;
        server_name www.xiaofang.com;
        location / {root /www/xiaofang/;
                index index.html index.htm;
        }
}

# 基于端口的虚拟主机
server {listen 80;
        server_name 192.168.100.25;
        location / {root /www/longshuai/;
                index index.html index.htm;
        }
}
server {listen 8080;
        server_name 192.168.100.25;
        location / {root /www/xiaofang/;
                index index.html index.htm;
        }
}

其中 server_name 指令可以定义多个主机名,第一个名字为虚拟主机的首要主机名。例如:

server_name  example.com   www.example.com;

主机名中可以含有星号(“*”),以替代名字的开始部分或结尾部分(只能是起始或结尾,如果要实现中间部分的通配,可以使用正则表达式)。例如 ”*.example.org” 不仅匹配 www.example.org,也匹配 www.sub.example.org。下面两条指令是等价的。

server_name    example.com   *.example.com   www.example.*;
server_name   .example.com   www.example.*;

也可以在主机名中使用正则表达式,就是在名字前面补一个波浪线(“~”):

server_name   www.example.com   ~^www\d+\.example\.com$;

nginx 允许定义空主机名:

server {listen       80;
    server_name  "";
    return       444;
}

这种主机名可以让虚拟主机处理没有 ”Host” 首部的请求,而不是让指定 ” 地址: 端口 ” 的默认虚拟主机来处理,而这正是本指令的默认设置。即使用非默认的虚拟主机处理请求头中不含 ”Host” 字段的请求。一般这样的请求处理方式是直接丢弃请求,并返回一个非标准的状态码来立即关闭连接,例如上面的 444。

如果 server 块中没有定义 server_name,nginx 使用空名字作为虚拟主机名。

本文目录:
1. nginx 简介
2. nginx 处理请求的过程简单说明
3. nginx 命令
4. nginx 模块及 http 功能速览
5. nginx 配置文件简单说明
5.1 main 和 events 段
5.2 http 段
5.2.1 配置文件概览
5.2.2 root 指令和 alias 指令
5.2.3 location 容器
5.2.4 error_page 指令
5.2.5 allow 和 deny
5.2.6 add_header 添加相应首部字段
5.3 虚拟主机和 server_name 指令
5.4 虚拟主机的匹配规则
5.5 stub_status 指令获取 nginx 状态信息
6. 访问日志 access_log
6.1 log_format 指令
6.2 access_log 指令
6.3 日志文件的分割
7. 配置 web 身份认证
8. 配置 https


 

1. nginx 简介

nginx 是一个优秀的 web 服务程序、反向代理程序。它采用非阻塞异步的套接字,使用 epoll 方式实现事件驱动,同时采用 一个 master+ N 个 worker 进程 (默认) 的方式处理请求,这种架构使得它在并发的处理能力上极其出色,可以比较轻松地解决 C10K 问题。

 

2. nginx 处理请求的过程简单说明

master 进程用于管理 worker 进程,例如接收外界信号、向 worker 进程发送信号、销毁 worker 进程、启动 worker 进程等等。

nginx 之所以性能良好,完全是由它的架构决定的。每个 worker 进程是业务处理进程,负责监听套接字、处理请求、响应请求、代理请求至后端服务器等。

作为 web server 处理静态资源时每个 worker 进程的大致流程:

(1). 监听套接字。
(2). 与客户端建立连接。
(3). 处理监听到的连接请求(加载静态文件)。
(4). 响应数据。
(5). 断开连接。

这几个过程是每个 web server 都具备的能力,但对于 nginx 来说,由于它的异步非阻塞,每个过程都不会阻塞(有些小过程必须阻塞的时候还是会阻塞),使得并发处理能力很好。

从监听套接字开始说。每个 worker 进程都是平等的,它们都可以去监听套接字,正常情况下不可避免地会造成争抢和 ” 惊群问题 ”,而 nginx 采用 ” 争抢 ”accept 互斥锁的方式,只有持有 accept 互斥锁的 worker 进程才有资格将连接请求接到自己的队列中并完成 TCP 连接的建立。但每个进程是相互独立而平等的,谁有资格去 ” 争抢 ” 互斥锁且有更大几率争抢成功?只要 worker 进程当前建立的连接数小于 worker_connections 指令指定的值 (实际上源码中设置的是该值的 7 /8),就允许争抢互斥锁,因为连接数超过了该值的 7 / 8 表示已经非常繁忙。除了繁忙程度限制资格,还有 epoll_wait 的 timeout 的指标,等待越久的 worker 进程争抢能力越强。 总之,在某一时刻,一定只有一个 worker 进程监听并 accept 新的连接请求

当已经监听到连接请求时,worker 进程与它进行三次握手,并最终 accpet 到自己的内存池中,并和客户端交互数据,处理客户端发送的 http 请求并响应数据给客户端。但是,nginx 的高效就在于它的异步非阻塞,无论是在 TCP 连接进入 ESTABLISHED 之前,还是等待客户端发送请求,亦或者是等待加载本地静态资源的 I /O,以及响应数据给客户端的任意一个过程中,nginx 都是非阻塞的,在任意等待发生时都可以去处理其它事情。当等待的某个资源已经准备成功时将产生事件通知 worker 进程,worker 进程可随后去处理。在此过程中,由于 worker 进程绑定在一个 CPU 核心上(推荐如此做),所有的连接都放在内存池中,这使得上下文切换时是极其轻量的,极大地减轻了 CPU 消耗。从理论上来说,当每个 worker 绑定了一个 CPU 核心时,它的并发处理能力主要依赖于内存的大小。

实际上 apache httpd 的 event MPM 也是异步非阻塞的,也可以采用 epoll,但它采用的是多线程方式,虽然异步,但它的异步似乎不体现在并发能力上,而仅仅只是一些具有特殊状态的连接 (如长连接) 的异步处理,在处理过程中 cpu 还是不断地需要在各线程之间大量切换,并发能力并不比 worker MPM 强多少,相比 nginx 更是远远不如。

 

3. nginx 命令

[root@xuexi nginx]# nginx -h
nginx version: nginx/1.12.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : 输出版本号
  -V            : 输出版本号以及编译选项
  -t            : 检查配置文件的语法
  -T            : 检查配置文件的语法并输出配置的内容
  -q            : 静默模式,不输出任何信息
  -s signal     : 向主进程发送信号:stop, quit, reopen, reload
  -p prefix     : 设置 nginx 的 basedir(默认为编译时的 prefix)
  -c filename   : 指定配置文件
  -g directives : 提前设置全局指令

-V选项输出编译选项。

[root@xuexi nginx]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.12.0 --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/subsys/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre

(1). 使用默认配置文件直接启动 nginx 和指定配置文件启动 nginx

nginx -c /usr/local/nginx/conf/nginx.conf

(2). 运行时重载配置文件。当 nginx 主进程接收到重载配置文件的命令后,它会先检查新配置文件语法,然后载入该配置文件到内存中并解析。然后,主进程 fork 一系列新的 worker 进程,并发送 QUIT 信号给旧的 worker 进程(graceful stop)。旧的工作进程接收到 QUIT 信号后,会停止接受新的连接请求,并继续处理旧的连接直到请求处理完成后才退出。

nginx -s reload

(3). 运行时快速关闭 nginx。

nginx -s stop

(4). 运行时优雅关闭 nginx。所有的工作进程会停止接受新的连接,并继续服务旧的连接请求直到所有的请求完成后才退出。

nginx -s quit

(5). 运行时重新打开日志文件。

ngnix -s reopen

 

4. nginx 模块及 http 功能速览

Nginx 的代码由一个核心和一系列的模块组成。

核心 (core functionality) 主要用于提供全局应用的基本功能,创建必要的运行时环境及确保不同模块之间平滑地进行交互等,对应于配置文件的 main 段和 event 段。核心涉及的指令官方文档:http://nginx.org/en/docs/ngx_core_module.html

还有很多功能都通过模块实现,nginx 是高度模块化程序。如 web 相关的功能模块有 ”ngx_http_*_module”,和 mail 相关的功能模块有 ”ngx_mail_*_module”,和 tcp 代理、负载均衡相关的功能模块有 ”ngx_stream_*_module”,这些类别的模块中又分为很多类别的模块,如 http 类别的模块中有基本核心模块、事件类模块、缓存类模块、SSL 相关模块、负载均衡类模块 upstream 等等。

以下是 http 功能模块类中常见的模块。

http 类模块名 模块功能说明
ngx_http_core_module http 核心模块,对应配置文件中的 http 段,包含很多指令,如 location 指令
ngx_http_access_module 访问控制模块,控制网站用户对 nginx 的访问,对应于配置文件中的 allow 和 deny 等指令
ngx_http_auth_basic_module 通过用户名和密码认证的访问控制,如访问站点时需要数据用户名和密码,指令包括 auth_basic 和 auth_basic_user_file
ngx_http_charset_module 设置网页显示字符集。指令之一为 charset,如 charset utf-8
ngx_http_fastcgi_module fastcgi 模块,和动态应用相关。该模块下有非常多的子模块。
ngx_http_flv_module 支持 flv 视频流的模块,如边下边播
ngx_http_mp4_module 同 flv 模块
ngx_http_gzip_module 压缩模块,用来压缩 nginx 返回的响应报文。一般只压缩纯文本内容,因为压缩比例非常大,而图片等不会去压缩
ngx_http_image_filter_module 和图片裁剪、缩略图相关模块,需要安装 gd-devel 才能编译该模块
ngx_http_index_module 定义将要被作为默认主页的文件,对应指令为 index。”index index.html,index.php”
ngx_http_autoindex_module 当 index 指令指定的主页文件不存在时,交给 autoindex 指令,将自动列出目录中的文件 autoindex {on/off}  
ngx_http_log_module 和访问日志相关的模块,指令包括 log_format 和 access_log
ngx_http_memcached_module 和 memcached 相关的模块,用于从 memcached 服务器中获取相应响应数据
ngx_http_proxy_module 和代理相关,允许传送请求到其它服务器
ngx_http_realip_module 当 nginx 在反向代理的后端提供服务时,获取到真正的客户端地址,否则获取的是反向代理的 IP 地址
ngx_http_referer_module 实现防盗链功能的模块
ngx_http_rewrite_module 和 URL 地址重写相关的模块,需要安装 pcre-devel 才能编译安装该模块
ngx_http_scgi_module simple cgi,是 cgi 的替代品,和 fastcgi 类似,但更简单
ngx_http_ssl_module 提供 ssl 功能的模块,即实现 HTTPS
ngx_http_stub_status_module 获取 nginx 运行状态信息
ngx_http_upstream 和负载均衡相关模块

这些模块共同组成了 nginx 的 http 功能。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-10/147744p2.htm

5.4 虚拟主机的匹配规则

通过名字查找虚拟主机时,如果一个名字可以匹配多个指定的配置,比如同时匹配上通配符和正则表达式,按下面优先级,使用先匹配上的虚拟主机:

  1. 确定的名称;
  2. 最长的以星号起始的通配符名字,比如 ”*.example.com”;
  3. 最长的以星号结束的通配符名字,比如 ”mail.*”;
  4. 第一个匹配的正则表达式名字(按在配置文件中出现的顺序)。

当开始接入请求时,(1)nginx 首先判断请求的套接字,即 IP 和端口号;(2)然后在 listen 套接字中选择一个能匹配名称的虚拟主机,如果没有选出能匹配的名称,则使用该套接字的默认虚拟主机。默认情况下,监听套接字的默认虚拟主机为该套接字主机组中的第一个虚拟主机,但可以通过 listen 指令的 default_server 属性手动指定。

例如下面定义了 4 个虚拟主机:前 3 个都监听在 192.168.100.1:80 上,第四个监听在 192.168.100.2:80 上。

server {listen      192.168.100.1:80;
    server_name example.org www.example.org;
    ...
}

server {listen      192.168.100.1:80 default_server;
    server_name example.net www.example.net;
    ...
}

server {listen      192.168.100.1:80;
    server_name example.com www.example.com;
    ...
}

server {listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}

(1). 从 192.168.100.1:80 上请求 www.example.com,能匹配虚拟主机 3,于是使用虚拟主机 3 的配置进行响应;
(2). 从 192.168.100.1:80 上请求 www.longshuai.com 时,无法匹配任何虚拟主机,于是使用默认虚拟主机 2 的配置进行响应。如果将 listen 的属性 default_server 去掉,则使用虚拟主机 1 进行响应;
(3). 从 192.168.100.2:80 上请求 www.example.com 时,使用虚拟主机 4 进行响应;
(4). 从 192.168.100.2:80 上请求 www.example.org 时,由于无法匹配该套接字上的任何主机,于是使用默认虚拟主机响应,即虚拟主机 4。

 

5.5 stub_status 指令获取 nginx 状态信息

使用 ngx_http_stub_status_module 模块提供的功能可以获取 nginx 运行的状态信息。对应的指令只有一个,即 stub_status。

例如,在某一个 server 下加上如下配置获取该 server 的状态信息。

server {listen 80;
    server_name www.longshuai.com;
    location / {root /www/longshuai/;
        index index.html index.htm;
    }
    location /status {stub_status on;
    }
}

还可以明确指定访问该信息不记录日志,且提供访问控制,不让外界人随意获取信息。

location /status {stub_status on;
    access_log off;
    allow 192.168.100.0/24;
    deny all;
}

重载配置文件后,只需在浏览器中输入 ” 主机名 /status” 即可获取信息。

Active connections: 291 
server accepts handled requests
 16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106

状态信息意义如下:

  • 第一行 active connections:291 表示当前处于活动状态的客户端连接数,包括正处于等待状态的连接。
  • 第四行 reading 数量为 6,表示 nginx 正在读取请求首部的数量,即正在从 socket recv buffer 中读取数据的数量;writing 数量为 179 表示 nginx 正在将响应数据写入 socket send buffer 以返回给客户端的连接数量;waiting 数量为 106 表示等待空闲客户端发起请求的客户端数量,包括长连接状态的连接以及已接入但 socket recv buffer 还未产生可读事件的连接,其值为 active-reading-writing。
  • 第二行 accepts 的数量为 16630948 表示从服务启动开始到现在已经接收进来的总的客户端连接数;handled 的数量为 16630948 表示从服务启动以来已经处理过的连接数,一般 handled 的值和 accepts 的值相等,除非作出了连接数限定;requests 的数量为服务启动依赖总的客户端请求数。一个连接可以有多个请求,所以可以计算出平均每个连接发出多少个请求。
  • 以下是第二行几个参数的官方原文:
    accepts:The total number of accepted client connections.
    handled:The total number of handled connections. Generally, the parameter value is the same as accepts unless some resource limits have been reached (for example, the worker_connections limit).
    requests:The total number of client requests.
    

 

6. 访问日志 access_log

  1. nginx 的访问日志相关功能由 ngx_http_log_module 模块提供,指令包括 log_format、access_log 和 open_log_file_cache。
  2. nginx 的日志可以先缓冲到 buffer 中,一定时间后再写入到日志文件中。从 buffer 刷盘到本地日志文件中时,可以进行压缩。
  3. nginx 的 worker 进程的运行身份需要有日志创建的权限,即对日志所在目录有写权限。
  4. 可以在多种上下文中定义是否开启日志以及日志的格式。最常见的三个上下文是 http,server,location。
  5. open_log_file_cache 指令存在的意义是为了缓存日志文件描述符。之所以提供这个指令,是 因为 nginx 每次日志的写入 (从缓存中刷盘到本地日志文件中) 都会打开、关闭一次日志文件。对于日志写入极其频繁的机器可以使用该指令缓存日志文件描述符,使得在缓存有效期内都可以续写到旧日志文件中。

 

6.1 log_format 指令

log_format 指定日志的格式,语法如下:log\_format name string...;。其中 name 指定日志格式名称,配置文件中 name 名称不能重复。

以下是默认提供的 main 格式。

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

在 main 后面的是一堆变量,除了这些变量之外还有其他很多变量可用,但如非特殊需求,默认的 main 格式就已经够完美了。以下是变量的意义:

$remote_addr:客户端的地址。如果 nginx 提供的 web 服务在后端,如前面有代理服务器或负载均衡等设备时,该变量只能获取到前端的 IP 地址。此时要获取到真正客户端地址需要使用变量$http_x_forward_for,但要求前端服务器要开启 x_forward_for 设置。$http_x_forward_for:如上所述。$remote_user:远程客户端用户名称。$time_local:记录访问时间和时区信息。$request:记录用户访问时的 url 和 http 协议信息。如:"GET /favicon.ico HTTP/1.1"$status:记录客户端请求时返回的状态码,如成功的状态码为200,page not found 的状态码为404$body_bytes_sent:记录服务器响应给客户端的主体大小。$http_referer:记录此次请求是从哪个链接过来的,需要模块 ngx_http_referer_module 支持,默认已装,可以防止倒链问题。$http_user_agent:记录客户端的浏览器信息。如使用什么浏览器发起的请求,是否是压力测试工具在测试等。

例如,以下是默认格式的日志信息。

192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"

 

6.2 access_log 指令

access_log 主要用于定义使用什么格式的日志,日志存放路径。语法如下:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;

path 指定路径,path 里可以使用变量。format 指定日志格式,不写时或者配置文件中未配置 access_log 指令时,默认为 combined。buffer=size 指定日志缓冲区大小(默认 64K),flush=time 指定日志刷盘的时间,if=condition 指定某些条件,gzip=level 指定日志刷盘前先压缩的压缩级别(默认 gzip=1)。

当指定了 buffer 或者 gzip 任意一个时,都会使用 buffer 先缓冲日志,然后再刷盘。

例如

access_log /spool/logs/nginx-access.log gzip buffer=32k;

 

6.3 日志文件的分割

默认 nginx 不会自动分割日志,也不支持在配置文件中使用 cronolog 以及 rotatelogs(apache 支持,因为支持管道传递)。要实现 nginx 的日志分割,需要通过移动旧日志、生成新日志来实现。

mv old_log new_log
# 然后
nginx -s reload
# 或者
nginx -s reopen
# 或者
kill -s USR1 master_pid

pid 可以通过 pid 文件获得。

kill -s USR1 $(cat /var/run/nginx/nginx.pid)

要实现自动分割,需要使用脚本,并设置定时任务。

cat /usr/local/nginx/logs/cut_longhsuai.sh
#!/bin/bash

# cut the access log for www.longshuai.com

basedir=/usr/local/nginx
old_log_path=$basedir/logs/access.log
log_save_path=$basedir/logs
save_log_name=access_$(date -d "yesterday" +"%Y%m%d").log

[-f "$old_log_path" ] || exit 1
/bin/mv $old_log_path $log_save_path/$save_log_name
$basedir/sbin/nginx -s reopen

再添加定时任务计划。

chmod +x /usr/local/nginx/logs/cut_longshuai.sh

crontab -e
00 00 * * * /bin/sh /usr/local/nginx/logs/cut_longshuai.sh &>/dev/null

7. 配置 web 身份认证

需要输入用户名和密码才能访问站点的功能为 web 身份认证功能。nginx 中由 ngx_http_auth_basic_module 模块提供该功能。指令包括 auth_basic 和 auth_basic_user_file。这两个指令可以在 http 根段、server 段、location 段使用。

auth_basic string | off
auth_basic_user_file path/to/user_passwd_file        # 密码文件使用相对路径时是相对 conf 目录的

passwd_file 的格式为:

user1:passwd1
user2:passwd2

需要注意的是,密码文件不能使用明文密码的方式。该类文件一般使用 apache 提供的工具 htpasswd 生成,该工具在 httpd-tools 包中,具体用法见htpasswd 命令。也可以使用 openssl passwd 生成相关密码然后复制到密码文件中。以下是一个示例:

server {listen 80;
    server_name www.longshuai.com  www1.longshuai.com;
    location / {root /www/longshuai/;
        index index.html index.htm;
        auth_basic "Auth your name";
        auth_basic_user_file /usr/local/nginx/htpasswd;
    }
}

然后使用 htpasswd 生成密码文件 /usr/local/nginx/conf/htpasswd。

yum -y install httpd-tools
htpasswd -b -c -m /usr/local/nginx/conf/htpasswd Jim 123456
htpasswd -b -m /usr/local/nginx/conf/htpasswd Tom 123456

-b选项是表示 batch 模式,不用交互输入密码。-c表示创建密码文件,只能为第一个用户使用该选项,否则后面使用会覆盖前面已经创建过的。-m表示强制使用 md5。Jim 和 Tom 是需要验证的用户名,123456 是密码。查看生成的密码文件。

[root@xuexi nginx]# cat htpasswd 
Jim:$apr1$URdS8lcY$GyghBlYInlqfkto0ndnH1.
Tom:$apr1$B/orDxHj$1jIWk1X5XabpH3hcFQzoN1

然后重载配置文件,在浏览器中测试。测试时最好不要用 IE。

也可以使用 openssl passwd 生成,下面的 ”-apr1″(数值 1 而非字母 L 的小写)选项是为 apache 密码做相关支持的。

openssl passwd -apr1 123456
$apr1$rD/3/kFH$L8KYfzAWFtHO8mOiR9dci1
# 或者加点盐
openssl passwd -apr1 -salt 'xyz' 123456
$apr1$xyz$j0n99G44SENB4NmJiwEfJ0

然后将得到的密码复制到密码文件中对应的用户名后面即可。如将得到的 ”$apr1$xyz$j0n99G44SENB4NmJiwEfJ0″ 作为 ”Admin” 用户的验证密码。

Admin: $apr1$xyz$j0n99G44SENB4NmJiwEfJ0

Nginx 知识点全面总结

 

8 配置 https

https 功能由 ngx_http_ssl_module 模块提供。https 连接的认证过程见SSL 握手机制。(见 http://www.linuxidc.com/Linux/2017-10/147745.htm) 简单版的过程如下:

  1. 客户端 say hello,并发送一个随机数给服务端。
  2. 服务端 say hello,并回复一个随机数给客户端。
  3. 服务端发送数字证书给客户端。
  4. 客户端使用信任的 CA 公钥解密数字证书得到服务端的公钥。
  5. 客户端使用服务端的公钥加密一个预备主密钥并发送给服务端。
  6. 服务端使用自己的私钥解密预备主密钥。
  7. 双方都得到了 2 个随机数加一个预备主密钥。通过这 3 个随机数形成一个会话主密钥,即 session key。至此 ssl 握手结束,连接的认证过程也完毕。

对于服务端而言,在配置 https 时,需要提供自己的数字证书用于发送给客户端,还要提供自己的私钥用于解密客户端发送的预备主密钥。当 ssl 连接建立完成后,后续连接要传输的数据都采用 session key 进行加密,但注意 session key 是对称加密,客户端和服务端是一样的。

还需注意,在创建证书请求时,由于需要指定 common name,这是需要使用 https 的站点,因此每个 ssl 证书只能为一个 server_name 提供 https 服务。

以下是配置文件中默认的关于 SSL 相关的指令设置。

#server {
#    listen       443 ssl;
#    server_name  localhost;

#    ssl_certificate      cert.pem;
#    ssl_certificate_key  cert.key;

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

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

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}

以下是建立 https 的相关过程:

  1. 自建 CA。
    cd /etc/pki/CA
    (umask 077;openssl genrsa -out private/cakey.pem 2048)
    openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650
    
  2. 建立相关序列和索引文件。
    touch index.txt
    echo "01" > serial
    
  3. nginx 端生成证书请求。
    (umask 077;openssl genrsa -out /usr/local/nginx/longshuai.key 2048)
    openssl req -new -key /usr/local/nginx/longshuai.key -out /usr/local/nginx/longshuai.csr
    
  4. CA 为证书请求颁发证书。
    openssl ca -in /usr/local/nginx/longshuai.csr -out longshuai.crt
    
  5. 将颁发的证书发送给 nginx 端。这里由于 CA 和 nginx 在同一主机上,所以直接移动即可。
    mv longshuai.crt /usr/local/nginx/
    

    此时,在 /usr/local/nginx/ 目录下就有了 nginx 自己的 私钥文件和证书文件

    [root@xuexi nginx]# ls longshuai*
    longshuai.crt  longshuai.csr  longshuai.key
    
  6. 修改配置文件,配置 ssl 相关选项。

    server {listen       443 ssl;
    server_name  www.longshuai.com;
    
    ssl_certificate      /usr/local/nginx/longshuai.crt;
    ssl_certificate_key  /usr/local/nginx/longshuai.key;
    
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    
    location / {root   html;
        index  index.html index.htm;
    }
    }
    
  7. 重载配置文件。
  8. 测试。在浏览器上输入 https:\\www.longshuai.com 测试。将会提示证书安全存在问题,说明配置成功。以后只要在客户端安装证书即可正常访问。

下面关于 Nginx 的文章您也可能喜欢,不妨参考下:

Nginx 403 forbidden 的解决办法  http://www.linuxidc.com/Linux/2017-08/146084.htm

CentOS 7 下 Nginx 服务器的安装配置  http://www.linuxidc.com/Linux/2017-04/142986.htm

CentOS 上安装 Nginx 服务器实现虚拟主机和域名重定向  http://www.linuxidc.com/Linux/2017-04/142642.htm

CentOS 6.8 安装 LNMP 环境(Linux+Nginx+MySQL+PHP)http://www.linuxidc.com/Linux/2017-04/142880.htm

Linux 下安装 PHP 环境并配置 Nginx 支持 php-fpm 模块  http://www.linuxidc.com/Linux/2017-05/144333.htm

Nginx 服务的 SSL 认证和 htpasswd 认证  http://www.linuxidc.com/Linux/2017-04/142478.htm

Ubuntu 16.04 上启用加密安全的 Nginx Web 服务器  http://www.linuxidc.com/Linux/2017-07/145522.htm

Linux 中安装配置 Nginx 及参数详解  http://www.linuxidc.com/Linux/2017-05/143853.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

CentOS 7.2 下 Nginx+PHP+MySQL+Memcache 缓存服务器安装配置  http://www.linuxidc.com/Linux/2017-03/142168.htm

CentOS6.9 编译安装 Nginx1.4.7  http://www.linuxidc.com/Linux/2017-06/144473.htm

Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147744.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计27375字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中