:::

在 PHP 使用 YUI Compressor 壓縮 JavaScript 跟 CSS

在 PHP 使用 YUI Compressor 壓縮 JavaScript 跟 CSS

2011-11-14_232832 yui logo

我在寫程式的時候,習慣搭配程式註解一併撰寫。寫JavaScript就搭配JSDoc,寫CSS就搭配CSSDoc,寫著寫著程式碼就會非常非常地龐大,造成使用者每次都要下載過大的檔案內容而效率緩慢。

YUI是一套開放原始碼的JavaScript與CSS框架,以BSD授權條款開放使用。它其中一個相當知名的功能是JavaScript與CSS的壓縮器(compressor)。這篇是要教你如何在PHP的環境中使用YUI Compressor來壓縮JavaScript與CSS。


安裝配置

由於這篇的目的是使用PHP作為開發環境,相信你已經有了一個運作PHP的環境。我自己的測試環境是以XAMPP 1.7.0架設,使用PHP 5.2.8。

首先,你要準備一個資料夾,用來擺放YUI Compressor與相關檔案。

再來將以下檔案下載到該資料夾中:

安裝Java

由於YUI Compressor使用Java,你必須確保你的環境中安裝了JDK才行。請到Java網站下載Java Platform (JDK),他有提供Windows與Linux各種版本。

然而我在CentOS作業系統中安裝JDK 7u1時不知為何地失敗了,所以我又回頭去裝了JDK 6u12。

下載之後,請調整該檔案的權限為755,然後執行該檔案。舉例來說指令如下:

[root@dspace ~]# chmod 755 jdk-6u12-linux-i586-rpm.bin
[root@dspace ~]# ./jdk-6u12-linux-i586-rpm.bin

如要確認Java能夠使用,請輸入以下指令並可能會看到如下訊息:(可能是因為我先裝7u1失敗的關係,以下版本顯示的是7u1而不是6u12)

[root@dspace ~]# java -version
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) Client VM (build 21.1-b02, mixed mode)

這樣就完成配置囉。


壓縮使用

使用YUI Compressor時,要先引用Minify_YUICompressor.php,然後透過它的靜態方法minifyJs()跟minifyCss()來輸入要壓縮的程式碼,並取得壓縮過後的程式碼。

以下是minifyJs跟minifyCss的用法:

/**
* Minify a Javascript string
*
* @param string $js
*
* @param array $options (verbose is ignored)
*
* @see http://www.julienlecomte.net/yuicompressor/README
*
* @return string
*/
public static function minifyJs($js, $options = array())

/**
* Minify a CSS string
*
* @param string $css
*
* @param array $options (verbose is ignored)
*
* @see http://www.julienlecomte.net/yuicompressor/README
*
* @return string
*/
public static function minifyCss($css, $options = array())

使用範例

為了讓大家更容易理解如何使用,請下載以下兩個範例檔案到上述Minify_YUICompressor.php跟yuicompressor-2.4.6.jar的同一個資料夾中。

我們先看一下blogger-template.css的原始碼,這是一個沒有經過壓縮的CSS程式,大概長得像下面這樣子,程式碼大小為19.9KB:

2011-11-14_232059 blogger-template.css

然後我們再透過minifyCss.php看一下壓縮過的樣子,壓縮過後程式碼大小為13.4KB,足足有67.3%的壓縮率:

2011-11-14_232133 minifyCss.php

以下是minifyCss.php的程式碼內容。這裡面包括了在HTTP標頭輸出為CSS格式的指令,以協助瀏覽器正確判斷資料內容。

<?php
header('Content-type: text/css', TRUE);

include("Minify_YUICompressor.php");
$script = file_get_contents("blogger-template.css");
$packed = Minify_YUICompressor::minifyCss($script);
echo $packed;

而JavaScript也是以此類推,以下是minifyJs.php壓縮JavaScript的標頭輸出與壓縮寫法:

<?php
header('Content-type: text/javascript', TRUE);

include("Minify_YUICompressor.php");
$script = file_get_contents("puliBloggerDigest.js");
$packed = Minify_YUICompressor::minifyJs($script);
echo $packed;


致謝與修改過程

YUI Compressor雖然一般是要透過Java以指令列的方式運作,不過多虧了minify專案開發了Minify_YUICompressor.php,讓我們得以輕易地以PHP使用YUI Compressor。

然而由於原本的Minify_YUICompressor.php需要將YUI Compressor跟暫存目錄指定為絕對路徑,我覺得不是很好用,所以將暫存目錄改為系統自訂的暫存目錄、YUI Compreesor改為跟Minify_YUICompressor.php相同的目錄,讓我們只要把兩個檔案擺在一起就能夠使用。這樣在程式碼轉移的時候特別方便,例如將PHP系統從Windows轉移到Linux的時候。

結語:最好搭配快取機制一起使用

YUI Compressor的壓縮功能雖然挺好用的,搭配上Minify程式之後就更容易讓PHP取用,但是運作效率卻有待堪慮。我在Windows環境中請YUI Compressor壓縮1MB左右的JavaScript的時候,通常會延遲個3秒鐘左右才完成。儘管這是因為我檔案太大的關係,但是如果太過頻繁的壓縮,恐怕仍會帶來效率上的問題。

我建議在使用YUI Compressor的時候,同時搭配一些快取機制(cache),將YUI Compressor的壓縮結果另存為一個靜態的JavaScript或CSS程式碼。下次就能讓系統直接讀取壓縮結果,而不需要經過YUI Compressor的壓縮。

(more...)

SSH資安防護建議

布丁布丁吃布丁

SSH資安防護建議

ssh

圖片來源:SSH tunnels for the common man (and woman)

SSH是Linux常用的通訊協定。儘管它是一種加密式的通訊協定,但是其實它很容易被用各種方法來取得進入的權限。為了提高SSH的安全性,我提出三層額外的SSH防護措施,以避免Linux直接暴露在網際網路的危險之中。


SSH簡介

SSH是Secure SHell protocol(安全的殼程式協定)的簡寫,他是一種封包加密技術,以確保封包在網路傳輸中不會因為中途竊取、監聽而暴露重要資料。SSH在Linux作業系統中已經被視為遠端操作用的基本工具,現在已經幾乎沒人在用telnet來操作Linux,除了BBS之外。詳細內容可以參考維基百科鳥哥的Linux私房菜的介紹。

然而,即使SSH已經是加密過的通訊協定,只要有心人士知道你的IP(用ping就可以抓到,或是各種方法都能知道你的伺服器IP)、連接埠(預設是22,或用連接埠掃描工具就知道)、帳號(預設是root)、密碼(透過暴力破解法猜測而得),那麼任何人依然可以輕易地登入你的主機、植入木馬、讓你的伺服器成為殭屍電腦

由於我們這邊常常有電腦遭駭客鎖定、攻擊,所以我思考了很多SSH防護的對策。以下介紹我目前的SSH三層防護措施:1. 防火牆設置白名單、2. 更改預設登入與連線方式、3. fail2ban。這三層的作法中,做完第一層就能達到一定程度的保護。如果不甚安心,或是無法限定白名單的話,那麼再進行第二層跟第三層的設定即可。


第一層:防火牆設置白名單

2011-11-14_171102 zentyal whitelist - mask

防火牆中的白名單(whitelist)是指較嚴謹的防護方式。只有白名單中IP範圍的電腦才能允許連線,否則全部都不能連線。

如果你所在網路中有架設防火牆統一管理,那麼可以請網路管理員幫忙設定。上圖是Zentyal防火牆套裝軟體的設定畫面,在這邊我將來源範圍設定為140.119.61.0/24,代表只有140.119.61.0~140.119.61.254這些IP範圍內的電腦才能連線,其他電腦都會被擋下來。

如果你沒有類似的防火牆伺服器,那麼也可以在Linux中使用iptables防火牆套件來配置。關於iptables請見我另一篇的說明,像是在iptables.allow的設定中加入以下設定:

iptables -A INPUT -i $EXTIF -s 140.119.61.0/255.255.255.0 -j ACCEPT #允許140.119.61.*的電腦連入

不過,當你不確定哪些電腦可以連入,譬如時常要從特定區域外面的網路中連回到Linux伺服器時,這種白名單就很難掌控。你有兩種作法可以作為應變:

  1. 準備一台白名單內的個人電腦,常常是公司內部的個人工作站,再透過該工作站連到Linux伺服器。
  2. 放棄使用白名單,僅做以下第二層與第三層的防護設定。

當然,我還是會建議你用第一種作法,而不是放棄白名單。

第二層:修改預設登入與連線方式

許多Linux安裝好之後,都會預設開放SSH(連接埠22),並允許root連線登入。所以駭客只要偵測到該IP開放22連接埠提供SSH服務,就可以用root帳號跟暴力破解法猜測密碼來登入。Ubuntu在這點做得不錯,它預設是關閉SSH,更不允許使用者用root直接登入。不過還是很多人打開了SSH連線,結果一樣很容易讓駭客進行暴力破解法猜測。

為了避免直接被猜測預設帳號與連線方式的方法,我提供以下幾個建議:

1. 新增另一個擁有root權限的帳號

為了避免直接被以root帳號猜測登入,我們要先準備另一個帳號,並給予他root般的權限,以方便進行伺服器管理。

Linux新增帳號的指令為useradd,然後再用passwd給予密碼。詳細操作請看鳥哥的帳號管理說明。舉例來說,我現在要以pudding作為另一個管理者帳號,作法如下:

[root@ipfire ~]# useradd pudding
[root@ipfire ~]# passwd pudding
Changing password for pudding
Enter the new password (minimum of 5, maximum of 127 characters)
Please use a combination of upper and lower case letters and numbers.
New password:
Re-enter new password:
Password changed.
[root@ipfire ~]#

接著修改帳號的uid,將之設為0,表示同等於root帳號。修改uid的位置在「/etc/passwd」檔案,打開該檔案之後,有一條設定將會是剛剛新增的帳號。舉例來說,剛剛新增的pudding帳號,其設定如下:

pudding:x:1001:1001::/home/pudding:

將這設定中的uid改成0,結果如下:(注意紅字的部份)

pudding:x:0:1001::/home/pudding:

關於「/etc/passwd」的詳細內容,請參考鳥哥的說明

2. 設定SSH,阻止root登入

SSH的設定檔預設位於「/etc/ssh/sshd_config」檔案中。

要阻止root帳號登入的話,則是在設定檔最後加上一條設定:(注意大小寫不同)

DenyUsers root

儲存之後,重新啟動SSH。之後SSH就不准給root登入了。

不使用PermitRootLogin no的理由

必須要說明的是,在此不使用大部分教學主張的「PermitRootLogin no」設定。這是因為該設定會一併擋掉前面建立的帳號,讓他無法登入。

如果是指令操作的話,還可以用su root換成root帳號。但是像是SFTP的操作就不能用su root切換,因此乾脆還是用擁有root權限的帳號比較方便。

3. 修改SSH連接埠

同樣是在「/etc/ssh/sshd_config」檔案中。

找到「Port 22」的設定,並將之改為其他的連接埠。舉例來說,如果要設定為透過64022來連接SSH的話,那就是改為「Port 64022」。

image

儲存之後,重新啟動SSH。之後SSH必須透過64022登入了。

弱點仍是暴力破解法

很遺憾的是,第二層作法只能防君子不能防小人。駭客依然可以透過掃描工具掃描伺服器連接埠,找到你修改後的SSH連接埠號碼,然後透過暴力破解法,猜測你的帳號與密碼組合。

具體來說,SSH雖然預設限制每次連線都只能嘗試登入5次,但是只要撰寫程式機器人,就可以不斷重複進行SSH並嘗試猜測帳號與密碼。這種程式並不難寫,可是卻很難防禦。為了阻止暴力破解法,你還需要第三層的防護:fail2ban。

第三層:fail2ban 限制登入失敗次數

fail2ban是Linux的一個套件,它會根據記錄檔來判斷使用者登入失敗的次數,來決定是否要阻止該使用者再次嘗試登入。舉例來說,你可以設定嘗試登入次數最高3次,超過次數之後必須等待1小時才能再登入。這樣駭客就很難用暴力破解法猜測你的密碼,因為他用錯誤的方式猜測,一天最多也能猜測24*3=72組帳號密碼而已。

關於fail2ban的安裝與設定方式,請參考我另一篇教學


結語

之前我這邊發生一件事情。我們同事平常用他工作用電腦連上Linux伺服器操作,然而他工作用電腦因為沒有定時更新防毒軟體,導致駭客入侵、成為殭屍電腦,一併感染了Linux伺服器。在這個案例中,第一層防護因為同事電腦位於白名單內而沒有效用,第二層與第三層防護,也因為同事電腦的帳號密碼直接被側錄,而跟著毫無效用。

同事的電腦不更新防毒軟體(實際上是已經過期了,卻又不更新授權),連帶導致的問題,讓計畫團隊足足有半個月沒有任何進度,而是在重灌伺服器跟修補漏洞。

這件事情告訴我們,任何角落都可能成為資安的漏洞來源,怎樣都擋不完。

不過,實際上也不要這麼悲觀。平時定期更新防毒軟體(免費的防毒軟體例如小紅傘Avira AntiVir PersonalAVG Anti-Virus FREE都不錯用)、架設伺服器時設定一下SSH的連線,將資訊安全當成常識一樣看待,將可以大幅降低駭客入侵的可能性。

(more...)

GLPI新增文件類型

布丁布丁吃布丁

GLPI新增文件類型

image

GLPI中上傳檔案時,會受到GLPI的文件類型管理限制。如果是未設定過的特殊文件類型,那上傳會失敗。這篇是講如何在GLPI 0.80.2中新增文件類型的方法。


1. 進入文件類型頁面

image

位置在「主頁 >設定 > 下拉列表」中,選擇「管理 文件類型」,再按下搜尋,就會進入文件類型的設定頁面。

2. 新增文件類型

image

新增文件類型的按鈕是上面導覽列的「+」。非常難發現,這是我覺得GLPI難以使用的缺點之一,雖然習慣就好。

image

接著進入「文件類型-建立」頁面。你可以輸入以下資料:

  • 名稱
  • 圖標(圖示)
  • 授權下載
  • 擴展名(副檔名的意思)
  • MIMIE類型
  • 備註說明

確定之後,按下「新增」按鈕就完成新增文件類型的動作。之後就可以用你設定的文件類型來上傳檔案了。


如果你使用GLPI的問題是檔案大小過大(預設是2MB),那必須調整php.ini的環境設定才行。關於放寬檔案大小設定的方法,請看我另一篇的說明。

(more...)

用JSON加快JavaScript的搜尋速度

用JSON加快JavaScript的搜尋速度

image

(圖片來源:ICON FINDER)

最近在寫JavaScript程式,在這邊跟大家分享一些程式撰寫的小技巧。JavaScript在網頁應用中通常是作為客戶端的應用程式,而JavaScript的運作速度時常取決於客戶端使用的瀏覽器與電腦效能。要執行複雜的JavaScript運算時,使用Google Chrome跟使用Internet Explorer (簡稱IE,特別是6以下)會有相當驚人的差距。

最近發現我的程式在IE上的瓶頸卡在「搜尋速度」上。如果修過資料結構的同學一定知道,資料結構最常探討的問題就是「搜尋」。提高搜尋速度有很多已知的方法,平常撰寫時通常只會實作最簡單但也是最沒效率的循序演算法(sequential search),而這也就是執行效率的瓶頸。然而多虧JavaScript的特殊資料結構JSON,我們也可以犧牲一些記憶體空間來換取非常快的執行速度,實作雜湊搜尋法(Hash Search)

以下就簡單介紹一下這些方法的差別。


低效率搜尋:循序演算法

現在我想要做一個函式(function),它會要求輸入一個字,並確認這個字是否是大寫英文,輸出「true」或「false」。

陣列版本

簡單一點的作法,我們可以用陣列(array)來實作:

/**
* 檢查一個字是否是英文大寫。(陣列搜尋版本)
* @param String _word 要檢查的字
* @return boolean 是英文,或不是英文
*/
function is_english_by_array(_word) {
var _english_list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];

for (var _i in _english_list)
{
if (_word == _english_list[_i])
return true;
}
return false;
}

alert(is_english_by_array('Z'));

這是很直覺的寫法,要比對的資料組成一個陣列資料集,然後再一一比對。雖然看起來有點冗長,效率也不高。

正規表示法版本

聰明一點的人會用正規表示法(Regular Expression)來作字串的搜尋,以下是改用正規表示法的寫法:

/**
* 檢查一個字是否是英文大寫。(正規表示法版本)
* @param String _word 要檢查的字
* @return boolean 是英文,或不是英文
*/
function is_english_by_reg(_word) {
var _reg = /^([A-Z])$/;
return _reg.test(_word);
}

alert(is_english_by_reg('Z'));

看起來簡潔多了。但其實正規表示法的效率極差,這樣子的搜尋速度並不會快到哪裡去。

JSON與雜湊演算法

自從學會使用JSON之後,我就愛上了這種特殊的資料格式,特別是用在雜湊演算法的時候實在是很方便。

JSON介紹

以下引用維基百科對JSON的介紹

JSON(Javascript Object Notation)是一種輕量級的資料交換語言,以文字為基礎,且易於讓人閱讀。

JSON用於描述數據結構,有以下形式存在。

  • 物件 (object):一個物件以「{」開始,並以「}」結束。一個物件包含一系列非排序的名稱/值對,每個名稱/值對之間使用「,」分割。
  • 名稱/值對(collection):名稱和值之間使用「:」隔開,一般的形式是:
{name:value}

一個名稱是一個字串; 一個值可以是一個字串,一個數值,一個物件,一個布林值,一個有序列表,或者一個null值。

  • 值的有序列表(Array):一個或者多個值用「,」分割後,使用「[」,「]」括起來就形成了這樣的列表,形如:
[collection, collection]

  • 字串:以""括起來的一串字元。
  • 數值:一系列0-9的數位組合,可以為負數或者小數。還可以用「e」或者「E」表示為指數形式。
  • 布林值:表示為 true 或者 false。
雜湊搜尋法

用JSON實作雜湊搜尋法的方式,跟上面用陣列來實作的方式有點像:他們一樣是要準備一個可供搜尋的資料集,只是資料結構的方式完全不同。

以下是用JSON實作的雜湊搜尋法:

/**
* 檢查一個字是否是英文大寫。(JSON版本)
* @param String _word 要檢查的字
* @return boolean 是英文,或不是英文
*/
function is_english_by_json(_word) {
var _english_list = {'A':1,'B':1,'C':1,'D':1,'E':1,'F':1,'G':1,'H':1,'I':1,'J':1,'K':1,'L':1,'M':1,'N':1,'O':1,'P':1,'Q':1,'R':1,'S':1,'T':1,'U':1,'V':1,'W':1,'X':1,'Y':1,'Z':1};
return (typeof(_english_list[_word])=="number");
}

alert(is_english_by_json('Z'));

跟陣列把要比對的資料放在「值」(value)的方式不同,雜湊法中要比對的資料是放在「名稱」(name)當中。因此一旦用typeof()確認資料集中是否有該名稱時,就能夠知道搜尋的結果。

至於資料集中的值為何是用1?其實在此問題中用什麼值是無所謂,因為我只要確認該_word是否在待比對資料集裡面就好了。


結語

寫JavaScript實在是很有趣。

傳統在教資料結構時,大多是用C或Java在做教學。然而由於語言先天上的限制,像是強型別(Strong Type)、僅有基本的資料型態等等的特性,在實作資料結構與演算法時,其實是需要非常多步驟。對於JavaScript來說,既有JSON這個萬用的資料結構,也可以把function當做是資料型態,因此寫起程式來可說是非常靈活。

然而不僅僅只是在客戶端的應用,現在也越來越多人把JavaScript拿到伺服器端來使用,稱之為Server-side JavaScript (SSJS),目前相當知名應用之一就是Node.js

相信未來JavaScript會更加蓬勃發展,大家一起加油吧。

(more...)

jQuery動態載入CKEditor注意事項

jQuery動態載入CKEditor注意事項

image

最近在寫標註工具的API,完成之前沒有好好做的載入器(loader),目標是要讓人用一行程式碼就能載入全部需要的工具。

在我做的KALS標註工具當中使用到了CKEditor,而要讓他與jQuery搭配,則需要額外載入一個調配器(adapters)。但是傳統的用法都是在<head>寫<script>標籤,這跟我要的動態載入不太一樣。

在四處碰壁嘗試之後,終於找到了正確的作法。在此做個筆記。


不可用的方法

由於我是要在網頁讀取完之後才開始動態載入,因此不能用document.write,否則會洗掉整個網頁。

原本我也想利用DOM建立<script>標籤,內含src屬性載入CKEditor,插入<head>當中,但卻發現這個插入的<script>標籤並不會執行,簡單來說就是沒有效果。

後來改用jQuery的getScript()方法,就能夠確實地讀取並執行CKEditor。不過仍有其他細節需要注意,以下說明。

正確的方法

正確的作法是:

  1. 建立<script src=”[CKEditor的網址]”></script>貼到<head>之中,供CKEditor本身去搜尋連結,自動載入其他檔案。
  2. 以jQuery.getScript()載入並執行CKEditor。
  3. 先載入CKEditor主程式,再載入調配器。

以下是簡單的範例程式碼:

//在這之前,你已經確認載入了jQuery

//路徑宣告
var _ckeditor_url = "/ckeditor/ckeditor.js";
var _adapters_url = "/ckeditor/adapters/jquery.js";

//載入函式
var _load_lib = function (_url, _callback) {
var _script_tag = $('<script type="text/javascript" src="' + _url + '"></script>');
_script_tag.appendTo($('head'));

$.getScript(_url, function () {
if (typeof(_callback) == 'function')
_callback();
});
};

//開始載入
_load_lib(_ckeditor_url, function () {
_load_lib(_adapters_url, function () {

//你接下來要做的其他程式

});
});

這是截自KALS載入器的部分程式,並沒有經過測試。有任何錯誤,請提醒我再檢查、修正。

(more...)

Proxmox VE建立虛擬區域網路 (VLAN) 方案 (3) 操作說明

Proxmox VE建立虛擬區域網路 (VLAN) 方案 (3) 操作說明

proxmox_logo 3 excute

終於來到了Proxmox VE虛擬區域網路方案的最後一篇。這一篇是介紹每建立一台虛擬機器時所需要的設定。儘管大部分的設定都在前一篇環境配置中設定完了,不過每一台虛擬機器還是需要手動設定不少參數。這邊也會介紹如何使用反向代理伺服器連接FQDN跟虛擬機器喔。

Proxmox VE建立虛擬區域網路(VLAN)方案目錄:

  1. 方案說明
  2. 環境配置
  3. 操作說明

1. 建立虛擬機器的網路設定

好,講了老半天,我們終於要在Proxmox VE建立虛擬機器了。登入Proxmox VE管理介面的網址是「https://192.168.11.13」,注意是https,而不是http。

由於它的介面已經很容易操作了,在此我就不再一步一步講述,只講需要注意的重點。

1-1. 建立虛擬機器

2011-10-24_155244 create vm - draw

  • 虛擬機器類型(Type):OpenVZ
  • 虛擬機器樣板(Template):Joomla! Content Management    debian-6.0-joomla_1.6-3_i386.tar.gz
  • 網路類型(Network Type):Brdged Ethernet (veth)
  • First DNS Server:140.119.1.110

最重要的是網路類型必須為veth,本篇不使用venet。其他的參數則就視你的需求做調整。

2011-10-22_001631 Open VNC console

建立好之後,就把這台虛擬機器開起來吧。進入主控台的位置在Open VNC console,如上圖。

1-2. 虛擬機器網路設定

這邊的網路設定必須要透過Proxmox VE的VNC console進入虛擬機器的指令列模式設定。

因為每一種Linux發行版的網路設定都不大相同,這邊介紹的是Debian。其實RedHat系的Linux發行版設定起來也差不多,可以參考使用CentOS的鳥哥教學

1-2-1. 編輯設定檔

請用vi修改/etc/network/interfaces 網路配置檔:

vi /etc/network/interfaces

因為目前還沒辦法連上網路安裝vim,所以只好先用vi。

預設的網路配置檔幾乎什麼都沒有設定,所以是無法連線到網際網路的。

設定網路的方式有兩種:DHCP與靜態網路,請選用其中一種來配置。

1-2-2a. 網路模式:DHCP

如果只是暫時要連到網際網路,而不需要讓網際網路的電腦連線至虛擬機器、讓它提供服務的話,你可以採用DHCP的配置方式。

請在網路配置檔加上以下設定:

auto eth0
iface eth0 inet dhcp
1-2-2b. 網路模式:靜態網路

如果是要對網際網路的電腦提供服務的虛擬機器,請使用靜態網路配置。配置如下:

auto eth0
iface eth0 inet static
address 10.10.10.1
netmask 255.255.255.0
gateway 10.10.10.254

設定時必須指定區域網路IP,在此使用10.10.10.1。同一個區域網路裡面不能有相同的IP,因此你可能需要另外的管理方法來確保IP之間不會相互衝突。

2011-10-24_161511 notes

我通常會將虛擬機器的區域網路IP跟FQDN資訊寫在Notes中,如上圖。

1-2-3. 重新啟動網路

請輸入以下指令以重新啟動網路:

/etc/init.d/networking restart

如果沒有錯誤訊息的話,那應該就是順利設定完成了。

1-2-4. 測試網路連線

你可以用最常見的ping指令,測試看看虛擬機器能不能連到Google:

ping www.google.com

如果順利的話,你可以看到以下畫面:

2011-10-22_012750 ping google

確認沒問題之後,按Ctrl + c取消ping指令。

如果網路順利接通的話,你就可以順便安裝vim,指令為:

apt-get install vim

到此為止,虛擬機器連到網際網路已經沒有問題了。但是反過來,若要網際網路的電腦能夠連到虛擬機器,那還需要其他的設定。以下繼續介紹。


2. Proxmox VE 網路路由設定

接下來我們要想辦法讓網際網路的電腦能夠連上虛擬機器。而這之間的橋接者,就是Proxmox VE了。

讓虛擬機器提供服務的方式有許多種,在此要介紹的是透過連接埠轉遞(port forwarding)跟反向代理伺服器(reverse proxy)的方法。

2-1. 網路設定規劃

在設定之前,有必要先釐清預期的網路設定。以下介紹中,我要讓人能夠連線到架設Joomla的虛擬機器。該虛擬機器是以靜態網路配置,區域網路IP為10.10.10.1。Joomla是走HTTP服務,連接埠80,在此設定Proxmox VE時,我規劃以31080連接埠轉遞到他的80連接埠;我們也希望能夠以SSH管理虛擬機器,SSH的連接埠為22,在此設定Proxmox VE時,我規劃以31022連接埠轉遞到他的22連接埠。但我們只希望特定的IP範圍能夠使用SSH連線到虛擬機器,範圍是192.168.11.0/24,也就是僅給192.168.11.0到192.168.11.254的IP連線。關於IP與子網路遮照的表示法,請參考Wikipedia的子網路介紹

此外,我們也設置了一個FQDN「joomla.example.com」,希望能夠讓網際網路的電腦透過此FQDN連線到虛擬機器。設定FQDN一般需要借助你網路環境中的DNS Server幫忙,或是你也可以修改自己電腦的hosts檔案,暫時加入IP與FQDN的對應表,以方便測試。Windows的hosts檔案位於C:\Windows\System32\drivers\etc\hosts,詳細請參考Wikipedia的介紹

2-2. 連接埠轉遞 (port forwarding)

簡單來說,我們要設定兩套連接埠轉遞的規則:(Proxmox VE表示實體機器,Joomla表示虛擬機器)

  • Proxmox VE:31080 –> Joomla:80
  • Proxmox VE:31022 –> Joomla:22

連到Proxmox VE的31080連接埠,就等於連到Joomla虛擬機器的80連接埠,提供HTTP服務;連到Proxmox VE的31022連接埠,就等於連到虛擬機器的22連接埠,提供SSH服務。其中第二套規則要加上來源IP的限制。

至於31080跟31022的設定,只是我自己的管理規劃。要用哪個連接埠並沒有特別技術上的限制,只要不要跟Proxmox使用的連接埠443衝突即可。

這些動作可以使用Webmin的Linux Firewall模組來進行,以下一一介紹。

2-2-1. 進入Linux Firewall模組的NAT設定

2011-10-22_013619 linux firewall - draw

請先登入Webmin,然後從左邊導覽列進入 Networking > Linux Firewall模組。然後點選Showing IPtable: Network address translation (nat),以進入NAT的設定頁面。

2-2-2. 新增規則

2011-10-24_170421 Linux Firewall Add Rule

我們要設定的規則是屬於Packets before routing (PREROUTING,封包被路由前的規則)鏈,請在PREROUTING右下角找到「Add Rule」進入新增。

2011-10-24_170816 Add Rule - HTTP 

剛進去的時候可能會被他繁雜的選項嚇到。別擔心,一步一步照著我以下的介紹來設定吧。

2-2-3. 新增HTTP的規則

2011-10-24_170816 Add Rule - HTTP - draw

首先先新增HTTP的連接埠轉遞。以下是要設定的欄位與建議參數,我將參數以粗體顯示。

Chain and action details的部份:

  • Rule comment: Joomla HTTP
  • Action to take: Destination NAT
  • IPs and ports for DNAT
    • IP range: 10.10.10.1 to 10.10.10.1
    • Port range: 80 to 80

Condition details的部份:

  • Destination address or network: Equals 192.168.11.13/32
  • Incoming interface: Equals eth0
  • Network protocal: Equals TCP
  • Destination TCP or UDP port: Equals Port(s) 31080

然後按左下角的「Create」按鈕,完成規則的建立。

2-2-4. 新增SSH的規則

接著新增SSH的連接埠轉遞。以下是要設定的欄位與建議參數,我將參數以粗體顯示。

Chain and action details的部份:

  • Rule comment: Joomla SSH
  • Action to take: Destination NAT
  • IPs and ports for DNAT
    • IP range: 10.10.10.1 to 10.10.10.1
    • Port range: 22 to 22

Condition details的部份:

  • Source address or network: Equals 192.168.11.0/24
  • Destination address or network: Equals 192.168.11.13/32
  • Incoming interface: Equals eth0
  • Network protocal: Equals TCP
  • Destination TCP or UDP port: Equals Port(s) 31022

跟HTTP規則相比,SSH規則多加了來源位置的限制,如上面紅字所示。然後按左下角的「Create」按鈕,完成規則的建立。

2-2-5. 套用設定

2011-10-24_172556 Firewall Apply Configuration

在Linux Firewall模組底下,按下「Apply Configuration」按鈕,套用上述設定即可。

2-3. 反向代理伺服器 (reverse proxy)

設定反向代理伺服器之後,就能夠用FQDN:joomla.example.com連到Joomla虛擬機器。

反向代理伺服器Pound的設定必須靠SSH連入Proxmox VE的指令列模式來操作。步驟很簡單,敘述如下:

2-3-1. 編輯設定檔

請以vim編輯/etc/pound/pound.cfg:

vim /etc/pound/pound.cfg

在設定檔最後加入以下設定:

ListenHTTP
Address 192.168.11.13
Port 80
Service
HeadRequire "Host: joomla.example.com.*"
BackEnd
Address 10.10.10.1
Port 80
End
End
End

你可以注意到,首先要設定Proxmox VE的IP、連接埠80;封包對象的FQDN網址規則「joomla.example.com.*」,表示是以「joomla.example.com」開頭的網址;以及要傳遞到區域網路的虛擬機器IP:10.10.10.1與連接埠80。

2-3-2. 重新啟動Pound與測試

重新啟動的指令如下:

/etc/init.d/pound restart

如果沒有任何錯誤訊息的話,那就是設定成功了。

你可以試著從自己電腦的瀏覽器打開「http://joomla.example.com/」順利的話就會出現以下畫面:

2011-10-24_203502 joomla.example.com

看到Joomla網站的話就大功告成啦!


結語

經由上述的方法,就能夠以一台伺服器、一個對外IP,架設起Proxmox VE環境。他可以讓虛擬機器處於一個區域網路中,並透過連接埠轉遞跟反向代理伺服器提供服務。儘管操作上是沒有VirtualBox這麼簡單,但是防火牆設定、反向代理伺服器等功能較符合網管的需求。

讓我覺得遺憾的是,Webmin還是太過複雜,儘管許多名詞已經註明,但是光看名詞也很難理解所有功能的意義。因此在操作的時候請務必多多參考鳥哥的Linux私房菜,不要冒然猜測設定參數的意義。

我本來是希望能找到能夠安裝在Debian,簡單易懂的防火牆設定工具。但是大多數防火牆工具都是像Zentyal這種套裝的系統,而不是讓人簡單安裝在Debian、並提供網頁服務的工具。

另一個方法是用KVM虛擬機器安裝獨立的防火牆系統,不過我目前缺少具備VT-x / AMD-V的伺服器,因此實際上我還沒用過KVM的功能。原本我在VMware ESXi的時候的確做過這樣的設定,但是這要耗掉兩個對外IP:VMware ESXi伺服器、以及防火牆伺服器。不過如果照上述的方法來設定的話,應該會有更簡單的作法才是。我簡單的規劃草圖如下,不過這樣的規劃究竟是否可行,也得等未來有機器之後再繼續研究吧。

Proxmox VE結合防火牆套件建構虛擬區域網路 

關於反向代理伺服器選擇Pound的理由。網路上常見以Apache跟Squid這兩套工具來做反向代理伺服器,但是他們在設定上相較於Pound複雜很多。不過Pound並沒有快取功能,他純粹是封包轉遞、負載平衡而已。請端看你的需求選擇反向代理伺服器。

話說回來,光是寫這篇就花掉我好幾天,能寫到結語真是太令人感動了。有時候精神不佳寫起來不是很清楚,或是有筆誤的地方,請不吝糾正,感謝。

總之,還有許多要研究的議題,這次就先走到這邊即可。未來還有進一步的研究發現,我會在上來跟大家分享。一起加油吧。

(more...)

Proxmox VE建立虛擬區域網路 (VLAN) 方案 (2) 環境配置

Proxmox VE建立虛擬區域網路 (VLAN) 方案 (2) 環境配置

proxmox_logo 2 configuration

繼前一篇講方案說明之後,這一篇則是講Proxmox VE的環境配置。基本上這些配置只要做一次,之後建立虛擬機器時就不用重複再做。步驟有點複雜,如果有講錯的地方,請不吝指正。

Proxmox VE建立虛擬區域網路(VLAN)方案目錄:

  1. 方案說明
  2. 環境配置
  3. 操作說明

1. 安裝Proxmox VE

Proxmox VE是採空機安裝的方式,你可以從官方網站下載ISO光碟映像檔,燒錄成CD光碟,然後就可以像是安裝一般作業系統一樣地安裝Proxmox VE。為了測試方便,我是安裝在VirtualBox 4.1.0虛擬機器中。

安裝過程中,他會要你配置網路與root管理者密碼。網路的部份,本文配置的IP為192.168.11.13。

本文是用Proxmox VE 1.8-60版安裝,不過目前Proxmox VE已經出到1.9版。變更功能並不大。

安裝完之後可以看到以下登入畫面,請用root跟剛剛設定的密碼來登入吧。

2011-10-24_203537 vm

2. 安裝vim編輯器

在確認網路能夠正常連線之後,我會習慣先安裝vim編輯器,以取代Proxmox VE原本的vi編輯器。安裝的指令為

apt-get install vim

image

關於vim的操作方式,請參考鳥哥的Linux私房菜

3. 網路卡設定調整成NAT模式

安裝Proxmox VE時,它會要求你設定網路。這個設定是寫入在/etc/network/interfaces檔案中,預設的內容如下:

auto lo
iface lo inet loopback

auto vmbr0
iface vmbr0 inet static
address 192.168.11.13
netmask 255.255.255.0
gateway 192.168.11.1
bridge_ports eth0
bridge_stp off
bridge_fd 0

你應該可以輕易發現到該檔案的address、netmask、gateway的參數都是在安裝Proxmox VE的過程中輸入的資料。為了避免之後修改發生錯誤,請先備份/etc/network/interfaces檔案

為了要讓Proxmox VE具備NAT的網路功能,我們要把eth0實體網路卡跟虛擬交換器vmbr0分開設定。設定參考自Proxmox VE的說明,具體設定細節如下:

# network interface settings
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.11.13
netmask 255.255.255.0
gateway 192.168.11.1
post-up echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
post-up iptables-restore < /etc/iptables.up.rules #Webmin的Firewall的設定

auto vmbr0
iface vmbr0 inet static
address 10.10.10.254
netmask 255.255.255.0
bridge_ports none
bridge_stp off
bridge_fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o eth0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o eth0 -j MASQUERAD

eth0配置IP為192.168.11.13,而vmbr0則配置成不同網段,設IP為10.10.10.254。這兩者不同的網路裝置之間是以iptables傳遞封包,vmbr0接收或送出到的封包都會轉給eth0。

eth0最後一行iptables-restore設定是Webmin加上去的,稍後會繼續說明。

整個網路設定完之後,不能只靠/etc/init.d/networking restart重新啟動就能生效,必須要將整個Proxmox VE重新開機才行。

附帶說明的是,這些設定並不會影響網路類型是venet的虛擬機器,請安心。

4. Webmin安裝

儘管SSH指令列操作可以完成大部分的功能,但我個人仍希望有簡單易用的網頁介面作為管理網路與防火牆的工具。

image

在本文中使用的是知名的Linux伺服器管理工具Webmin。Proxmox VE的作業系統為Debian,安裝方式可以參考Installing on Debian的說明

簡單來說,步驟如下:

  1. wget http://prdownloads.sourceforge.net/webadmin/webmin-1.570_all.deb
  2. apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python
  3. dpkg --install webmin_1.570_all.deb

順利的話,就能夠看到Webmin安裝完成的訊息。

如果webmin-1.570_all.deb已經不能下載,那也可以下載我傳到SkyDrive的備份。SkyDrive無法用wget直接連線,請以網頁下載之後,再上傳到Proxmox VE吧。

5. 進入Webmin

image

安裝完成之後,就能夠以https://192.168.11.13:10000/進入Webmin的管理介面。登入帳號與密碼如同Proxmox VE的使用者,你可以用預設的root使用者與之前設定的密碼來登入Webmin。

image

一開始常常會被他複雜的功能弄得不知所措。不過並不是所有功能都需要學習,本文主要是關注在Firewall防火牆與DHCP伺服器這兩個功能。以下一一說明要使用的功能。

6. 安裝Webmin模組

Webmin安裝完預設只有基本功能,如果要其他的功能,則必須安裝模組(module)。

2011-10-21_235306 webmin modules - draw

安裝Webmin模組的位置在左側導覽列 > Webmin > Webmin Configuration > Webmin Modules,如上圖。

2011-10-21_235815 install - draw

以下的模組是要從www.webmin.com下載。請選擇Install from Standard module from www.webmin.com ,然後再按右邊「…」按鈕開啟選單。

接著請安裝以下模組。

7. 安裝firewall模組

firewall模組是用iptables設定Linux的防火牆,能夠編輯所有的表格(table)、鏈(chain)、規則(rule)與選項(option)。

上面網路卡設定NAT模式時也使用了iptables,iptables可說是非常強大、靈活的防火牆工具。然而也由於他太複雜的,光靠指令操作實在難以管理,因此我才希望仰賴Webmin透過網頁管理。

關於iptables的功能,可以參考鳥哥的介紹。之後也會有詳細的介紹。

8. 安裝dhcpd模組

dhcpd模組是管理分享的網路(network)、子網路(subnet)與ISC DHCPS群組的工具。

安裝dhcpd模組時,因為Proxmox VE並沒有安裝dhcpd-server,所以Webmin會顯示提示,並指引你一起安裝dhcpd-server3。所有操作都是在網頁端進行,一下子就完成。我也對Webmin的高整合性感到相當的驚艷。

關於dhcpd-server的功能,一樣可以參考鳥哥的DHCP伺服器介紹。下一節則會講述如何從Webmin設定。

9. 設定DHCP Server

安裝完dhcpd模組之後,我們就可以馬上來設定DHCP Server,以便之後提供虛擬機器DHCP服務。

9-1. 進入DHCP Server設定

 2011-10-22_002932 enter dhcp server - draw

DHCP Server可從左邊導覽列 > Servers > DHCP Server進入。首先,我們先來Add a new subnet (新增子網域)。

9-2. 新增子網域 Create Subnet

image

在Create Subnet中,我們要設定的參數主要有四項,其他都用預設值即可:

  • Subnet description: vlan
  • Network address: 10.10.10.0
  • Netmask: 255.255.255.0
  • Address ranges: 10.10.10.101- 10.10.10.200

Subnet description任意名稱皆可,而Address ranges表示這個子網域的電腦可以從10.10.10.101分配到10.10.10.200,可提供100臺伺服器。根據OpenVZ的介紹來看,一臺配備良好的Proxmox VE應該可以架設100臺提供Apache靜態網頁的伺服器。

至於為何IP是從10.10.10.101開始呢?那是因為10.10.10.1到10.10.10.100是留給靜態分配IP的伺服器使用,而使用DHCP服務的伺服器則是用101後面的IP。

這部份都可以自行規劃。

9-3. 編輯預設路由器與DNS伺服器

新增完子網域之後,接著還要編輯子網域中各個客戶端(client)的選項。請編輯剛剛新增的子網域,並按下面的「Edit Client Option」按鈕進入編輯客戶端選項介面中。

2011-10-24_150759 Client Options

在這邊要編輯的只有兩個選項:

  • Default routers: 10.10.10.254
  • DNS Servers: 140.119.1.110

這邊的路由器(router)是指虛擬交換器vmbr0,也是負責與外面網際網路交接的閘道(gateway)。DNS Servers則是配置你所在網路環境的DNS伺服器即可。由於我在政大網路中,DNS就是配置140.119.1.110。

接著按「Save」一路回到DHCP Server管理模組。

9-4. 選擇網路介面 Edti Network Interface

在DHCP Server模組下面,請點「Edit Network Interface」按鈕進入編輯網路介面的畫面。

2011-10-22_013156 dhcp listen

在此我們只針對連接到vmbr0的客戶端提供DHCP服務。請選擇vmbr0,然後按下「Save」儲存。

9-5. 套用變更 Apply Changes

在DHCP Server模組下面,請點選「Apply Changes」按鈕以套用剛剛的設定。

10. 安裝Pound

為了提供反向代理伺服器(reverse proxy)的功能,在此我使用的是Pound。以下介紹安裝前注意事項、安裝方式、設定方式。

10-1. 關閉Apache2的80連接埠

由於Proxmox VE網頁管理介面的Apache2伺服器佔用了80連接埠,這會導致Pound無法使用80連接埠做反向代理伺服器,因此在此要先調整Apache2伺服器的設定。

請編輯/etc/apache2/port.conf,並將「Listen 80」設定註解掉,改成「#Listen 80」。僅保留「Listen 443」就好。

由於Proxmox VE的管理介面本來就是用443連接埠以https提供服務,所以80連接埠不使用也無所謂。

10-2. 安裝Pound

安裝Pound的指令為:

apt-get install pound

沒意外的話應該可以順利安裝完成。不過安裝的時候他會提示你要設定Pound,否則無法順利運作。

10-3. 設定Pound自動啟動

請編輯/etc/default/pound,設定「startup=1」。

10-4. 重新啟動Pound

指令為:

/etc/init.d/pound restart

沒有任何錯誤訊息的話,就代表設定成功。

當然,這樣子還不算是完成,這只是基本環境配置而已。下一篇建立虛擬機器時,會介紹如何設定一個FQDN,並透過Pound轉遞到虛擬機器,讓虛擬機器提供服務。

11. 重新開機

上述設定完成之後,接著是把Proxmox VE重新開機,以便讓所有設定確實生效(特別是網路的部份)。

重新啟動的指令為「reboot」。

如果順利重新啟動的話,那Proxmox VE的環境配置就差不多完成囉。

(more...)