web服务之nginx变量,https,第三方模块

Nginx 状态页

基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --
with-http_stub_status_module,否则配置完成之后监测会是提示语法错误
注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态

#配置示例:
[root@centos8 ~]# cat /apps/nginx/conf/conf.d/pc.conf
server{
    listen 80;
    server_name www.longxuan.vip;
    root /data/nginx/html/pc;
    location /nginx_status {
       stub_status;
    }
}

#访问测试
http://www.longxuan.vip/nginx_status

#状态页用于输出nginx的基本状态信息:
#输出信息示例:
Active connections: 281
server accepts handled requests
    16630886 16630886 31070465
    上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106

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

范例:分析网站当前访问量

[root@centos7 ~]# curl http://wang:123456@www.longxuan.vip/nginx_status 2> /dev/null | awk '/Reading/{print $2,$4,$6}'
0 1 15

Nginx 第三方模块

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

https://github.com/openresty/echo-nginx-module

范例:

[root@centos8 ~]# systemctl stop nginx
[root@centos8 ~]# vim /apps/nginx/conf/conf.d/pc.conf
location /main {
    index index.html;
    default_type text/html;
    echo "hello world,main-->";
    echo $remote_addr ;
    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;
}
[root@centos8 ~]# /apps/nginx/sbin/nginx -t
nginx: [emerg] unknown directive "echo_reset_timer" in
/apps/nginx/conf/conf.d/pc.conf:86
nginx: configuration file /apps/nginx/conf/nginx.conf test failed
#解决以上报错问题
[root@centos8 ~]# cd /usr/local/src
[root@centos8 src]# yum install git -y
[root@centos8 src]# git clone https://github.com/openresty/echo-nginx-module.git

#重新编译
[root@centos8 src]# cd nginx-1.18.0/
[root@centos8 src]# ./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 \
--with-http_perl_module \
--add-module=/usr/local/src/echo-nginx-module   #指定模块源代码路径

[root@centos8 src]# make && make install
#确认语法检测通过

#重启nginx访问测试
[root@centos8 ~]# systemctl restart nginx

Nginx 变量使用

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

内置变量

官方文档

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

常用内置变量

$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没
有X-Forwarded-For,就使用$remote_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://www.longxuan.vip/main/index.do?id=20210612&partner=search
#返回结果为: id=20210612&partner=search
$is_args
#如果有参数为? 否则为空
“?” if a request line has arguments, or an empty string otherwise
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html。

$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比
如:http://www.longxuan.vip/main/index.do?id=20210612&partner=search会被定义
为/main/index.do
#返回结果为:/main/index.do
$host;
#存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用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
$request_uri;
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?
id=20210612&partner=search
$scheme;
#请求的协议,例如:http,https,ftp等
$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
#保存了服务器的IP地址
$server_name;
#请求的服务器的主机名
$server_port;
#请求的服务器的端口号
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的所有cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
arbitrary request header field; the last part of a variable name is the field
name converted to lower case with dashes replaced by underscores #用下划线代替横线

#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量
有问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;

范例:

[root@centos8 ~]#vi /apps/nginx/conf/conf.d/pc.conf
location /main {
    index index.html;
    default_type text/html;
    echo "hello world,main-->";
    echo $remote_addr ;
    echo $args ;
    echo $document_root;
    echo $document_uri;
    echo $host;
    echo $http_user_agent;
    echo $http_cookie;
    echo $request_filename;
    echo $scheme;
    echo $scheme://$host$document_uri?$args;
}

[root@centos6 ~]# curl -b title=ceo 'http://www.longxuan.vip/main/index.do?id=20210612&partner=search'
hello world,main-->
172.31.0.6
id=20210612&partner=search
/apps/nginx/html
/main/index.do
www.longxuan.vip
curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2
title=ceo
/apps/nginx/html/main/index.do
http
http://www.longxuan.vip/main/index.do?id=20210612&partner=search

范例:

[root@centos8 conf.d]#vim www.conf
.....{
location /echo {
    echo $request;
    echo $proxy_add_x_forwarded_for;
    echo $args;
    echo $document_uri;
    echo $request_uri;
    echo $document_root;
    echo $host;
    echo $request_method;
    echo $request_filename;
    echo $scheme;
    set $test $http_host;
    echo $test;
    echo $http_User_Agent;
    echo $http_cookie;
    echo $cookie_key1;
}
}
[root@centos7 ~]# curl -b 'key1=v1;key2=v2'
"http://www.longxuan.vip/echo/index.html?id=123456&partner=search"
GET /echo/index.html?id=123456&partner=search HTTP/1.1
10.0.0.7
id=123456&partner=search
/echo/index.html
/echo/index.html?id=123456&partner=search
/data/nginx/html/pc
www.longxuan.vip
GET
/data/nginx/html/pc/echo/index.html
http
www.longxuan.vip
curl/7.29.0
key1=v1;key2=v2
v1

