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體系,利用數字證書進行身份認證),並協商通信中使用的安全參數、密碼套件以及主密鑰。后續通信使用的所有密鑰都是通過主密鑰生成。

  • 應用階段:

    在握手階段完成后進入,在應用階段通信雙方使用握手階段協商好的密鑰進行安全通信。

image

1.3 https的實現原理

  • HTTPS的工作過程如下:

image

  1. 客戶端發起HTTPS請求:

    客戶端訪問某個web端的https地址,一般都是443端口。

  2. 服務端的配置:

    采用https協議的服務器必須要有一套證書,可以通過一些組織申請,也可以自己制作,目前國內很多網站都自己做的,當你訪問一個網站的時候提示證書不可信任就表示證書是自己做的,證書就是一個公鑰和私鑰匙,就像一把鎖和鑰匙,正常情況下只有你的鑰匙可以打開你的鎖,你可以把這個送給別人讓他鎖住一個箱子,別人不知道里面放了什么而且別人也打不開,只有你的鑰匙是可以打開的。

  3. 傳送證書:

    服務端給客戶端傳遞證書,其實就是公鑰,里面包含了很多信息,例如證書的頒發機構、過期時間等等。

  4. 客戶端解析證書:

    這部分工作是有客戶端完成的,首先會驗證公鑰的有效性,比如頒發機構、過期時間等等(這里客戶端需要提前存在CA的證書,用於驗證服務器證書的有效性),如果發現異常則會彈出一個警告框提示證書可能存在問題,如果證書沒有問題就生成一個隨機值,然后用證書對該隨機值進行加密,就像2步驟所說把隨機值鎖起來,不讓別人看到。

  5. 傳送4步驟的加密數據:

    就是將用證書加密后的隨機值傳遞給服務器,目的就是為了讓服務器得到這個隨機值,以后客戶端和服務端的通信就可以通過這個隨機值進行加密解密了。

  6. 服務端解密信息:

    服務端用私鑰解密5步驟加密后的隨機值之后,得到了客戶端傳過來的隨機值(私鑰),然后把內容通過該值進行對稱加密,對稱加密就是將信息和私鑰通過算法混合在一起,這樣除非你知道私鑰,不然是無法獲取其內部的內容,而正好客戶端和服務端都知道這個私鑰,所以只要機密算法夠復雜就可以保證數據的安全性。

  7. 傳輸加密后的信息:

    服務端將用私鑰加密后的數據傳遞給客戶端,在客戶端可以被還原出原數據內容。

  8. 客戶端解密信息:

    客戶端用之前生成的私鑰獲解密服務端傳遞過來的數據,由於數據一直是加密的,因此即使第三方獲取到數據也無法知道其詳細內容。

  • Q:為什么HTTPS的數據傳輸是用對稱加密?

    A:首先,非對稱加密的加解密效率是非常低的,而 HTTP 的應用場景中通常端與端之間存在大量的交互,非對稱加密的效率是無法接受的。
    另外,在 HTTPS 的場景中只有服務端保存了私鑰,一對公私鑰只能實現單向的加解密,所以 HTTPS 中內容傳輸加密采取的是對稱加密,而不是非對稱加密。

    HTTPS的通信過程確保了對稱加密算法的私鑰的私密性。

  • Q:為什么需要 CA 認證機構頒發證書?

    A:若不存在認證機構CA,任何人都可以制作證書,這帶來的安全風險便是經典的“中間人攻擊”問題。

    中間人攻擊的具體流程如下:

    1. 本地請求被劫持(如 DNS 劫持等),所有請求均發送到中間人的服務器。
    2. 客戶端創建隨機數,通過中間人證書的公鑰對隨機數加密后傳送給中間人,然后憑隨機數構造對稱加密對傳輸內容進行加密傳輸。
    3. 中間人因為擁有客戶端的隨機數,可以通過對稱加密算法進行內容解密。
    4. 中間人以客戶端的請求內容再向正規網站發起請求。
    5. 因為中間人與服務器的通信過程是合法的,正規網站通過建立的安全通道返回加密后的數據。
    6. 中間人憑借與正規網站建立的對稱加密算法對內容進行解密。
    7. 中間人通過與客戶端建立的對稱加密算法對正規內容返回的數據進行加密傳輸。
    8. 客戶端通過與中間人建立的對稱加密算法對返回結果數據進行解密。
    9. 由於缺少對證書的驗證,所以客戶端雖然發起的是 HTTPS 請求,但客戶端完全不知道自己的網絡已被攔截,傳輸內容被中間人全部竊取。
  • Q:證書的主要內容時什么?

    A:證書包含信息如下:

    • 頒發機構信息,即CA信息

    • 服務器端公鑰

    • 公司信息

    • 網站域名

    • 證書有效期

    • 指紋

  • Q:證書的合法性依據是什么?

    A:首先,權威機構是要有認證的,不是隨便一個機構都有資格頒發證書,不然也不叫做權威機構。

    另外,證書的可信性基於信任制,權威機構需要對其頒發的證書進行信用背書,只要是權威機構生成的證書,我們就認為是合法的。

    所以權威機構會對申請者的信息進行審核,不同等級的權威機構對審核的要求也不一樣,於是證書也分為免費的、便宜的和貴的。

  • Q:瀏覽器如何驗證證書的合法性?

    A:瀏覽器發起 HTTPS 請求時,服務器會返回網站的 SSL 證書。

    瀏覽器需要對證書做以下驗證:

    • 驗證域名、有效期等信息是否正確。證書上都有包含這些信息,比較容易完成驗證。

    • 判斷證書來源是否合法。每份簽發證書都可以根據驗證鏈查找到對應的根證書,操作系統、瀏覽器會在本地存儲權威機構的根證書,利用本地根證書可以對對應機構簽發證書完成來源驗證。

    • 判斷證書是否被篡改。需要與 CA 服務器進行校驗。

    • 判斷證書是否已吊銷。通過 CRL(Certificate Revocation List 證書注銷列表)和 OCSP(Online Certificate Status Protocol 在線證書狀態協議)實現。

      其中 OCSP 可用於第 3 步中以減少與 CA 服務器的交互,提高驗證效率。

    以上任意一步都滿足的情況下瀏覽器才認為證書是合法的。

    這里有一個問題:既然證書是公開的,如果要發起中間人攻擊,我在官網上下載一份證書作為我的服務器證書,那客戶端肯定會認同這個證書是合法的,如何避免這種證書冒用的情況?

    其實這就是非加密對稱中公私鑰的用處,雖然中間人可以得到證書,但私鑰是無法獲取的。

    一份公鑰是不可能推算出其對應的私鑰,中間人即使拿到證書也無法偽裝成合法服務端,因為無法對客戶端傳入的加密數據進行解密。

image

  • 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證書后正常。

image

image

客戶端使用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;
    
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM