CentOS – HTTPS (HTTP + SSL + CA)

WordPress 的需求建議 https://wordpress.org/about/requirements/ 裡面有提到要使用 https ,所謂的 https 就是 http with SSL (Secure Sockets Layer) 或是 TLS (Transport Layer Security) 還要加上 CA.

先來了解一下什麼是 SSL (Secure Sockets Layer) ?
SSL (Secure Socket Layer) 是由 Netscape 所提出來的資料保密協定,採用了對稱式 ,One way hash 以及非對稱式加密演算法再加上 CA (Certification Authority) 來確定身份所組合而成的.

  • Symmetric Algorithms 對稱式加密,所謂的對稱式加密就是加密以及解密都是使用同一支鑰匙.
  • Asymmetric Algorithms 非對稱式或稱公鑰密碼演算法的一種.所謂的非對偁式加密會使用兩把公與私鑰 (Public / Private Key), public key 會當成加密用, Private key 就會當解密用
  • One Way Hashes 主要會產生一組固定長度字串 (fingerprint or message digests),這組字串用來比對原資料是否遭到修改.
  • CA (Certification Authority) 公正的第三者,主要用來驗證公鑰的真假.

剛剛的 SSL 是怎麼樣應用到 HTTP 協定上,變成 HTTPS 的.

使用者端有一支對稱式加密的鑰匙要給伺服器端,讓接下來的資料都經過加密的方式來傳送,但這隻鑰匙是無法直接透過網路來傳送,所以會使用非對稱式或稱公鑰的方式來傳送剛剛說的那一支對稱式加密的鑰匙.

另一個問題是使用者端也無法確定伺服器端的真假,所以會使用 CA (Certification Authority) 的方式來確認伺服器端的身份.

我們來看一下 HTPS (SSL) 的交易方式.

  1. 伺服器端會給使用者端 公鑰(用來加密使用者端的對稱式加密鑰匙) 與 數位簽名的憑證(身份確認).
  2. 使用者端接到數位簽名的憑證,會先去 Root CA 詢問資料是否真的由該網站所核發.
  3. 使用者端產生一支對稱式加密的鑰匙,並使用伺服器端的公鑰加密並回傳給伺服器端,伺服器端使用自己的私鑰解開還原使用者端給的對稱式加密鑰匙.
  4. 等到伺服器端,使用者端都有對稱式加密的鑰匙後,就使用這對稱式加密的鑰匙來進行接下來的資料傳送與交易.

那 TLS (Transport Layer Security) 是什麼呢!
IETF 將 SSL 標準化,並稱之為 TLS(Transport Layer Security)

測試環境為 CentOS 7 x86_64 + Apache2 (虛擬機) , 使用 Ubuntu 16.04 x86_64 + Apache2 請參考 – http://benjr.tw/96655

CentOS 6 方式也一樣,控制服務程式從 systemctl 改成 service 即可.

HTTP+PHP

先安裝 Web server 所需套件.

  1. Apache (Httpd)
    Web Server 可以自行選擇 Apache 或是 Nginx .下面使用的是 Apache

    [root@localhost ~]# yum install -y httpd
    
    [root@localhost ~]# systemctl enable httpd
    Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
    [root@localhost ~]# systemctl start httpd
    [root@localhost ~]# systemctl status httpd
    ● httpd.service - The Apache HTTP Server
       Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
       Active: active (running) since Fri 2017-07-21 12:03:23 CST; 5s ago
         Docs: man:httpd(8)
               man:apachectl(8)
     Main PID: 6418 (httpd)
       Status: "Processing requests..."
       CGroup: /system.slice/httpd.service
               ├─6418 /usr/sbin/httpd -DFOREGROUND
               ├─6419 /usr/sbin/httpd -DFOREGROUND
               ├─6420 /usr/sbin/httpd -DFOREGROUND
               ├─6421 /usr/sbin/httpd -DFOREGROUND
               ├─6422 /usr/sbin/httpd -DFOREGROUND
               └─6423 /usr/sbin/httpd -DFOREGROUND
    


    如果連不上請先確一下 Firewall 的狀態.

    [root@localhost ~]# systemctl stop firewalld
    
  2. PHP
    PHP 是一種直譯式的程式語言,用於網頁的撰寫,不同於靜態式的 HTML 它可以依據使用者的需求來呈現不同的網頁內容.

    [root@localhost ~]# yum install -y php php-pear php-mysql php-mbstring
    

    可以安裝 mcrypt 擴充套件,預設的 YUM Repo 並沒有這些套件,需要新增 Repo 檔 (epel-release, Extra Packages for Enterprise Linux) .

    [root@localhost ~]# yum install -y epel-release
    [root@localhost ~]# yum install -y php-mcrypt
    

    順便試一下 PHP 功能運作是否正常.你可以用自己喜歡的編輯器來鍵入下面的內容.

    [root@localhost ~]# vi /var/www/html/phpinfo.php
    <?php
    phpinfo();
    ?>
    
    [root@localhost ~]# systemctl restart httpd
    [root@localhost ~]# systemctl status httpd
    ● httpd.service - The Apache HTTP Server
       Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
       Active: active (running) since Fri 2017-07-21 14:54:28 CST; 1s ago
         Docs: man:httpd(8)
               man:apachectl(8)
      Process: 7072 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
     Main PID: 7078 (httpd)
       Status: "Processing requests..."
       CGroup: /system.slice/httpd.service
               ├─7078 /usr/sbin/httpd -DFOREGROUND
               ├─7080 /usr/sbin/httpd -DFOREGROUND
               ├─7081 /usr/sbin/httpd -DFOREGROUND
               ├─7082 /usr/sbin/httpd -DFOREGROUND
               ├─7083 /usr/sbin/httpd -DFOREGROUND
               └─7084 /usr/sbin/httpd -DFOREGROUND
    

    /var/www/html 是 Apache 預設的目錄,你可以修改 /etc/httpd/conf/httpd.conf 修改 DocumentRoot .
    這是 PHP 的格式,開啟你的網頁連上你 http://localhost/phpinfo.php ,如果一切運作正常那你會看到和下面一樣的網頁.

HTTPS

HTTPS 伺服器端需要 1. Root CA 給的 數位簽名憑證 與 2. 公私鑰非對偁式加密鑰匙 ,才能讓 http 伺服器端進行 SSL 加密 (需要 mod_ssl 模組).

[root@localhost ~]# yum install -y mod_ssl

建立 Root CA (Certification Authority)
如何獲得 Root CA (Certification Authority) 給的數位簽名憑證, 數位簽名憑證採用的是 X.509,是由上至下階層式的評證制度.Serer 必須付費給 Root CA 才能使用.

所以這邊簡單做個實驗,我們建立屬於自己的 Root CA 並發數位憑證給自己.因為不是公正的第三方,所以使用者端的瀏覽器需要使用者自行決定是否要信任這個網站.

要發數位憑證需產生一組公私鑰非對偁式加密鑰匙,檔案建議儲存路徑為 /etc/ssl/private ,並限制只有 root 能存取.

[root@localhost ~]# mkdir /etc/ssl/private
[root@localhost ~]# chmod 700 /etc/ssl/private

透過下面的指令可以產生 1. 發數位憑證所需產生一組 Private Key ,並產生 2. Certificate 的 CSR (憑證申請書) 與 CRT (憑證).

[root@localhost ~]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt

openssl 參數說明:

  • req -x509: Root CA (Certification Authority) 的數位簽名憑證採用的是 X.509 (由上至下階層式的評證制度).
  • -nodes: 產生的 apache-selfsigned.key 不使用 passphrase 作加密保護.
  • -days 365: 設定該 Certificate 有效期限.
  • -newkey rsa:2048: 產生新的 Certificate 所需的 Private Key (RSA 為非對稱式或稱公鑰密碼演算法,2048 為加密長度).
  • -keyout: 指定 Private key 檔案名稱與其存放位置.
  • -out: 指定 Certificate 檔案名稱與其檔案的存放位置,會產生 CSR (憑證申請書) 與 CRT (憑證).