自定义变量

假如需要自定义变量名称和值,使用指令set $variable value;
语法格式:

Syntax: set $variable value;
Default: —
Context: server, location, if

范例:

set $name longxuan;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";

#输出信息如下
[root@centos6 ~]# curl www.longxuan.vip/main
longxuan
80
www.longxuan.vip:80

Nginx 自定义访问日志

访问日志是记录客户端即用户的具体请求内容信息,而在全局配置模块中的error_log是记录nginx服务
器运行时的日志保存路径和记录日志的level,因此两者是不同的,而且Nginx的错误日志一般只有一
个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路
径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。
访问日志由 ngx_http_log_module 模块实现

官方帮助文档:

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

语法格式

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time]
[if=condition]];
access_log off; #关闭访问日志
Default:
access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except

自定义默认格式日志

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

#注意:此指令只支持http块,不支持server块
log_format nginx_format1 '$remote_addr - $remote_user [$time_local] "$request"'
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"'
                       '$server_name:$server_port';
                       
#注意:此指令一定要在放在log_format命令后
access_log logs/access.log nginx_format1;

#重启nginx并访问测试日志格式
==> /apps/nginx/logs/access.log <==
10.0.0.1 - - [22/Feb/2019:08:44:14 +0800] "GET /favicon.ico HTTP/1.1" 404 162 "-
" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:65.0) Gecko/2
0100101 Firefox/65.0" "-"www.longxuan.vip:80

自定义json格式日志

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

    log_format  access_json '{"@timestamp":"$time_iso8601",'
        '"host":"$server_addr",'
        '"clientip":"$remote_addr",'
        '"size":"$body_bytes_sent",'
        '"responsetime":"$request_time",'   #总的处理时间
        '"upstreamtime":"$upstream_response_time",'
        '"upsteamhost":"$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"}';

    access_log /apps/nginx/logs/access_json.log access_json;

#重启Nginx并访问测试日志格式
[root@centos8 ~]# tail -f /apps/nginx/logs/access_json.log 

{"@timestamp":"2021-06-12T23:12:29+08:00","host":"172.31.0.28","clientip":"172.31.0.1","size":"31","responsetime":"0.000","upstreamtime":"-","upsteamhost":"-","http_host":"www.longxuan.vip","uri":"//index.html","xff":"-","referer":"-","tcp_xff":"-","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36","status":"200"}

json 格式的日志访问统计

[root@centos8 ~]# yum install -y python3
[root@centos8 ~]# cat nginx_log.py 
#!/usr/bin/env python3
#coding:utf-8

