运维开发宝典059-大型网站nginx服务器管理全集5

大型网站nginx服务器管理全集5

三、HTTPS 基本原理

1、https 介绍

HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),其实 HTTPS 并不是一个新鲜协议,Google 很早就开始启用了,初衷是为了保证数据安全。 近些年,Google、Baidu、Facebook 等这样的互联网巨头,不谋而合地开始大力推行 HTTPS, 国内外的大型互联网公司很多也都已经启用了全站 HTTPS,这也是未来互联网发展的趋势。

为鼓励全球网站的 HTTPS 实现,一些互联网公司都提出了自己的要求:

  1. Google 已调整搜索引擎算法,让采用 HTTPS 的网站在搜索中排名更靠前;
  2. 从 2017 年开始,Chrome 浏览器已把采用 HTTP 协议的网站标记为不安全网站;
  3. 苹果要求 2017 年App Store 中的所有应用都必须使用 HTTPS 加密连接;
  4. 当前国内炒的很火热的微信小程序也要求必须使用 HTTPS 协议;
  5. 新一代的 HTTP/2 协议的支持需以 HTTPS 为基础。

等等,因此想必在不久的将来,全网 HTTPS 势在必行。

1、HTTPS 协议介绍

  • HTTP 协议(HyperText Transfer Protocol,超文本传输协议):是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。

  • HTTPS 协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS, 即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。

    如上图所示 HTTPS 相比 HTTP 多了一层 SSL/TLS

    • SSL(Secure Socket Layer,安全套接字层):1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。
    • TLS(Transport Layer Security,传输层安全):其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。

2、加密算法

据记载,公元前400年,古希腊人就发明了置换密码;在第二次世界大战期间,德国军方启用了"恩尼格玛"密码机,所以密码学在社会发展中有着广泛的用途。

  1. 对称加密

    有流式、分组两种,加密和解密都是使用的同一个密钥。

    例如:DES、AES-GCM、ChaCha20-Poly1305等

  2. 非对称加密

    加密使用的密钥和解密使用的密钥是不相同的,分别称为:公钥、私钥,公钥和算法都是公开的,私钥是保密的。非对称加密算法性能较低,但是安全性超强,由于其加密特性,非对称加密算法能加密的数据长度也是有限的。

    例如:RSA、DSA、ECDSA、 DH、ECDHE

  3. 哈希算法

    将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。

    例如:MD5、SHA-1、SHA-2、SHA-256 等

  4. 数字签名

    签名就是在信息的后面再加上一段内容(信息经过hash后的值),可以证明信息没有被修改过。hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。

3、HTTPS 原理

1、HTTP 访问过程

抓包如下:

如上图所示,HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,"裸奔"在互联网上,所以很容易遭到黑客的攻击,如下:

可以看到,客户端发出的请求很容易被黑客截获,如果此时黑客冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉,所以我们经常会听到一词"劫持",现象如下:

下面两图中,浏览器中填入的是相同的URL,左边是正确响应,而右边则是被劫持后的响应(从貌美如花变成如花。。。)

所以 HTTP 传输面临的风险有:

  • 窃听风险:黑客可以获知通信内容。
  • 篡改风险:黑客可以修改通信内容。
  • 冒充风险:黑客可以冒充他人身份参与通信。
2、HTTP 向 HTTPS 演化的过程

第一步:为了防止上述现象的发生,人们想到一个办法:对传输的信息加密(即使黑客截获,也无法破解)

如上图所示,此种方式属于对称加密,双方拥有相同的密钥,信息得到安全传输,但此种方式的缺点是:

(1)不同的客户端、服务器数量庞大,所以双方都需要维护大量的密钥,维护成本很高

(2)因每个客户端、服务器的安全级别不同,密钥极易泄露

第二步:既然使用对称加密时,密钥维护这么繁琐,那我们就用非对称加密试试

如上图所示,客户端用公钥对请求内容加密,服务器使用私钥对内容解密,反之亦然,但上述过程也存在缺点:

(1)公钥是公开的(也就是黑客也会有公钥),所以第 ④ 步私钥加密的信息,如果被黑客截获,其可以使用公钥进行解密,获取其中的内容

第三步:非对称加密既然也有缺陷,那我们就将对称加密,非对称加密两者结合起来,取其精华、去其糟粕,发挥两者的各自的优势

如上图所示

(1)第 ③ 步时,客户端说:(咱们后续回话采用对称加密吧,这是对称加密的算法和对称密钥)这段话用公钥进行加密,然后传给服务器

(2)服务器收到信息后,用私钥解密,提取出对称加密算法和对称密钥后,服务器说:(好的)对称密钥加密

(3)后续两者之间信息的传输就可以使用对称加密的方式了

遇到的问题:

(1)客户端如何获得公钥

(2)如何确认服务器是真实的而不是黑客

第四步:获取公钥与确认服务器身份

1、获取公钥

(1)提供一个下载公钥的地址,回话前让客户端去下载。(缺点:下载地址有可能是假的;客户端每次在回话前都先去下载公钥也很麻烦)

(2)回话开始时,服务器把公钥发给客户端(缺点:黑客冒充服务器,发送给客户端假的公钥)

2、那有木有一种方式既可以安全的获取公钥,又能防止黑客冒充呢? 那就需要用到终极武器了:SSL 证书(申购)

如上图所示,在第 ② 步时服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有:

(1)证书的发布机构CA

(2)证书的有效期

(3)公钥

(4)证书所有者

(5)签名

.........

3、客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:

(1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验

(2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

(3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。

(4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密

(5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比

(6)对比结果一致,则证明服务器发来的证书合法,没有被冒充

(7)此时浏览器就可以读取证书中的公钥,用于后续加密了

4、所以通过发送SSL证书的形式,既解决了公钥获取问题,又解决了黑客冒充问题,一箭双雕,HTTPS加密过程也就此形成

所以相比HTTP,HTTPS 传输更加安全

(1) 所有信息都是加密传播,黑客无法窃听。

(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。

(3) 配备身份证书,防止身份被冒充。

3、HTTPS 总结

综上所述,相比 HTTP 协议,HTTPS 协议增加了很多握手、加密解密等流程,虽然过程很复杂,但其可以保证数据传输的安全。所以在这个互联网膨胀的时代,其中隐藏着各种看不见的危机,为了保证数据的安全,维护网络稳定,建议大家多多推广HTTPS。

HTTPS 缺点:

  1. SSL 证书费用很高,以及其在服务器上的部署、更新维护非常繁琐
  2. HTTPS 降低用户访问速度(多次握手)
  3. 网站改用HTTPS 以后,由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时(多数网站采用302跳转)
  4. HTTPS 涉及到的安全算法会消耗 CPU 资源,需要增加大量机器(https访问过程需要加解密)

4、构建私有的 CA 机构

1、CA 介绍

CA(Certificate Authority)证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能:加密、签名、身份验证。

2、构建私有 CA
1、检查安装 openssl
复制代码
rpm -qa openssl

如果未安装,安装 openssl

复制代码
yum install openssl openssl-devel
2、查看配置文件

openssl 配置/etc/pki/tls/openssl.cnf有关CA的配置。如果服务器为证书签署者的身份那么就会用到此配置文件,此配置文件对于证书申请者是无作用的。

复制代码
####################################################################
[ ca ]
default_ca      = CA_default            # 默认的CA配置;CA_default指向下面配置块

####################################################################
[ CA_default ]

dir             = /etc/pki/CA           # CA的默认工作目录
certs           = $dir/certs            # 认证证书的目录
crl_dir         = $dir/crl              # 证书吊销列表的路径
database        = $dir/index.txt        # 数据库的索引文件


new_certs_dir   = $dir/newcerts         # 新颁发证书的默认路径

certificate     = $dir/cacert.pem       # 此服务认证证书,如果此服务器为根CA那么这里为自颁发证书
serial          = $dir/serial           # 下一个证书的证书编号
crlnumber       = $dir/crlnumber        # 下一个吊销的证书编号
                                        
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem# CA的私钥
RANDFILE        = $dir/private/.rand    # 随机数文件

x509_extensions = usr_cert              # The extentions to add to the cert

name_opt        = ca_default            # 命名方式,以ca_default定义为准
cert_opt        = ca_default            # 证书参数,以ca_default定义为准


default_days    = 365                   # 证书默认有效期
default_crl_days= 30                    # CRl的有效期
default_md      = sha256                # 加密算法
preserve        = no                    # keep passed DN ordering


policy          = policy_match          #policy_match策略生效

# For the CA policy
[ policy_match ]
countryName             = match         #国家;match表示申请者的申请信息必须与此一致
stateOrProvinceName     = match         #州、省
organizationName        = match         #组织名、公司名
organizationalUnitName  = optional      #部门名称;optional表示申请者可以的信息与此可以不一致
commonName              = supplied
emailAddress            = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]                     #由于定义了policy_match策略生效,所以此策略暂未生效
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
3、根证书服务器目录

根CA服务器:因为只有 CA 服务器的角色,所以用到的目录只有/etc/pki/CA

网站服务器:只是证书申请者的角色,所以用到的目录只有/etc/pki/tls

4、创建所需要的文件
复制代码
[root@server ~]# cd /etc/pki/CA/
[root@server CA]# ls
certs  crl  newcerts  private
[root@server CA]# touch index.txt        #生成证书索引数据库文件
[root@server CA]# ls
certs  crl  index.txt  newcerts  private
[root@server CA]# echo 01 > serial       #指定第一个颁发证书的序列号
[root@server CA]# ls
certs  crl  index.txt  newcerts  private  serial
5、创建密钥

在根CA服务器上创建密钥,密钥的位置必须为/etc/pki/CA/private/cakey.pem,这个是openssl.cnf中中指定的路径,只要与配置文件中指定的匹配即可。

复制代码
[root@server CA]# (umask 066; openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
........................................................+++
.........................+++
e is 65537 (0x10001)
6、生成自签名证书

根CA自签名证书,根CA是最顶级的认证机构,没有人能够认证他,所以只能自己认证自己生成自签名证书。

shell 复制代码
[root@server CA]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out /etc/pki/CA/cacert.pem -days 7300
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) []:BEIJING      
Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:CA
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:ca.xulei.com
Email Address []:
[root@server CA]# ls
cacert.pem  certs  crl  index.txt  newcerts  private  serial
shell 复制代码
-new: 	生成新证书签署请求
-x509: 	专用于CA生成自签证书
-key: 	生成请求时用到的私钥文件
-days n:	证书的有效期限
-out /PATH/TO/SOMECERTFILE: 	证书的保存路径
7、下载安装证书

/etc/pki/CA/cacert.pem就是生成的自签名证书文件,使用 SZ/xftp 工具将他导出到窗口机器中。然后双击安装此证书到受信任的根证书颁发机构

3、CA 证书申请及签名
1、检查安装 openssl
复制代码
rpm -qa openssl

如果未安装,安装 openssl

复制代码
yum install openssl openssl-devel
2、客户端生成私钥文件
复制代码
[root@node1 ~]# (umask 066; openssl genrsa -out /etc/pki/tls/private/www.xulei.com.key 2048)
Generating RSA private key, 2048 bit long modulus
......................+++
....................................................................................+++
e is 65537 (0x10001)
[root@node1 ~]# cd /etc/pki/tls/private
[root@node1 private]# ls
www.xulei.com.key
3、客户端用私钥加密生成证书请求
复制代码
[root@node1 private]# ls ../
cert.pem  certs  misc  openssl.cnf  private  
[root@node1 private]# openssl req -new -key /etc/pki/tls/private/www.xulei.com.key -days 365 -out /etc/pki/tls/www.xulei.com.csr
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) []:BEIJING
Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:QF
Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:www.xulei.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@node1 private]# cd ../
[root@node1 tls]# ls
cert.pem  certs  misc  openssl.cnf  private  www.xulei.com.csr

CSR(Certificate Signing Request)包含了公钥和名字信息。通常以.csr为后缀,是网站向CA发起认证请求的文件,是中间文件。

在这一命令执行的过程中,系统会要求填写如下信息:

要求添写的内容
Country Name (2 letter code) 使用国际标准组织(ISO)国码格式,填写2个字母的国家代号。中国请填写CN
State or Province Name (full name) 省份,比如填写BeiJing
Locality Name (eg, city) 城市,比如填写BeiJing
Organization Name (eg, company) 组织单位,比如填写公司名称的拼音
Organizational Unit Name (eg, section) 比如填写IT Dept
Common Name (eg, your websites domain name) 城市,比如填写BeiJing
Email Address 邮件地址,可以不填
A challenge password 可以不填
An optional company name 可以不填

最后把生成的请求文件(/etc/pki/tls/www.xulei.com.csr)传输给CA ,这里我使用scp命令,通过ssh协议,将该文件传输到CA下的/etc/pki/CA/private/目录

复制代码
root@node1 tls]# scp www.xulei.com.csr 192.168.95.134:/etc/pki/CA/private/
root@192.168.95.134's password: 
www.xulei.com.csr                          100%  997   777.2KB/s   00:00    
4、CA 签署证书
shell 复制代码
[root@server ~]# openssl ca -in /etc/pki/CA/private/www.xulei.com.csr -out /etc/pki/CA/certs/www.xulei.com.ctr -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Mar 14 13:45:02 2019 GMT
            Not After : Mar 13 13:45:02 2020 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BEIJING
            organizationName          = QF
            organizationalUnitName    = OPT
            commonName                = www.xulei.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                08:65:70:98:2B:0B:15:D0:74:FE:69:58:05:B8:02:BC:45:D8:23:9B
            X509v3 Authority Key Identifier: 
                keyid:60:6B:BC:F1:A1:01:BF:72:FD:7D:02:A8:BD:15:BE:9C:3B:3E:03:30

Certificate is to be certified until Mar 13 13:45:02 2020 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

证书通常以.crt为后缀,表示证书文件

1、可能遇到的问题
shell 复制代码
[root@server ~]# openssl openssl ca -in /etc/pki/CA/private/www.xulei.com.csr -out /etc/pki/CA/certs/www.xulei.com.ctr -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
The organizationName field needed to be the same in the
CA certificate (CA) and the request (QF)

因为默认使用/etc/pki/tls/openssl.cnf,里面要求其一致,修改organizationName=supplied

修改 /etc/pki/tls/openssl.cnf

shell 复制代码
# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = supplied
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
2、查看生成的证书的信息
shell 复制代码
[root@server ~]# openssl x509 -in /etc/pki/CA/certs/www.xulei.com.ctr -noout -subject
subject= /C=CN/ST=BEIJING/O=QF/OU=OPT/CN=www.xulei.com
3、将生成的证书发放给请求客户端
shell 复制代码
[root@server ~]# scp www.xulei.com.ctr root@192.168.95.135:/etc/pki/CA/certs/
root@192.168.95.135's password: 
www.xulei.com.ctr                            100% 4422     1.3MB/s   00:00  
4、CA吊销证书
1、知道客户端吊销的证书的serial
shell 复制代码
[root@server ~]#openssl x509 -in /PATH/FROM/CERT_FILE -noout -serial -subject
2、吊销证书

先根据客户提交的serial与subject信息,对比检验是否与index.txt文件中的信息一致;然后

shell 复制代码
[root@server ~]#openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem
3、生成吊销证书的编号

第一次吊销一个证书时才需要执行

shell 复制代码
[root@server ~]#echo 01 > /etc/pki/CA/crlnumber
4、更新证书吊销列表
shell 复制代码
[root@server ~]#openssl ca -gencrl -out thisca.crl
5、查看证书吊销列表
shell 复制代码
[root@server ~]#openssl crl -in /PATH/FROM/CRL_FILE.crl -noout -text

5、nginx HTTPS 部署实战

  1. 申请证书与认证
  2. 证书下载与配置
  3. 问题分析与总结
1、申请证书与认证

要搭建https服务首先需有SSL证书,证书通常是在第三方申请,在阿里云的安全服务中有SSL证书这一项,可以在里面申请免费的证书;

也可以在自己电脑中生成,虽然也能完成加密,但是浏览器是不认可的,因此最好还是去第三方申请

1、证书申请

阿里云提供免费的证书,不需要人工审核,用来做测试是非常不错的选择,申请地址如下URL。

复制代码
https://common-buy.aliyun.com/?spm=5176.2020520163.cas.1.1aa12b7aWWn20O&commodityCode=cas#/buy

免费型的证书隐藏的比较深,想要申请免费证书需要先选择 1个域名->Symantec->免费型 ,所以读者这里需要注意一下,如下图参考。

选择之后,一直点击下一步,便可购买完成,免费购买证书之后笔者需要回到证书控制台,在控制台有一个补全信息的链接地址,需要通过此地址补充申请人的联系信息,参考下图填写

2、域名验证

补全个人信息之后,还需要给阿里云验证当前域名是属于本人的,验证方式有两种,第一种是通过dns解析认证,第二种是通过上传验证文件认证,这里采用的是验证文件认证,首先需要下载文件,如下图

在下载验证文件完成之后,笔者需要把文件放到服务器中去,这里提供一条复制命令

复制代码
[root@web ~]#scp ~/Downloads/fileauth.txt  root@192.168.43.34:~/

将验证文件复制到服务器之后,还需要将验证文件放到站点对应目录,参考命令如下:

复制代码
[root@web ~]# -p /website/.well-known/pki-validation  &&  cp  fileauth.txt  /website/.well-known/pki-validation/

现在要验证文件放置的位置是否正确,通过两种方式进行了验证,分别是手动验证,和阿里云验证。

1、手动验证

手动验证的目的是首先确保文件位置放置是否正确,可以通过访问站点的url是否成功进行判断,比如笔者可以访问如下URL,如果返回如果页面能够正常打开,并且可以看到某些值,则代表配置成功。

复制代码
http://www.xulei.com/.well-known/pki-validation/fileauth.txt
2、通过阿里云来验证

在确保文件放置正确之后,关键的是能让阿里云能访问到,阿里云这里提供了一个检查配置的功能,在下载验证文件页面,有一个检测配置的链接,单击之后便可进行检查,如下图。

当点击 检查配置 之后,如果阿里云能够正常访问,则会在左侧给出提示,现在可以返回证书列表,在列表中可以看到当前状态为审核中,如下图

审核因为不需要人为干预,所以很快就能下发证书,下发证书的时间大约是2分钟左右。

2、证书下载与配置
1、证书下载

证书签发之后,可以在列表中可以看到状态栏中为 已签发 ,同时操作栏可以下载以及查看详情等,如下图所示

点击下载后,会跳转到下载详情页面,在下载详情页可以选择自己相对应的web服务,比如使用nginx,当选择nginx之后,下方还会很贴心的提示如何配置,下载nginx配置文件。

下载配置文件之后,需要将其解压,解压之后可以看见里面包含了两个证书文件

xxx.key

xxx.pem

接着需要把这两个证书文件给复制到服务器当中去,首先需要在服务器创建对应的文件夹,参考命令如下

复制代码
[root@web ~]#cd  /usr/local/nginx/conf/  &&  mkdir cert    #此命令在服务器执行

在服务器创建完成对应文件夹之后,执行命令将证书文件复制到服务器中,参考命令如下:

复制代码
[root@web ~]#scp ~/Downloads/214905423420461/*  root@192.168.43.34:/usr/local/nginx/conf/cert
2、证书配置

证书复制完成之后,可以对nginx配置文件进行更改,使用vim命令编辑nginx配置文件,参考命令如下:

复制代码
[root@web ~]#vim /usr/local/nginx/conf/nginx.conf

在vim界面把之前http的配置部分复制一份,复制之后修改监听的端口(listen)为443,并在其后面添加ssl的信息,参考配置如下:

复制代码
    listen 443;
    ssl on;
    ssl_certificate   cert/214905423420461.pem;
    ssl_certificate_key  cert/214905423420461.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
3、重启Nginx

修改配置文件之后,需要测试nginx配置文件是否正确

复制代码
[root@web ~]#nginx -t 

当nginx如果没有出现error相关信息,基本配置没有问题,下面是我的nginx返回结果:

复制代码
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

nginx 配置没有问题之后,笔者需要重启nginx让其生效,参考命令如下

复制代码
[root@web ~]#nginx -s reload
4、检验效果

现在所有该做的工作都做好了,笔者可以通过浏览器来访问可以正常访问,打开如下URL。

复制代码
https://www.xxx.com

浏览器地址栏显示如下图所示

如果看到浏览器,展示安全,并且显示绿色就说明大功告成了

6、nginx 性能优化

当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨

  • 当前系统结构瓶颈
  • 了解业务模式
  • 性能与安全
1、当前系统结构瓶颈

首先需要了解的是当前系统瓶颈,用的是什么,跑的是什么业务。里面的服务是什么样子,每个服务最大支持多少并发。比如针对nginx而言,我们处理静态资源效率最高的瓶颈是多大?能支持多少qps访问请求?怎么得出系统当前的结构瓶颈?

可以通过查看当前cpu负荷,内存使用率,进程使用率来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应的日志,查看请求数量。也可以通过nginx http_stub_status_module模块来查看对应的连接数,总握手次数,总请求数。也可以对线上进行压力测试,来了解当前的系统能性能,并发数,做好性能评估。

2、了解业务模式

虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为业务服务的。我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况平时流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层在中间层做的是代理还是动静分离,还是后台进行直接服务。需要我们对业务接入层和系统层次要有一个梳理

3、性能与安全

性能与安全也是一个需要考虑的因素,往往大家注重性能忽略安全或注重安全又忽略性能。比如说我们在设计防火墙时,如果规则过于全面肯定会对性能方面有影响。如果对性能过于注重在安全方面肯定会留下很大隐患。所以大家要评估好两者的关系,把握好两者的孰重孰轻,以及整体的相关性。权衡好对应的点。

4、系统与nginx性能优化

大家对相关的系统瓶颈及现状有了一定的了解之后,就可以根据影响性能方面做一个全体的评估和优化。

  • 网络(网络流量、是否有丢包,网络的稳定性都会影响用户请求)
  • 系统(系统负载、饱和、内存使用率、系统的稳定性、硬件磁盘是否有损坏)
  • 服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)
  • 程序(接口性能、处理请求速度、每个程序的执行效率)
  • 数据库、底层服务

