2015年9月2日 星期三

LNAMP 環境啟用支援 SSL 的 HTTPS 協定

LNAMP 環境啟用支援 SSL 的 HTTPS 協定

目前找到比較好的 LNAMP 整合並存 HTTP / HTTPS 存取 WordPress / Discuz 的方式:

1. Apache 當後台, 不做 SSL 相關設定, 只 Listen 來自 localhost 的 request, 避免使用者直接輸入 Apache port 來存取網頁
檔案: /etc/apache2/ports.conf
設定:
把 Listen 8080 設限只聽來自 localhost 的 request 如下:
Listen localhost:8080
該設定檔 SSL 的部份, 因為 Apache 的 SSL module 我們沒啟用所以不需要做任何更改。

2. 自行產生一組免費的 self-signed private key 與 public certificate key 來試用, 可先產生 private key 再產生 public key 或兩者一起產生, 範例如下:
$ sudo openssl genrsa -out privkey.pem 2048
$ sudo openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
或
$ sudo openssl req -x509 -nodes
     -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key 
     -out /etc/apache2/ssl/apache.crt -days 365 
3. Nginx 端啟用 HTTP/80, HTTPS/443 並存服務, proxy_pass 要 include 預設的 proxy_params 參數來 pass X-Forwarded-Proto 參數給後端的 Apache server
檔案: /etc/nginx/sites-available/default
增加協定:
    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        # 允許 HTTPS 連線
        listen 443 ssl;
        ssl_certificate         /etc/nginx/rex_ssl_key/cacert.pem;
        ssl_certificate_key     /etc/nginx/rex_ssl_key/privkey.pem;
4. 在 Apache 的 VirtualHost 的設定中加入以下指令
檔案: /etc/apache2/sites-available/000-default.conf
加入: SetEnvIf X-Forwarded-Proto https HTTPS=1
來告知 Apache 前端是不是由 HTTPS request 來的; 如果是的話就打開 HTTPS 參數, 讓 php 程序知道要用HTTPS方式處理。其中 X-Forwarded-Proto 是設定在 Nighx proxy_params 裡的, proxy_pass 時我們設定讓它一起傳給 Apache

5. WordPress 控制台設定的主網址使用 http:// 即可, 不用改為 https:// , 只需注意在控制台的頁面有些預覽的連結是直接參考主網址設定的協定, 如果在 HTTP 和 HTTPS 間切換會將登入狀態 reset; 而外部使用者在瀏覽頁面時不論是以 HTTP 連線或是 HTTPS 連線是完全沒問題的。
如此設定好後 WordPress 或 Discuz! 都可以使用 HTTP 或 HTTPS 來連線。
Discuz! 因為有緩存機制, 把協定直接寫進了緩存區, 所以對 HTTPS 的支援比較不完整, 在 HTTPS 模式下使用到 HTTP 模式產生的緩存位址該資源可能就無法讀取。不過目前看起來文章的撰寫和瀏覽是沒受到這些緩存資源影響的,可能是因為緩存的大多是靜態圖檔, 對於非安全協定存取的圖檔, 瀏覽器雖會警告但仍然會將它載入。再來有一些無法存取的 css 或 js 檔看起來是插件向站外存取的, 所以不影響 Discuz! 的基本功能。
我們目前使用的模式不需在 Apache 做 SSL 的相關設定, 不過這裡記錄一下 Apache 如何做 SSL 設定供日後有需求時可以參考:

SSL 支援在 Ubuntu 14.04 後的 Apache 已經是標準安裝, 只要啟用和重新啟動 Apache 即可:
$ sudo a2ensite default-ssl
$ sudo a2enmod ssl
$ sudo service apache2 restart
Apache 的 SSL 支援一樣要用到 certificate key pairs, 產生方式同本文前述。

Apache 的 SSL 支援設定範本在 /etc/apache2/sites-available/default-ssl.conf , 若要併用 HTTP 和 HTTPS 設定可將該設定檔下相關的設定複製到 /etc/apache2/sites-available/000-default.conf 中。 合併設定檔後就不需要也不能用 a2ensite default-ssl / a2dissite default-ssl 來開關 SSL 服務!

取消 Apache SSL 支援的指令:
$ sudo a2dismod ssl
$ sudo a2dissite default-ssl
$ sudo service apache2 restart

WordPress 在測試 HTTPS 期間遇到的一些問題和解法:

1. 為啥控制台設定主頁網址不用改 https:// 就可讓 http 或 https 兩者方式存取?
OK> 目前先假設 WordPress 內部運作是透過現用 Protocle + URI 而不是透過指定的 URL 來存取文章, 可暫時先忽略這個問題, 唯一的麻煩是點選 "造訪網頁" 或 "預覽修改" 的功能時, 都會切回主網頁設定的 Protocol 而不考慮現用的 Protocol !
有發現一件事: 站台設定為 http 連線時, 使用http連線, 所有連結都為 http 連結; 使用 https 連線, 除 "造訪網頁" 主網址和 "預覽修改" 都回切回設定的 protocol, 其他所有連結都會使用 https 連結; 如果站台設定為 https 連線, 則不論一開頭是用 http 或 https 連線的, 所有連結都會直接指定為 https 連結。
目前做 HTTP / HTTPS 並存測試時, 最佳設定主網頁的方式就是以 http 設定, 然後點選 "造訪網站" 或 "預覽修改" 時只做檢視, 不要再從中點選 Edit 或任何回控制台的連結, 避免不同 protocol 將登入的連線 reset!
以後只單開 HTTP 或 HTTPS 時 (若 HTTPS 沒問題應為首選) 就沒這個問題了!

2. 網頁會固定用 http 去找外部 googleapis 的字型, 造成當以 https 連線時這些字型會被禁用, 還要找方法解決!
OK> 要解決這個問題似乎要修改 WordPress 的 code! 目前這個字型影響不大先不管! 後來發現這是 theme 造成的不是 WordPress 本身的問題, 所以就當沒這個問題了!

3. 進入控制台時出現一個 theme 下的檔案找不到的問題, 猜測是 theme 本身的問題, 先不用管!
OK> 猜測是 theme 本身的問題, 先不用管!

4. 不使用 /wp/ 轉址會有無限回圈的問題!
OK> 原因是 WordPress 主頁下的 index.php 程式很堅持要透過主網站路徑來存取才可以, 例如 http://localhost/wp/ 這樣子, 連寫定 index.php 成 http://localhost/wp/index.php 也不允許, 也要強制他回轉回 http://localhost/wp/ 來隱藏式地讀取 index.php 執行! 所以 Nginx 只能將存取 WordPress 主網站目錄的任何需求立刻直接傳給 Apache 來處理, 讓 Apache 自己找到底下的 index.php 來用才不會有問題!

5. 使用固定網址時, 出現 apache 找不到檔案的 error, 看起來有點像編碼的問題, 要再查查!
OK> 確認和編碼無關, 估計又是 WordPress 的主頁堅持要用主頁目錄來存取, 例如 /wp/, 而不能加上 index.php 成 /wp/index.php, 遇到以 /wp/index.php 來開啟網頁就直接重導向 /wp/。把整個 WordPress 的 request 都丟給 Apache 在 Apache 那端開啟 Rewrite 功能就一切 OK 了!

6. 新的問題是: 東西全丟給 Apache 那 loading 都在 Apache 那邊, Nginx 不就沒作用了!
OK> 根據網上的資料已經找到 Nginx 中設定 Proxy cache 的方法!
Discuz! 在測試 HTTPS 期間遇到的一些問題和解法:

1. 有些網址寫定連至 8080 port, 將 Apache 設定為只能 localhost 存取會讓這些資源抓不到,處理目標還是看怎麼讓這些網址不要指定存取 8080 port 比較正向解決
NG> 好像 port 資料是 cache 在緩存中, 要想辦法怎麼讓產生的緩存檔不記 port 資料!

2. admin.php 網頁的存取問題, 為啥如果 Nginx 設定沒明指 servername 為 ip 的話, 一定要指定 8080 ports 才能使用
OK> 因為 Discuz! X3.2 的後台管理中心 admin.php 程序在處理過程中預設有做 IP 檢查, 不允需過程中有來源 IP 的切換, 若有 IP 切換就重來, 所以唯一的解決方法是修改 Discuz 根目錄下的 /config/config_global.php 程序, 關掉後台管理中心的 IP 檢查, 因為 Nginx 的 servername 如果設定為 localhost, 當以 Nginx 為 Entry 點來 proxy 給 Apache 時, IP 會輪流用 ipv4 及 ipv6 來嘗試, 造成 Apache 收到的 client IP 一下是 ::1, 一下是 127.0.0.1 造成 IP 不一致; 而以 Apache 為 Entry 點時, 因為 request 完全不經過 Nginx 所以 IP 不會變動沒有問題。
Discuz 設定檔: /config/config_global.php
$_config['admincp']['checkip'] = 1; 改為 = 0;
3. 因為在 LNAMP 中我們設定了禁止外部直接存取 Apache 服務, 而 admin.php 不透過 8080 port 又無法登入, 造成 admin 無法使用
OK> 2 的問題解決了, 3 就沒問題了!

沒有留言:

張貼留言