台中辦公室施工兩三事

這半年來事情太多了,公事忙,家裡事情也忙,看到了 Dropbox 裡去年在台中辦公室施工時的幾張照片,留言做個記錄好了

從裝修中的台中辦公室看出來,景觀很棒,據說是台中市數一數二貴的地段,但是和台北市地段普通的辦公室比起來,還是便宜了些,哈哈

台中辦公室景觀

因為有其它會議的關係,我不是第一天就來這邊,這天早上到現場時 I大 和 R哥 正坐在工地裡"施工",這間其實是台中辦公室的會議室,旁邊那些一箱一箱的東西就是我們的傢斯,裡面有網購訂來的手推車、工具箱,燦坤買的 Sony 電視用來做視訊會議用的,事先請托運弄下去的 SSG-140 和 server (記得是舊的 2950),Wifi AP… 由於台中辦公室還沒有同仁上班,大門在白天施工期間也沒門禁,師傅在忙大概也不太方便幫我們看東西,所以這些東西都得要協調好在 I大, R哥 下去的第一天就到齊,然後兩位自然是早早來,晚晚走,走時順便鎖門了。我還記得 I大 很不放心那台 Polycom 500 用托運的下去,畢竟小小一台要價二十幾萬呀,所以他自己抱著坐高鐵下去。

IR 連線

這天先到的中華電信 “使用說明" ,話說台灣辦公室可以申請這種有固定 IP 的光世代真是省錢啊,一個月不用兩張小朋友就有 60M/20M 加上 6 個固定 IP,在新加坡的辦公室就不能申請這類他們所謂「家用型」的費率,這種價錢如果拿去 IDC 租國內頻寬的話,連 2Mbps/月 都租不到哩。當然這類的光世代因為有集縮比,所以拿來架站是不實際的,但是放辦公室給同事上上網查資料,收個信或開個視訊會議,完全是綽綽有餘的。況且我們對辦公室的慣例是一次申請兩間固網的線路來做備援,算是相對省錢又安心的作法。

光世代

中間發生了一件小插曲,這間辦公室的大樓提供了很多地插給我們用,我個人還蠻喜歡地插這種設計的,只是… 這個地插好像和我之前用過的不一樣說,帶來的延長線頭插不進去,真尷尬,後來還特別交代台中要買延長線時要特別小心。

地插

Server room 留的空間有點小,計畫中這裡是暫時不放 MIS 人員的,以後就算有也是負責維護辦公室 PC/NB 這類設備,所有的主要伺服器還是放台北,所以原本的 19″ 標準機櫃改成了開放式機櫃,水電師傅原本還不太懂什麼叫開放式機櫃,照我們台北的圖上面插滿線他好像也看不太出來,後來去拍賣上找了張示意圖給他,最後就弄來了這座。這種開放式機櫃自然是指能上 Switch, Router 這類的 1U 輕設備,也當成是集中式線槽面板用,伺服器顯然是上不去的,那… 剛剛地上還說有台 2950 ?  最後就是放地上了,倒是我們的工頭很貼心的在這裡專門留了個冷氣孔,所以這間是很冷的,雖然我記得當初是請他不用留冷氣孔的,原本我們也只打算放 PC 當 server 用,既然有冷氣了就把淘汰下來的 2950 搬一台來用了。

開放式機櫃

這張被我手指檔到了,給大家看一下地上那堆從辦公室各處網路接孔收攏來的 Cat5e 最後都要打在這個開放式機櫃上。

打上 Pannel 前的線路

認真的師傅最帥氣,要刷這種 Idea Paint 似乎要多道工序,跑了 Scrum,上了看板之後,現在公司的同仁都還蠻喜歡畫白板了,老闆就多弄幾處 Idea Paint 讓大家畫個爽

油漆師傅

半成品的走道,地上又看到一堆網路線,等等它們可是都要收到地板下的,過兩天地毯也是會再蓋上去。其實這已經是完工前的三四天吧,大概就叫做術業有專攻吧,我也沒想到現在看似亂糟糟的工地過幾天後就變得漂漂亮亮的了。

半成品走道

台中辦公室有間頗有設計感的會議室,想來設計師應該是想把它做成立體玻璃櫥窗的感覺,但是放這轉角處害我轉彎小小的撞倒了,辦公室啟用後這裡就放了座明顯的盆栽,也算是在設計與實用間做了取捨。

玻璃櫥窗

廣告

讓你的 SSL 更安全 – 移除弱 SSL 加密方式 (Cipher)

SSL安全性如何強化,含括了當前流行的各種伺服器的設定方式,包括IIS, Apache, F5 Load balancer, A10 等

SSL 通訊協定下,一開始 Client 與 Server 進行 Handshake 時,彼此會「溝通」有哪些加密方式是彼此都支援的,然後約定好稍後傳輸資料的加密方式。會使用哪一種加密方式和我們買的 SSL 憑證的價格並沒有絕對直接的關係,既使你買的是一年價值 TWD 35,000 的 VeriSign Secure Site with EV,也可能因為設定的緣故而導致於只用到 40 bits 的加密方式。

由於硬體的處理能力逐年的提升,舊加密方式的安全性會相對的變得容易破解,所以新的及更高規格的加密方式就不斷的被開發出來。但是一來是因為新的加密方式推出之後不一定所有的廠商都支援,另外有些舊規格的硬體也許無法負擔較高規格加密方式的運算需求,既使是沒有以上兩種限制,但光從實務面上,我們也很難要求世界上所有 Client 與 Server 都可以隨時更新到最新的版本。所以一般來說,就只會建議禁用那些特別弱或已經證實可被破解的加密方式。而一個好的系統管理員,或有在重視網站安全性的公司,就會定期去檢驗所管理網站上的弱安全性加密方式是否已經被禁用了,畢竟一旦當客戶上了我們的網站,若因為 SSL 加密方式太弱而讓客戶的機密資訊外洩,損失的也是我們自己。不過很可惜的是,台灣有許多的網站並不太注重這件事情,我不太清楚原因為何?不過老實說,就算是我們用了這些所謂的弱 SSL 加密方式,想要側錄並進行破解還是得有一定的配合條件,一般的駭客或木馬想來應該寧願把功夫先花在那些未加密的連線或是 Key strokes 的側錄,而非花功夫去破解這些已經加密過後的東西。

只是身為一個知名網站的管理者,為了避免駭客針對性的攻擊,我們還是得用 100 分的標準來看待這件事情,以台灣的網站來看,我們利用 Qualys Labs 所提供的免費檢測工具,檢查了幾個國內的知名網站:

知名遊戲網站 1:
01

知名遊戲網站 2:
02

知名電信公司 1:
03

知名電信公司 2:
04

知名網購:
05

若以該網站的統計數據來看,拿到 B 的網站是最大宗的,第二名反倒是拿到 F 的網站,由於這是個英文網站,測試的標的應該來自於全世界各地,可見得就算是把這個標準放在全世界來看,拿到 A 級分的網站比例也是不高的。 (2016/11/28 更新,截至目前為止,拿到 A 的比例已經是最高的了,SSL Labs 測試的樣本中,有 48.3% 的網站都可以拿到 A 以上)

06

其實拿到 B 也不表示這個網站不夠安全,讓我們來看看這個分數的組成定義,首先是 Certificate ,從以上的例子來看,這個項目的分數大家都是拿 100,表示大家的 SSL 憑證都沒有過期,而且是和網址相符的,也沒有 Chain certificate 的問題。表示上述每一個網站的 SSL 憑證都有被正常的申請及安裝。

第二個項目是 Protocol Support ,由該網站的定義中可以發現,他是用 SSL 2.0, 3.0 和 TLS 1.0, 1.1, 1.2 的支援程度來做加權平均的,而且自 2014 年 1 月起,不支援 TLS 1.2 的就會被打到 B 去,可見得這個網站也是越來越嚴格。我看很多台灣人還是在使用 Windows XP ,這些人既使安裝了 XP 能支援到的 IE8,其 TLS 也只支援到 TLS 1.0 的版本,連 TLS 1.1 都不支援,更遑論 TLS 1.2 了。而 Windows 7 上的 IE 則是需要到 IE 11 才支援 TLS 1.2,若你的 Windows 7 上安裝的是 IE 10 ,那也只支援到 TLS 1.1。那表示既使是伺服器已經可以支援到 TLS 1.2 ,瀏覽器沒有支援到位的話,他們之間還是會以較低的加密方式來處理 SSL。所以你說可不可以從伺服器端把 TLS 1.0 禁用?那表示你不打算讓 Windows XP 的 IE 使用者連上來了。

第三和第四個項目是 Key Exchange 與 Cipher Strength 這一點,基本上這個網站會告訴你,哪些 Cipher Suites 是安全的,哪些是安全性較弱,而哪些是完全不安全的,以下圖來看,那些有用到 MD5 作為演算法的加密方法都被標示為 INSECURE,由於 MD5 在 2009 年已經被證實在一般的電腦上只要花數秒的時間即可破解,所以無論是多少長度的金鑰也是無濟於事。另外那些短於 1024 bits 長度金鑰則會被歸類為 WEAK,因為長度過短,所以相對來說容易被破解,最好也是禁用掉。

07

其實不管是 Web server (IIS 或 Apache),能作為 SSL Proxy 的設備或服務 (如 Load Balancer, CDN),當推出新版本時,都會適當的在預設值中就禁用一些不安全的憑證,但是身為系統管理員,就會知道有時候因為升級版本需要新的授權預算,有時候是因為應用程式和新版本不相容等等的原因,我們並沒有辦法每一次都跟著廠商一起升級,所以瞭解你所管理的系統該怎麼禁用不安全的加密方式就顯得非常重要了。

要檢查你的網站目前支援了哪些加密方式除了可以用上述的網站之外,如果你不太希望「公開」地留下查詢的資料,或是希望在還沒有正式上線前進行檢查,也可以利用 OpenSSLSSLScan (Windows 版),來查詢或驗證。我自己是用後者,因為操作起來方便又簡單,執行出來的結果就如下圖所示,其中 Accepted 的 Cipher 已經很少了
(* 2015/07/27 更改 SSLScan 連結,原版本已經久未更新,我另外在 Github 上找了另外一個版本,用法相同,但顯示方式不同)

08

如何禁用?在 Windows 上的 IIS 會挺麻煩,根據這篇文章所示,你必須手動去更改 Registry,而且改完之後必須要重開機,由於每個加密方式在 Registry 的命名方式不太一樣,所以需要時要去找出來,或參考這篇。感覺上有點麻煩嗎?那請服用網友推薦的這個小工具,直接用選的,而且還內附 Qualys SSL Labs 的捷徑。

09

至於 Apache ,基本上就是在設定檔中把想要禁用的 Cipher string 給加入就可以了,一般我們會不太希望把所有設定都搞在 httpd.conf 中,所以大家一般都是把這樣子的禁用字串寫到 /etc/httpd/conf.d/ssl.conf 裡。語法請參考這裡。另外這裡有提供簡單的說明網頁

由於 F5 也是和 Apache 一樣使用 OpenSSL 來提供 SSL 功能,所以在 Local Traffic -> Profiles -> SSL -> Client 選單中,選擇你要修改的 clientssl profile,然後選 Advanced,就可以在 Ciphers 欄位中填入欲禁用的字串

10

如同之前有提到的,F5 每個版本都會禁用掉一些不安全的加密方式,這裡是 10.x 以前版本的啟用清單,而這裡放的就是 11.x 的啟用清單。

A10 的 SSL Cipher 支援則是比較特別一點,它是可以用「選」的,

11

Windows 2008/2012 支援的加密方式如此頁面所示,OpenSSL 則在該頁面中有列出不再支援的加密方式 (Deprecated SSL v2.0 cipher suites)。但很顯然的,Windows 或 OpenSSL 預設禁用的加密方式就不會太多,所以自己提高警覺,根據你的需要去設定要支援的加密方式,才是最佳的安全之道。

  • 至於其他 Web server ,我猜只要是使用 OpenSSL 套件的,應該可以在某個設定檔/設定畫面中找到放禁用字串的地方
  • 補充:文中所提到的 Qualys Labs 的工具網站也增加了最近熱門的 HeartBleed 偵測 (2014/04/22)
  • Qualys Labs 的工具網站也增加了最近熱門的 POODLE (SSLv3 漏洞) 偵測 (2014/10/21)
  • 2014/10/21 更新: 10/14 時有個 SSLv3 的漏洞被發佈 CVE-2014-3566 ,由於預設採用 SSLv3 的瀏覽器很少(幾乎沒有),且多半還可以走 TLS ,所以 Linode 就建議把 SSLv3 給關掉,Linode 網站 上提有供各種 Open source web server 的 SSLv3 關閉方法,請自行參閱。F5 也提供了對應措施,有趣的是,F5 早在 2014/03/03 發表的 11.5.0 版本時就把 SSLv3 給關掉了
  • 2020/04/07 更新: 沒想到從 2020/01/31 開始,TLS 1.0 和 1.1 也變成不那麼安全了,全打到 Grade B 去

把 Exchange 上的全域通訊錄同步到手機上

公司自從去年把郵件伺服器換成了 Exchange 2013 之後,不時的就有人在問是不是可以把公司的全域通訊錄同步到手機上來,由於公司向來有把每個人的手機號碼記錄到 AD 上的習慣,二來公司的人數沒有很多(所以全部同步下來也不會太誇張),加上公司同仁常常出國出差,一般也不會很浪費的都在國外買全程的 3G 上網,所以把通訊錄同步到手機上,臨時有急事時不管在國內國外找起來都比較方便。

我們一開始開放大家用手機收信之後(不是用 POP3), 就發現每次要搜尋公司通訊錄時,在我的 New HTC One 上面就非得要按一下「搜尋公司通訊錄中的聯絡人」選項之後,它才會透過網路去 Exchange 上搜尋(而且小於 4 個字元還不讓你搜尋),原先一直以為這是 Android 4.3 的 bug,後來我的 New HTC One 升級到 4.4 之後也是無濟於事,加上同事的 iPhone 也是一樣的狀況,所以我們便開始研究這中間發生了什麼事

經過幾次錯誤的嘗試之後,發現原來不管是 Android 或 iPhone,在設定了 Exchange 帳號連線之後,都是可以同步聯絡人下來的,只是這個「聯絡人」,指的是個人在 Exchange 上的「通訊錄」,而非「全域通訊錄」。好吧,知道弄錯了之後,我就可以手動的把全域通訊錄中我想同步到手機上的名單一個一個捉進我的個人「通訊錄」了

1

2

然後在 Outlook 中我就可以看到這筆名單出現在我的個人通訊錄中,然後我的手機裡頭過幾分鐘之後也就出現了這筆資料,嗯,看來問題解決了?!

3

啥?!老闆問說,那萬一全域通訊錄有更新時要怎麼辦?我們多了幾位員工或是有人改了電話?我想一位稍有智慧的 MIS 是不會這麼回答老闆的:老闆,就請你自己每天或要出差前記得把全域通訊錄全選起來,然後一次加到你的個人通訊錄中。

所以找來 Google 大神來神一下,發現有這篇文章:Importing Global Address List entries into a user’s Contacts folder

趕緊把裡頭的 script 下載下來拿去 Exchange server 上執行,嗯,步驟有點囉唆,紀錄一下免得自己以後忘記:

首先先找到 Exchange 的 Management Power Shell ,我自己是對 2012 這個如同 Windows 8 的 Metro GUI 是很不習慣的,找個功能還要用搜尋的才找得到…

4

接著執行下面這個指令,新增一個 MailArchivaImpersonation 的角色,使其擁有 Impersonation 的權限,並賦予你現在用來管理 Exchange 的這個使用者擁有這個角色的權限

[PS] C:\>New-ManagementRoleAssignment -Name:MailArchivaImpersonation -Role:ApplicationImpersonation -User:[your account]

5

然後執行剛剛下載下來的 script ,這樣子就可以把全域通訊錄複製到該帳號的個人通訊錄中

[PS] C:\>.\Copy-OrgContactsToUserMailboxContacts.ps1 -Mailbox [account you want to sync GAL] -FolderName Contacts

6

執行完畢之後,我是會把這個權限移除掉,因為感覺上有點危險

[PS] C:\>Remove-ManagementRoleAssignment MailArchivaImpersonation

然後該帳號的 Outlook 個人通訊錄、手機就都會有這些名單了

7

8

由於這個 script 的動作是 複製+覆蓋,所以只要把它設定到 Windows 的工作排程中每天執行,就可以每天 “同步" 全域通訊錄下去了

要讓 Windows 定期執行 Exchange 2013 的 Power Shell command 還有點小學問,不是執行執行那個 *.ps1 檔案就好了,請參考這裡吧:
http://www.msexchange.org/kbase/ExchangeServerTips/ExchangeServer2013/Powershell/scheduling-exchange-powershell-task.html

* 原本該 script 作者只會把全域通訊錄中 1) 有 E-Mail 地址  2) 有手機或公司電話 的資料複製下去,不過由於我們公司對於離職員工的帳號會先 disable 保存一段時間,所以我改了該 script 的 76 行,把被 disabled 的帳號也過濾掉了,改過之後的 script 放在下面,因為 WordPress 似乎不給放 *.ps1 檔案,所以我先壓縮過後改附檔名為 *.doc,有需要的人請自行下載後去掉 *.doc 然後解壓縮就可以得到該 script 了

Copy-OrgContactsToUserMailboxContacts.zip

新 Dell Latitude 14 7440 開箱

這次拿到是 Dell Latitude 14 7440 ,由於上次的 7240 被 Programmer 嫌螢幕太小,寫程式不方便,而且沒有 Full HD ,所以這次就拿了 7440,外觀上差不多,規格是寫 1.61kg ,憑感覺拿起來大概沒有差距太大,就當成是 1.61kg 好了,至少和我們以前公司用的 Latitude 6420, 6430 比較起來是輕了很多

2013-12-20 12.01.19

鍵盤上有小藍點,試用了一下之後覺得還不錯用,一改以前我一直認為小藍點比小紅點差一大截的的想法

2013-12-20 12.01.46

機身右側邊只有 USB,耳機麥克風共用接口,Wifi 開關,不知道是不是全面改用 USB 3.0 的關係,這台機器上面都沒有特別用藍色標示 USB 接口了

2013-12-20 12.02.11

左側邊就空空的,只有散熱孔

2013-12-20 11.02.40

剩下的接口就都在背面,便利性就見仁見智了,我還是喜歡這台機器有標準大小的 hdmi 接頭,和公司的投影機直接搭配

2013-12-20 11.03.10

背面一貫的精簡,也是支援舊 E 系列的 Docking ,但是那個 Docking 的插入角度要自己對齊,因為接口位置並不像小黑一樣有考慮舊有 Dock 的位置,而且插上去會覺得有點醜,會有看起來不是很合身的感覺

2013-12-20 11.04.27

電池是 3 cell

2013-12-20 12.04.50

開背蓋的方法和 7240 一樣,拆兩根螺絲就可以打開了,裡頭可以塞一個 msata SSD 和一個 2.5 HDD,是我最喜歡的配置方式

2013-12-20 12.08.47

HDD 的部分需要額外的連接線,當初廠商忘記附上了,又花了一週另外寄來

2013-12-20 11.09.41

這是原本放在 HDD 位置的支架,看 Dell 說明書,原本應該是要把 msata SSD 放在這個位置才對 (所以現在放 SSD 的那個位置應該是設計用來放 WLAN card 的)

2013-12-20 11.09.50

Full HD (無觸控) 的 14″ 螢幕感覺上很細緻,其實我個人不太習慣這麼細的字

2013-12-20 11.16.25

msata + HDD 可正常開機,速度上沒有特別測試,感覺上是有 SSD 的開機速度了,不過因為這個畫面會稍微停住一兩秒,讓開機時間變常了些

2013-12-20 11.17.26

右邊是內附的變壓器,尺寸和重量上和以前相比算是進步很多了,不過還是比不上我上次在自動買特價時購入的樹昌萬用變壓器(含 USB 充電埠),不過它的接頭維持和以往 Dell 一樣的規格,我們舊的變壓器就可以繼續使用,讚

2013-12-20 11.04.03

 

* 補充說明 (2014/03/17):這個自動買上面特價購入的萬用變壓器,其轉接頭並無內含 Dell 特殊晶片,所以接上去之後可以供電,但無法為電池充電,我後還是在拍賣上買了特殊有帶 Dell 晶片的轉接頭,才能使用,而且一頭是 5mm ,另一頭才是 Dell 的接頭,也就是會轉接兩次的意思。光華商場那裡的電子器材行也有賣,但是要問一下老闆才會拿出來給你。

新 Dell Latitude 12 7240 開箱

今天早上到公司收到一台廠商借測的新筆電:Latitude 系列的 Ultrabook,12 吋

第一眼看到覺得這外型長得有點像 Macbook Air 了

圖片

掀開蓋子,型號是 E7240,開蓋後看起來就有 Latitude 的特色了,有完整的獨立方向鍵,Page Up/Page Down 鍵,鍵盤顆粒似乎小了一些些,我的手指不算粗,加上鍵程還算 OK,打起來的感覺算是不錯。而且我很喜歡有獨立音量、靜音鍵的設計,有時候臨時要靜音時不會找不到

圖片

背面算是很精簡,支援舊的 E-port docking 大大的加分,現在拍賣上的二手 E-port dock 最便宜的才 NT$680,缺點就是舊款的 dock 很醜,如果有錢的話,這台還支援無線的 dock ,號稱只要靠近 dock 就直接指揮挺組合了,聽起來真是優雅

圖片

後面的連接孔,值得稱讚的是沿用 Dell 舊有的變壓器介面,這年頭許多公司的 Ultrabook 出來之後就把變壓器接頭給改了,像我們公司用了多年的 Dell ,大多數都是每個人配兩條變壓器,那些 NB 壞了但變壓器沒壞的還一堆。另外標準大小的 HDMI 接頭也是和我們公司現用的投影機很搭

圖片

左側只有無線開關,另外就是承襲 Latitude 傳統而來的 Smartcard 插槽,對我們公司來說那些常出差很久,需要在國外處裡一些銀行問題的同事就不用多帶一台讀卡機了

圖片

右側有耳機喇叭接頭、一個 USB port 和 mini Display port,美中不足的是不是裝 D-Sub ,現在台灣有 Display port 的螢幕、投影機算少的,希望這個 mini display port 和 Macbook Air 的是通用的,這樣子網路上一堆便宜的 mini display port to d-sub 相容品可以買

圖片

打開背蓋只要先取下電池,然後拆兩顆螺絲就可以了

圖片

從這邊可以看到有兩個 RAM 的插槽可以用,原本是插 4G 的 RAM,所以再加一條 4G 的對我們來說也就很夠用了,有趣的地方是,這台機器只有兩個 msata 的插槽,左邊的那個是出廠就裝好的 Samsung 128G SSD,右邊的那個被我裝上公司的備品,Crucial M4 128G,開機之後運作正常,不過不是配一個 2.5″ HDD 的插槽讓我有些失望就是了

圖片

結論,我手上拿到的這台機器 CPU 是 4200U 的型號,光以測速的結果來看,還比我現用小黑的 2nd gen i5-2520M 要慢上幾百分,但是實際使用上差異並不大,換來的卻是省電和輕薄,省電方面同事和我都沒有實際測試過時間,不過看 Windows 內建的電池計數器在充滿電時顯示可以使用 6-7 hr 左右,以 3 cell,1.36 kg 水準的筆電來說算是很好用的了。

另外值得一提的是,雖然 x220 號稱裝了 4 cell 電池也是 1.39 kg ,但不知道是不是配重的關係,這台 NB 拿起來非常的輕,加上頗為類似 MBA 的外型,可以上到 Full HD 的螢幕,我們之後如果有要再新採購 NB 時應該就是這一台了

IDC 分級

以前我一直把 IDC分級和 ISP分級 搞混在一起,以致於到國外參觀機房時,對方說他們是 Tier 3 IDC 時,我還以為他們是最 low 的 (ISP 分級中 Tier 3 是最 low 的),後來經前輩提醒,我才看了英文版的 Wiki 的 IDC分級,這下子才搞懂,以下就做個簡單的翻譯好了:

說是搞懂了其實也不太對,因為從 Wiki 的說明看來,喜歡搞「分級標準」的老外還不只一間,例如美國的 ANSI 就在 TIA-942 標準內定義了四個分級,我們一般辦公室內的 Server Room 叫做 Tier 1,而機房那種有各種備援機制、進出需在額外的隔離空間管制的叫 Tier 4 機房

而德國的標準則分成五類

Wiki 上最後一個有放表格的則是我常聽到那些 IDC 自我吹噓時使用的分類,原始出處應該是這裡

ier Level Requirements
1
  • 有一個放置 IT 設備的獨立空間
  • 沒有備援的機制也沒關係
  • 這些基礎設施必須要每年關機維護檢查
  • 基礎設施 (我想是電力、空調、消防、安全及環控) 的可用性要可以達到 99.671%
2
  • 符合所有 Tier 1 的要求
  • 可用性達 99.741% 
  • 必須要有備援機制,但備援機制維護時允許服務中斷
3
  • 符合所有 Tier 1, Tier 2 的要求
  • Multiple independent distribution paths (我猜也是冷氣、電力、網路) 這些基礎設施,也就是任何基礎設施都要有備援的意思
  • 所有的 IT 設備在電源方面都要有雙迴路,而且雙迴路要和機房的架構是相容的 (也就是說自己弄的雙迴路不算數,要那種大樓切換迴路時也會生效的迴路才算)
  • 所有的基礎設施都要能達到可同時維護性的要求,且可用性需達到 99.982%
4
  • 符合所有 Tier 1, Tier 2 和 Tier 3 的要求
  • 所有冷卻系統都必須是獨立的雙電源迴路,包含冷卻設備(水塔、冷排?),散熱器、通風扇和空調設備系統
  • 可用性需達到 99.995%
  • 全球僅有 12 座機房達到 Tier 4 的要求?

中國那邊某網站找到的圖表似乎還更詳盡,看起來 Tier 3 和 Tier 4 的最大差異應該就是在基礎設施上都需要有 HA,基礎設施包含冷氣、電、UPS 及他們的管線,一個是 Active-Standby ,另一個是 Active-Active:

Supernetting PHP 實做-2

asdf
<?php
asdf

sfdfd

<?php $time_start = microtime(true);

/**  * Initial  *  * */ $start = $_POST[“start"]; $Origin = $_POST[“Origin"]; $Join = $_POST[“Join"]; $Percentage = $_POST[“Percentage"]; $masktype = $_POST[“masktype"]; $is_debug = $_POST[“is_debug"]; $testType = $_GET[“testType"]; $TFile[“default"][“O"] = “./example/Origin.txt"; $TFile[“default"][“J"] = “./example/Join.simple.txt"; $TFile[“mask"][“O"] = “./example/Origin_mask.txt"; $TFile[“mask"][“J"] = “./example/Join.simple_mask.txt"; $TFile[“full"][“O"] = “./example/Origin.txt"; $TFile[“full"][“J"] = “./example/Join.full.txt"; $TFile[“waste"][“O"] = “./example/origin-waste.txt"; $TFile[“waste"][“J"] = “./example/join-waste.txt";

include(“./libs/supernetting_func.php");

if(trim($start) == NULL) {  if($testType == NULL) $testType = “default";    $TestFile = $TFile[$testType];    $fp = fopen($TestFile[“O"], “r");  $Origin =  fread($fp, filesize($TestFile[“O"]));    $fp = fopen($TestFile[“J"], “r");  $Join =  fread($fp, filesize($TestFile[“J"]));    } else {  $OriginList = explode(“\r\n", $Origin);  $JoinList = explode(“\r\n", $Join);    $Supernetting = new Supernetting();  $Supernetting->setMaskType($masktype);  if($is_debug == “yes") $Supernetting->enableDebug();  $Supernetting->start($OriginList, $JoinList, $Percentage / 100);  //$Supernetting->aggregateSupernetting($OriginList, $JoinList, $Percentage / 100);      $Origin = $Supernetting->getOrigin();  $Join = $Supernetting->getJoin();  $ResultList = $Supernetting->getResultList();  $AddList = $Supernetting->getAddList();  $DeleteList = $Supernetting->getDeleteList();

$AddMessage = $Supernetting->AddMessage;  $DeleteMessage = $Supernetting->DeleteMessage; }

$time_end = microtime(true);

?>

<html> <head> <title>Supernetting</title> <link type="text/css" href="./css/supernetting.css" rel="stylesheet" />     </head> <body>

<form method=POST action="<?php echo $_SERVER[“PHP_SELF"]; ?>"> <table> <tr>  <th colspan=6 style="color:#F00;"><?php echo $Supernetting->errorMessage; ?></th> </tr> <tr>  <th colspan=6>Supernetting.    Use Case:   {    <a href="./supernetting.php?testType=default">Default</a>,    <a href="./supernetting.php?testType=full">Full</a>,    <a href="./supernetting.php?testType=waste">IP waste</a>,    <a href="./supernetting.php?testType=mask">Mask</a>   }  </th> </tr> <tr>  <td>Origin</td>  <td>Join</td>  <td style="background-color: #BAD2BA" rowspan=2></td>  <td>Result</td>  <td>Add</td>  <td>Delete</td> </tr> <tr>  <td><textarea name="Origin" cols=32 rows=30><?php echo (!is_array($Origin))?$Origin:implode(“\n", $Origin); ?></textarea></td>  <td><textarea name="Join" cols=32 rows=30><?php echo (!is_array($Join))?$Join:implode(“\n", $Join); ?></textarea></td>  <td><textarea cols=32 rows=30><?php echo (!is_array($ResultList))?"":implode(“\n", $ResultList); ?></textarea></td>  <td><textarea cols=32 rows=30><?php echo (!is_array($AddList))?"":implode(“\n", $AddList); ?></textarea></td>  <td><textarea cols=32 rows=30><?php echo (!is_array($DeleteList))?"":implode(“\n", $DeleteList); ?></textarea></td> </tr> <tr>  <th colspan=6>   Convert mask:    <input type=radio name="masktype" value=cidr <?php echo ($masktype == “cidr" or empty($masktype))?"checked":"" ?> > CIDR    <input type=radio name=masktype value=mask <?php echo ($masktype == “mask")?"checked":"" ?> > Mask  </th> </tr> <tr>  <th colspan=6>Percentage: <input type=text name="Percentage" value="<?php echo ($Percentage < 1)?20:$Percentage; ?>" >% </th> </tr> <tr>  <th colspan=6>   Spend Time(sec): <?php echo round($time_end – $time_start, 3); ?>   Debug: <input type="checkbox" name="is_debug" value="yes" <?php echo ($is_debug == “yes")?"checked":"" ?>>    </th> </tr><tr>  <th colspan=6> <input type=submit name=start value=Go> </th> </tr> </table>

<?php

if($is_debug != “yes")  ; else {  //echo json_encode($AddMessage);  //echo json_encode($DeleteMessage);  echo “<hr />"   ."<table>"    ."<tr>"     ."<td colspan=\"2\" style=\"font-weight:bold;text-align:center;\">Debug Information</td>"    ."</tr>";    if($masktype != NULL AND $masktype != “cidr")   echo “<tr>"     ."<td colspan=\"2\" style=\"font-weight:bold;text-align:center;color:#F00;\">Debug mode only support CIDR. </td>"    ."</tr>";   else  {   echo  “<tr>"        ."<td style=\"font-weight:bold;text-align:center;\">Add List</td>"      ."<td style=\"font-weight:bold;text-align:center;\">Delete List</td>"     ."</tr>"     ."<tr>";       echo “<td style=\"text-align:left;\">";   @reset($AddList);   while(list($key, $thisValue) = @each($AddList))   {    echo “[“.$thisValue."]<br />";    @ksort($AddMessage[$thisValue], SORT_NATURAL);    @reset($AddMessage[$thisValue]);    while(list($key2, $Value2) = @each($AddMessage[$thisValue]))    {     echo " … from “.$key2."<br />";    }     }   echo “</td>";      echo “<td style=\"text-align:left;\">";   @reset($DeleteList);   while(list($key, $thisValue) = @each($DeleteList))   {    echo “[“.$thisValue."]<br />";    @ksort($DeleteMessage[$thisValue], SORT_NATURAL);    @reset($DeleteMessage[$thisValue]);    while(list($key2, $Value2) = @each($DeleteMessage[$thisValue]))    {     echo " … to “.$key2."<br />";    }   }   echo “</td>";  }    echo “</tr></table>"; }

?>

</body> </html>


	

Supernetting PHP 實做

<?php
$time_start = microtime(true);
/**
 * Initial
 * 
 * */
$start = $_POST["start"]; 
$Origin = $_POST["Origin"];
$Join = $_POST["Join"];
$Percentage = $_POST["Percentage"];
$masktype = $_POST["masktype"];
$is_debug = $_POST["is_debug"];
$testType = $_GET["testType"];
$TFile["default"]["O"] = "./example/Origin.txt";
$TFile["default"]["J"] = "./example/Join.simple.txt";
$TFile["mask"]["O"] = "./example/Origin_mask.txt";
$TFile["mask"]["J"] = "./example/Join.simple_mask.txt";
$TFile["full"]["O"] = "./example/Origin.txt";
$TFile["full"]["J"] = "./example/Join.full.txt";
$TFile["waste"]["O"] = "./example/origin-waste.txt";
$TFile["waste"]["J"] = "./example/join-waste.txt";

include("./libs/supernetting_func.php");
if(trim($start) == NULL)
{
 if($testType == NULL) $testType = "default";

 $TestFile = $TFile[$testType];

 $fp = fopen($TestFile["O"], "r");
 $Origin = fread($fp, filesize($TestFile["O"]));

 $fp = fopen($TestFile["J"], "r");
 $Join = fread($fp, filesize($TestFile["J"])); 

}
else
{
 $OriginList = explode("\r\n", $Origin);
 $JoinList = explode("\r\n", $Join);

 $Supernetting = new Supernetting();
 $Supernetting->setMaskType($masktype);
 if($is_debug == "yes") $Supernetting->enableDebug();
 $Supernetting->start($OriginList, $JoinList, $Percentage / 100);
 //$Supernetting->aggregateSupernetting($OriginList, $JoinList, $Percentage / 100);

 $Origin = $Supernetting->getOrigin();
 $Join = $Supernetting->getJoin();
 $ResultList = $Supernetting->getResultList();
 $AddList = $Supernetting->getAddList();
 $DeleteList = $Supernetting->getDeleteList();
$AddMessage = $Supernetting->AddMessage;
 $DeleteMessage = $Supernetting->DeleteMessage;
}
$time_end = microtime(true);
?>

<html>
<head>
<title>Supernetting</title>
<link type="text/css" href="./css/supernetting.css" rel="stylesheet" /> 
</head>
<body>
<form method=POST action="<?php echo $_SERVER["PHP_SELF"]; ?>">
<table>
<tr>
 <th colspan=6 style="color:#F00;"><?php echo $Supernetting->errorMessage; ?></th>
</tr>
<tr>
 <th colspan=6>Supernetting. 
 Use Case:
 {
 <a href="./supernetting.php?testType=default">Default</a>, 
 <a href="./supernetting.php?testType=full">Full</a>, 
 <a href="./supernetting.php?testType=waste">IP waste</a>, 
 <a href="./supernetting.php?testType=mask">Mask</a>
 }
 </th>
</tr>
<tr>
 <td>Origin</td>
 <td>Join</td>
 <td style="background-color: #BAD2BA" rowspan=2></td>
 <td>Result</td>
 <td>Add</td>
 <td>Delete</td>
</tr>
<tr>
 <td><textarea name="Origin" cols=32 rows=30><?php echo (!is_array($Origin))?$Origin:implode("\n", $Origin); ?></textarea></td>
 <td><textarea name="Join" cols=32 rows=30><?php echo (!is_array($Join))?$Join:implode("\n", $Join); ?></textarea></td>
 <td><textarea cols=32 rows=30><?php echo (!is_array($ResultList))?"":implode("\n", $ResultList); ?></textarea></td>
 <td><textarea cols=32 rows=30><?php echo (!is_array($AddList))?"":implode("\n", $AddList); ?></textarea></td>
 <td><textarea cols=32 rows=30><?php echo (!is_array($DeleteList))?"":implode("\n", $DeleteList); ?></textarea></td>
</tr>
<tr>
 <th colspan=6>
 Convert mask: 
 <input type=radio name="masktype" value=cidr <?php echo ($masktype == "cidr" or empty($masktype))?"checked":"" ?> > CIDR 
 <input type=radio name=masktype value=mask <?php echo ($masktype == "mask")?"checked":"" ?> > Mask
 </th>
</tr>
<tr>
 <th colspan=6>Percentage: <input type=text name="Percentage" value="<?php echo ($Percentage < 1)?20:$Percentage; ?>" >% </th>
</tr>
<tr>
 <th colspan=6>
 Spend Time(sec): <?php echo round($time_end - $time_start, 3); ?>
 Debug: <input type="checkbox" name="is_debug" value="yes" <?php echo ($is_debug == "yes")?"checked":"" ?>> 

 </th>
</tr><tr>
 <th colspan=6> <input type=submit name=start value=Go> </th>
</tr>
</table>
<?php
if($is_debug != "yes")
 ;
else
{
 //echo json_encode($AddMessage);
 //echo json_encode($DeleteMessage);
 echo "<hr />"
 ."<table>"
 ."<tr>"
 ."<td colspan=\"2\" style=\"font-weight:bold;text-align:center;\">Debug Information</td>"
 ."</tr>";

 if($masktype != NULL AND $masktype != "cidr")
 echo "<tr>"
 ."<td colspan=\"2\" style=\"font-weight:bold;text-align:center;color:#F00;\">Debug mode only support CIDR. </td>"
 ."</tr>"; 
 else
 {
 echo "<tr>" 
 ."<td style=\"font-weight:bold;text-align:center;\">Add List</td>"
 ."<td style=\"font-weight:bold;text-align:center;\">Delete List</td>"
 ."</tr>"
 ."<tr>";

 echo "<td style=\"text-align:left;\">";
 @reset($AddList);
 while(list($key, $thisValue) = @each($AddList))
 {
 echo "[".$thisValue."]<br />";
 @ksort($AddMessage[$thisValue], SORT_NATURAL);
 @reset($AddMessage[$thisValue]);
 while(list($key2, $Value2) = @each($AddMessage[$thisValue]))
 {
 echo " ... from ".$key2."<br />";
 } 
 }
 echo "</td>";

 echo "<td style=\"text-align:left;\">";
 @reset($DeleteList);
 while(list($key, $thisValue) = @each($DeleteList))
 {
 echo "[".$thisValue."]<br />";
 @ksort($DeleteMessage[$thisValue], SORT_NATURAL);
 @reset($DeleteMessage[$thisValue]);
 while(list($key2, $Value2) = @each($DeleteMessage[$thisValue]))
 {
 echo " ... to ".$key2."<br />";
 }
 }
 echo "</td>";
 }

 echo "</tr></table>";
}
?>

</body>
</html>