上面列举出来每一级都会有关联,也会影响整体性能,这里主要关注的是nginx服务这一层。

1、文件句柄

在linux/unix操作系统中一切皆文件,我们的设备是文件,文件是文件,文件夹也是文件。当我们用户每发起一次请求,就会产生一个文件句柄。文件句柄可以简单的理解为文件句柄就是一个索引。文件句柄就会随着请求量的增多,进程调用频繁增加,那么产生的文件句柄也就会越多。

系统默认对文件句柄是有限制的,不可能会让一个进程无限制的调用句柄。因为系统资源是有限的,所以我们需要限制每一个服务能够使用多大的文件句柄。操作系统默认使用的文件句柄是1024个句柄。

2、设置方式
  • 系统全局性修改
  • 用户局部性修改
  • 进程局部性修改
3、系统全局性修该和用户局部性修改
shell 复制代码
[root@server ~]#vim /etc/security/limits.conf

在文件最下面找到

shell 复制代码
#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4

#root只是针对root这个用户来限制,soft只是发提醒,操作系统不会强制限制,一般的站点设置为一万左右就ok了
root soft nofile 65535
root hard nofile 65535
# *代表通配符 所有的用户
*    soft nofile 25535
*    hard nofile 25535

可以看到root*,root代表是root用户,*代表的是所有用户,后面的数字就是文件句柄大小。大家可以根据个人业务来进行设置。

4、进程局部性修改
shell 复制代码
[root@server ~]#vim /etc/nginx/nginx.conf
user  nginx;
worker_processes  1;  

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

worker_rlimit_nofile 65535; #进程限制

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

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

    access_log  /var/log/nginx/access.log  main;

    sendfile        on; 
    #tcp_nopush     on; 

    keepalive_timeout  65; 

    #gzip  on; 

    include /etc/nginx/conf.d/*.conf;
}

worker_rlimit_nofile 是在进程上面进行限制。

5、cpu的亲和配置

cpu的亲和能够使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu,把进程通常不会在处理器之间频繁迁移,进程迁移的频率小,来减少性能损耗。nginx 亲和配置

查看物理cpu

shell 复制代码
[root@server ~]#cat /proc/cpuinfo|grep "physical id"|sort |uniq|wc -l

查看cpu核心数

shell 复制代码
[root@server ~]#cat /proc/cpuinfo|grep "cpu cores"|uniq

查看cpu使用率

shell 复制代码
[root@server ~]#top  回车后按 1
6、配置worker_processes
shell 复制代码
[root@server ~]#vim /etc/nginx/nginx.conf

将刚才查看到自己cpu * cpu核心就是worker_processes

shell 复制代码
worker_processes 2; #根据自己cpu核心数配置
7、cpu亲和配置

假如小菜的配置是2cpu,每个cpu是8核。配置如下

shell 复制代码
worker_processes 16;
worker_cpu_affinity 1010101010101010 0101010101010101;

配置完成后可以通过下面命令查看nginx进程配置在哪个核上

shell 复制代码
[root@server ~]#ps -eo pid,args,psr |grep [n]ginx

在nginx 1.9版本之后,就帮我们自动绑定了cpu;

shell 复制代码
worker_cpu_affinity auto;
5、nginx通用配置优化
shell 复制代码
[root@server ~]#vim /etc/nginx/nginx.conf
#将nginx进程设置为普通用户,为了安全考虑
user nginx; 

#当前启动的worker进程,官方建议是与系统核心数一直
worker_processes 2;
#方式一, 第一个work进程绑定第一个cpu核心,第二个work进程绑定到第二个cpu核心,依次内推 直到弟16个
#wokrer_cpu_affinity 0000000000000000 0000000000000001 0000000000000010 0000000000000100 ... 1000000000000000

#方式二,当 worker_processes 2 时,表明 第一work进程可以绑定第 2 4 6 8 10 12 14 16 核心,那么第二work进程就绑定 奇数核心
#worker_cpu_affinity 1010101010101010 0101010101010101;

#方式三,就是自动分配绑定
worker_cpu_affinity auto;

#日志配置成warn
error_log /var/log/nginx/error.log warn; 
pid /var/run/nginx.pid;

#针对 nginx 句柄的文件限制
worker_rlimit_nofile 35535;
#事件模型
events {
    #使用epoll内核模型
    user epoll;
    #每一个进程可以处理多少个连接,如果是多核可以将连接数调高 worker_processes * 1024
    worker_connections 10240;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    charset utf-8;  #设置字符集

    #设置日志输出格式,根据自己的情况设置
    log_format  main  '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" '
                      '"$args" "$request_uri"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;   #对静态资源的处理比较有效
    #tcp_nopush     on;   #如果做静态资源服务器可以打开
    #tcp_nodeny     on;   #当nginx做动态的服务时可以选择打开

    keepalive_timeout  65; 

    ########
    #Gzip module
    gzip  on;    #文件压缩默认可以打开
    gzip_disable "MSIE [1-6]\."; #对于有些浏览器不能识别压缩,需要过滤如ie6
    gzip_http_version 1.1;

    include /etc/nginx/conf.d/*.conf;
}
shell 复制代码
#查看 核心绑定的nginx work进程
[root@server ~]#ps -eo pid,args,psr | grep [n]ginx
6、ab接口压力测试工具

ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。

shell 复制代码
# 安装工具
[root@server ~]#yum install httpd-tools

# 使用
[root@server ~]#ab -n 2000 -c 2 http://127.0.0.1/index.html
-n 总的请求数
-c 并发数
-k 是否开启长连接
1、参数选项
linux 复制代码
-n:即requests,用于指定压力测试总共的执行次数
-c:即concurrency,用于指定的并发数
-t:即timelimit,等待响应的最大时间(单位:秒)
-b:即windowsize,TCP发送/接收的缓冲大小(单位:字节)
-p:即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数
-u:即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数
-T:即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain
-v:即verbosity,指定打印帮助信息的冗余级别
-w:以HTML表格形式打印结果
-i:使用HEAD请求代替GET请求
-x:插入字符串作为table标签的属性
-y:插入字符串作为tr标签的属性
-z:插入字符串作为td标签的属性
-C:添加cookie信息,例如:"Apache=1234"(可以重复该参数选项以添加多个)
-H:添加任意的请求头,例如:"Accept-Encoding: gzip",请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)
-A:添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开
-P:添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开
-X:指定使用的和端口号,例如:"126.10.10.3:88"
-V:打印版本号并退出
-k:使用HTTP的KeepAlive特性
-d:不显示百分比
-S:不显示预估和警告信息
-g:输出结果信息到gnuplot格式的文件中
-e:输出结果信息到CSV格式的文件中
-r:指定接收到错误信息时不退出程序
-H:显示用法信息,其实就是ab -help
2、内容解释
linux 复制代码
Server Software:        nginx/1.10.2 (服务器软件名称及版本信息)
Server Hostname:        192.168.1.106(服务器主机名)
Server Port:            80 (服务器端口)
Document Path:          /index1.html. (供测试的URL路径)
Document Length:        3721 bytes (供测试的URL返回的文档大小)
Concurrency Level:      1000 (并发数)
Time taken for tests:   2.327 seconds (压力测试消耗的总时间)
Complete requests:      5000 (的总次数)
Failed requests:        688 (失败的请求数)
Write errors:           0 (网络连接写入错误数)
Total transferred:      17402975 bytes (传输的总数据量)
HTML transferred:       16275725 bytes (HTML文档的总数据量)
Requests per second:    2148.98 [#/sec] (mean) (平均每秒的请求数) 这个是非常重要的参数数值,服务器的吞吐量 
Time per request:       465.338 [ms] (mean) (所有并发用户(这里是1000)都请求一次的平均时间)
Time  request:       	0.247 [ms] (mean, across all concurrent requests) (单个用户请求一次的平均时间)
Transfer rate:          7304.41 [Kbytes/sec] received 每秒获取的数据长度 (传输速率,单位:KB/s)
...
Percentage of the requests served within a certain time (ms)
  50%    347  ## 50%的请求在347ms内返回 
  66%    401  ## 60%的请求在401ms内返回 
  75%    431
  80%    516
  90%    600
  95%    846
  98%   1571
  99%   1593
 100%   1619 (longest request)
3、示例演示
复制代码
[root@server ~]#ab -n 50 -c 20 http://walidream.com/sub_module

输出内容

linux 复制代码
Server Software:        nginx/1.14.1
Server Hostname:        walidream.com
Server Port:            80

Document Path:          /sub_module
Document Length:        169 bytes

Concurrency Level:      20
Time taken for tests:   0.005 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Non-2xx responses:      50
Total transferred:      14900 bytes
HTML transferred:       8450 bytes
Requests per second:    9746.59 [#/sec] (mean)
Time per request:       2.052 [ms] (mean)
Time per request:       0.103 [ms] (mean, across all concurrent requests)
Transfer rate:          2836.41 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     1    1   0.3      1       2
Waiting:        0    1   0.2      1       1
Total:          1    2   0.3      2       2

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      2
  90%      2
  95%      2
  98%      2
  99%      2
 100%      2 (longest request)
5、注意事项

● 测试机与被测试机要分开

● 不要对线上的服务器做压力测试

● 观察测试工具ab所在机器,以及被测试的前端机的CPU、内存、网络等都不超过最高限度的75%

6、ab性能指标
1、吞吐率(Requests per second)

服务器并发处理能力的量化描述,单位是reqs/s,指的是在某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。记住:吞吐率是基于并发用户数的。这句话代表了两个含义:

复制代码
● 吞吐率和并发用户数相关

● 不同的并发用户数下,吞吐率一般是不同的

计算公式:总请求数/处理完成这些请求数所花费的时间,即

复制代码
Request per second=Complete requests/Time taken for tests

必须要说明的是,这个数值表示当前机器的整体性能,值越大越好

2、并发连接数(The number of concurrent connections)

并发连接数指的是某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。

3、并发用户数(Concurrency Level)

要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。在HTTP/1.1下,IE7支持两个并发连接,IE8支持6个并发连接,FireFox3支持4个并发连接,所以相应的,我们的并发用户数就得除以这个基数。

4.用户平均请求等待时间(Time per request)

计算公式:处理完成所有请求数所花费的时间/(总请求数/并发用户数),即:

复制代码
Time per request=Time taken for tests/(Complete requests/Concurrency Level)
5.服务器平均请求等待时间(Time per request:across all concurrent requests)

计算公式:处理完成所有请求数所花费的时间/总请求数,即:

复制代码
Time taken for/testsComplete requests

可以看到,它是吞吐率的倒数。同时,它也等于用户平均请求等待时间/并发用户数,即

复制代码
Time per request/Concurrency Level

7、cfssl 部署 CA

1、下载cfssl工具
shell 复制代码
[root@server ~]#wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@server ~]#chmod +x cfssl_linux-amd64
[root@server ~]#sudo mv cfssl_linux-amd64 /root/local/bin/cfssl
 
[root@server ~]#wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@server ~]#chmod +x cfssljson_linux-amd64
[root@server ~]#sudo mv cfssljson_linux-amd64 /root/local/bin/cfssljson
 
[root@server ~]#wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@server ~]#chmod +x cfssl-certinfo_linux-amd64
[root@server ~]#sudo mv cfssl-certinfo_linux-amd64 /root/local/bin/cfssl-certinfo
 
[root@server ~]#export PATH=/root/local/bin:$PATH
2、生成默认的配置文件和证书签名请求文件
shell 复制代码
[root@server ~]#cfssl print-defaults config > ca-config.json
[root@server ~]#cfssl print-defaults csr > ca-csr.json
1、查看并修改CA 配置文件
shell 复制代码
[root@server ~]#cat ca-config.json 
{
    "signing": {
        "default": {
            "expiry": "9999h"
        },
        "profiles": {
            "www": {
                "expiry": "9999h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "9999h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            }
        }
    }
}
  • ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;

  • signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE

  • server auth:表示 client 可以用该 CA 对 server 提供的证书进行验证;

  • client auth:表示 server 可以用该 CA 对 client 提供的证书进行验证;

2、查看并修改 CA 证书签名请求
shell 复制代码
{
  "CN": "registry.test.com",
  "hosts": [
    "127.0.0.1",
    "172.16.160.38",
    "registry.test.com"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
  • "CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;

  • "O":Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);

3、生成 CA 证书和私钥
shell 复制代码
[root@server ~]#cfssl gencert -initca ca-csr.json | cfssljson -bare ca    #重新执行
[root@server ~]#ls ca*
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem
4、分发证书
3、校验证书
1、使用 openssl 命令校验证书
shell 复制代码
[root@server ~]#openssl x509  -noout -text -in  kubernetes.pem
...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=Kubernetes
        Validity
            Not Before: Apr  5 05:36:00 2017 GMT
            Not After : Apr  5 05:36:00 2018 GMT
        Subject: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=kubernetes
...
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                DD:52:04:43:10:13:A9:29:24:17:3A:0E:D7:14:DB:36:F8:6C:E0:E0
            X509v3 Authority Key Identifier:
                keyid:44:04:3B:60:BD:69:78:14:68:AF:A0:41:13:F6:17:07:13:63:58:CD
 
            X509v3 Subject Alternative Name:
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:10.64.3.7, IP Address:10.254.0.1
...
 
 
+ 确认 `Issuer` 字段的内容和 `ca-csr.json` 一致;
+ 确认 `Subject` 字段的内容和 `kubernetes-csr.json` 一致;
+ 确认 `X509v3 Subject Alternative Name` 字段的内容和 `kubernetes-csr.json` 一致;
+ 确认 `X509v3 Key Usage、Extended Key Usage` 字段的内容和 `ca-config.json` 中 `kubernetes` profile 一致;
2、使用 cfssl-certinfo 命令校验证书
shell 复制代码
[root@server ~]#cfssl-certinfo -cert kubernetes.pem
...
{
  "subject": {
    "common_name": "kubernetes",
    "country": "CN",
    "organization": "k8s",
    "organizational_unit": "System",
    "locality": "BeiJing",
    "province": "BeiJing",
    "names": [
      "CN",
      "BeiJing",
      "BeiJing",
      "k8s",
      "System",
      "kubernetes"
    ]
  },
  "issuer": {
    "common_name": "Kubernetes",
    "country": "CN",
    "organization": "k8s",
    "organizational_unit": "System",
    "locality": "BeiJing",
    "province": "BeiJing",
    "names": [
      "CN",
      "BeiJing",
      "BeiJing",
      "k8s",
      "System",
      "Kubernetes"
    ]
  },
  "serial_number": "174360492872423263473151971632292895707129022309",
  "sans": [
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local",
    "127.0.0.1",
    "10.64.3.7",
    "10.64.3.8",
    "10.66.3.86",
    "10.254.0.1"
  ],
  "not_before": "2017-04-05T05:36:00Z",
  "not_after": "2018-04-05T05:36:00Z",
  "sigalg": "SHA256WithRSA",
...
3、使用浏览器验证

导入证书

​ ca.pem改名为ca.crt。将正式导入浏览器。

构建https服务

shell 复制代码
[root@server ~]#cd /root/ssl_test
[root@server ~]#cat > http-server.js <<EOF
var https = require('https');
var fs = require('fs');
 
var options = {
    key: fs.readFileSync('./keys/app-key.pem'),
    cert: fs.readFileSync('./keys/app.pem')
};
 
https.createServer(options, function (req, res) {
    res.writeHead(200);
    res.end('hello world');
}).listen(8000);
EOF
 
[root@server ~]#yum install nodejs -y
[root@server ~]#npm install https -g
[root@server ~]#node http-server.js

修改hosts文件添加

shell 复制代码
172.16.160.28 www.test.com

在浏览器访问https://www.test.com:8000 发现网站显示为安全

4、附加内容

数字证书中主题(Subject)中字段的含义

  • 一般的数字证书产品的主题通常含有如下字段:
字段名 字段值
公用名称 (Common Name) 简称:CN 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端证书则为证书申请者的姓名;
单位名称 (Organization Name) 简称:O 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端单位证书则为证书申请者所在单位名称;
  • 证书申请单位所在地
字段名 字段值
所在城市 (Locality) 简称:L 字段
所在省份 (State/Provice) 简称:S 字段
所在国家 (Country) 简称:C 字段,只能是国家字母缩写,如中国:CN
  • 其他一些字段
字段名 字段值
电子邮件 (Email) 简称:E 字段
多个姓名字段 简称:G 字段
介绍 Description 字段
电话号码: Phone 字段,格式要求 + 国家区号 城市区号 电话号码,如: +86 732 88888888
地址: STREET 字段
邮政编码: PostalCode 字段
显示其他内容 简称:OU 字段

例子:

shell 复制代码
[root@server ca]#cat ca-config.json 
{
    "signing": {
        "default": {
            "expiry": "9999h"
        },
        "profiles": {
            "www": {
                "expiry": "9999h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "9999h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            }
        }
    }
}
 
[root@server ca]#cat ca-csr.json 
{
  "CN": "registry.test.com",
  "hosts": [
    "127.0.0.1",
    "172.16.160.38",
    "registry.test.com"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
 
[root@server ca]#ll
总用量 8
-rw-r--r-- 1 root root 568 11月 14 15:59 ca-config.json
-rw-r--r-- 1 root root 289 11月 14 16:02 ca-csr.json
 
[root@dev ca]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2018/11/14 16:05:01 [INFO] generating a new CA key and certificate from CSR
2018/11/14 16:05:01 [INFO] generate received request
2018/11/14 16:05:01 [INFO] received CSR
2018/11/14 16:05:01 [INFO] generating key: rsa-2048
2018/11/14 16:05:01 [INFO] encoded CSR
2018/11/14 16:05:01 [INFO] signed certificate with serial number 303515642193399207794287652931621857332460556169
 
[root@server ca]#ll
总用量 20
-rw-r--r-- 1 root root  568 11月 14 15:59 ca-config.json
-rw-r--r-- 1 root root 1082 11月 14 16:05 ca.csr
-rw-r--r-- 1 root root  289 11月 14 16:02 ca-csr.json
-rw------- 1 root root 1679 11月 14 16:05 ca-key.pem
-rw-r--r-- 1 root root 1379 11月 14 16:05 ca.pem
 
 
[root@server ~]#openssl x509  -noout -text -in ca.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            35:2a:1c:b2:f6:1a:f3:82:38:50:05:8c:fb:65:ef:9e:89:74:8f:89
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=harbor
        Validity
            Not Before: Nov 14 08:00:00 2018 GMT
            Not After : Nov 13 08:00:00 2023 GMT
        Subject: C=CN, ST=BeiJing, L=BeiJing, O=k8s, OU=System, CN=harbor
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b7:2e:6a:52:f4:d2:34:8b:5e:3f:95:5d:c8:b0:
                    85:9a:1b:ef:c5:0f:1b:94:b9:94:12:fe:fa:66:0d:
                    8c:67:b8:9e:82:30:fc:e1:42:94:6e:00:fb:c0:fd:
                    84:be:65:2c:e4:8f:f1:f1:93:e5:ae:8e:5b:74:7a:
                    d5:94:25:9c:01:76:f9:96:4e:02:b9:27:a2:44:e0:
                    da:b3:f3:09:82:5c:9f:26:a6:26:54:35:15:e6:a6:
                    7a:4b:14:99:07:9d:e3:c3:b8:bd:3f:b6:76:53:05:
                    82:02:bb:e2:61:21:23:5b:3b:23:4c:08:eb:a7:51:
                    00:fb:01:5f:b7:f8:b9:67:5b:a1:99:19:23:42:7a:
                    d2:22:0a:11:01:1d:75:34:9e:25:9c:c8:9f:31:d7:
                    f5:f3:98:14:b8:c4:07:f3:5a:a1:fa:96:bd:0f:b3:
                    dc:13:5b:8e:03:e8:66:3b:b5:bd:8d:08:ee:61:c2:
                    4f:78:dc:9a:ee:37:f8:87:6b:5f:e3:87:ae:91:b0:
                    8c:c9:40:51:44:cb:57:47:23:f1:2d:34:af:0f:5f:
                    42:89:14:ac:de:73:d4:32:54:c2:de:99:38:96:d4:
                    b8:de:f3:df:5c:a5:55:54:8f:a1:b7:fa:42:8b:d9:
                    fe:2d:14:1f:d5:62:d9:c7:c1:4d:55:41:3b:a9:d3:
                    0d:2d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:2
            X509v3 Subject Key Identifier: 
                15:1F:81:A2:AC:41:18:DA:DD:19:36:03:61:18:7B:EF:3D:94:10:AE
            X509v3 Authority Key Identifier: 
                keyid:15:1F:81:A2:AC:41:18:DA:DD:19:36:03:61:18:7B:EF:3D:94:10:AE
 
            X509v3 Subject Alternative Name: 
                IP Address:127.0.0.1, IP Address:172.16.160.38
    Signature Algorithm: sha256WithRSAEncryption
         62:41:3c:40:6d:91:29:d2:0b:6d:ce:08:a1:e4:47:64:0a:66:
         0e:c0:55:eb:c4:6b:30:6d:79:51:b4:97:8c:02:1e:15:ba:0f:
         84:ce:2a:3c:c7:86:29:3c:1f:55:35:a1:da:df:70:5d:58:93:
         45:24:c4:20:4d:c1:c7:bb:83:8d:52:0c:7d:43:e2:7c:5b:00:
         5d:57:5a:b5:bf:d0:56:5a:57:32:ca:fc:29:59:23:ab:5e:1e:
         0e:9b:f9:f6:8d:e8:e4:c6:cb:e6:fe:9f:e3:cd:55:2e:7b:35:
         1e:bc:80:0f:ba:d8:66:ae:43:19:bf:d1:bb:81:17:d6:4a:3b:
         01:ba:d4:28:da:3f:19:63:82:72:6f:df:7a:b4:bc:d4:cf:a9:
         b1:fc:a6:c7:c1:5d:9b:09:2e:72:2a:d4:18:ed:f4:3d:97:1e:
         e6:43:81:5c:eb:40:2c:f9:aa:6f:90:16:70:46:77:52:09:64:
         43:83:00:0c:44:59:de:17:65:7b:7e:3d:51:df:54:6e:bb:80:
         cb:22:13:e2:20:80:91:f8:3f:5e:83:70:32:68:ad:ad:7e:4a:
         15:32:45:a7:a5:c4:ed:1c:d4:e4:cc:38:ac:8a:9d:d1:bb:4e:
         1c:21:17:56:a2:a0:f9:39:f3:73:e4:96:00:ac:98:93:f3:80:
         96:9d:b5:97
[root@dev ca]#

如果出现

shell 复制代码
[root@server ~]#docker login registry.test.com
Username (admin): admin
Password: 
Error response from daemon: Get https://registry.mayocase.com/v1/users/: x509: certificate signed by unknown authority

检查下目录/etc/docker/certs.d/registry.test.com下是否有ca.crt文件,可能需要重启docker

shell 复制代码
[root@server ~]#cp ca.pem /etc/docker/certs.d/registry.test.com/ca.crt
[root@server ~]#systemctl restart docker

修改harbor证书后操作:

shell 复制代码
[root@server ~]#cd /data/harbor    #一定要在此目录下运行以下命令。
[root@server ~]#ll
总用量 878344
drwxr-xr-x 4 root root        35 7月  31 2017 common
-rw-r--r-- 1 root root      1988 7月  31 2017 docker-compose.notary.yml
-rw-r--r-- 1 root root      3155 7月  31 2017 docker-compose.yml
-rw-r--r-- 1 root root      4304 7月  31 2017 harbor_1_1_0_template
-rw-r--r-- 1 root root      4178 7月  31 2017 harbor.cfg
-rw-r--r-- 1 root root      1082 7月  31 2017 harbor.csr
-rw-r--r-- 1 root root       288 7月  31 2017 harbor-csr.json
-rw-r--r-- 1 root root 448963966 7月  31 2017 harbor.v1.1.1.tar.gz
-rw-r--r-- 1 root root 450041094 7月  31 2017 harbor.v1.1.2.tar.gz
-rwxr-xr-x 1 root root      5169 7月  31 2017 install.sh
-rw-r--r-- 1 root root    337600 7月  31 2017 LICENSE
-rw-r--r-- 1 root root       472 7月  31 2017 NOTICE
-rwxr-xr-x 1 root root     16522 7月  31 2017 prepare
-rwxr-xr-x 1 root root      4550 7月  31 2017 upgrade 
# 停止 harbor
[root@server harbor]# docker-compose down -v        #多运行几次直到所有docker都删除
# 修改配置
[root@server harbor]# vim harbor.cfg
# 更修改的配置更新到 docker-compose.yml 文件
[root@server harbor]# ./prepare
# 启动 harbor
[root@server harbor]#  docker-compose up -d

8、特例: https 为什么慢,把nginx 跑到 qat 卡上

Intel QAT 助力 Nginx 压缩处理

1、什么是Intel® QAT?

Intel® QuickAssist Technology是Intel®公司提供的一种高性能数据安全和压缩的加速方案。该方案利用QAT芯片分担对称/非对称加密计算,DEFLATE无损压缩等大计算量的任务,来降低CPU使用率并提高整体平台性能。该方案可以主板芯片,独立的PCI-E加速卡或者SOC三种方式部署。

QAT支持硬件加速Deflate无损压缩算法,在处理海量数据时,QAT在不增加CPU开销的前提下,通过压缩来减少需要传输和存盘的数据量,从而减少了网络带宽和磁盘读写的开销,最终提高了整体的系统性能。 例如,在Web Serer上使用QAT硬件加速压缩处理,可将CPU从繁重的压缩计算中解放出来,以处理更多的连接请求。

2、什么是Nginx Web Server

Nginx(发音同engine x)是一款使用异步框架的高性能Web服务器,相较于Apache、lighttpd等其他Web Server,Nginx具有占有内存少,稳定性高等优势。根据Netcraft 2018年一月的Web Server市场调查报告, Nginx的装机率达25.39%,位列Web Server市场第三,并在持续增长中1

Nginx中的GZIP模块实现了对HTTP压缩的支持,该模块通过调用Zlib库实现对网页内容进行Deflate压缩。由于使用软件实现无损压缩,需要消耗大量CPU运算时间进行压缩运算。

然而,在大并发流量的网站接入层的Nginx需要处理相当多的业务,包括https连接建立,安防攻击,流量镜像,链路追踪等等。使得CPU进行HTTP压缩处理成为Web Server最主要的CPU开销,进而限制了网站支持最大并发连接数。根据客户提供的接入层流量模型分析来看, GZIP 单个模块 CPU 消耗占比达到 15%-20% 左右,且占比呈上升趋势。所以,若能使用加速Nginx的网页压缩处理,可以极大的提高网站性能。

3、Zlib-SHIM API

Zlib作为广泛部署的软件压缩库,提供Deflate压缩的软件实现,被包括Nginx在内的广大应用程序所采用。Intel® QuickAssist Technology提供了与Zlib类似接口的Zlib-SHIM 软件库来适配上层应用,减少了应用迁移的开发量。该库提供了与Zlib一致的Deflate API,只需对源代码做少量修改,并将原有应用与Zlib-SHIM编译链接,就能使用QuickAssit提供的硬件加速功能。

Zlib-SHIM库实现了DeflateInit,DeflateInit2,Deflate,DeflateEnd等常用API并支持Stateful和Stateless压缩,可以替代Zlib的绝大部分功能。

Zlib-SHIM提供了Deflate API同步模式接口(调用程序阻塞在Deflate API上,直到压缩任务完成),而其内部实现调用了异步模式API,即在CPU上运行的QAT驱动程序向QAT协处理器提交了一个数据压缩请求后即返回,期间使用Polling 接口定期检查压缩请求是否完成,等到QAT硬件完成压缩处理后通过回调函数通知CPU端的应用程序进行下一步操作。这样的设计, 在不影响上层应用程序原有设计的前提下,实现了高并发场景中CPU和QAT的协同工作:CPU专注于网络链接处理而QAT处理复杂的压缩计算, 各司其职,最终提高了系统整体性能。

Zlib-SHIM 层次图

4、Zlib-SHIM工作原理

采用这种异步模式API实现对外的同步接口,在实现上有三种方法:Direct Polling,Indirect Polling Spinning和Indirect Polling Semaphore模式。

使用Direct Polling模式时,Deflate调用者会在当前线程直接调用Polling接口,若压缩结果还没有返回则休眠一段时间后再检查,直到压缩成功后Deflate 调用才返回。Direct Polling模式下CPU开销小,但是单个Request从发出到返回结果延迟较长,只有在多进程多线程高并发模式下才能充分发挥QAT的压缩性能。

Direct polling 模式流程图

Indirect Polling模式,是通过创建一个轮询线程定期调用Polling接口来检查压缩请求在QAT 协处理器中的执行状态,轮询线程一旦发现有请求执行完毕就通过回调函数(Callback Function)通知CPU端程序进行后续处理。

Indirect pooling模式时序图

根据回调通知方式的不同,Indirect Polling模式又可细分为Spinning模式和Semaphore模式:

Spinning模式中,Deflate函数调用线程定期轮询与回调函数共享的任务完成标志,若尚未完成则主动休眠,若已完成则进行后续处理。

Semaphore模式中,Deflate调用线程通过互斥锁来隔离与轮询线程共享的任务完成标志的访问操作,若任务尚未完成则Deflate调用线程休眠,一旦任务完成,轮询线程中的回调函数会通过信号量唤醒调用线程进行后续处理。

采用Indirect Polling模式无论Deflate调用数目多少都需要启动轮询线程,在压缩请求数不大的情况下增加了CPU的Polling开销,但是当压缩任务作为CPU的主要任务时可以减少不必要的Polling调用,提高CPU的使用率。

Nginx为了实现高性能的高并发处理能采用了单进程单线程异步工作模式,如果使用Indirect Polling模式,就需要在每个Nginx Worker进程中创建一个轮询线程 (Polling Thread), 从而增加了线程间切换的开销和共享数据的互斥的操作, 所以在Nginx和Zlib-SHIM集成中,我们使用了Direct Polling Mode。

5、USDM优化

USDM是QAT为了优化内存使用效率而提供的用户态内存管理工具。由于QAT和CPU之前需要频繁高速的交换数据,使用传统的Memory Copy方式不仅效率低而且消耗CPU资源,所以QAT支持DMA方式进行数据传输,CPU只需分配好拥有物理连续内存的输入地址和输出地址,QAT会自动完成的从该地址的输入读取或输出写回的操作。QAT Driver中的USDM模块,利用了Linux 内核提供的Huge-Page特性来获得物理地址连续内存并使用SLAB算法进行内存管理。

对于每一个新分配的Huge-Page,USDM会对应地在Devfs中新建一个临时文件,并通过mmap将临时文件描述符与新申请到的Huge-Page关联上,当USDM发现该Huge-Page上所有内存块均已释放,并不需将其留作缓存时,就关闭该临时文件以释放Huge-Page。当Zlib-SHIM运行过程中需要使用连续的内存时,就使用USDM Alloc接口从内存池中申请连续物理地址的内存, 并在发送压缩请求时将申请到的连续内存地址作为参数传递给QAT。

USDM DMA传输

6、测试结果

基于以上设计的Zlib-SHIM可以很方便的替换原有Zlib库,使得调用者可以方便的利用QAT进行压缩加速。 在实际应用中, 客户就是将Zlib-SHIM与基于Nginx定制的Web Server进行集成,在接入层的性能优化上取得了理想的效果。

客户的Web Server运行在Intel® Xeon® CPU上(CPU型号:Intel® Xeon® CPU E5-2650 v2 @ 2.60GHz 32核 内核:2.6.32 Zlib版本:zlib-1.2.8 QAT驱动版本:intel-qatOOT40052 ),在相同网络流量条件下,未开启QAT加速的CPU平均使用率为48%左右,而开启QAT加速后CPU平均使用率为41%左右。

CPU使用率对比2

相同条件下,开启QAT加速后系统load平均值为12.09,关闭QAT加速时系统load平均值为14.22,如下图所示:

系统load对比2

综合以上数据,Web Server在QPS 10K的压力下,使用QAT加速后可以节省CPU 15%左右,且Gzip基本上完全卸载、随着其占比变高,优化效果将越好。

7、总结

拥有和Zlib相同API接口的Zlib-SHIM可以很方便的与上层应用集成,利用QAT的硬件加速性能。此外,为了最大限度的发挥QAT的新能,Intel还提供了使用专有API的QATzip软件库,相应的Nginx module也在开发中,相信不久的将来集成QATzip的Web Server能够提供更好的性能。

性能测试中使用的软件和工作负荷可能仅在英特尔微处理器上进行了性能优化。诸如SYSmark和MobileMark等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。上述任何要素的变动都有可能导致测试结果的变化。请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。

Nginx为了实现高性能的高并发处理能采用了单进程单线程异步工作模式,如果使用Indirect Polling模式,就需要在每个Nginx Worker进程中创建一个轮询线程 (Polling Thread), 从而增加了线程间切换的开销和共享数据的互斥的操作, 所以在Nginx和Zlib-SHIM集成中,我们使用了Direct Polling Mode。

5、USDM优化

USDM是QAT为了优化内存使用效率而提供的用户态内存管理工具。由于QAT和CPU之前需要频繁高速的交换数据,使用传统的Memory Copy方式不仅效率低而且消耗CPU资源,所以QAT支持DMA方式进行数据传输,CPU只需分配好拥有物理连续内存的输入地址和输出地址,QAT会自动完成的从该地址的输入读取或输出写回的操作。QAT Driver中的USDM模块,利用了Linux 内核提供的Huge-Page特性来获得物理地址连续内存并使用SLAB算法进行内存管理。

对于每一个新分配的Huge-Page,USDM会对应地在Devfs中新建一个临时文件,并通过mmap将临时文件描述符与新申请到的Huge-Page关联上,当USDM发现该Huge-Page上所有内存块均已释放,并不需将其留作缓存时,就关闭该临时文件以释放Huge-Page。当Zlib-SHIM运行过程中需要使用连续的内存时,就使用USDM Alloc接口从内存池中申请连续物理地址的内存, 并在发送压缩请求时将申请到的连续内存地址作为参数传递给QAT。

外链图片转存中...(img-mfI9klR4-1785229121368)USDM DMA传输

6、测试结果

基于以上设计的Zlib-SHIM可以很方便的替换原有Zlib库,使得调用者可以方便的利用QAT进行压缩加速。 在实际应用中, 客户就是将Zlib-SHIM与基于Nginx定制的Web Server进行集成,在接入层的性能优化上取得了理想的效果。

客户的Web Server运行在Intel® Xeon® CPU上(CPU型号:Intel® Xeon® CPU E5-2650 v2 @ 2.60GHz 32核 内核:2.6.32 Zlib版本:zlib-1.2.8 QAT驱动版本:intel-qatOOT40052 ),在相同网络流量条件下,未开启QAT加速的CPU平均使用率为48%左右,而开启QAT加速后CPU平均使用率为41%左右。

外链图片转存中...(img-O4obWuDI-1785229121368)\]CPU使用率对比\[2

相同条件下,开启QAT加速后系统load平均值为12.09,关闭QAT加速时系统load平均值为14.22,如下图所示:

外链图片转存中...(img-LggPmZtb-1785229121368)\]系统load对比\[2

综合以上数据,Web Server在QPS 10K的压力下,使用QAT加速后可以节省CPU 15%左右,且Gzip基本上完全卸载、随着其占比变高,优化效果将越好。

7、总结

拥有和Zlib相同API接口的Zlib-SHIM可以很方便的与上层应用集成,利用QAT的硬件加速性能。此外,为了最大限度的发挥QAT的新能,Intel还提供了使用专有API的QATzip软件库,相应的Nginx module也在开发中,相信不久的将来集成QATzip的Web Server能够提供更好的性能。

性能测试中使用的软件和工作负荷可能仅在英特尔微处理器上进行了性能优化。诸如SYSmark和MobileMark等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。上述任何要素的变动都有可能导致测试结果的变化。请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。

相关推荐
cesium vue14 小时前
nginx 流媒体配置
运维·nginx
zhougl99615 小时前
Gateway 和 Nginx 路由区别
运维·nginx·gateway
布兰妮甜17 小时前
跨域全方案对比:CORS、Nginx 反向代理、JSONP、iframe、postMessage
nginx·跨域·cors·前端架构·浏览器安全
韩楚风17 小时前
【参天引擎】一次宕机后的数据恢复,让我把 Cantian 持久化与恢复的六大机制全搞明白了
服务器·网络·数据库·分布式·mysql·架构·cantian
kirs_ur18 小时前
SSD 安全特性 — 加密与 TCG Opal
服务器·网络·安全
智购科技智能售货柜18 小时前
无人售货机连不上服务器?MQTT 频繁掉线排查全流程~YH
运维·服务器
Mortalbreeze18 小时前
深入 Linux Socket 编程:端口号、网络字节序与 struct sockaddr 详解
linux·服务器·网络·c++
難釋懷18 小时前
Nginx-proxy缓存断点续传缓存 range
运维·nginx·缓存
躺柒18 小时前
读半导体简史08大型机
linux·服务器·c语言·数据库·unix·ibm