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) 的交易方式.
- 伺服器端會給使用者端 公鑰(用來加密使用者端的對稱式加密鑰匙) 與 數位簽名的憑證(身份確認).
- 使用者端接到數位簽名的憑證,會先去 Root CA 詢問資料是否真的由該網站所核發.
- 使用者端產生一支對稱式加密的鑰匙,並使用伺服器端的公鑰加密並回傳給伺服器端,伺服器端使用自己的私鑰解開還原使用者端給的對稱式加密鑰匙.
- 等到伺服器端,使用者端都有對稱式加密的鑰匙後,就使用這對稱式加密的鑰匙來進行接下來的資料傳送與交易.
那 TLS (Transport Layer Security) 是什麼呢!
IETF 將 SSL 標準化,並稱之為 TLS(Transport Layer Security)
測試環境為 Ubuntu 16.04 x86_64 + Apache2 (虛擬機).使用 CentOS 7 x86_64 + Apache2 請參考 – https://benjr.tw/101894
HTTP+PHP
先安裝 Web server 所需套件.
- Apache2
Apache 是一種 Web Server ,和 Windows 的 IIS 是一樣的功能).root@ubuntu:~# apt-get update root@ubuntu:~# apt-get upgrade root@ubuntu:~# apt-get install apache2
root@ubuntu:~# systemctl status apache2 ● apache2.service - LSB: Apache2 web server Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled) Drop-In: /lib/systemd/system/apache2.service.d └─apache2-systemd.conf Active: active (running) since Thu 2017-11-30 17:07:26 PST; 1h 38min ago
透過 web browser 瀏覽器連上你 http://yourIP, 如果 httpd 能正確運作,那你可以看到內容如下面一樣的網頁.
- PHP
部分的 Web 程式主要透過 PHP 的程式語言架構出來的,而 PHP 是一種直譯式的程式語言,用於網頁的撰寫,不同於靜態式的 HTML 它可以依據使用者的需求來呈現不同的網頁內容.root@ubuntu:~# apt-get install php libapache2-mod-php php-mysql The following additional packages will be installed: libapache2-mod-php7.0 php-common php7.0 php7.0-cli php7.0-common php7.0-json php7.0-mysql php7.0-opcache php7.0-readline Suggested packages: php-pear The following NEW packages will be installed: libapache2-mod-php libapache2-mod-php7.0 php php-common php-mysql php7.0 php7.0-cli php7.0-common php7.0-json php7.0-mysql php7.0-opcache php7.0-readline 0 upgraded, 12 newly installed, 0 to remove and 3 not upgraded. Need to get 3,610 kB of archives.
Ubuntu 16.04 搭配的是 PHP7.
順便試一下 PHP 功能運作是否正常.你可以用自己喜歡的編輯器來鍵入下面的內容.
root@ubuntu:~# vi /var/www/html/phpinfo.php <?php phpinfo(); ?> root@ubuntu:~# systemctl restart apache2 root@ubuntu:~# systemctl status apache2 ● apache2.service - LSB: Apache2 web server Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled) Drop-In: /lib/systemd/system/apache2.service.d └─apache2-systemd.conf Active: active (running) since Mon 2017-10-23 23:26:18 PDT; 7s ago Docs: man:systemd-sysv-generator(8) Process: 9929 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS Process: 9954 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCE CGroup: /system.slice/apache2.service ├─9971 /usr/sbin/apache2 -k start ├─9974 /usr/sbin/apache2 -k start ├─9975 /usr/sbin/apache2 -k start ├─9976 /usr/sbin/apache2 -k start ├─9977 /usr/sbin/apache2 -k start └─9978 /usr/sbin/apache2 -k start
/var/www/html 是 Apache 預設的目錄,你可以修改 /etc/httpd/conf/httpd.conf 修改 DocumentRoot .
<?php phpinfo(); ?> 這是 PHP 的格式,開啟你的網頁連上你 http://yourIP/phpinfo.php ,如果一切運作正常那你會看到和下面一樣的網頁.
如果有遇到無法開啟或是開啟時有問題,可以在 Linux 下查看 Apache 的 log ( 位於 /var/log/apache2/error.log ) 找出問題點.root@ubuntu:~# cat /var/log/apache2/error.log
HTTPS
HTTPS 伺服器端需要 1. Root CA 給的 數位簽名憑證 與 2. 公私鑰非對偁式加密鑰匙,才能讓 http 伺服器端進行 SSL 加密.
建立 Root CA (Certification Authority)
如何獲得 Root CA (Certification Authority) 給的數位簽名憑證, 數位簽名憑證採用的是 X.509,是由上至下階層式的評證制度.Serer 必須付費給 Root CA 才能使用.
所以這邊簡單做個實驗,我們建立屬於自己的 Root CA 並發數位憑證給自己.因為不是公正的第三方,所以使用者端的瀏覽器需要使用者自行決定是否要信任這個網站.
要發數位憑證需產生一組 公私鑰非對偁式加密鑰匙 ,檔案建議儲存路徑為 /etc/ssl/private ,並限制只有 root 能存取.
[root@localhost ~]# chmod 700 /etc/ssl/private
透過下面的指令可以產生 1. 發數位憑證所需產生一組 Private Key ,並產生 2. Certificate 的 CSR (憑證申請書) 與 CRT (憑證).
root@ubuntu:~# openssl req -new -x509 -sha256 -days 365 -nodes -out /etc/ssl/certs/example.com.crt -keyout /etc/ssl/private/example.com.key
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/example.com.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) [AU]:TW State or Province Name (full name) [Some-State]:TAIWAN Locality Name (eg, city) []:Taipei Organization Name (eg, company) [Internet Widgits Pty Ltd]:Benjr Organizational Unit Name (eg, section) []:Benjr Common Name (e.g. server FQDN or YOUR name) []: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) : 如果你剛填的是公司,那這就是公司部門的名稱
- Common Name (e.g. server FQDN or YOUR name) : 如果是伺服器憑證那就填上伺服器的全名(benjr.tw) .若是 E-mail 憑證那就填上 E-mail.Root CA 填上組織名稱加上 RSA/2048 以供辨識.
- Email Address :這裡請填上你的 e-mail 信箱
剛剛的指令做了三件事情.
- 製作 Root CA Private Key
指令會產生 2048 bits 的 Private Key (RSA 為非對稱式或稱公鑰密碼演算法) ,名稱為 example.com.key ,也可以單獨使用下面指令來產生.root@ubuntu:~# openssl genrsa -out /etc/ssl/private/example.com.key 2048
建立私鑰後最好將權限加以設限,以免被其他使用者取用.
root@ubuntu:~# chmod 400 /etc/ssl/private/example.com.key
你可以用下面的指令來看 RSA 產生的 Private Key 內容.
root@ubuntu:~# openssl rsa -noout -text -in /etc/ssl/private/example.com.key Private-Key: (2048 bit) modulus: 略... publicExponent: 65537 (0x10001) privateExponent: 略... prime1: 略... prime2: 略... exponent1: 略... exponent2: 略... coefficient: 略...
- 填寫憑證申請書 (CSR)+ 3. 簽發憑證 (CRT)
前面指令直接產生 example.com.csr (憑證申請書) ,並立即簽發憑證給自己 example.com.crt (憑證) 也可以單獨使用下面指令來產生.
正常步驟是需要給 Root CA 做簽合.root@ubuntu:~# openssl req -new -key /etc/ssl/private/example.com.key -out /etc/ssl/certs/example.com.csr
root@ubuntu:~# openssl x509 -req -days 365 -signkey /etc/ssl/private/example.com.key -in /etc/ssl/certs/example.com.csr -out /etc/ssl/certs/example.com.crt
建立憑證後最好將權限加以設限,以免被其他使用者取用.
root@ubuntu:~# chmod 400 /etc/ssl/certs/example.com.crt
可以用下面的指令來查看產生的 crt 憑證內容.
root@ubuntu:~# openssl x509 -noout -text -in /etc/ssl/certs/example.com.crt Certificate: Data: Version: 3 (0x2) Serial Number: 15367654869432319015 (0xd544e0aeb350bc27) Signature Algorithm: sha256WithRSAEncryption Issuer: C=TW, ST=TAIWAN, L=Taipei, O=Benjr, OU=Benjr, CN=benjr.tw/emailAddress=admin@benjr.tw Validity Not Before: Oct 18 01:44:07 2017 GMT Not After : Oct 18 01:44:07 2018 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: 略... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 略... X509v3 Authority Key Identifier: 略... X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha256WithRSAEncryption 略...
可以看到的他的內容包括下列的東西
第一部分是要申請的憑證內容
第二部分是 Public Key
第三部分將剛才的內容(第一二部分)經過 on way hash (SHA256) 所得到的訊息摘要 (Digest Hash).這可確定在傳送過程資料不會遭到修改.
編輯 Apache2 https 設定檔
在 /etc/apache2/sites-available/000-default.conf 設定檔 <VirtualHost *:80> </VirtualHost> 後面加入以下的內容.
root@ubuntu:~# vi /etc/apache2/sites-available/000-default.conf <VirtualHost *:443> SSLEngine On # SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt SSLCertificateFile /etc/ssl/certs/example.com.crt # SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key SSLCertificateKeyFile /etc/ssl/private/example.com.key DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
root@ubuntu:~# a2enmod ssl Considering dependency setenvif for ssl: Module setenvif already enabled Considering dependency mime for ssl: Module mime already enabled Considering dependency socache_shmcb for ssl: Enabling module socache_shmcb. Enabling module ssl. See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates. To activate the new configuration, you need to run: service apache2 restart root@ubuntu:~# systemctl restart apache2 root@ubuntu:~# systemctl status apache2 ● apache2.service - LSB: Apache2 web server Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled) Drop-In: /lib/systemd/system/apache2.service.d └─apache2-systemd.conf Active: active (running) since Mon 2019-08-26 20:07:01 PDT; 7s ago Docs: man:systemd-sysv-generator(8) Process: 12113 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS) Process: 12140 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS) CGroup: /system.slice/apache2.service ├─12155 /usr/sbin/apache2 -k start ├─12158 /usr/sbin/apache2 -k start ├─12159 /usr/sbin/apache2 -k start ├─12160 /usr/sbin/apache2 -k start ├─12161 /usr/sbin/apache2 -k start └─12162 /usr/sbin/apache2 -k start
瀏覽 HTTPS 網頁
直接透過 wget 來試試,要加入 –no-check-certificate ,不然會出現錯誤訊息.
root@ubuntu:~# wget https://192.168.95.219/index.html --2019-08-26 18:40:48-- https://192.168.95.219/index.html Connecting to 192.168.95.219:443... connected. ERROR: cannot verify 192.168.95.219's certificate, issued by ‘emailAddress=admin@astl.com,CN=ASTL,OU=ASTL,O=ASTL,L=TAIPEI,ST=TAIWAN,C=TW’: Self-signed certificate encountered. ERROR: certificate common name ‘ASTL’ doesn't match requested host name ‘192.168.95.219’. To connect to 192.168.95.219 insecurely, use `--no-check-certificate'.
root@ubuntu:~# wget --no-check-certificate https://192.168.95.219/index.html --2019-08-26 18:41:19-- https://192.168.95.219/index.html Connecting to 192.168.95.219:443... connected. WARNING: cannot verify 192.168.95.219's certificate, issued by ‘emailAddress=admin@astl.com,CN=ASTL,OU=ASTL,O=ASTL,L=TAIPEI,ST=TAIWAN,C=TW’: Self-signed certificate encountered. WARNING: certificate common name ‘ASTL’ doesn't match requested host name ‘192.168.95.219’. HTTP request sent, awaiting response... 200 OK Length: 11321 (11K) [text/html] Saving to: ‘index.html’ index.html 100%[===================>] 11.06K --.-KB/s in 0s 2019-08-26 18:41:19 (94.5 MB/s) - ‘index.html’ saved [11321/11321]
也可以使用 https:// 來開啟網站,但會看到如下的畫面.
因為 Root CA 是自己(不是公正的第三方)而且並發數位憑證給自己,所以使用者端的瀏覽器需要使用者自行決定是否要信任這個網站.
清楚了 HTTPS 的架構後就可以正式找公正的第三方發數位憑證,大部分都需要收費, Let’s Encrypt 不收費但我也還沒使用過,請參考 https://free.com.tw/ssl-for-free/ 的說明.