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

Nginx知识点全面总结

414次阅读
没有评论

共计 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、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7992960
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

300元就能买到的”小钢炮”?惠普7L四盘位小主机解析

  300 元就能买到的 ” 小钢炮 ”?惠普 7L 四盘位小主机解析 最近...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...