8. Nginx高级配置

3 Nginx高级配置

3.1 Nginx状态页

  • 基于ngx_http_stubs_module模式实现, 在编译安装时, 需要添加编译参数, --with-http_stub_status_module, 否则配置完成之后监测会提示语法错误

  • 状态页显示的是整个服务器的状态, 而非虚拟主机的状态

# 在任意一个虚拟主机配置即可
        location  /nginx_status {
                stub_status;
                auth_basic "auth log";
                auth_basic_user_file /apps/nginx/conf/.htpasswd;
                allow 120.78.154.82;
                deny all;
        }

  • 状态页用于输出nginx的基本状态信息
Active connections: 2 
server accepts handled requests
 4(accepts) 4(handled) 3(requests) 
Reading: 0 Writing: 1 Waiting: 1 
  • 状态页参数
Active connections: # 当前处于活动状态的客户端连接数, 包括连接等待, 空闲连接数 = reading+writing+waiting
accepts: # 统计总值, Nginx自启动后, 已经接受的客户端请求的总数
handled: # 统计总值, Nginx自启动后, 已经处理完成的客户端请求总数, 通常等于accepts, 除非有因worker_connections限制等被拒绝的连接
requests: # 统计总值, Nginx自启动后客户端发来的总的请求数
Reading: # 当前状态, 正在读取客户端请求报文首部的连接的连接数, 数值越大, 说明排队现象越严重, 性能不足
Writing: # 当前状态, 正在向客户端发送响应报文过程中的连接数, 数值越大, 说明访问量越大
Waiting: # 当前状态, 正在等待客户端发出请求的空闲连接数, 开启 keep-alive的情况下, 这个值等于active - (reading+writing)

3.2 Nginx 第三方模块

第三方模块是对nginx的功能扩展, 第三方模块需要在编译安装nginx的时候使用参数--add-module=PATH指定路径添加, 有的模块是由公司的开发人员针对业务需求定制开发的, 有的模块是开源爱好者开发好之后上传到github进行开源的模块, nginx支持第三方模块, 需要从源码重新编译, 比如:开源的echo模块: https://github.com/openresty/echo-nginx-module