Generating a 2048 bit RSA private key
............+++
....................................................................+++
writing new private key to '/etc/ssl/private/apache-selfsigned.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:TW
State or Province Name (full name) []:TAIWAN
Locality Name (eg, city) [Default City]:TAIPEI
Organization Name (eg, company) [Default Company Ltd]:Benjr
Organizational Unit Name (eg, section) []:Benjr
Common Name (eg, your name or your server's hostname) []:benjr.tw
Email Address []:admin@benjr.tw

依據網站內容填寫憑證申請書的內容.

  • Country Name (2 letter code) : 國家代碼,台灣是 TW
  • State or Province Name (full name) : 省份,你可以直接填台灣 TAIWAN
  • Locality Name (eg, city) : 城市名,你可以填台北 TAIPEI
  • Organization Name (eg, company) : 你的組織名稱,通常是公司,我這裡填的是 Benjr
  • Organizational Unit Name (eg, section) : 如果你剛填的是公司,那這就是公司部門的名稱 Benjr
  • Common Name (e.g. server FQDN or YOUR name) : 如果是伺服器憑證那就填上伺服器的全名 (benjr.tw) .若是 E-mail 憑證那就填上 E-mail.Root CA 填上組織名稱加上 RSA/2048 以供辨識.
  • Email Address :這裡請填上你的 e-mail 信箱

剛剛的指令做了三件事情.

  1. 製作 Root CA Private Key
    指令會產生 2048 bits 的 Private Key (RSA 為非對稱式或稱公鑰密碼演算法) ,名稱為 apache-selfsigned.key ,也可以單獨使用下面指令來產生.

    [root@localhost ~]# openssl genrsa -out /etc/ssl/private/apache-selfsigned.key 2048
    Generating RSA private key, 2048 bit long modulus
    .......................+++
    ..........................................................................+++
    e is 65537 (0x10001)
    

    建立私鑰後最好將權限加以設限,以免被其他使用者取用.

    [root@localhost ~]# chmod 400 /etc/ssl/private/apache-selfsigned.key
    

    你可以用下面的指令來看 RSA 產生的 Private Key 內容.

    [root@localhost ~]# openssl rsa -noout -text -in /etc/ssl/private/apache-selfsigned.key
    Private-Key: (2048 bit)modulus:
    略...
    publicExponent: 65537 (0x10001)
    privateExponent:
    略...
    prime1:
    略...
    prime2:
    略...
    exponent1:
    略...
    exponent2:
    略...
    coefficient:
    略...
    
  2. 填寫憑證申請書 (CSR)+ 3. 簽發憑證 (CRT)
    前面指令直接產生 apache-selfsigned.csr (憑證申請書) ,並立即簽發憑證給自己 apache-selfsigned.crt (憑證) 也可以單獨使用下面指令來產生.
    正常步驟是需要給 Root CA 做簽合.

    [root@localhost ~]# openssl req -new -key /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.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]:TW
    State or Province Name (full name) []:TAIWAN
    Locality Name (eg, city) [Default City]:TAIPEI
    Organization Name (eg, company) [Default Company Ltd]:Benjr
    Organizational Unit Name (eg, section) []:Benjr
    Common Name (eg, your name or your server's hostname) []:benjr.tw
    Email Address []:admin@benjr.tw
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    
    [root@localhost ~]# openssl x509 -req -days 365 -signkey /etc/ssl/private/apache-selfsigned.key -in /etc/ssl/certs/apache-selfsigned.csr -out /etc/ssl/certs/apache-selfsigned.crt
    Signature ok
    subject=/C=TW/ST=TAIWAN/L=TAIPEI/O=Benjr/OU=Benjr/CN=benjr.tw/emailAddress=admin@benjr.tw
    Getting Private key
    

    建立憑證後最好將權限加以設限,以免被其他使用者取用.

    [root@localhost ~]# chmod 400 /etc/ssl/certs/apache-selfsigned.crt
    

    可以用下面的指令來查看產生的 crt 憑證內容.

    [root@localhost ~]# openssl x509 -noout -text -in /etc/ssl/certs/apache-selfsigned.crt
    Certificate:
        Data:
            Version: 1 (0x0)
            Serial Number:
                8b:a9:05:f5:e5:ee:9d:77
        Signature Algorithm: sha256WithRSAEncryption
            Issuer: C=TW, ST=TAIWAN, L=TAIPEI, O=Benjr, OU=Benjr, CN=benjr.tw/emailAddress=admin@benjr.tw
            Validity
                Not Before: Aug 27 15:17:57 2019 GMT
                Not After : Aug 26 15:17:57 2020 GMT
            Subject: C=TW, ST=TAIWAN, L=TAIPEI, O=Benjr, OU=Benjr, CN=benjr.tw/emailAddress=admin@benjr.tw
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    Public-Key: (2048 bit)
                    Modulus:
                        00:ca:a5:09:02:cc:36:9d:a9:67:3c:f3:4b:38:9b:
    略... 
                    Exponent: 65537 (0x10001)
        Signature Algorithm: sha256WithRSAEncryption
             9f:b2:e0:b6:1b:f6:ff:0f:3a:b7:1a:62:92:15:9c:e4:d9:2c:
    略... 
    

    可以看到的他的內容包括下列的東西
    第一部分是要申請的憑證內容
    第二部分是 Public Key
    第三部分將剛才的內容(第一二部分)經過 on way hash (SHA1256) 所得到的訊息摘要 (Digest Hash) . 這可確定在傳送過程資料不會遭到修改.

編輯 Apache2 https 設定檔
修改 /etc/httpd/conf.d/ssl.conf 設定檔 <VirtualHost _default_:443> </VirtualHost> 中間的內容.

[root@localhost ~]# vi /etc/httpd/conf.d/ssl.conf
DocumentRoot "/var/www/html"
ServerName benjr.tw:443
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2019-08-27 23:25:07 CST; 4s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 3632 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 3636 (httpd)
   Status: "Processing requests..."
    Tasks: 6
   CGroup: /system.slice/httpd.service
           ├─3636 /usr/sbin/httpd -DFOREGROUND
           ├─3638 /usr/sbin/httpd -DFOREGROUND
           ├─3639 /usr/sbin/httpd -DFOREGROUND
           ├─3640 /usr/sbin/httpd -DFOREGROUND
           ├─3641 /usr/sbin/httpd -DFOREGROUND
           └─3642 /usr/sbin/httpd -DFOREGROUND

瀏覽 HTTPS 網頁
直接透過 wget 來試試,要加入 –no-check-certificate ,不然會出現錯誤訊息.

[root@localhost ~]# wget https://192.168.95.251/phpinfo.php
--2019-08-27 23:26:16--  https://192.168.95.251/phpinfo.php
Connecting to 192.168.95.251:443... connected.
ERROR: cannot verify 192.168.95.251's certificate, issued by '/C=TW/ST=TAIWAN/L=TAIPEI/O=Benjr/OU=Benjr/CN=benjr.tw/emailAddress=admin@benjr.tw':
  Self-signed certificate encountered.
    ERROR: certificate common name 'benjr.tw' doesn't match requested host name '192.168.95.251'.
To connect to 192.168.95.251 insecurely, use `--no-check-certificate'.
[root@localhost ~]# wget --no-check-certificate https://192.168.95.251/phpinfo.php
--2019-08-27 23:26:33--  https://192.168.95.251/phpinfo.php
Connecting to 192.168.95.251:443... connected.
WARNING: cannot verify 192.168.95.251's certificate, issued by '/C=TW/ST=TAIWAN/L=TAIPEI/O=Benjr/OU=Benjr/CN=benjr.tw/emailAddress=admin@benjr.tw':
  Self-signed certificate encountered.
    WARNING: certificate common name 'benjr.tw' doesn't match requested host name '192.168.95.251'.
HTTP request sent, awaiting response... 200 OK
Length: unspecified 
Saving to: 'phpinfo.php'

    [ <=>                                                           ] 59,448      --.-K/s   in 0s      

2019-08-27 23:26:33 (227 MB/s) - 'phpinfo.php' saved [59448]

也可以使用 https:// 來開啟網站,但會看到如下的畫面.

因為 Root CA 是自己(不是公正的第三方)而且並發數位憑證給自己,所以使用者端的瀏覽器需要使用者自行決定是否要信任這個網站.

在檢視憑證中可以看到我們剛剛設定 CA 的詳細資料.

清楚了 HTTPS 的架構後就可以正式找公正的第三方發數位憑證,大部分都需要收費, Let’s Encrypt 不收費但我也還沒使用過,請參考 https://free.com.tw/ssl-for-free/ 的說明.

沒有解決問題,試試搜尋本站其他內容

2 thoughts on “CentOS – HTTPS (HTTP + SSL + CA)

  1. ssl 流程 3 寫錯了吧。
    “伺服器端 使用私鑰將這對稱式加密的鑰匙加密傳送,使用者端再用公鑰將資料解密還原成原本的對稱式加密的鑰匙. ”
    這樣的話攔到公鑰的人都可以解密訊息。
    應該是使用者用公鑰加密, 而只有持有私鑰的 server 能解開。

發佈回覆給「gholk」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料