status_200=[]
status_404=[]
with open("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("状态码200的有---:",len(status_404))

# 加执行权限
[root@centos8 ~]# chmod +x nginx_log.py 

#python2
[root@centos8 ~]# dnf -y install python2
[root@centos8 ~]# cat log.py
#!/usr/bin/env python
#coding:utf-8
status_200= []
status_404= []
with open("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)

#保存日志文件到指定路径并进测试:
[root@centos7 ~]# python nginx_log.py
状态码200的有--: 1809
状态码404的有--: 16

#转换python2语法到python3
[root@centos8 ~]# pip3 install 2to3
[root@centos8 ~]# 2to3 -w log.py

Nginx 压缩功能

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

官方文档: https://nginx.org/en/docs/http/ngx_http_gzip_module.html

配置指令如下:

#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_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;
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on | off;

#重启nginx并进行访问测试压缩功能
[root@centos8 ~]# cp /apps/nginx/logs/access.log /data/nginx/html/pc/m.txt
[root@centos8 ~]# echo "test" > /data/nginx/html/pc/test.html #小于1k的文件测试是否会压缩
[root@centos8 ~]# vim /apps/nginx/conf/nginx.conf
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并访问测试:
[root@centos8 ~]# curl --head --compressed http://www.longxuan.vip/test.html
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 22 Feb 2019 01:52:23 GMT
Content-Type: text/html
Last-Modified: Thu, 21 Feb 2019 10:31:18 GMT
Connection: keep-alive
Keep-Alive: timeout=65
Vary: Accept-Encoding
ETag: W/"5c6e7df6-171109"
Content-Encoding: gzip #压缩传输
#验证不压缩访问的文件大小:

https 功能

Web网站的登录页面通常都会使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信
息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用
HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信
息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

https 实现过程如下:
1.客户端发起HTTPS请求:
客户端访问某个web端的https地址,一般都是443端口
2.服务端的配置:
采用https协议的服务器必须要有一套证书,可以通过一些组织申请,也可以自己制作,目前国内很多网站都
自己做的,当你访问一个网站的时候提示证书不可信任就表示证书是自己做的,证书就是一个公钥和私钥匙,
就像一把锁和钥匙,正常情况下只有你的钥匙可以打开你的锁,你可以把这个送给别人让他锁住一个箱子,里
面放满了钱或秘密,别人不知道里面放了什么而且别人也打不开,只有你的钥匙是可以打开的。
3.传送证书:
服务端给客户端传递证书,其实就是公钥,里面包含了很多信息,例如证书得到颁发机构、过期时间等等。
4.客户端解析证书:
这部分工作是有客户端完成的,首先回验证公钥的有效性,比如颁发机构、过期时间等等,如果发现异常则会
弹出一个警告框提示证书可能存在问题,如果证书没有问题就生成一个随机值,然后用证书对该随机值进行加
密,就像2步骤所说把随机值锁起来,不让别人看到。
5.传送4步骤的加密数据:
就是将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的
通信就可以通过这个随机值进行加密解密了。
6.服务端解密信息:
服务端用私钥解密5步骤加密后的随机值之后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进
行对称加密,对称加密就是将信息和私钥通过算法混合在一起,这样除非你知道私钥,不然是无法获取其内部
的内容,而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性。
7.传输加密后的信息:
服务端将用私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容。
8.客户端解密信息:
客户端用之前生成的私钥获解密服务端传递过来的数据,由于数据一直是加密的,因此即使第三方获取到数据
也无法知道其详细内容。

https 配置参数

nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数
ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编
译安装的nginx需要指定编译参数--with-http_ssl_module开启

官方文档:
https://nginx.org/en/docs/http/ngx_http_ssl_module.html

配置参数如下:

ssl on | off;
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
listen 443 ssl;
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存
off: #关闭缓存
none: #通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大
小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m

自签名证书

#自签名CA证书
[root@centos8 ~]# cd /apps/nginx/
[root@centos8 nginx]# mkdir certs
[root@centos8 nginx]# cd certs/
[root@centos8 nginx]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt 
#自签名CA证书
Generating a 4096 bit RSA private key
.................++
.....
Country Name (2 letter code) [XX]:CN #国家代码
State or Province Name (full name) []:BeiJing #省份
Locality Name (eg, city) [Default City]:Beijing #城市名称
Organization Name (eg, company) [Default Company Ltd]:longxuan.Ltd #公司名称
Organizational Unit Name (eg, section) []:longxuan #部门
Common Name (eg, your name or your server's hostname) []:ca.longxuan.vip #通用名称
Email Address []: #邮箱
[root@centos8 certs]# ll ca.crt
-rw-r--r-- 1 root root 2118 Feb 22 12:10 ca.crt

#自制key和csr文件
[root@centos8 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.longxuan.vip.key -out www.longxuan.vip.csr
Generating a 4096 bit RSA private key
........................................................................++
......
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:longxuan
Organizational Unit Name (eg, section) []:longxuan.vip
Common Name (eg, your name or your server's hostname) []:www.longxuan.vip
Email Address []:xxx@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@centos8 certs]# ll
total 16
-rw-r--r-- 1 root root 2118 Feb 22 12:10 ca.crt
-rw-r--r-- 1 root root 3272 Feb 22 12:10 ca.key
-rw-r--r-- 1 root root 1760 Feb 22 12:18 www.longxuan.org.csr
-rw-r--r-- 1 root root 3272 Feb 22 12:18 www.longxuan.org.key

#签发证书
[root@centos8 certs]# openssl x509 -req -days 3650 -in www.longxuan.vip.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.longxuan.vip.crt

#验证证书内容
[root@centos8 certs]# openssl x509 -in www.longxuan.vip.crt -noout -text
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
...

#合并CA和服务器证书成一个文件,注意服务器证书在前
[root@centos8 certs]# cat www.longxuan.vip.crt ca.crt > www.longxuan.vip.pem

https 配置

server {
   listen 80;
   listen 443 ssl;
   server_name www.longxuan.vip;
   ssl_certificate /apps/nginx/certs/www.longxuan.vip.pem;
   ssl_certificate_key /apps/nginx/certs/www.longxuan.vip.key;
   ssl_session_cache shared:sslcache:20m;
   ssl_session_timeout 10m;
   root /data/nginx/html;
}
#重启Nginx并访问验证
https://www.longxuan.vip

实现多域名 https

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

范例: SNI功能

[root@centos8 ~]# 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.1c FIPS 28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --withhttp_
ssl_module --with-http_v2_module --with-http_realip_module --withhttp_
stub_status_module --with-http_gzip_static_module --with-pcre --with-stream
--with-stream_ssl_module --with-stream_realip_module --add-module=../echo-nginxmodule/

范例:

#制作key和csr文件
[root@centos8 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout
m.longxuan.vip.key -out m.longxuan.vip.csr
Generating a 4096 bit RSA private key
..........
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:longxuan
Organizational Unit Name (eg, section) []:longxuan
Common Name (eg, your name or your server's hostname) []:m.longxuan.vip
Email Address []:xxxxx@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

#签名证书
[root@centos8 certs]# openssl x509 -req -days 3650 -in m.longxuan.vip.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out m.longxuan.vip.crt

#验证证书内容
[root@centos8 certs]# openssl x509 -in m.longxuan.vip.crt -noout -text
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
bb:76:ea:fe:f4:04:ac:07
...

#合并证书文件
[root@centos8 certs]# cat m.longxuan.vip.crt ca.crt > m.longxuan.vip.pem

#Nginx 配置
[root@centos8 certs]# cat /apps/nginx/conf/conf.d/moba.conf
server {
    listen 80 default_server;
    server_name m.longxuan.vip;
rewrite ^(.*)$ https://$server_name$1 permanent;
}
server {
    listen 443 ssl;
    server_name m.longxuan.vip;
    ssl_certificate /apps/nginx/certs/m.longxuan.vip.pem;
    ssl_certificate_key /apps/nginx/certs/m.longxuan.vip.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
    location / {
        root "/data/nginx/html/mobile";
    }
}

实现 HSTS

官方文档:

https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

注意: 配置rewrite才能实现http跳转到https

范例:

server {
    listen 443 ssl;
    server_name www.longxuan.vip;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"
    always;
    location / {
    if ( $scheme = http ) {
        rewrite ^/(.*)$ https://www.longxuan.vip/$1 redirect;
    }
.....
    }
}

关于 favicon.ico

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

解决办法:

#方法一:服务器不记录访问日志:
location = /favicon.ico {
    log_not_found off;
    access_log off;
}

#方法二:将图标保存到指定目录访问:
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
    root /data/nginx/html/pc/images;
    expires 365d; #设置文件过期时间
}

升级 OpenSSL 版本

4.8 升级 OpenSSL 版本
OpenSSL程序库当前广泛用于实现互联网的传输层安全(TLS)协议。心脏出血(Heartbleed),也简
称为心血漏洞,是一个出现在加密程序库OpenSSL的安全漏洞,此漏洞于2012年被引入了软件中,
2014年4月首次向公众披露。只要使用的是存在缺陷的OpenSSL实例,无论是服务器还是客户端,都可
能因此而受到攻击。此问题的原因是在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检
查),因此漏洞的名称来源于“心跳”(heartbeat)。该程序错误属于缓冲区过读,即可以读取的数据比
应该允许读取的还多。

范例: 升级OpenSSL解决安全漏洞

#准备OpenSSL源码包:
[root@centos8 ~]# cd /usr/local/src
[root@centos8 src]# wget https://www.openssl.org/source/openssl-1.1.1h.tar.gz
[root@centos8 src]# tar xvf openssl-1.1.1h.tar.gz

#编译安装Nginx并制定新版本OpenSSL路径:
[root@centos8 ~]# cd /usr/local/src/nginx-1.18.0/
[root@centos8 nginx-1.18.0]#./configure \
--prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--withhttp_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 \
--withopenssl=/usr/local/src/openssl-1.1.1h

[root@centos8 nginx-1.18.0]# make && make install

#验证并启动Nginx:
[root@centos8 ~]# 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
[root@centos8 ~]# systemctl restart nginx
posted @ 2021-06-20 21:29  空白的旋律  阅读(240)  评论(0编辑  收藏  举报