[17:12:39 root@nginx ~]#systemctl stop nginx
[17:47:15 root@nginx ~]#cp -a /apps/nginx/sbin/nginx{,.bak}
[17:48:00 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {                                                                                                                                                                            
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;

    location  / {                                                                                                                                                        
        root /data/nginx/html/pc;
    }
    location /main {
    
        index index.html;
        default_type text/html; # 必须指定默认类型为文件, 否则会认为是不识别的默认模式, 浏览器会把main文件下载下来
        echo "hello world,main-->"; # 访问/main时, 会打印hello world,main--> remote_addr(远程连接客户端地址)
        echo $remote_addr; # 远程连接客户端地址, 公网ip
        echo_reset_timer; # 将计时器开始时间重置为现在
        echo_location /sub1; # 调用/sub1 location里的指令
        echo_location /sub2; # 调用/sub2 location里的指令
        echo "took $echo_timer_elapsed sec for total."; # 打印访问/main, 总共花费的时间
    
    }
    location /sub1 {
    
        echo_sleep 1;
        echo sub1;
    }
    location /sub2 {
    
        echo_sleep 1;
        echo sub2;
    }
}
# 此时, 因为nginx编译时没有把echo模块编译进去, 因此, 重新加载服务会报错
[17:52:12 root@nginx ~]#nginx -s reload
nginx: [emerg] unknown directive "echo" in /apps/nginx/conf.d/pc.conf:14
  • 下面准备重新编译nginx, 把echo模块编译进去
[17:12:39 root@nginx ~]#systemctl stop nginx # 停止nginx服务
[17:47:15 root@nginx ~]#cp -a /apps/nginx/sbin/nginx{,.bak} # 将现有的二进制文件做备份
cd /usr/local/src
yum -y install git
git clone https://github.com/openresty/echo-nginx-module.git
[18:13:01 root@nginx /usr/local/src]#ls
echo-nginx-module-master.zip  nginx-1.18.0  nginx-1.18.0.tar.gz
[18:18:22 root@nginx /usr/local/src]#unzip echo-nginx-module-master.zip 
[18:19:05 root@nginx /usr/local/src]#ls
echo-nginx-module-master  echo-nginx-module-master.zip  nginx-1.18.0  nginx-1.18.0.tar.gz

[18:13:04 root@nginx /usr/local/src]#cd nginx-1.18.0/

./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--add-module=/usr/local/src/echo-nginx-module-master

make && make install
# 编译成功
[18:21:07 root@nginx /usr/local/src/nginx-1.18.0]#ll /apps/nginx/sbin/nginx
-rwxr-xr-x 1 root root 8126344 Mar 17 18:21 /apps/nginx/sbin/nginx
[18:21:17 root@nginx /usr/local/src/nginx-1.18.0]#ll /apps/nginx/sbin/
total 22768
-rwxr-xr-x 1 root  root  8126344 Mar 17 18:21 nginx # 新的二进制程序
-rwxr-xr-x 1 nginx nginx 7591104 Mar 15 15:22 nginx.bak # 手动的备份
-rwxr-xr-x 1 nginx nginx 7591104 Mar 15 15:22 nginx.old # 编译后会自动备份

[18:21:37 root@nginx /usr/local/src/nginx-1.18.0]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[18:22:26 root@nginx /usr/local/src/nginx-1.18.0]#systemctl start nginx
图片.png

3.3 Nginx变量使用

nginx的变量可以在配置文件中引用, 作为功能判断或者日志等场景使用
变量可以分为内置变量和自定义变量
内置变量是由nginx模块自带, 通过变量可以获取到众多的与客户端访问相关的值

3.3.1 内置变量

  • 官方文档:
http://nginx.org/en/docs/varindex.html
  • 常用内置变量
$remote_addr;
# 显示客户端地址, 一般是用户的公网出口ip, 请求通告DNS解析到企业的防护墙入口, 通告DNAT发送到四层负载(HA), 再由HA转发给七层的Nginx, 由于HA工作在四层时并不会修改请求报文的源ip, 防火墙的DNAT也不会修改源ip, 因此请求报文到达Nginx后, 源ip还是用户公网出口ip, 也就会被记录到$remote_addr;

$http_name;
#所有请求报文的字段, 都可以用$http_name变量来获取, name就是请求报文字段的名字

$proxy_add_x_forwarded_for;
# 此变量表示将客户端ip追加到请求报文中X-Forwarded-For首部字段, 多个ip之间用逗号分隔, 如果请求报文中没有X-Forwarded-For, 就使用$remore_addr;
the “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.

$args;
# 变量中存放了URL中的参数, 例如访问: http://pc.wang.org/main/index.do?id=202020202&partner=search
# 返回结果为, id=202020202&partner=search

$document_root;
# 保存了针对当前资源的请求的系统根目录, 例如:/apps/nginx/html

$document_uri;
# 保存了当前请求中, 不包含参数的URI, 注意是不包含请求的指令, 比如 http://pc.wang.org/main/index.do?id=202020202&partner=search 会被定义为/main/index.do
# 返回结果为: /main/index.do

$host;
# 存放了请求的host名称

limit_rate 10240
echo $limit_rate;
# 如果nignx服务器使用了limit_rate配置了限制下载速度, 则会显示具体速度, 否则显示0

$remote_port;
# 客户端请求nginx服务器随机打开的端口号, 这里是每个客户端自己的端口

$remote_user;
# 已经经过auth basic module验证的用户名

$request_body_file;
# 做反向代理时发给后端服务器的本地资源的名称

$request_method;
# 请求资源的方式, GET/PUT/DELETE等

$request_filename;
# 当前请求的资源文件的磁盘路径, 由/root或alias指令与URI请求生成的文件组成的绝对路径
如: /apps/nginx/html/main/index.html
# 当请求的资源总是找不到时, 可以在对应的location下, 添加$request_filename来查看具体是找的磁盘上哪个文件

$request_uri; 除了FQND剩下的链接内容
# 包含请求参数的原始URI, 不包含主机名, 相当于: $document_uri?$args, 例如: /main/index.do?id=20200221&partner=search

$scheme;
# 请求的协议, 例如: http, https, ftp等
# 通过$scheme可以实现, 当用户用http访问时, 自动跳转的https

$server_protocol;
# 保存了客户端请求资源使用的协议的版本, 例如: HTTP/1.0, HTTP/1.1, HTTP/2.0等

$server_addr;
# 保存了服务器的ip地址

$server_name;
# 请求的服务器的主机名

$server_port;
# 请求的服务器的端口号

$http_name;
# name为任意请求报文首部字段, 表示记录请求报文的首部字段

$http_user_agent;
# 客户端浏览器的详细信息

$http_cookie;
# 客户端的cookie信息

$cookie_name;
# name为任意请求报文首部字段cookie的key名
  • 范例: $args
[18:53:45 root@nginx /apps/nginx/conf.d]#vim pc.conf 


server {
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;

    location  / {
        root /data/nginx/html/pc;
    }
    location /main {

        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        echo $remote_addr;
        echo $args;                                                                                                                                                                  
        echo_reset_timer;
        echo_location /sub1;
        echo_location /sub2;
        echo "took $echo_timer_elapsed sec for total.";

    }
    location /sub1 {

        echo_sleep 1;
        echo sub1;
    }
    location /sub2 {

        echo_sleep 1;
        echo sub2;
    }
}
[18:55:03 root@nginx /apps/nginx/conf.d]#nginx -s reload
图片.png
  • 范例: $document_root
server {
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;

    location  / {
        root /data/nginx/html/pc;
    }
    location /main {

        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        echo $remote_addr;
        echo $document_root;
   }                                                                                                                                                                                
}

[19:11:22 root@nginx /apps/nginx/conf.d]#nginx -s reload
[19:11:23 root@nginx /apps/nginx/conf.d]#curl http://pc.wang.org/main/
hello world,main-->
10.0.0.86
/apps/nginx/html # 因为location /main中没有定义document_root, 而且访问/main不会匹配/, 因此会用编译安装时定义的编译路径+html, 和server中的设置无关
  • 范例: $document_uri
  • 范例: $host
server {
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;

    location  / {
        root /data/nginx/html/pc;
    }
    location /main {

        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        echo $remote_addr;
        echo $document_root; 
        echo $document_uri;
        echo $host;                                                                                                                                                                 
   }
}

nginx -s reload
[19:17:57 root@nginx /apps/nginx/conf.d]#curl 'http://pc.wang.org/main/index.do?id=202020202&partner=search'
hello world,main-->
10.0.0.86
/apps/nginx/html
/main/index.do # $document_uri的返回结果, 不带域名, 不带参数
pc.wang.org # 请求的主机头
  • 范例: $scheme
  • 范例: $http_user_agent
  • 范例: $http_cookie
  • 范例: $cookie_name
  • 范例:
$scheme://$host$document_uri?$args # 可以显示用户访问的完整路径
server {
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;

    location  / {
        root /data/nginx/html/pc;
    }
    location /main {

        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        echo $remote_addr;
        echo $document_root;
        echo $scheme;
        echo $host;
        echo $document_uri;
        echo $args;
        echo $scheme://$host$document_uri?$args;                                                                                                                                    
   }
}
nginx -s reload
# curl -b "cookie_key=cookie_name;key=name;key=name", curl -b可以模拟浏览器携带cookie访问
[19:28:36 root@nginx /apps/nginx/conf.d]#curl -b name=admin 'http://pc.wang.org/main/index.do?id=202020202&partner=search'
hello world,main-->
10.0.0.86
/apps/nginx/html
http # $scheme返回值
pc.wang.org $host返回值, FQDN
/main/index.do $request_uri返回值, 除了FQDN和参数, 剩下的部分
id=202020202&partner=search # $args, 返回URL中的参数
http://pc.wang.org/main/index.do?id=202020202&partner=search # 访问的整个URL路径

3.3.2 自定义变量

假如需要自定义变量名称和值, 可以使用指令set $variable value; 另外自定义变量也可引用内置变量的值

语法格式:

set $variable value;
可以用在 server, location, if中

范例: 自定义变量的使用

    location /main {
        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        set $name admin;                                                                                                                                                            
        echo $name; 
        set $client_ip $remote_addr;
        echo $client_ip;
   }
[19:42:57 root@nginx /apps/nginx/conf.d]#curl pc.wang.org/main
hello world,main-->
admin # echo $name
10.0.0.86 # 把$remote_addr的值, 赋值给$client_ip, 然后打印

3.4 Nginx自定义访问日志

访问日志是记录客户端即用户的具体请求内容信息, 全局配置模块中的error_log是记录nignx服务器运行时的错误日志, 错误日志一般只有一个, 但是访问日志可以在不同的虚拟主机中定义多个
定义一个日志需要使用access_log指定的日志保存路径, 使用log_format指定日志的格式, 格式中定义要保存的具体日志内容

访问日志由ngx_http_log_module模块实现

注意: log_format只支持在http语句块中定义, 因此, 如果想实现不同虚拟主机使用不同的日志, 那么需要在http语句块中定义多个日志格式, 之后在server语句块中利用access_log去调用不同的格式, access_log支持在不同的语句块设置

3.4.1 自定义默认格式日志

定义日志格式    #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;
10.0.0.86 - - [17/Mar/2021:19:43:21 +0800] "GET /main HTTP/1.1" 200 57 "-" "curl/7.61.1"

如果想要保留日志的原始格式, 只是添加相应的日志内容, 则配置如下:

范例: 给pc和mobile两个站点, 定制不同的默认格式access日志

# 先在主配置文件的http语句块定义两个不同的日志格式

http {
    include       mime.types;
    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;

    log_format pc_log '$remote_addr [$time_local] "$request" $status ' '"$http_user_agent"';
    log_format mobile_log '$remote_addr [$time_local] "$request" ' '$status $body_bytes_sent';
# 在pc和mobile的子配置文件中, 定义访问日志存放路径, 并且调用响应的格式

server {
    listen 80;
    server_name pc.wang.org;
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;
    access_log /data/nginx/logs/pc_access.log pc_log;                                                                                                                               
    location  / {                                                                                                                                                        
        root /data/nginx/html/pc;
    }
    location /main {
    
        index index.html;
        default_type text/html;
        echo "hello world,main-->";
        set $name admin;
        echo $name;
        set $client_ip $remote_addr;
        echo $client_ip;
   }
}


server {
  
    listen 80;
    server_name m.wang.org;
    root /data/nginx/html/mobile;
    index index index.html;
    access_log /data/nginx/logs/mobile_access.log mobile_log;                                                                                                                       
}

# 重新加载nginx验证
nginx -s reload
[20:19:35 root@nginx ~]#ll /data/nginx/logs/
total 8
-rw-r--r-- 1 root root   0 Mar 17 20:18 mobile_access.log
-rw-r--r-- 1 root root  73 Mar 17 20:18 pc_access.log

图片.png
图片.png

3.4.2 自定义JSON格式日志

Nginx的默认访问日志记录内容相对比较单一, 默认的格式也不方便后期做日志统计分析, 生成环境中通常将Nginx日志转换为JSON日志, 然后配置使用ELK做日志收集-统计和分析

  • 范例: 将访问日志定义为JSON格式, 利用Python脚本提取信息
key:value
#定义JSON格式访问日志

    log_format access_json '{"@timestamp":"$time_iso8601",'
        '"host":"$server_addr",'
        '"clientip":"$remote_addr",'
        '"size":$body_bytes_sent,'
        '"responsetime":$request_time,' # 总的处理时间
        '"upstreamtime":"$upstream_response_time",' # 后端应用服务器处理时间
        '"upstreamhost":"$upstream_addr",'
        '"http_host":"$host",'
        '"uri":"$uri",'
        '"xff":"$http_x_forwarded_for",'
        '"referer":"$http_referer",'
        '"tcp_xff":"$proxy_protocol_addr",'
        '"http_user_agent":"$http_user_agent",'
        '"status":"$status"}';


# 虚拟主机中调用JSON格式日志
access_log logs/access_json.log access_json;
[21:16:14 root@naruto ~]#tail /apps/nginx/logs/access_json.log  -f




{"@timestamp":"2021-03-17T21:16:41+08:00","host":"172.18.152.251","clientip":"120.78.154.82","size":0,"responsetime":0.000,"upstreamtime":"0.000","upstreamhost":"127.0.0.1:9000","http_host":"120.78.154.82","uri":"/wp-cron.php","xff":"-","referer":"-","tcp_xff":"-","http_user_agent":"WordPress/5.3.2; http://120.78.154.82","status":"499"}
{"@timestamp":"2021-03-17T21:16:41+08:00","host":"172.18.152.251","clientip":"113.228.11.154","size":22702,"responsetime":0.069,"upstreamtime":"0.069","upstreamhost":"127.0.0.1:9000","http_host":"120.78.154.82","uri":"/index.php","xff":"-","referer":"-","tcp_xff":"-","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0","status":"200"}
  • 利用python脚本提取返回状态码和所有的ip地址
[21:34:16 root@nginx ~]#vim log.py

#!/usr/bin/python3
status_200 = []
status_404 = []
with open("/apps/nginx/logs/access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":                                                                                                                                           
            status_404.append(line.get)
        else:
            print("状态码 ERROR")
        print(line.get("clientip"))
f.close()
print("状态码200的有--:",len(status_200))
print("状态码404的有--:",len(status_404))

[21:34:15 root@nginx ~]#python3 log.py 
10.0.0.86
10.0.0.1
10.0.0.1
状态码200的有--: 1
状态码404的有--: 2

  • 补充: python2代码转换成python3代码工具
2to3
[21:34:38 root@nginx ~]#pip3 install 2to3

# 查看需要改动的代码
[21:35:19 root@nginx ~]#2to3 log.py 
# 直接让工具修改
[21:35:19 root@nginx ~]#2to3 -w log.py 

3.5 Nginx压缩功能

Nginx支持对指定类型的文件进行压缩, 然后再传输给客户端, 而且压缩还可以设置压缩比例, 压缩后的文件大小将比源文件显著变小, 这样有助于降低出口带宽的利用率, 降低企业的IT支出, 不会占用相应的CPU资源

Nginx对文件的压缩功能依赖于模块: ngx_http_gzip_module

  • 配置指令
# 启用或禁用gzip压缩, 默认关闭
gzip on | off;

# 压缩比由低到高从1到9, 默认为1
gzip_comp_level level;

# 禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";

# gzip压缩的最小文件, 小于设置值的文件将不会压缩
gzim_min_length 1k;

# 启用压缩功能时, 协议的最小版本, 默认为HTTP/1.1
gzip_http_version 1.0 | 1.1;

# 指定Nginx服务需要向服务器申请的缓存空间的个数和大小, 平台不同, 默认, 32 4k 或者 16 8k
gzip_buffers number size;

# 指明仅对哪些类型的资源执行压缩操作, 默认为gzip_types text/html, 不用显示指定, 否则出错
gzip_types mime-type ...;

# 如果启用压缩, 是否在响应报文头部插入"Vary: Accept-Encoding", 一般建议打开
gzip_vary on | off;
  • 范例:
[22:41:19 root@nginx ~]#ll /var/log/messages  -h
-rw-------. 1 root root 2.1M Mar 17 22:06 /var/log/messages
[22:42:34 root@nginx ~]#cp /var/log/messages /data/nginx/html/pc/messages
[22:47:21 root@nginx ~]#chmod +r /data/nginx/html/pc/messages # 日志文件默认只有root能读, 需要修改权限
mv /data/nginx/html/pc/messages /data/nginx/html/pc/m.txt # 修改成压缩支持的mime格式
# 把日志文件拷贝到pc.wang.org站点的家目录下, 测试对其压缩
# 压缩前
图片.png
# 修改pc.wang.org站点的配置文件
# gzip可以配置在server语句块
    gzip on;
    gzip_comp_level 5;
    gzip_min_length 1k;                                                                                                                                                             
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;
    gzip_vary on;

nginx -s reload
# 压缩后
图片.png
10.0.0.86 [17/Mar/2021:22:59:36 +0800] "GET /m.txt HTTP/1.1" 200 297417

3.6 Nginx实现https

Nginx的https功能基于模块ngx_http_ssl_module实现, 因此编译安装时, 需要添加参数,ngx_http_ssl_module, 开启ssl功能, --with-http_ssl_module

3.6.1 https配置参数

配置参数:

ssl on | off;
listen 443 ssl;

# 指向包含当前虚拟主机的证书和CA的两个证书信息的文件, 一般是crt文件(nginx证书一个有两个文件, 一个是服务器私钥, 一个是服务器的证书和CA的证书)
ssl_certificate /path/to/file;

# 当前虚拟主机使用的私钥文件, 一般是key文件
ssl_certificate_key /path/to/file;

# 支持ssl协议版本, 早期为ssl, 现在是tls, 默认为后三个
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]

# 配置ssl缓存: 
      off 关闭缓存
      none 通知客户端支持ssl session cache, 但是实际不支持
      builtin[:size] 使用OpenSSL内建缓存, 是每个worker进程私有的
      [shared:name:size] 在各woker之间使用一个共享的缓存, 需要定义一个缓存名称和缓存空间大小, 一兆可以存储4000个会话信息, 多个虚拟主机可以使用相同的缓存名称

# 客户端连接可以复用ssl session cache中缓存的有效时长, 默认5m
ssl_session_timeout time;

3.6.2 自签名证书

[23:15:17 root@nginx ~]#cd /apps/nginx/
[23:24:54 root@nginx /apps/nginx]#mkdir certs
[23:24:56 root@nginx /apps/nginx]#cd certs
# 生成CA的自签名证书
[23:38:56 root@nginx /apps/nginx/certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
Generating a RSA private key
.............................................................................................++++
...........................................................................................++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
# CA信息
Country Name (2 letter code) [XX]:CN # 所属国家 
State or Province Name (full name) []:LN # 所属省份
Locality Name (eg, city) [Default City]:AS # 所属城市
Organization Name (eg, company) [Default Company Ltd]:wang.org # CA公司名称
Organizational Unit Name (eg, section) []:IT # 所属部门
Common Name (eg, your name or your server's hostname) []:ca.wang.org # CA域名
Email Address []:anshan88@qq.com # 邮箱


[23:39:21 root@nginx /apps/nginx/certs]#ll
total 8
-rw-r--r-- 1 root root 2090 Mar 17 23:39 ca.crt
-rw------- 1 root root 3272 Mar 17 23:38 ca.key

3.6.3 CA制作服务器私钥和证书申请文件

[23:41:01 root@nginx /apps/nginx/certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout pc.wang.org.key -out pc.wang.org.csr
Generating a RSA private key
........++++
.......................++++
writing new private key to 'pc.wang.org.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
# 网站信息
-----
Country Name (2 letter code) [XX]:CN # 网站所属国家
State or Province Name (full name) []:LN # 网站所属省份
Locality Name (eg, city) [Default City]:AS # 网站所属城市
Organization Name (eg, company) [Default Company Ltd]:wang.org # 网站所属公司
Organizational Unit Name (eg, section) []:IT # 部门
Common Name (eg, your name or your server's hostname) []:pc.wang.org # 网站域名
Email Address []:anshan88@qq.com # 邮箱

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3.6.4 CA签发证书

[23:42:46 root@nginx /apps/nginx/certs]#openssl x509 -req -days 3650 -in pc.wang.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out pc.wang.org.crt
Signature ok
subject=C = CN, ST = LN, L = AS, O = wang.org, OU = IT, CN = pc.wang.org, emailAddress = anshan88@qq.com
Getting CA Private Key


[23:43:05 root@nginx /apps/nginx/certs]#ll
total 24
-rw-r--r-- 1 root root 2090 Mar 17 23:39 ca.crt
-rw------- 1 root root 3272 Mar 17 23:38 ca.key
-rw-r--r-- 1 root root 1968 Mar 17 23:42 pc.wang.org.crt
-rw-r--r-- 1 root root 1728 Mar 17 23:41 pc.wang.org.csr
-rw------- 1 root root 3272 Mar 17 23:41 pc.wang.org.key

3.6.5 验证证书内容

[23:43:05 root@nginx /apps/nginx/certs]#openssl x509 -in pc.wang.org.crt -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            09:95:d7:63:66:c8:bd:70:6a:2b:a0:36:ad:61:33:c7:82:21:25:40
        Signature Algorithm: sha256WithRSAEncryption
   #证书发布者     Issuer: C = CN, ST = LN, L = AS, O = wang.org, OU = IT, CN = ca.wang.org, emailAddress = anshan88@qq.com
        Validity
            Not Before: Mar 17 15:42:54 2021 GMT
            Not After : Mar 15 15:42:54 2031 GMT
   #证书接收者        Subject: C = CN, ST = LN, L = AS, O = wang.org, OU = IT, CN = pc.wang.org, emailAddress = anshan88@qq.com

3.6.6 将ca的自签名证书和颁发给pc.wang.org的证书合并

apache的ssl证书有三个文件:
apache私钥
apache的证书
chain证书链, 指向上级ca信息

nginx的ssl证书有两个文件:
nginx私钥
nginx和ca的证书, 放在一个文件pem文件中
[00:16:09 root@nginx /apps/nginx/certs]#cat pc.wang.org.crt ca.crt > pc.wang.org.pem # 需要先cat服务器证书, 再cat上级CA证书, 否则会报错

3.6.7 配置nginx支持https



server {
    listen 80;
    listen 443 ssl;
    server_name pc.wang.org;
    ssl_certificate /apps/nginx/certs/pc_wang.org.pem;
    ssl_certificate_key /apps/nginx/certs/pc.wang.org.key;                                                                                                                          
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
    
    error_page 404  /index.html;
    error_log /data/nginx/logs/pc_wang_org_error.log;
    access_log /data/nginx/logs/pc_access.log mobile_log;
        

    location  / {
        root /data/nginx/html/pc;
    }
}
~    
[23:47:37 root@nginx /apps/nginx/certs]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[23:47:38 root@nginx /apps/nginx/certs]#nginx -s reload

图片.png
图片.png
图片.png

3.6.8 实现多域名https

Nginx支持基于多个IP实现多域名的功能, 并且还支持单个IP多域名的基础之上实现HTTPS, 其功能是基于Nginx的SNI(Server Name Indicatioin)功能实现, SNI是为了解决一个Nginx服务器内使用一个IP绑定多个域名和证书的功能, 其具体功能是客户端在连接到服务器建立SSL连接之前先发送要访问站点的域名(Hostname), 这样服务器再根据这个域名返回给客户端一个合适的证书

  • 范例: SNI功能
[00:00:04 root@nginx /apps/nginx/certs]#nginx -V
nginx version: nginx/1.18.0
built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) 
built with OpenSSL 1.1.1g FIPS  21 Apr 2020
TLS SNI support enabled # SNI功能启用
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/echo-nginx-module-master

# 给m.wang.org站点制作证书

[00:00:10 root@nginx /apps/nginx/certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout m.wang.org.key -out m.wang.org.csr
Generating a RSA private key
...............................................................................................................................................................................++++
..........++++
writing new private key to 'm.wang.org.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:LN
Locality Name (eg, city) [Default City]:AS
Organization Name (eg, company) [Default Company Ltd]:wang.org
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:m.wang.org
Email Address []:anshan88@qq.com       

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[00:02:15 root@nginx /apps/nginx/certs]#openssl x509 -req -days 3650 -in m.wang.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out m.wang.org.crt
Signature ok
subject=C = CN, ST = LN, L = AS, O = wang.org, OU = IT, CN = m.wang.org, emailAddress = anshan88@qq.com
Getting CA Private Key

[00:23:53 root@nginx /apps/nginx/certs]#ll
total 40
-rw-r--r-- 1 root root 2090 Mar 17 23:39 ca.crt
-rw------- 1 root root 3272 Mar 17 23:38 ca.key
-rw-r--r-- 1 root root 2090 Mar 18 00:13 m.wang.org.crt
-rw-r--r-- 1 root root 1724 Mar 18 00:02 m.wang.org.csr
-rw------- 1 root root 3272 Mar 18 00:01 m.wang.org.key
-rw-r--r-- 1 root root 1968 Mar 17 23:42 pc.wang.org.crt
-rw-r--r-- 1 root root 1728 Mar 17 23:41 pc.wang.org.csr
-rw------- 1 root root 3272 Mar 17 23:41 pc.wang.org.key
-rw-r--r-- 1 root root 4058 Mar 18 00:21 pc.wang.org.pem

[00:23:55 root@nginx /apps/nginx/certs]#cat m.wang.org.crt  ca.crt > m.wang.org.pem
[00:24:25 root@nginx /apps/nginx/certs]#ll
total 48
-rw-r--r-- 1 root root 2090 Mar 17 23:39 ca.crt
-rw------- 1 root root 3272 Mar 17 23:38 ca.key
-rw-r--r-- 1 root root 2090 Mar 18 00:13 m.wang.org.crt
-rw-r--r-- 1 root root 1724 Mar 18 00:02 m.wang.org.csr
-rw------- 1 root root 3272 Mar 18 00:01 m.wang.org.key
-rw-r--r-- 1 root root 4180 Mar 18 00:24 m.wang.org.pem
-rw-r--r-- 1 root root 1968 Mar 17 23:42 pc.wang.org.crt
-rw-r--r-- 1 root root 1728 Mar 17 23:41 pc.wang.org.csr
-rw------- 1 root root 3272 Mar 17 23:41 pc.wang.org.key
-rw-r--r-- 1 root root 4058 Mar 18 00:21 pc.wang.org.pem

# 配置mobile站点

server {
  
    listen 80;
    server_name m.wang.org;
    listen 443 ssl;
    ssl_certificate /apps/nginx/certs/m.wang.org.pem;
    ssl_certificate_key /apps/nginx/certs/m.wang.org.key;                                                                                                                           
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    root /data/nginx/html/mobile;
    index index index.html;
    access_log /data/nginx/logs/mobile_access.log mobile_log;
}

[00:39:29 root@nginx ~]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[00:39:31 root@nginx ~]#nginx -s reload


图片.png
图片.png

注意: 使用了SSL证书后, 需要全站的连接都是HTTPS, 否则证书会无效, 浏览器访问网站时仍然会显示不安全

3.6.9 实现HSTS

  • 配置文件
server {
  listen 443 ssl;
  server_name pc.wang.org
  add_header Strict-Transport-Security "max-age=3153600; includeSubDomains" always;
  localtion / {
    ....
  }
}
  • 范例: 在pc.wang.org站点开启HSTS
[01:01:42 root@nginx /data/nginx/html/pc/images]#vim /apps/nginx/conf.d/pc.conf
# 添加在server语句块
    add_header Strict-Transport-Security "max-age=3153600; includeSubDomains" always;  
[01:01:42 root@nginx /data/nginx/html/pc/images]#vim /apps/nginx/conf.d/pc.conf
[01:05:08 root@nginx /data/nginx/html/pc/images]#nginx -s reload

  • 验证
[01:05:35 root@nginx /data/nginx/html/pc/images]#curl -ikL https://pc.wang.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Wed, 17 Mar 2021 17:05:55 GMT
Content-Type: text/html
Content-Length: 11
Last-Modified: Mon, 15 Mar 2021 12:57:27 GMT
Connection: keep-alive
ETag: "604f59b7-b"
Strict-Transport-Security: max-age=3153600; includeSubDomains
Accept-Ranges: bytes

pc website

3.7 关于favicon.so

favicon.so文件是浏览器打开网站时, 显示的小图标, 当客户端使用浏览器访问页面时, 浏览器会自动主动发起请求获取页面的favicon.ico文件, 但是当浏览器请求的favicon.ico文件不存在时, 服务器会记录404日志, 而且浏览器也会显示404报错

方法1: 服务器不记录访问日志

lcation = /favicon.ico {
  log_not_found off;
  access_log off;
}

方法2: 将图标保存到指定目录访问

    location = /favicon.ico {
        root /data/nginx/html/pc/images;
        expires 365d;                                                                                                                                                               
    }

[00:58:18 root@nginx /data/nginx/html/pc]#mkdir images
[00:58:22 root@nginx /data/nginx/html/pc]#cd images/
[00:58:54 root@nginx /data/nginx/html/pc/images]#ls
favicon.ico

10.0.0.86 - - [17/Mar/2021:20:18:44 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1"

3.8 升级OpenSSL版本

# 当前OpenSSL版本
built with OpenSSL 1.1.1g FIPS  21 Apr 2020
# 准备升级到1.1.1h
# 当前的nginx二进制文件

[01:08:18 root@nginx ~]#ll /apps/nginx/sbin/
total 22768
-rwxr-xr-x 1 root  root  8126344 Mar 17 18:21 nginx
-rwxr-xr-x 1 nginx nginx 7591104 Mar 15 15:22 nginx.bak
-rwxr-xr-x 1 nginx nginx 7591104 Mar 15 15:22 nginx.old

# 下载最新版本OpenSSL源码包
[01:08:22 root@nginx ~]#cd /usr/local/src
[01:09:19 root@nginx /usr/local/src]#wget https://www.openssl.org/source/openssl-1.1.1h.tar.gz
[01:10:57 root@nginx /usr/local/src]#tar xvf openssl-1.1.1h.tar.gz

[01:14:54 root@nginx /usr/local/src/nginx-1.18.0]#cd nginx-1.18.0/
[01:14:54 root@nginx /usr/local/src/nginx-1.18.0]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/echo-nginx-module-master --with-openssl=/usr/local/src/openssl-1.1.1h

[01:15:40 root@nginx /usr/local/src/nginx-1.18.0]#make && make install

# 编译后
[01:20:13 root@nginx /apps/nginx/sbin]#ll
total 26672
-rwxr-xr-x 1 root  root  11587608 Mar 18 01:19 nginx # 新的二进制文件
-rwxr-xr-x 1 nginx nginx  7591104 Mar 15 15:22 nginx.bak
-rwxr-xr-x 1 root  root   8126344 Mar 17 18:21 nginx.old

# 无需重启nginx, 即可生效
[01:20:13 root@nginx /apps/nginx/sbin]#nginx -V
nginx version: nginx/1.18.0
built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) 
built with OpenSSL 1.1.1h  22 Sep 2020
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/echo-nginx-module-master --with-openssl=/usr/local/src/openssl-1.1.1h
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容