2018年10月26日 星期五

架設在Ubuntu14.04的XOOPS2.5.9網站,要改成HTTPS


SSL(Secure Sockets Layer),即安全通訊端層協定,傳輸層安全協定使用X.509認證,利用非對稱加密演算來對通訊方做身分認證,之後再交換對稱金鑰作為會談金鑰(Session key)。這個會談金鑰是用來將通訊兩方交換的資料做加密,保證兩個應用間通訊的保密性和可靠性,使客戶與伺服器應用之間的通訊不被攻擊者竊聽。(內容擷取自維基百科)

HTTPS(Hyper Text Transfer Protocol Secure,超文本傳輸安全協議),是一種透過電腦網路進行安全通訊的傳輸協定,在傳輸過程中,封包會受到加密保護,啟用SSL,才能使用HTTPS傳輸協定。

XOOPS是一套開放原始碼的內容管理系統,採用PHP語言跟MySQL資料庫。 模組化設計的功能與界面,便於建置網頁設計。XOOPS本身已經支援HTTPS協定,所以倘使伺服器主機已經將SSL服務設定好,XOOPS原則上就可以通過HTTPS協定瀏覽。

但並不是每件事情都是美好的,上面的訊息沒告訴我,假如我的XOOPS是以前架設的,而我如今想朝SSL協定、HTTPS協定靠攏,那我該怎麼辦呢?
也因為是以前的就架好的網站,瀏覽器網址列前總是出現「不安全」三個字,到底危不危險,我應該怎麼辦呢?

註1:不安全其實只是說網站沒有SSL憑證,傳輸封包時會以明碼傳遞。學校網頁又沒什麼機密資訊,明碼傳遞也沒差,但是當瀏覽器評斷你的網站不安全,就會讓有些人誤以為這個網站有病毒、有危險,總之就是不喜歡)。

我的學校網站是用XOOPS架設的,印象中是兩年前使用2.5.7版開始架設,後來經過幾次的升級改版,倘使這時候打掉重練,要通過SSL憑證驗證,是非常容易,但內容重製卻是非常辛苦的,所以我決定直接想辦法將HTTP的網站改造成HTTPS的網站,以符合SSL規範。

簡單分析一下可能會遇到的問題:

  1.  需要申請SSL及設定。
  2.  修改XOOPS主要設定檔mainfile.php的Schema資訊
  3.  修改XOOPS資料庫中自身網站的URI連結
  4.  處理混合式內容警告
  5.  強迫HTTP網址自動轉為 HTTPS
  6.  持續不斷的修正


一、申請SSL及設定

要將XOOPS設定為HTTPS連線,首先要先有可信任的SSL憑證,在這邊我是參考How To Secure Apache with Let's Encrypt on Ubuntu 14.04以及ET Wang的用certbot申請SSL,五分鐘搞定,申請了Let't Encrypt免費憑證,為什麼會選用Let't Encrypt的原因,主要是因為他申請非常容易簡單,此外它還有一個certbot機器人,只要執行這個機器人指令,他就會自動幫你把憑證延期。

了解這句話的意思嗎?一般來說,免費憑證通常都只有三個月的生命週期,期限到了,就必須還要展期或重新申請,這對我們這種懶人而言是件麻煩的差事,所以啦!如果有機器人可以代勞,我們只要把指令加入排程中,他就會替我們自動展期,但是還是要附帶一提,免費的憑證雖然可以幫你通過瀏覽器的SSL檢測,但是若是不幸發生封包傳輸過程中,加密被破解時,這些免費憑證公司也是免責的,你無法對這些免費憑證公司要求賠償或申訴,所以假如你的網站資料很重要、很機密,最好的做法還是花錢去申請公信力佳的憑證喔!

前提:

  • Ubuntu 14.04,以及擁有sudo能力的使用者
  • 要有完整的網域名稱

Setp 1 - 下載Let's Encrypt用戶端

想要將Let's Encrypt憑證安裝在主機上,前提是要安裝Certbot軟體,但因為他第三方軟體,所以要先將他寫入儲存庫中,才方便使用apt安裝與更新。

1.將第三方軟體certbot加入repository
sudo add-apt-repository ppa:certbot/certbot

2.更新
sudo apt-get update

3.安裝 python-certbot-apache
sudo apt-get install python-certbot-apache

Setp 2 - 設定SSL憑證

1. 設定SSL憑證、指定完整的網域、自動轉換一次搞定,只要一個指令,這過程中會問你一些問題,就請你自己回答吧,或者請你參考ET Wang的certbot申請SSL,五分鐘搞定說明。(紅字的地方,要改成你的完整網域)
sudo certbot --apache -d example.com

程式執行成功後,可以到以下網站檢測,SSL憑證是否已經啟用。(紅字的地方,要改成你的完整網域)
https://www.ssllabs.com/ssltest/analyze.html?d=example.com&latest

Setp 3 - Certbot自動更新

1.測試更新
sudo certbot renew --dry-run

2.寫入排程,每三個月更新一次憑證
0 0 * */3 * /root/certbot-auto renew --quiet


二、修改XOOPS主要設定檔mainfile.php的Schema資訊

當你上面的憑證設定完成後,基本上你若使用https://example.com,瀏覽你的網站時,你會發現版面是錯亂的,這主要問題是控制版面的css、js檔,被指定為http路徑,在目前的HTTPS狀況下這些css、js檔無法順利被讀取。

sudo vi /var/www/html/mainfile.php

大約20行左右,自動取得網址的副程式中
parse_url()函式中的http改成https
if(!function_exists('get_xoops_url')){
  function get_xoops_url(){
    $u=parse_url("https://".$_SERVER["HTTP_HOST"].$_SERVER['REQUEST_URI']);

註2:這地方其實有我所不解的地方,XOOPS另有一個判斷HTTPS的伺服器變數$_SERVER['HTTPS'],但是它卻為空,無法自動判斷。

三、修改XOOPS資料庫中自身網站的URI連結

修改到這裡,畫面會比較正常,但是許多的連結仍是http的,而這些URI連結是寫入在資料庫中,所以就參考以前寫的Xoops移機的步驟,把這些原本是http的網址改成https,在這裡因為會修改到資料庫,所以強烈建議:倒出來的sql檔,一定要備份再備份,避免難以回復的錯誤

先將舊機網頁停機,避免還有人透過網頁將資料寫入資料庫

1. sudo service apache2 stop

2.在舊機器上,利用mysqldump將資料備份出來

mysqldump  -uroot  -p  --default-character-set=utf8  xoops > /home/webadmin/xoops.sql

3.編輯資料庫備份檔,將舊IP取代為新IP

sudo vi /home/webadmin/xoops.sql
在vi模式下執行取代工作
格式
:1,$s/舊IP/新IP/s

執行以下的指令
:1,$s/http:\/\/www.dches.chc.edu.tw/https:\/\/www.dches.chc.edu.tw/g
:1,$s/http:\/\/163.23.112.196/https:\/\/163.23.112.196/g

註3:
紅字的地方請根據自己的狀況修改。這裡的「\/\/」這不是W(打不溜)喔!「\」是拖曳符號,後面接續著「/」,repeat兩次,,這樣才能正確解析出「\\」

4.在新機器上將資料庫備份檔匯入(前提是新機器已經裝了Xoops)

mysqladmin -uroot -p create xoops
mysql -uroot -p  xoops < /home/webadmin/xoops.sql

5.重啟Apache2

sudo service apache2 start

四、處理混合式內容警告

什麼是混合式內容呢?簡單來說,就是你的網頁中嵌入的圖片、iframe框架、css、js....等等,混雜了HTTP以及HTTPS鏈結兩種樣式,既然現在已改成SSL認證,傳統的HTTP練結是不被允許的,所以瀏覽器依舊不秀出鎖頭讓你輕鬆通過。

其實上面我們上面第二點、第三點修改mainfile.php以及修改資料庫的動作,主要就是在修改混合式內容警告的問題,但難免仍有漏網之魚,像是自己手動輸入網址的圖片或是自訂頁面的框架(例如iframe),有些不見得都有寫入資料庫中,這時就得手動尋找手動修正。

我遇到的狀況比較單純,只剩幾張圖片有混合式問題,我是利用FireFox火狐狸,在頁面上點選右鍵 /「檢視頁面資訊」/「媒體」,查看網頁中的圖片,有無http開頭的,如果有的話,就把它修正成HTTPS連結也可以檢視的狀態。

舉例來說:
我的網頁中有連結指定家庭教育中心的一張圖檔,我先試著把他的協定改成https://chc.xxx.xxx.xxx/img_helpline.png
看看他會不會正常顯示,如果該網站也有申請SSL憑證的話,這樣子的修正就正常顯示,但是假如該網站並沒有使用SSL認證,這樣的圖片鏈結指定當然是錯誤的,所以啦,要嘛就不要再連到那裡去,要嘛就乾脆把該圖片下載回到自己主機上,重設連結,但須要提醒的是,如果採用第二種做法,要注意智慧財產權的問題喔,因為你已經下載回來己用,公開散播囉!



五、強迫HTTP網址自動轉為 HTTPS

好了,花了這麼多時間修改,基本上已經OK了,但是別人如果還是輸入http://xxx.xxx.xxx要來瀏覽你的網站,基本上還是不安全的嘛,那你幹嘛還要花那麼多時間修改,所以只好放大絕了,修改主機的Apache設定,將凡是連結到80埠瀏覽網頁的,全導向443埠。
寫法很多種,有人說要寫到.htaccess,但是我比較偷懶,直接修改Apache虛擬站的000-default.conf就好了,這樣最快。而倘使你寫入的規則沒有執行,要嘛就是你的mod_rewrite模組沒有裝、要嘛沒有啟用,請參考[Rewrite note.] 重寫規則筆記這篇。


sudo vi /etc/apache2/sites-enabled/000-default.conf

在</VirtualHost>前的任一位置,寫上

▲寫法1: RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

或是
▲寫法2:RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

或是
▲寫法3:
Redirect permanent / https://www.dches.chc.edu.tw
如果上面的做法都不成,第三種做法是,只要是連到網站,強制導到https://www.dches.chc.edu.tw

註4:紅字的地方要改喔,不然就全導向我們學校了,第三種寫法其實有點小問題,還是建議先嘗試使用寫法1或寫法2

六、持續不斷地修正

沒有人可以跟你保證,經過上面的修正後一切都可以高枕無憂,上面介紹的方法,應該可以解決大部分的移轉問題,但接下來依舊要不斷地檢視網頁內容,尤其是網站分枝如果夠多,混合式內容警告還是有可能會出現,一旦出現,按上述方法持續不斷地修正喔!


參考網站:

2018年10月4日 星期四

常用的正規表示式

可以使用時機除了網頁的表單設計外,最近才發現原來Google表單可以這樣來使用

身分證的正規表示式
^[A-Z][0-9]{9}$

市話的正規表示式
例:04-7123456
^[0][2-9]{1,2}\-\d{6,7}$

西元格式的正規表示式
^[1-9][0-9]{3}\/[1]{0,1}[0-9]\/[123]{0,1}[0-9]$

^[1-9]\d{3}\/[1]?\d\/[123]?\d$

手機的正規表示式
例:0912-3456789
^[0][9]\d{2}\-\d{6}$

參考網頁: