WEB服务与NGINX(17)- https协议及使用nginx实现https功能
1. https协议及使用nginx实现https功能
1.1 https协议概述
-
为什么要使用https?
HTTP是采用明文的方式传输数据,在传输一些敏感信息,例如账号密码,交易信息等时容易遭到拦截篡改,而HTTPS协议是对数据进行加密后传输的,能够有效的避免传输过程中信息的泄露。
-
什么是HTTPS?
HTTPS为安全的超文本传输协议,https有两部分组成,HTTP+SSL/TLS,即在HTTP头之上又增加了一个处理加密信息的模块,这个模块就是SSL/TLS。
1.2 TLS/SSL协议原理
- SSL: 安全套接层(Secure Socket Layer) 早期名称,由Netscape(网景)公司开发的。
- TLS: 传输层安全(Transport Layer Security) 由IETF(Internet工程任务组) 将SSL命名的国际标准名称,目前主流的为1.2版本。
TLS/SSL工作在应用层和传输层之间,在HTTP报文之上再封装TLS/SSL报文头部进行数据加密。
TLS/SSL的主要功能有:
-
实现数据的加密
-
认证,实现双方身份的验证
-
实现数据的完整性
-
防重放攻击
数据在发送中不允许重新发送。举个例子,A和B在通信过程中,若A往B发送数据请求登录验证,正常情况下会使用B的公钥对数据进行加密,并发送给B。若A的数据发送给B之前,被C来拦截下来了,由于数据已经被A使用B的公钥加密过了,因此C是破解不了数据的。但是C如果能将这个数据的IP头部信息修改成自己的IP地址并重新发送给B,那么C就间接实现了登录操作。
TLS/SSL的实现过程:
分为握手阶段和应用阶段
-
握手阶段(协商阶段)
客户端和服务器端认证对方身份(依赖于PKI体系,利用数字证书进行身份认证),并协商通信中使用的安全参数、密码套件以及主密钥。后续通信使用的所有密钥都是通过主密钥生成。
-
应用阶段:
在握手阶段完成后进入,在应用阶段通信双方使用握手阶段协商好的密钥进行安全通信。
1.3 https的实现原理
- HTTPS的工作过程如下:
-
客户端发起HTTPS请求:
客户端访问某个web端的https地址,一般都是443端口。
-
服务端的配置:
采用https协议的服务器必须要有一套证书,可以通过一些组织申请,也可以自己制作,目前国内很多网站都自己做的,当你访问一个网站的时候提示证书不可信任就表示证书是自己做的,证书就是一个公钥和私钥匙,就像一把锁和钥匙,正常情况下只有你的钥匙可以打开你的锁,你可以把这个送给别人让他锁住一个箱子,别人不知道里面放了什么而且别人也打不开,只有你的钥匙是可以打开的。
-
传送证书:
服务端给客户端传递证书,其实就是公钥,里面包含了很多信息,例如证书的颁发机构、过期时间等等。
-
客户端解析证书:
这部分工作是有客户端完成的,首先会验证公钥的有效性,比如颁发机构、过期时间等等(这里客户端需要提前存在CA的证书,用于验证服务器证书的有效性),如果发现异常则会弹出一个警告框提示证书可能存在问题,如果证书没有问题就生成一个随机值,然后用证书对该随机值进行加密,就像2步骤所说把随机值锁起来,不让别人看到。
-
传送4步骤的加密数据:
就是将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值进行加密解密了。
-
服务端解密信息:
服务端用私钥解密5步骤加密后的随机值之后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,对称加密就是将信息和私钥通过算法混合在一起,这样除非你知道私钥,不然是无法获取其内部的内容,而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性。
-
传输加密后的信息:
服务端将用私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容。
-
客户端解密信息:
客户端用之前生成的私钥获解密服务端传递过来的数据,由于数据一直是加密的,因此即使第三方获取到数据也无法知道其详细内容。
-
Q:为什么HTTPS的数据传输是用对称加密?
A:首先,非对称加密的加解密效率是非常低的,而 HTTP 的应用场景中通常端与端之间存在大量的交互,非对称加密的效率是无法接受的。
另外,在 HTTPS 的场景中只有服务端保存了私钥,一对公私钥只能实现单向的加解密,所以 HTTPS 中内容传输加密采取的是对称加密,而不是非对称加密。HTTPS的通信过程确保了对称加密算法的私钥的私密性。
-
Q:为什么需要 CA 认证机构颁发证书?
A:若不存在认证机构CA,任何人都可以制作证书,这带来的安全风险便是经典的“中间人攻击”问题。
中间人攻击的具体流程如下:
- 本地请求被劫持(如 DNS 劫持等),所有请求均发送到中间人的服务器。
- 客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间人,然后凭随机数构造对称加密对传输内容进行加密传输。
- 中间人因为拥有客户端的随机数,可以通过对称加密算法进行内容解密。
- 中间人以客户端的请求内容再向正规网站发起请求。
- 因为中间人与服务器的通信过程是合法的,正规网站通过建立的安全通道返回加密后的数据。
- 中间人凭借与正规网站建立的对称加密算法对内容进行解密。
- 中间人通过与客户端建立的对称加密算法对正规内容返回的数据进行加密传输。
- 客户端通过与中间人建立的对称加密算法对返回结果数据进行解密。
- 由于缺少对证书的验证,所以客户端虽然发起的是 HTTPS 请求,但客户端完全不知道自己的网络已被拦截,传输内容被中间人全部窃取。
-
Q:证书的主要内容时什么?
A:证书包含信息如下:
-
颁发机构信息,即CA信息
-
服务器端公钥
-
公司信息
-
网站域名
-
证书有效期
-
指纹
-
-
Q:证书的合法性依据是什么?
A:首先,权威机构是要有认证的,不是随便一个机构都有资格颁发证书,不然也不叫做权威机构。
另外,证书的可信性基于信任制,权威机构需要对其颁发的证书进行信用背书,只要是权威机构生成的证书,我们就认为是合法的。
所以权威机构会对申请者的信息进行审核,不同等级的权威机构对审核的要求也不一样,于是证书也分为免费的、便宜的和贵的。
-
Q:浏览器如何验证证书的合法性?
A:浏览器发起 HTTPS 请求时,服务器会返回网站的 SSL 证书。
浏览器需要对证书做以下验证:
-
验证域名、有效期等信息是否正确。证书上都有包含这些信息,比较容易完成验证。
-
判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证。
-
判断证书是否被篡改。需要与 CA 服务器进行校验。
-
判断证书是否已吊销。通过 CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现。
其中 OCSP 可用于第 3 步中以减少与 CA 服务器的交互,提高验证效率。
以上任意一步都满足的情况下浏览器才认为证书是合法的。
这里有一个问题:既然证书是公开的,如果要发起中间人攻击,我在官网上下载一份证书作为我的服务器证书,那客户端肯定会认同这个证书是合法的,如何避免这种证书冒用的情况?
其实这就是非加密对称中公私钥的用处,虽然中间人可以得到证书,但私钥是无法获取的。
一份公钥是不可能推算出其对应的私钥,中间人即使拿到证书也无法伪装成合法服务端,因为无法对客户端传入的加密数据进行解密。
-
-
Q:用了 HTTPS 会被抓包吗?
HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,无法直接查看。
但是,正如前文所说,浏览器只会提示安全风险,如果用户授权仍然可以继续访问网站,完成请求。
因此,只要客户端是我们自己的终端,我们授权的情况下,便可以组建中间人网络,而抓包工具便是作为中间人的代理。
通常 HTTPS 抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互。
然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环。
既然 HTTPS 不能防抓包,那 HTTPS 有什么意义?HTTPS 可以防止用户在不知情的情况下通信链路被监听,对于主动授信的抓包操作是不提供防护的,因为这个场景用户是已经对风险知情。
要防止被抓包,需要采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解。
-
HTTPS的颜色提示
Https不支持续费,证书到期需重新申请新并进行替换 。
Https不支持三级域名解析,如test.m.xu.com。
Https显示绿色,说明整个网站的url都是https的,并且都是安全的。
Https显示黄色说明网站代码中有部分URL地址是http不安全协议的 。
Https显示红色要么证书是假的,要么证书已经过期。
1.4 使用openssl申请证书
-
首先要搭建一台CA服务器,具体操作如下:
#1.查看openssl的配置文件/etc/pki/tls/openssl.cnf,需要按照配置文件的要求存放证书,私钥等文件,主要内容如下: [ ca ] default_ca = CA_default # The default ca section [ CA_default ] dir = /etc/pki/CA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha256 # use SHA-256 by default preserve = no # keep passed DN ordering [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional #上述参数的主要意义如下: dir :CA存放文件的根路径 certs:生成的证书文件存放的目录 crl_dir:crl吊销列表的文件夹 database:index.txt,证书的数据库摘要信息,需要手工创建,创建后系统会自动添加 certificate:CA服务器的根证书(自签名证书)文件 serial:CA要签发的下一个证书的序列号(16进制) crlnumber:下一个吊销证书的编号 private_key :CA服务器的私钥文件 default_days:颁发证书的默认有效期 default_crl_days:默认吊销列表的有效期 default_md:默认使用的哈希算法 policy:使用哪个policy策略 [ policy_match ] countryName = match 国家 match表示必须匹配 stateOrProvinceName = match 省 必须匹配 organizationName = match 公司 必须匹配 organizationalUnitName = optional 部门 可选,可以不填 commonName = supplied 证书名:必填项 emailAddress = optional #2.按照配置文件的要求手动创建不存在的文件 [root@xuzhichao ~]# cd /etc/pki/CA/ #生成证书索引数据库文件 [root@xuzhichao CA]# touch index.txt #指定第一个颁发证书的序列号为01,数字为16进制 [root@xuzhichao CA]# echo "01" > serial #其他文件和目录都已经存在 [root@xuzhichao CA]# tree . ├── certs ├── crl ├── index.txt ├── newcerts ├── private └── serial #3.生成CA的私钥文件,可以对私钥文件进行加密保存,并临时修改私钥文件权限为600,只有root可访问,确保私钥文件安全性。 #根据配置文件,私钥文件路径和名称为private/cakey.pem,建议使用2048位。 [root@xuzhichao CA]# (umask 066; openssl genrsa -out private/cakey.pem 2048) Generating RSA private key, 2048 bit long modulus .....+++ .+++ e is 65537 (0x10001) #4.CA生成自签名证书(根证书) [root@xuzhichao CA]# openssl req -new -x509 -key private/cakey.pem -days 3650 -out cacert.pem 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) []:henan <==省份 Locality Name (eg, city) [Default City]:zhengzhou <==城市 Organization Name (eg, company) [Default Company Ltd]:maipu <==公司名称 Organizational Unit Name (eg, section) []:devops <==公司部门 Common Name (eg, your name or your server's hostname) []:rootxu <==主机名称 Email Address []: #参数解释: -new: 生成新证书签署请求 -x509: 专用于CA生成自签证书 -key: 生成请求时用到的私钥文件 -days n:证书的有效期限 -out /PATH/TO/SOMECERTFILE: 证书的保存路径 #查看证书内容 [root@xuzhichao CA]# openssl x509 -in cacert.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: df:ad:de:59:f6:17:0b:aa Signature Algorithm: sha256WithRSAEncryption Issuer: C=CN, ST=henan, L=zhengzhou, O=maipu, OU=devops, CN=rootxu Validity Not Before: Jun 20 15:47:06 2021 GMT Not After : Jun 18 15:47:06 2031 GMT Subject: C=CN, ST=henan, L=zhengzhou, O=maipu, OU=devops, CN=rootxu Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:e4:fa:6a:25:6d:3b:29:60:a5:16:92:41:0c:e3: 21:09:a0:f2:fa:ac:f0:a6:91:6b:c7:5b:57:79:a3: 8f:e1:c8:56:b4:84:2e:57:ec:49:d1:41:76:10:14: 33:1d:bd:09:91:37:d0:06:79:e1:4e:bb:a5:70:fa: 1e:fd:43:53:37:98:fe:dc:b7:9d:b4:49:49:4e:24: a5:aa:a8:41:ba:f7:ea:6c:1e:00:7f:05:60:7e:58: 9b:8e:47:bd:46:9f:af:74:c1:58:f9:10:15:5b:d2: 94:f8:4e:7a:9a:a7:ba:32:5c:83:3a:51:49:9e:c7: 1e:0b:b5:31:ea:01:53:08:24:0b:9f:42:6e:24:cf: 3a:5a:95:47:ee:27:67:f8:1e:c6:77:09:97:5e:c0: 71:58:30:b6:e2:00:d6:17:57:d3:81:7f:0c:43:4d: 7f:09:a0:34:02:c5:3d:a0:f2:9f:ae:18:29:e1:b9: d3:a5:87:43:b4:23:91:be:e8:b3:ff:55:fd:bc:51: 33:b7:c3:51:63:29:81:c1:d8:bf:0d:06:b4:b4:3d: 3b:02:6b:5a:c7:8a:b8:26:90:c0:29:cf:a8:93:84: d9:c0:68:55:7e:53:69:29:87:e3:a5:31:56:c2:55: 7e:87:47:19:5c:99:cb:11:c4:01:66:aa:8c:14:0f: 5b:bf Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: CB:3C:AA:49:A6:8B:B8:04:90:2D:62:30:DF:1A:E0:4D:31:29:5F:85 X509v3 Authority Key Identifier: keyid:CB:3C:AA:49:A6:8B:B8:04:90:2D:62:30:DF:1A:E0:4D:31:29:5F:85 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha256WithRSAEncryption 26:56:89:9d:22:dc:ad:7d:fa:f1:c6:86:32:7e:6b:f1:76:ba: ad:f7:74:b8:01:8a:9a:85:c0:4a:2a:56:35:d9:54:a7:60:5f: c1:05:2d:00:f3:bb:32:7a:5f:d0:14:86:b1:ce:54:e0:48:97: 70:51:5a:ac:49:4a:c0:fc:20:73:68:1d:64:ab:ce:8a:93:45: f1:4a:52:bf:ca:c1:2b:32:11:c2:c9:19:5f:3a:54:2b:90:bd: ec:48:55:b6:d1:cd:85:ba:52:55:c6:a5:65:06:bb:70:28:10: 7d:3a:42:26:60:85:ba:6e:89:84:4e:03:27:85:e8:92:c5:bb: b3:3e:16:61:48:df:3b:f5:ed:27:1c:60:d2:81:50:3b:5b:20: 51:c9:6d:cc:bd:3b:7a:c5:e0:bd:c4:8c:7c:02:e2:a9:d2:3e: 6f:69:3d:09:12:80:7d:b7:ad:a9:45:7a:f1:6c:2e:4c:69:dc: da:51:af:32:0d:cd:e0:15:74:ad:40:c7:40:18:5f:f6:97:91: 4a:27:b4:54:d7:f1:f2:da:a8:29:e7:4f:eb:a5:4c:c7:dc:16: 20:48:87:94:08:d6:f6:38:63:80:f2:7f:f2:9b:7e:2b:3b:06: c5:29:b3:33:c0:64:d8:fc:2f:84:93:f2:bc:c3:61:48:17:b3: 80:01:0c:cd #查看根证书主题 [root@xuzhichao CA]# openssl x509 -in cacert.pem -noout -subject subject= /C=CN/ST=henan/L=zhengzhou/O=maipu/OU=devops/CN=rootxu
-
客户端申请证书的步骤:
#1.客户端生成私钥,私钥的存放目录,根据应用程序进行选择,不同的服务都有自己的工作目录,此处给nginx服务器使用,生成私钥放在其下配置文件夹中/etc/nginx/certs中,将来申请的证书也放在一起。 [root@nginx01 ~]# cd /etc/nginx/ [root@nginx01 nginx]# mkdir certs [root@nginx01 nginx]# (umask 066; openssl genrsa -out certs/xuzhichao.key 2048) Generating RSA private key, 2048 bit long modulus .............................................+++ ...................................................................+++ e is 65537 (0x10001) #2.客户端生成证书请求文件,证书申请文件后缀为.csr。 #注意:默认国家,省,公司名称三项必须和CA一致,因为CA配置文件中这三项为match,同时需要注意申请的主机名必须和server_name保持一致。 [root@nginx01 nginx]# openssl req -new -key certs/xuzhichao.key -out certs/xuzhichao.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) []:henan Locality Name (eg, city) [Default City]:zhengzhou Organization Name (eg, company) [Default Company Ltd]:maipu Organizational Unit Name (eg, section) []:devops Common Name (eg, your name or your server's hostname) []:www.xuzhichao.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: #3.将生成的请求文件发送给CA服务器。 [root@nginx01 nginx]# scp certs/xuzhichao.csr 192.168.20.17:/etc/pki/CA The authenticity of host '192.168.20.17 (192.168.20.17)' can't be established. ECDSA key fingerprint is SHA256:G8+byxRD1GdKHww8nN1ZbyiAKEcMtVhaPOTTxt0Aldc. ECDSA key fingerprint is MD5:fa:e1:df:9f:ae:c2:3d:f3:67:65:c0:12:3a:e1:ce:cc. Are you sure you want to continue connecting (yes/no)? yes root@192.168.20.17's password: xuzhichao.csr #4.CA签发证书 [root@xuzhichao CA]# openssl ca -in xuzhichao.csr -days 365 -out certs/xuzhichao.crt 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: Jun 20 16:08:43 2021 GMT Not After : Jun 20 16:08:43 2022 GMT Subject: countryName = CN stateOrProvinceName = henan organizationName = maipu organizationalUnitName = devops commonName = www.xuzhichao.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: AF:3F:92:C8:BE:4F:2D:69:8B:C5:5D:BF:27:18:D1:50:9A:00:C1:C2 X509v3 Authority Key Identifier: keyid:CB:3C:AA:49:A6:8B:B8:04:90:2D:62:30:DF:1A:E0:4D:31:29:5F:85 Certificate is to be certified until Jun 20 16:08:43 2022 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 #查看证书 [root@xuzhichao CA]# openssl x509 -in certs/xuzhichao.crt -noout -subject subject= /C=CN/ST=henan/O=maipu/OU=devops/CN=www.xuzhichao.com #5.把生成的证书和CA证书传给客户端。 [root@xuzhichao CA]# scp cacert.pem certs/xuzhichao.crt 192.168.20.20:/etc/nginx/certs The authenticity of host '192.168.20.20 (192.168.20.20)' can't be established. ECDSA key fingerprint is SHA256:G8+byxRD1GdKHww8nN1ZbyiAKEcMtVhaPOTTxt0Aldc. ECDSA key fingerprint is MD5:fa:e1:df:9f:ae:c2:3d:f3:67:65:c0:12:3a:e1:ce:cc. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.20.20' (ECDSA) to the list of known hosts. root@192.168.20.20's password: cacert.pem 100% 1310 1.0MB/s 00:00 xuzhichao.crt 100% 4452 1.2MB/s 00:00 [root@nginx01 nginx]# ll certs/ total 20 -rw-r--r-- 1 root root 1310 Jun 21 00:12 cacert.pem -rw-r--r-- 1 root root 4452 Jun 21 00:12 xuzhichao.crt -rw-r--r-- 1 root root 1013 Jun 21 00:03 xuzhichao.csr -rw------- 1 root root 1675 Jun 20 23:59 xuzhichao.key
1.5 nginx实现https
nginx实现https功能使用的是ngx_http_ssl_module 模块,需要确保在编译时启用了–with-http_ssl_module选项。
使用的主要指令如下:
-
ssl on | off;
支持环境:http, server
为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代。
-
ssl_certificate file;
支持环境:http, server
指定当前虚拟主机使用使用的公钥文件,一般是crt文件。
如果除主证书外还需要指定中间证书的话,安装顺序指定,先指定主证书,然后指定中间证书,要求版本OpenSSL 1.0.2及以上
-
ssl_certificate_key file;
支持环境:http, server
当前虚拟主机使用的私钥文件,一般是key文件
-
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支持环境:http, server
默认配置:ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
支持ssl协议版本,默认为后三个,TLSv1.1和TLSv1.2只有在使用OpenSSL 1.0.1或更高版本时才能工作。
-
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
支持环境:http, server
默认配置:ssl_session_cache none
设置ssl存储会话参数的缓存的类型和大小
参数说明
-
off:严格禁止使用会话缓存,Nginx显式地告诉客户端会话不可重用
-
none:通知客户端支持ssl session cache,但实际不支持
-
builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有,默认大小为20480次会话
-
[shared:name:size]:在各worker之间使用一个共享的缓存,大小以字节为单位,1兆字节可以储存4000个会话,建议使用共享内存。Name为自行定义,例如ssl_session_cache shared:SSL:20m;
-
-
ssl_session_timeout time;
支持环境:http, server
客户端连接可以复用ssl session cache中缓存的有效时长,默认5分钟。
nginx实现https的示例:
在上一小节中nginx已经为虚拟主机www.xuzhichao.com申请了证书文件,此处借用此证书文件。
此处同时启用了http和https的功能,均能提供服务。
#1.nginx的配置文件如下:
[root@nginx01 conf.d]# cat /etc/nginx/conf.d/xuzhichao.conf
server {
listen 443 ssl;
listen 80;
server_name www.xuzhichao.com;
access_log /var/log/nginx/access_xuzhichao.log access_json;
ssl_certificate /etc/nginx/certs/xuzhichao.crt;
ssl_certificate_key /etc/nginx/certs/xuzhichao.key;
ssl_session_cache shared:ssl_cache:30m;
ssl_session_timeout 10m;
location / {
root /data/nginx/html/xuzhichao;
index index.html;
}
}
#2.建立对应的站点目录
[root@nginx01 conf.d]# mkdir /data/nginx/html/xuzhichao/
[root@nginx01 conf.d]# echo "<h1>www.xuzhichao.com</h1>" > /data/nginx/html/xuzhichao/index.html
#3.重启nginx服务
[root@nginx01 conf.d]# systemctl reload nginx.service
#4.查看监听端口,443和80端口同时进行监听
[root@nginx01 conf.d]# ss -ntlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:443 *:* users:(("nginx",pid=50508,fd=19),("nginx",pid=50507,fd=19),("nginx",pid=1094,fd=19))
LISTEN 0 128 *:80 *:* users:(("nginx",pid=50508,fd=7),("nginx",pid=50507,fd=7),("nginx",pid=1094,fd=7))
客户端测试:
在页面中提示存在风险,是因为浏览器没有导入CA的证书,验证服务器证书不合法,导入浏览器CA证书后正常。
客户端使用curl命令验证:
#1.指定CA证书进行验证服务器证书
[root@xuzhichao ~]# curl --cacert /etc/pki/CA/cacert.pem https://www.xuzhichao.com
<h1>www.xuzhichao.com</h1>
#2.忽略证书验证进行访问网站
[root@xuzhichao ~]# curl -k https://www.xuzhichao.com
<h1>www.xuzhichao.com</h1>
#3.使用http方式访问
[root@xuzhichao ~]# curl http://www.xuzhichao.com
<h1>www.xuzhichao.com</h1>
1.6 实现多域名HTTPS
Nginx支持基于单个IP实现多域名的功能,并且还支持单IP多域名的基础之上实现HTTPS,这一点Apache Httpd是不支持的,其实是基于Nginx的SNI(Server Name Indication)功能实现,SNI是为了解决一个Nginx服务器内使用一个IP绑定多个域名和证书的功能,其具体功能是客户端在连接到服务器建立SSL连接之前先发送要访问站点的域名(Hostname),这样服务器再根据这个域名返回给客户端一个合适的证书。
实现过程就是再上一小节的基础上再增加一个HTTPS站点www.xuzhichao.net,实现访问即可,具体过程如下:
#1.在服务器上为新域名制作私钥key和csr文件,并上传到CA服务器上签发。
[root@nginx01 nginx]# (umask 022; openssl genrsa -out certs/www.xuzhichao.net.key 2048)
Generating RSA private key, 2048 bit long modulus
..................+++
.....................................................................................................+++
e is 65537 (0x10001)
[root@nginx01 nginx]# openssl req -new -key certs/www.xuzhichao.net.key -out certs/www.xuzhichao.net.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) []:henan
Locality Name (eg, city) [Default City]:zhengzhou
Organization Name (eg, company) [Default Company Ltd]:maipu
Organizational Unit Name (eg, section) []:devops
Common Name (eg, your name or your server's hostname) []:www.xuzhichao.net
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@nginx01 nginx]# scp certs/www.xuzhichao.net.csr 192.168.20.17:/etc/pki/CA/certs/
root@192.168.20.17's password:
www.xuzhichao.net.csr 100% 1013 780.5KB/s 00:00
#2.CA服务器签发证书,并回传给客户端
[root@xuzhichao CA]# openssl ca -in certs/www.xuzhichao.net.csr -days 365 -out certs/www.xuzhichao.net.crt
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 2 (0x2)
Validity
Not Before: Jun 21 02:20:09 2021 GMT
Not After : Jun 21 02:20:09 2022 GMT
Subject:
countryName = CN
stateOrProvinceName = henan
organizationName = maipu
organizationalUnitName = devops
commonName = www.xuzhichao.net
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
DC:23:1B:B4:DF:E3:FB:D5:31:99:0A:A3:EA:85:EA:A9:FA:F5:BB:E0
X509v3 Authority Key Identifier:
keyid:CB:3C:AA:49:A6:8B:B8:04:90:2D:62:30:DF:1A:E0:4D:31:29:5F:85
Certificate is to be certified until Jun 21 02:20:09 2022 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
[root@xuzhichao CA]# openssl x509 -in certs/www.xuzhichao.net.crt -noout -subject
subject= /C=CN/ST=henan/O=maipu/OU=devops/CN=www.xuzhichao.net
[root@xuzhichao CA]# scp certs/www.xuzhichao.net.crt 192.168.20.20:/etc/nginx/certs
root@192.168.20.20's password:
www.xuzhichao.net.crt 100% 4452 3.6MB/s 00:00
#3.nginx新增配置文件如下:
[root@nginx01 nginx]# cat conf.d/www.xuzhichao.net.conf
server {
listen 443 ssl;
listen 80;
server_name www.xuzhichao.net;
access_log /var/log/nginx/access_xuzhichao.net.log access_json;
ssl_certificate /etc/nginx/certs/www.xuzhichao.net.crt;
ssl_certificate_key /etc/nginx/certs/www.xuzhichao.net.key;
ssl_session_cache shared:ssl_cache:30m;
ssl_session_timeout 10m;
location / {
root /data/nginx/html/xuzhichao.net;
index index.html;
}
}
[root@nginx01 nginx]# mkdir /data/nginx/html/xuzhichao.net
[root@nginx01 nginx]# echo "<h1>www.xuzhichao.net</h1>" > /data/nginx/html/xuzhichao.net/index.html
[root@nginx01 nginx]# systemctl reload nginx.service
#4.客户端测试,可以实现多域名的访问:
[root@xuzhichao CA]# curl http://www.xuzhichao.net
<h1>www.xuzhichao.net</h1>
[root@xuzhichao CA]# curl -k https://www.xuzhichao.net
<h1>www.xuzhichao.net</h1>
1.7 http自动跳转https
很多时候网站基于安全考虑,需要实现全站https,但是客户端有时并不会使用https方式访问网站,而是使用http方式,此时依然存在安全隐患,此时需要在服务器端实现不影响用户请求的情况下将http请求自动跳转到https请求,实现https访问。
此时需要使用rewrite功能,配置示例如下:
#1.nginx的配置文件如下
[root@nginx01 nginx]# cat conf.d/xuzhichao.conf
server {
listen 443 ssl;
listen 80;
server_name www.xuzhichao.com;
access_log /var/log/nginx/access_xuzhichao.log access_json;
ssl_certificate /etc/nginx/certs/xuzhichao.crt;
ssl_certificate_key /etc/nginx/certs/xuzhichao.key;
ssl_session_cache shared:ssl_cache:30m;
ssl_session_timeout 10m;
location / {
root /data/nginx/html/xuzhichao;
index index.html;
if ( $scheme = http ) { <==若未加判断条件,会导致死循环
rewrite / https://www.xuzhichao.com permanent;
}
}
}
#2.重启nginx服务
[root@nginx01 nginx]# systemctl reload nginx.service
#3.客户端测试,访问的是http,但是通过301重定向到了https
[root@xuzhichao CA]# curl -L -k -i http://www.xuzhichao.com
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 21 Jun 2021 03:07:53 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.xuzhichao.com <==跳转到https
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 21 Jun 2021 03:07:54 GMT
Content-Type: text/html
Content-Length: 27
Last-Modified: Mon, 21 Jun 2021 01:30:51 GMT
Connection: keep-alive
ETag: "60cfebcb-1b"
Accept-Ranges: bytes
<h1>www.xuzhichao.com</h1>
1.8 https性能优化
SSL的运行计算需要消耗额外的CPU资源SSL通讯过程中握手阶段的运算最占用CPU资源,有如下几个方面可以进行调整与优化。
- 1.设置worker进程数设置为等于CPU处理器的核心数。worker_processes auto;
- 2.启用keepalive长连接, 一个连接发送更多个请求。
- 3.启用shared会话缓存,所有worker工作进程之间共享的缓存,避免进行多次SSL握手!。
- 4.禁用builtin内置于OpenSSL中的缓存,仅能供一个worker工作进程使用。[使用shared缓存即禁止builtin]
配置示例如下:
work_processes auto;
server {
listen 443 ssl;
server_name www.xuzhichao.com;
access_log /var/log/nginx/access_xuzhichao.log access_json;
ssl_certificate /etc/nginx/certs/xuzhichao.crt;
ssl_certificate_key /etc/nginx/certs/xuzhichao.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:ssl_cache:30m;
ssl_session_timeout 10m;
keepalive_timeout 65;
}