「分散式系統,就是一台你甚至不知道它存在的電腦故障了,卻能讓你自己的電腦不能用的系統。」——蘭波特(Leslie Lamport)

「名字算什麼?我們稱為玫瑰的那種花,換個名字仍然一樣芬芳。」——莎士比亞(William Shakespeare)

為什麼分散式系統的基本功攸關安全#

要建造任何有點規模、穩健的分散式系統,我們需要的遠不只認證、存取控制與密碼學。有些事必須快速發生、或以正確順序發生;而對幾台機器來說微不足道的事情,一旦有了配備複雜韌性安排的超大規模資料中心,就成了大問題。

每個人大概都注意過:當你在某個線上服務更新通訊錄時,更新可能一秒後就出現在另一台裝置上,也可能好幾小時後才出現。

過去五十年間,我們在建造從電話系統、支付網路到網際網路本身的過程中,學到了很多關於並行、故障復原與命名的知識。我們有扎實的理論,也有大量得來不易的經驗。

  • 前面已描述過因並行失敗而產生的協定攻擊。
  • 如果我們複製資料讓系統容錯,就可能提高資料被竊的風險。
  • 命名可能是個棘手問題:人與物件跟帳號、工作階段、文件、檔案、指標、金鑰及其他命名方式之間有複雜的互動。

許多組織正試圖建立更大、更扁平的命名空間——不論是用身分證追蹤公民,還是用裝置 ID 追蹤物件——但我們實際能做的有其極限。大數據意味著要處理大量識別符,其中許多曖昧不明甚至會變動,而很多事情會出錯

並行#

若行程能同時執行,就稱為並行的(concurrent),而這對效能至關重要。但並行很難做得穩健,尤其當行程可以對同一份資料動作時:

  • 行程可能使用舊資料
  • 它們可能做出不一致的更新
  • 更新的順序可能重要也可能不重要;
  • 系統可能死鎖
  • 不同系統中的資料可能永遠不會收斂到一致的值;
  • 當「讓事情以正確順序發生」很重要、甚至只是「知道確切時間」時,這都可能比你想的更棘手。

系統因為若干理由變得越來越並行:

  1. 規模:Google 也許只從四台機器起步,但 2011 年其機隊已超過一百萬台。
  2. 裝置複雜度:一輛豪華房車現在可含數十到數百顆不同的處理器;你的筆電與手機也一樣。在每顆 CPU 深處,指令是平行執行的——這種複雜度導致了存取控制那章討論的 Spectre 攻擊。
  3. 虛擬化:Xen 這類技術是現代雲端服務建立的平台,可能把伺服器中的少數幾顆真實 CPU 變成數百甚至數千顆虛擬 CPU。
  4. 互動複雜度:往上到應用層,租車這類日常交易可能呼叫其他系統去查你的信用卡、信用機構評分、保險理賠紀錄等等,而這些系統又可能依賴別的系統。

電腦科學家被教的是 Amdahl 定律:若可平行化的比例為 p、額外資源帶來的加速為 s,整體加速為 (1 − p + p/s)⁻¹。

所以若你程式的四分之三可平行化、剩下四分之一不行,最大加速是四倍;而若你丟八個核心進去,實際加速還不到三倍。

使用舊資料 vs. 為傳播狀態付費#

我們已描述過兩種並行問題:

  • 對協定的重播攻擊:攻擊者設法混用過期的憑證。
  • 競爭條件:兩個程式競相更新某個安全狀態。

一個 1960 年代的例子:在最早的多使用者作業系統之一 IBM OS/360 中,嘗試開啟檔案會導致它被讀取並檢查權限;若使用者被授權存取,它會再被讀一次。使用者可以安排在這兩次之間把檔案改掉。

這些是檢查時到使用時(TOCTTOU)攻擊的例子。我們有系統性的方法在檔案系統中找出這類攻擊,但攻擊仍在較低層次(虛擬化環境中的系統呼叫)與較高層次(商業邏輯)冒出來。

案例研究:信用卡的熱卡清單為什麼不能即時全球同步

自 1970 年代信用卡與簽帳卡普及以來,銀行業就必須管理熱卡(hot card)清單(被竊或被濫用的卡),而 1980 年代卡片網路走向國際後問題穩定惡化。

實際做法是多層次的代行處理(stand-in processing),利用「多數付款是本地的、小額的、或兩者兼具」這個事實:

  • 商店終端機被允許離線處理某個限額(樓層限額)以下的交易;
  • 較大的交易需要與商店的銀行線上驗證——它會知道所有本地熱卡、加上正被積極濫用的外國卡;
  • 超過另一個限額的可能會把交易轉給 VISA 這類網路,那裡有一份相當即時的國際清單;
  • 而最大的交易需要參照發卡銀行。

實際上,只有本地或大額的交易會在使用前立即被檢查。

經驗接著教會我們:對付壞終端機,較集中式的取徑可能效果更好。約有一半的全球 ATM 交易使用一項服務——當有人在某台 ATM 試用被竊卡片、或猜錯 PIN 時,訂閱的銀行會收到警示。FICO 觀察到罪犯會拿一小疊被竊卡片到提款機一張一張試,於是他們維護一份「全球最近被用於詐欺嘗試最頻繁的 40 台 ATM」清單,訂閱其服務的銀行會拒絕這些機器上的所有交易——這些機器因此對那些銀行的卡片在大約半小時內不可用。多數竊賊不理解這件事,就把卡丟了。

直到約 2010 年,支付卡網路擁有管理安全狀態全球傳播的最大系統,而它們的經驗教會我們:快速且全球規模地撤銷被攻陷的憑證是昂貴的。

這個教訓在別處也學到了:美國國防部在 1999–2005 年間發出 1,600 萬張憑證,到那時它必須每天把一千萬張被撤銷的憑證下載到所有安全伺服器上,有些系統啟動時光做這件事就要半小時。

傳播安全狀態的成本會導致集中化。 Google、Facebook 與微軟這類大型服務公司反正都要為數十億使用者維護憑證,所以它們把登入當服務提供給其他網站。

2011 年,從伊朗 IP 位址操作的駭客攻陷了荷蘭憑證機構 Diginotar。7 月 9 日他們產生假憑證,對伊朗運動人士的 Gmail 做中間人攻擊。Diginotar 在 19 日注意到憑證被錯誤簽發,卻只是找了稽核師。此事在 29 日曝光,Google 於 9 月 3 日把所有 Diginotar 憑證從 Chrome 移除,並讓 Mozilla 跟進。

這立即導致該公司倒閉,而荷蘭公共服務有許多天無法線上使用,因為各部會忙著向其他供應商取得網頁服務憑證。

用鎖定防止不一致的更新#

人們並行處理一份文件時,可能用版本控制系統確保任一時間只有一個人對文件的任一部分有寫入權,或至少在有競爭時提出警告並標示不一致的編輯。**鎖定(locking)**是管理資源競爭、讓衝突更新較不可能發生的一般方法。

另一種取徑是回呼(callback):伺服器可以保存一份「所有倚賴它取得安全狀態之客戶端」的清單,並在狀態改變時通知它們。

信用卡再度提供了例子。如果我開一家旅館而顧客在入住時出示信用卡,我會向發卡公司要求預先授權,記錄我在不久的將來會想扣款;我可能登記「至多 500 美元」的請求權。這靠分離授權系統與清算系統實作。

處理失敗模式可能很棘手:若該卡隔天被取消,我的銀行可以打電話給我,要我聯絡警方或請她付現金。這是分散式系統中「發布-登記-通知」穩健授權模型的一個例子。

以護照為例:在許多國家,政府 ID 是許多交易所必需的,但政府不會提供任何擔保,而多數公民會反對政府保存每次身分文件被出示的紀錄。事實上,對印度政府「要求 Aadhaar 生物辨識 ID 被用於越來越多交易」的常見反對意見之一,正是在所有重要交易中檢查公民的指紋或虹膜碼,會創造出一條「他們在哪些地方做過生意」的稽核軌跡,而這對官員、以及任何願意賄賂官員的人都可取用。

一個一般性的區分是:憑證的使用是否對簽發者產生某種義務。信用卡會,護照不會。其中一個差別是憑證的使用是否改變重要狀態(除了可能加進日誌或其他監控系統之外)。這又與「更新的順序是否重要」相連。

更新的順序#

如果有兩筆交易抵達政府的銀行帳戶——比方說一筆 50 萬美元的貸記與一筆 40 萬美元的借記——那麼套用它們的順序也許不太重要。但若它們抵達的是「我的」銀行帳戶,順序對結果就有巨大影響!

事實上,「決定交易套用順序」這個問題沒有乾淨的解法。 它與「如何平行化一項計算」的問題密切相關,而建造高效分散式系統的技藝,大半在於安排事情使行程要嘛單純循序、要嘛完全平行。

  • 傳統銀行演算法:把交易整批留到夜間,先套用每個帳戶的所有貸記,再套用所有借記。來自 ATM 與支票分類機的輸入先被批次成日記帳,再做夜間對帳。跳票的付款接著必須被反轉出去——而在 ATM 與簽帳交易中現金已經出去了,你可能落得客戶未經授權地借了錢。

  • 即時全額清算(RTGS):近年來一國接一國導入,交易依抵達順序入帳。

  • 信用卡採混合策略:信用額度即時運作,而清算則像老派支票帳戶那樣。

2010 年代末對加密貨幣的興趣浪潮,讓一些創業者相信區塊鏈也許能解決不一致更新的問題,簡化供應鏈管理這類應用。

能源成本排除了多數應用使用基於工作量證明的區塊鏈;但也許某種其他形式的僅可附加公共帳本會找到殺手級應用?我們得等著看。

同時,加密貨幣社群大量使用鏈下(off-chain)機制,那往往非常令人聯想到支票帳戶的做法:離線的應用提出暫定更新,稍後才被對帳並套用到主鏈上。

經驗顯示一般情況下沒有魔法解方——或許除了「有少數幾家非常大、技術非常好的銀行」之外。

死鎖#

另一個問題是死鎖(deadlock):兩個系統各自等對方先動。Dijkstra 用哲學家用餐問題著名地解釋了這個問題:若干哲學家圍桌而坐,每兩人之間有一根筷子,而哲學家只有在能拿起兩側的筷子時才能吃。所以若所有人同時想吃、且各自拿起右邊的筷子,就卡住了。

當你有多個跨系統分散的鎖的階層,其中有些會失效(而失效可能意味著鎖不可靠)時,這會變得非常複雜。

而死鎖不只關乎技術:「Catch-22」這個片語已流行起來,用來描述官僚流程中的死鎖。當流程是人工的,也許能找到某種蒙混辦法繞過陷阱;但當一切都變成軟體,這個選項可能就不再存在了。

在一個著名的商業問題——表單之戰——中,一家公司開出附有自己合約條款的訂單,另一家公司在自己的條款下接受它,而交易就在沒有進一步協議的情況下進行下去。過去這件事可能只有在出事、雙方鬧上法院時才會被解決;即使如此,一家公司的條款可能指定美國法院、另一家指定英格蘭法院。

隨著交易越來越電子化,贏家往往是那個能迫使輸家用它的網站交易、從而接受它的條款的公司。 各公司越來越努力確保事情以對自己有利的方式失敗。由此產生的責任賽局,對安全與 safety 都可能有相當負面的後果。

非收斂狀態#

設計更新分散式系統狀態的協定時,「天經地義」的原則是 ACID——交易應是不可分割(atomic)、一致(consistent)、隔離(isolated)與持久(durable)的:

  • 不可分割:「要嘛全做、要嘛全不做」,這讓故障後的復原較容易。
  • 一致:某個不變式被保持,例如帳必須平。銀行系統中這靠堅持每筆交易的貸記與借記總和為零達成。
  • 隔離:它們是可序列化的。
  • 持久:一旦完成就不能被撤銷。

一方面,它們每一個都可能以許多晦澀的方式失敗或被攻擊;另一方面,把系統設計成收斂的(convergent)往往就夠了——意思是若交易量逐漸減少,最終整個系統會達到一致狀態。收斂通常靠時戳與版本號這類語意技巧達成,這在「交易被附加到檔案而非覆寫」時往往就足夠。

安全或稽核經理的日子可能是一場對抗熵的持續戰鬥:表面上的短缺(與盈餘)總是冒出來,而有時就是無法解釋。例如不同國家的系統對「銀行交易紀錄中哪些欄位是必填、哪些是選填」有不同想法,所以支付閘道常必須猜資料才能讓事情運作。有時它們猜錯了;有時人們看見並利用了直到很久以後(如果有的話)才被理解的漏洞。最後事情可能被蒙混過去——加一個修正因子,並設定「把它壓在某個年度門檻以下」的目標。

持久性在交易處理中是個有爭議的主題:

釣魚與鍵盤側錄攻擊的出現意味著,任一時間都有一小部分銀行帳戶處於罪犯控制之下;錢會從它們流出、也會流經它們。當帳戶被攻陷被偵測到時,銀行會凍結它,並可能反轉最近從它做出的付款。

釣魚者自然會試圖把資金移經那些不做交易反轉、或至少做得慢且不情願的機構或司法管轄區。

這在「支付系統的可復原性與韌性」與「交易的持久性與終局性」之間造成了張力。

安全的時間#

對安全工程師特別重要的最後一個並行問題,是準確時間的提供。由於 Kerberos 這類認證協定可以靠誘發時鐘誤差來攻擊,光是信任某個隨機的外部時間源是不夠的

一種可能是灰姑娘攻擊:若防火牆這類攸關安全的程式有帶時間鎖的授權,攻擊者可能把你的時鐘往前撥,「讓你的防火牆變成一顆南瓜」。

鑑於可能攸關 safety、且以我們理解不深的方式使用時間的 IoT 裝置正在擴散,現在有人擔心可能出現大規模的阻斷服務攻擊。

提供安全時間有幾種可能做法:

  • 給每台電腦一個無線電時鐘(你的智慧手機有 GPS)——但那可能被路過的卡車司機干擾

  • 放棄絕對時間,改用 Lamport 時間:你只在乎事件 A 是否發生在事件 B 之前,而非今天是幾號。基於穩健性理由,Google 在其內部憑證中不使用時間,而是用序號範圍搭配撤銷機制。

  • 網路時間協定(NTP):有中等程度的保護(時鐘投票與時間伺服器認證),對許多用途夠可靠。

    Netgear 把它的家用路由器硬編碼成使用威斯康辛大學麥迪遜分校的一台 NTP 伺服器,該校因此每秒被數十萬個封包淹沒;Netgear 最後付了 37.5 萬美元維持該時間服務三年。 不久後 D-Link 重複了同樣的錯誤。

    其次,自 2016 年起出現了利用 NTP 伺服器作為放大器的阻斷服務攻擊;數百萬台伺服器被發現可被濫用,於是許多 ISP 甚至 IXP 開始封鎖它們。

    所以如果你打算在企業網路之外部署大量倚賴 NTP 的裝置,最好認真想想你要信任哪些伺服器,並注意 CERT 的最新指引。

容錯與故障復原#

故障復原往往是安全工程最重要的面向,卻也是最被忽視的。

多年來,多數電腦安全的研究論文處理的是機密性,其餘多數處理真實性與完整性;可用性幾乎被忽略。

然而現代資訊業(不論是銀行還是搜尋引擎)的實際支出恰恰相反:花在可用性與復原機制(多個處理據點、備援網路)上的,遠多於花在程式碼審查與內部稽核這類完整性機制上的;而後者又遠多於花在加密上的。

隨著你讀完本書,你會看到從防盜警報、電子戰到保護公司免於 DDoS 攻擊等許多應用,根本上都是關於可用性。容錯與故障復原往往是安全工程師工作的核心。

古典容錯通常基於備援,並以日誌與鎖定這類機制加固;當它必須抵擋對這些機制的惡意攻擊時,就大為複雜化。

定義上:故障(fault)可能導致錯誤(error),也就是不正確的狀態;這可能導致失效(failure),也就是偏離系統規定的行為。我們為容忍故障與從失效中復原而建入系統的韌性,會有故障偵測、錯誤復原與(必要時)失效復原等成分。

失效模型#

拜占庭失效#

首先,我們關心的失效可能是正常的或惡意的,而我們常把後者建模為**拜占庭式(Byzantine)**的。

拜占庭失效的靈感來自:有 n 位將軍在守衛拜占庭,其中 t 位已被進攻的土耳其人收買,要製造盡可能多的混亂。將軍們可以透過信使傳遞口頭訊息,而信使是可信的,所以每位將軍都能與其他每位將軍交換保密且真實的通訊。最多能容忍多少叛徒 t?

關鍵觀察是:若我們只有三位將軍——Anthony、Basil 與 Charalampos——而 Anthony 是叛徒,那麼他可以對 Basil 說「我們進攻」、對 Charalampos 說「我們撤退」。Basil 現在可以對 Charalampos 說「Anthony 說進攻」,但這不讓 Charalampos 能斷定 Anthony 就是叛徒——那也可能是 Basil:Anthony 可能對兩人都說了「撤退」,而 Basil 在說「Anthony 說進攻」時撒了謊。

Lamport、Shostak 與 Pease 這個優美的洞見證明了:這個問題有解,當且僅當 n ≥ 3t + 1。

當然,如果將軍們能對訊息簽名,就沒有將軍敢對兩位不同的同僚說不同的話。這說明了數位簽章之力量,以及一般而言端對端安全機制之力量。

另一個教訓是:如果一個失效的(或能被對手誘使失效的)元件給出「錯的答案」而非「沒有答案」,那麼用它建造有韌性的系統就困難得多。

元件失效時就直接停下來、或至少能被快速識別並列入黑名單,是很有用的。

與容錯的互動#

我們可以用幾種方式約束失效率,最明顯的兩種是備援故障即停(fail-stop)行程。後者把錯誤更正資訊與資料一起處理,並在偵測到不一致時停止——例如銀行交易處理通常會在處理任務後偵測到不平衡狀況時停下來。

從太空梭到 Google:容錯多處理器的演化

1970 年代有由太空梭計畫驅動的**容錯多處理器(FTMP)**先驅工作,探索哪些元件應該備援、以及「錯誤偵測在哪裡發生、一切要同步得多緊密」的相關設計取捨。這類研究最終驅動了用於各種潛艦與太空船的容錯處理器設計,以及波音與空巴使用的架構。

FTMP 的想法也被 Tandem、接著被 Stratus 商業化,後者販售用於支付處理的機器。

一張替換卡會用郵寄送來;你把它拿到機房、注意到 5 號卡有個閃爍的紅燈,把它拔出來換上新的——而這一切都在機器每秒處理數十筆交易的同時進行。

如今大型服務公司的資料中心有精緻得多的協定,確保機器失效時另一台接手;機架失效時另一個機架接手;甚至資料中心失效時,其工作負載也能在其他中心快速復原。 Google 是相關軟體堆疊的先驅之一,它在 2000 年代初發現:用一般 PC 加聰明軟體建造大規模系統,遠比向專門廠商買越來越大的伺服器便宜。

但備援有代價:

  1. 我們必須應付更複雜的軟體堆疊與工具鏈。 銀行最終離開了 Stratus,因為它們發現它整體上比傳統大型主機更不可靠:雖然硬體失效造成的停機較少,但這無法補償不熟悉的開發環境所造成的額外軟體失效。

  2. 若我有多個帶備份資料的據點,任何一個被攻陷都可能導致機密性失效;而若我有法定銷毀義務的資料,要從多卷備份磁帶中清除它會很頭痛。

    在備援雲端服務上用容器開發軟體的當代問題,不在程式語言、也不在透過資料中心被攻陷,而在於開發者不熟悉雲端服務商的存取控制工具,太常把敏感資料留成全世界可讀。

還有給粗心者的陷阱。 作者曾以專家身分被找去一個案子:他的客戶在商店用信用卡時被逮捕、被指控持有偽卡並被警方毆打。他堅稱卡片是真的。很久以後我們讓 VISA 檢驗那張卡,確認它確實是真的。

我們盡可能重建出來的經過是這樣:信用卡磁條上有兩種備援——把磁軌上所有位元組互斥或起來得到的簡單檢核值,以及一個密碼式檢核值。前者用來偵測錯誤,後者用來偵測偽造。在這個特定案例中,商家的讀卡機看來是失準到造成了偶數個位元錯誤,這些錯誤在簡單檢核值中碰巧互相抵消,卻讓密碼檢核值失敗。結果是一次假警報,以及我的客戶生活中的一場重大災難。

訓練飛行員駕駛雙發動機飛機涉及先在模擬器、再在有教官陪同的真飛機上反覆演練引擎失效程序。新手飛行員實際上更可能在雙發動機飛機上被引擎失效害死,而不是在單發動機飛機上——對他們而言,降落在最近的田地比應付突然的不對稱推力危險性更低。

儀表失效也一樣:如果在壓力下你倚賴的是那個壞掉的,駕駛艙裡有三個人工地平儀也幫不上忙。

飛機比許多現代資訊系統簡單得多——然而仍有飛行員未能管理好本該保他們安全之備援而造成的空難。也有複雜的失效,例如兩架波音 737 Max 因單一感測器失效而墜毀——飛機有兩個感測器,但軟體沒有讀取兩者,而飛行員未受過診斷該問題與管理其後果的訓練。

系統設計者太常放進多重保護機制,卻沒有夠仔細地想透其後果。許多其他安全失效是可用性的失效——備援不是拙劣設計的解藥。

韌性是為了什麼#

把備援或其他韌性機制引入系統時,我們必須理解它們是為了什麼,以及各行為者面對的誘因。因此韌性是本地的、還是跨越地理或組織邊界的,就很重要。

  • 本地情況:複製可以是伺服器的內部特性,讓它更值得信賴。從 1980 年代的 Stratus 與 Tandem,到元件層次的標準硬體複製(如 RAID);1990 年代末以來則有大量投資在機架級系統,讓多台便宜 PC 做昂貴伺服器的工作,並確保失效的伺服器能被快速接手、失效的機架也能在熱備機架上復原。這些現在是雲端服務架構的標準元件:任何營運數十萬台伺服器的公司,失效多到復原必須大體自動化。

  • 但情況常常複雜得多:一個服務可能必須假設它的部分客戶端正試圖欺騙它,同時也可能必須倚賴若干都不完全準確的服務。開戶或簽發護照時,我們可能想比對從選民名冊、信用機構到駕照資料庫的服務,而結果常常不一致

  • 不信任的方向會影響協定設計:一台面對多個不可信客戶端的伺服器,與一個倚賴多台可能不稱職、不可用或惡意之伺服器的客戶端,兩者都會想控制協定中的訊息流向,以遏制阻斷服務的效果。

  • 有時重點在安全的可更新性(renewability):明顯的例子是銀行卡——銀行可以不時寄出新版卡片來升級安全性(從磁條升級到晶片,或從便宜晶片升級到更精密的),也能在被攻陷時對受影響客戶提前寄卡以復原。付費電視與行動電話有點類似。

備援在哪一層#

系統可以在若干層次上被做成能抵抗錯誤、攻擊與設備失效。如同存取控制,往堆疊上層走時,它們會逐漸變得更複雜、更不可靠。

層次機制能防什麼/不能防什麼
硬體Stratus 系統、RAID 磁碟簡單複製無法防禦惡意軟體,也擋不住利用有缺陷軟體的入侵者
行程群組在不同位置的多台伺服器跑多份系統並比對輸出能擋住對手取得機器實體存取權並顛覆它(機械破壞或插入未授權軟體)的攻擊;擋不住授權使用者的攻擊、或壞的授權軟體造成的損害(後者可以直接下令刪除關鍵檔案)
備份定期取得系統副本(檢查點),通常存在不可覆寫的媒體上;也可能保存檢查點之間所有交易的日誌不只讓我們能從實體資產毀損中復原,也確保若我們在邏輯層次受到攻擊,仍有希望復原。1980 年代的經典例子是「在特定日期刪除客戶資料庫的定時炸彈」;自加密貨幣出現以來,流行的是勒索軟體
應用層(最高層)後備(fallback)系統——主系統不可用時處理轉回的、能力較低的系統例子是電子終端機失效時用手動壓印機從卡片浮凸擷取信用卡交易
  • 備援磁碟保護不了你免於「刪除所有帳戶檔案的惡意程式設計師」;
  • 而如果他不是刪檔案、而是寫程式慢慢插入越來越多的錯誤,備份也擋不住他
  • 兩者對資料機密性的攻擊都提供不了太多保護。
  • 另一方面,如果你的資料處理中心燒掉了,世界上最好的加密也幫不了你。

真實世界的復原計畫與機制涉及以上全部的混合。

備份演練的演化:從一年一次到「混沌猴」

作者在 1980 年代做銀行業時,他們估計在主處理中心被摧毀後大概能在一小時內讓備份系統運作,但測試受限於他們不想在營業時間冒險處理交易:他們一年會在某個星期六把正式系統復原到備份資料中心一次。

  • 1990 年代初,英國超市 Tesco 已進展到實兵演練:他們一年一次在不預警操作員的情況下拔掉主處理中心的插頭,確保備份能在 40 秒內起來。
  • 2011 年,Netflix 發展出**「混沌猴(chaos monkeys)」**——會隨機打掉一台機器、一個機架、甚至整個資料中心的系統,以持續測試韌性。
  • 到 2019 年,大型服務公司已達到不需要這個的規模。如果你有跨三十個資料中心的三百萬台機器,你會持續失去機器、經常失去機架,而整個資料中心失效的頻率也高到你必須把東西工程化成能繼續運轉。

所以如今你可以直接付錢,讓雲端服務商替你操心很多細節。但你必須真正理解 Amazon、Google 或微軟能替你處理哪種失效、以及哪些你必須自己面對。

主要供應商的標準服務等級協議允許他們每月中斷你的服務相當多小時;而若你用較小的雲端服務(即使是政府雲),它會有你必須仔細思考的容量限制。

值得試著弄清楚你倚賴哪些在你直接供應鏈之外的服務。

英國 2001 年發生油罐車司機罷工,一些醫院因人力短缺而必須關閉——而這本來不該發生。政府為醫師與護理師配給了汽油,卻沒配給學校老師。於是學校關了,護理師得留在家裡照顧孩子,於是醫院也關了。

這幫助罷工者擊敗了首相布萊爾:他放棄了自己的招牌環境政策——穩定調高燃料稅。

隨著我們越來越互相依賴,應變規劃只會越來越難。

阻斷服務攻擊#

我們想讓安全服務容錯的理由之一,是讓阻斷服務攻擊較不吸引人、較無效,或兩者兼具。這類攻擊常被用作更大計畫的一部分:例如打掉一台安全伺服器以迫使其他伺服器使用快取的憑證副本,或淹沒一台網頁伺服器讓它暫時離線,再讓另一台機器提供受害者試圖下載的網頁。

如果主體是匿名的——例如有數個等效服務在負載平衡器之後,而對手不知道該攻哪一個——他可能就無效了。

在做不到、而對手知道該攻哪裡的情況下,有些阻斷服務攻擊能被備援與韌性機制擋下,有些不能。

例如 TCP/IP 協定幾乎沒有有效機制讓主機保護自己免於網路洪泛,而洪泛有各式各樣的變種。對付這類攻擊的防禦,往往涉及把你的站點搬到有專門「洗封包」硬體的更強力託管服務——或者追查並逮捕加害者。

DDoS 的二十年演化史:從 Panix 到「booter」服務

分散式阻斷服務(DDoS)攻擊在 1996 年被用來讓紐約 ISP Panix 停擺數天時進入公眾視野。1990 年代末,它們偶爾被腳本小子用來打掉聊天伺服器。

2001 年之後的三年,勒索者開始使用它們:他們會組建一個由被攻陷 PC 構成的殭屍網路,用封包流量淹沒目標網頁伺服器,直到其擁有者付錢請他們罷手。典型目標是線上博彩公司,勒索金額通常在 1 萬到 5 萬美元之間,而典型的博彩業者第一次遇到時都付了錢。

當攻擊持續時,第一個解法是複製:業者把網站搬到 Akamai 這類託管服務,其伺服器數量之多(且離客戶之近)足以承受一般殭屍網路所能丟出的任何東西。

到 2018 年我們繞了一整圈:約有五十個壞人在經營 DDoS 即服務,主要賣給想打掉對手 teamspeak 伺服器的遊戲玩家。這些服務以「booter」(把你的對手踢出遊戲)之名在線上販售;幾美元就能買到大概 100 Gbit/秒的洪泛。服務業者也用更委婉的說法稱它們為「壓力測試器(stressors)」——說法是你可以用它們測試自己網站的穩健性。

這騙不了任何人。 2018 年聖誕節前夕,FBI 拿下了其中十五個網站、逮捕了若干業者,並使 DDoS 流量在數個月間顯著下降。

最後,若存在較脆弱的後備系統,一個常見技巧是用阻斷服務攻擊逼受害者進入後備模式。經典例子是支付卡:智慧卡一般比磁條卡更難偽造,但每年大概有 1% 因靜電與接點磨損而失效,也還有些觀光客仍使用磁條卡。所以多數卡片支付系統仍有使用磁條的後備模式。 一個簡單的攻擊是用假終端機、或插進真終端機纜線的竊聽器,擷取卡片明細,再把它們寫進一張晶片已死之卡片的磁條上。

命名#

命名在一般分散式系統中是個次要但麻煩的面向,但在安全工程中它變得出奇地難。

1990 年代網路泡沫期間,SSL 被發明、我們開始建造公鑰憑證機構時,就撞上了「憑證上該放什麼名字」的問題。

一張只說「名叫 Ross Anderson 的人被允許管理機器 X」的憑證用處不大。作者過去以為自己是唯一的 Ross Anderson;但搜尋引擎一出現,他就找到了幾十個。 而他自己也在數十個不同系統中以不同名字為人所知。名字存在於脈絡之中。

概念上,命名空間可以是階層式或扁平的。你可以把作者識別為「在英格蘭劍橋教電腦科學的那個 Ross Anderson」、或「郵件地址是 rossjanderson@gmail.com 的那個 Ross Anderson」、甚至「護照號碼是某某的那個 Ross Anderson」。但這些不是同一種東西,而把它們連起來會造成各式各樣的問題。

一張只說「這是管理機器 X 的金鑰」的公鑰憑證是持有人憑證(bearer token),就像一把金屬門鑰匙;誰控制該憑證的私鑰誰就是管理員,就好像 root 密碼裝在銀行金庫的信封裡。

但一旦牽涉到我的名字、我必須出示護照或身分證來證明我是誰,系統就取得了進一步的依賴。 如果我的護照被攻陷,後果可能極為深遠;而我真的不想給政府一個「以我的名義為它的探員簽發一本假護照」的誘因。

911 之後,各國政府開始強迫企業在先前不被認為必要的場合要求政府核發的照片 ID。例如在英國,你不能再只用購票的信用卡登上國內航班;你必須出示護照或駕照——而你在分行辦理超過 1000 英鎊的轉帳、租房、聘律師甚至找工作時也需要它。這類措施不只不便,還把新的失效模式引進各式各樣的系統。

世界走向更大、更扁平命名空間的第二個理由是大型服務公司在線上認證中日益取得的支配地位。你的名字越來越是全球性的:你的 Gmail 或 Hotmail 地址、你的 Twitter 帳號、你的 Facebook 帳號。

這些公司不只受惠於技術外部性與商業外部性,它們也算是解決了命名的一部分問題。但我們不能自滿,因為還有許多問題存在。

Needham 的十條命名原則#

二十世紀最後二十五年,建造分散式系統的工程師撞上許多命名問題。把名字綁定到位址的基本演算法稱為會合(rendezvous):匯出名字的主體在某處公告它,而想匯入並使用它的主體去搜尋它。明顯的例子包括電話簿與檔案系統目錄。

以下是 Needham 的十條原則:

  1. 名字的功能是促進共享。

    我的銀行帳號存在,是為了與這週我想提款的櫃員分享「我上週存了錢」這個資訊。一般而言,當要共享的資料是可變的時,才需要名字。 若我只想提出與存入完全相同的金額,一張持有人存單就夠了。

    反過來,資料不會被連結時,名字也不必被共享或連結:除非我要用該帳戶付電話費,否則沒必要把我的銀行帳號連到我的電話號碼。

  2. 命名資訊未必全在一處,所以解析名字會帶來分散式系統的一切一般性問題。

    這一點格外強烈成立。銀行帳戶與電話號碼之間的連結假設兩者都保持穩定,於是每個系統都倚賴另一個,而對其中之一的攻擊會影響另一個。

    許多銀行用雙通道授權對抗釣魚——你線上下單付款,手機就收到簡訊說「若您要付 X 給帳戶 Y,請把以下四位數碼輸入瀏覽器」。標準攻擊是騙子向電話公司宣稱自己是你、報告手機遺失,於是他們給他一張能用你號碼的新 SIM,他就捲款而去。電話公司本可以阻止這件事,但它不太在乎認證,因為它頂多損失一些邊際成本為零的通話時間。而最新的攻擊是用 Android 惡意程式竊取認證碼——Google 本可以靠把 Android 平台鎖得像 Apple 一樣緊來阻止,但它缺乏這麼做的誘因。

  3. 假設「只會需要這麼多名字」是壞事。

    IP 位址短缺(催生了 IPv6)已被充分討論。較不為人知的是:信用卡業者做過最貴的升級,就是把十三位數的卡號改成十六位。 發卡者原本假設十三位夠了,但系統最後有數萬家銀行,其中許多有數十種產品,所以需要六位數的銀行識別碼;有些發卡者有數百萬客戶,所以九位數的帳號成為常態;還要有一位檢查碼。

  4. 全域名字買到的比你想的少。

    IPv6 的 128 位元位址理論上能讓宇宙中每個物件都有唯一名字。然而要讓你我做生意,我這端的本地名字必須被解析成這個唯一名字、再解析回你那端的本地名字。

    在中間喚起一個唯一名字可能什麼也沒買到;如果那個唯一命名服務耗時、花錢或偶爾失效(它必然會),它甚至會礙事。事實上,名字服務本身通常必須是一個與我們試圖保護之系統同等規模(與同等安全等級)的分散式系統。所以這方面不會有銀彈。

  5. 名字意味著承諾,所以要讓方案彈性到足以應付組織變動。

    英國政府的安全郵件金鑰管理系統忽略了這條健全的原則:主體的私鑰是從其郵件地址產生的。於是頻繁的組織重整意味著安全基礎設施每次都得重建——而且還得花更多錢解決「人們如何存取舊材料」這類次生問題。

  6. 名字可能兼作存取票證或能力。

    一般而言,假設「今天的名字不會是明天的密碼或能力」是個壞主意。

    例如挪威過去認為公民 ID 號碼是公開的,但它最後在太多應用中被當成某種密碼使用,以致他們不得不讓步、把它變成私密的。美國社會安全號碼(SSN)也有類似問題。於是國防部創造了一個代用號碼 EDIPI,本應不敏感;但果不其然,人們開始把它當認證符而非識別符使用。

    有時名字與密碼的角色是曖昧的。作者過去要進入大學的一個停車場,必須對著閘門的麥克風說出自己的姓與停車證號碼。所以如果他說「Anderson, 123」,哪一個是密碼? 其實是「Anderson」——因為任何人都可以走過停車場,從車擋風玻璃上的停車許可抄下有效的證號。

  7. 如果錯的名字一目了然,事情會簡單得多。

    在標準分散式系統中,這讓我們能對快取採取寬鬆態度。在支付系統中,只要卡號看起來有效(最後一位是前十五位的適當檢查碼)且不在熱卡清單上,終端機離線時就會接受信用卡號。現代晶片卡上的憑證提供了同一基本概念的更高品質實作。

    仍然可能出錯的例子:愛爾蘭警方為一位因未繳超過五十張交通罰單而被通緝的「Prawo Jazdy」先生建了五十多份卷宗——直到他們發現那是波蘭文的「駕駛執照」。

  8. 一致性很難,而且常被蒙混。

    若目錄被複製,你可能因為可用的目錄太多或太少而無法讀或無法寫。

    命名一致性以許多方式對企業造成問題,其中最惡名昭彰的大概是條碼系統。這在理論上夠簡單——每項產品一個唯一數字碼——但實務上不同的製造商、經銷商與零售商在資料庫中對同一組條碼附上相當不同的描述。 於是搜尋「Kellogg’s」的產品,會因為有沒有插入撇號而得到完全不同的結果,這在供應鏈中可能造成混亂。

  9. 別太聰明。

    Signal 與 WhatsApp 這類較現代的系統改用行動電話號碼。同樣地,早期在 SET 這類協定中用公鑰憑證取代銀行帳號與信用卡號的嘗試失敗了;但在肯亞 M-Pesa 這類行動支付系統中,它們被電話號碼取代了。

  10. 有些名字綁定得早、有些不早;一般而言,能避免的話早綁定是壞事。

    謹慎的程式設計師通常會避免把絕對位址或檔名寫死,因為那會讓升級或更換機器變難。通常較好的做法是把它留給組態檔或 DNS 這類外部服務。

    然而安全系統往往想要穩定且可問責的名字,因為任何用於最後一刻解析的第三方服務都可能成為攻擊點。設計者因此必須注意命名資訊去哪裡、裝置如何被個人化寫入它、以及它們如何被升級——包括安全性可能倚賴之服務的名字,例如前述的 NTP 服務。

命名還會出什麼錯#

Needham 的原則是為 1990 年代初的世界打造的,那時命名系統可以依系統擁有者的方便強加。一旦我們進入以全球規模運作、基於網路且互相連結的現代服務業現實,我們發現還有更多要補充。

到 2000 年代初我們學到:沒有任何命名系統能同時做到全域唯一、去中心化,且對人有意義。 事實上這是個經典的三難(Zooko 三角):三個屬性你只能取其二。

  • 過去工程師選的是唯一且有意義(如 URL),或唯一且去中心化(如 PGP 中的公鑰、或 Android 中作為 app 名稱的自簽憑證)。
  • 人的名字有意義且是本地的,但無法擴展到網際網路規模。

Facebook 這類網站的創新,是在真正大的規模上證明名字不必唯一。我們可以用社會脈絡建造既去中心化又有意義的系統——這正是我們大腦演化來應付的東西。每個 Ross Anderson 有不同的朋友集合,你可以用那個把我們區分開來。

命名與身分#

安全協定中的主體通常以許多不同種類的名字為人所知——銀行帳號、公司登記號、姓名加生日或郵政地址、電話號碼、護照號碼、健保病人號碼,或某個電腦系統上的使用者代號。

一個經典例子來自不動產產權登記:想賣房子的人常用著與買房時不同的名字——她可能因結婚、性別轉換而改名,或開始使用中間名。土地登記系統必須應付大量這類身分問題。

導致淪陷的身分失敗有兩種類型:

  • 我樂意冒充任何人:包括為洗網路犯罪所得而開帳戶。
  • 我想冒充特定個人:例子是 SIM 卡置換(我想複製某位執行長的手機,好洗劫公司銀行帳戶)。

如果銀行(或電話公司)只是要求人們提供兩份地址證明(如帳單),那很容易。要求政府核發的照片 ID,可能要求我們去分析「持有銀行帳號 12345678 的 Aaron Bell,就是護照號碼 98765432、生日 1956/3/4 的 Aaron James Bell」這樣的陳述。

這可以視為兩個獨立系統(銀行的與護照局的)之間的符號連結。而後半部分又封裝了進一步的陳述:「美國護照局的檔案編號 98765432,對應到紐約出生登記中 1956/3/4 的 Aaron James Bell。」如果 Aaron 一般被叫做 Jim,事情就更亂了。

  • 大量護照詐欺是發照前詐欺:壞人以「尚未申請護照、且出生證明容易取得」的真實公民之名申請護照。死後申請也很常見。
  • Second Life 的營運商 Linden Labs 曾導入一個方案:你藉由提供一位年滿 18 歲者的駕照號碼或社會安全號碼來證明自己已滿 18 歲。如今網路搜尋很快就能查到許多人的這類資料,例如饒舌歌手 Tupac Amaru Shakur;而是的,Linden Labs 確實接受了 Shakur 先生的駕照號碼——即使該駕照已過期,而且他已經去世了。
制度性失敗與紀錄遺失

制度性失敗:例如阿拉伯聯合大公國開始為所有訪客做虹膜掃描,因為那些因賣淫罪被驅逐回巴基斯坦的女性,會在幾週後帶著一本用不同名字簽發的真護照、陪著不同的「丈夫」出現。類似問題使許多國家改發生物辨識簽證,好讓自己不必倚賴自己不想信任之國家的護照簽發者。

除了貪腐之外,一個普遍的失敗是原始紀錄的遺失。

在出生、婚姻與死亡登記由地方以紙本保存的國家,有些會遺失,而聰明的冒名者會利用這些。

你可能以為數位化正在修正這個問題,但數位紀錄的長期保存即使對富裕國家也是難題:文件格式改變,軟硬體過時,而你要嘛得模擬舊機器、要嘛得轉譯舊資料,兩者都不理想。明智的已開發國家仍保留紙本原件作為長期的存證文件。

在較不已開發的國家,你可能得在政府 IT 的不穩定天然災害之間航行——同時還聽著發展顧問「把它放上區塊鏈!」的塞壬之歌。

文化假設#

名字底下的假設因國家而異。

  • 在英語世界中,人們一般想用多少名字就用多少;名字就是你被稱呼的東西。但有些國家禁止使用別名,另一些則要求別名必須登記。
  • 出生、婚姻、民事伴侶關係、性別轉換與死亡的民事登記極其複雜,往往政治化,在許多國家與宗教及身分文件的簽發糾纏在一起。而國與國之間不相容的規則,會對移民、觀光客乃至有海外客戶的公司造成真實的問題。
當名字衝突:從教授到跨性別者的實例

作者實驗室已故的 Karen Spärck Jones 教授,因婚後合法改名但繼續用原名發表,每年都收到大學來信問她為什麼沒有發表任何東西(她在薪資名冊上叫 Karen Needham)。發表追蹤系統就是應付不了人事系統所知道的一切。

而隨著軟體進入一切、系統被連起來,衝突可能有意想不到的遠端效應。Karen 也是大英圖書館的理事,當圖書館開始用持有人所屬大學圖書證上的名字簽發自己的入館證時,她並不以為然。當大學導入一套以薪資名冊姓名為索引、用於統一通行建築、圖書館與餐廳的 ID 卡系統時,這些問題造成了更多摩擦。

  • 想阻止公司使用其舊性別姓名的跨性別者
  • 分居或離婚時想停用夫姓的女性——若她們正在逃離施虐伴侶,這可能是必須的
  • 因宗教改宗而改名的人。

衝突的來源沒有盡頭。如果你在建造一個希望能全球規模化的系統,你最終得處理它們全部。

人名慣例也因文化而異:

  • 香港來的中國人可能同時有英文與中文的名,英文名在姓之前、中文名在姓之後。
  • 南印度、印尼與蒙古的許多人只有一個名字(單名 mononym)。
  • 印度的慣例是加兩個縮寫——出生地與父名。所以「BK Rajan」可能表示「來自 Bangalore、Kumar 之子 Rajan」。南印度移民到美國的常見做法是把父名(此處是 Kumar)當姓;但當西方電腦系統把 Rajan 誤解為姓時,混亂就產生了。
  • 俄羅斯人以名、父名、姓為人所知。
  • 冰島人沒有姓;他們的名之後接父名(男性)或母名(女性)。過去當「Maria Trosttadóttir」抵達美國移民關卡、官員得知「Trosttadóttir」既不是姓也不是父名時,標準做法是強迫她採用一個父名作為姓(例如若她父親叫 Carl 就用「Carlsson」)。美國的許多印度人也遇過類似問題,全都造成了不必要的冒犯。
  • 還有些文化中,你的名字在生了孩子之後會改變。

另一條常被認為的文化分界,是「基於隱私理由不接受身分證的英語系國家」與「身分證是常態的、被拿破崙或蘇聯征服過的國家」。較不為人知的是,大英帝國樂於對許多被統治人口強加 ID,所以真正的分界也許是「一個國家是否曾被征服」。

ID 的在地歷史制約了各式各樣的假設:

  • 作者認識一些德國人,他們拒絕相信一個國家能在沒有適當人口登記與身分證系統的情況下運作,卻也承認自己很少被要求出示身分證(例如開銀行帳戶或結婚時)。他們的卡號不能當名字,因為那是文件編號、每次換發新卡就會變。
  • 冰島的 ID 卡號則是靜態的:它就是公民的生日加上兩位數字。更甚者,法律要求銀行帳號中必須含帳戶持有人的 ID 號碼。這大概是私密與公開 ID 編號的兩個極端。

最後,在許多較不已開發的國家,登記公民並發給他們 ID 這件事不只沒效率,而且是政治性的。

執政的部族可能藉由讓對方領土上的出生登記變困難、或讓取得身分證變不方便,來剝奪其他部族的公民權。有時卡片會在選舉前重新簽發,以更新或強化這種歧視。 卡片可與營業許可及福利給付綁定;延誤可被用來索賄。

有些國家(如巴西)在州與聯邦層級有分離的登記系統,另一些(如馬拉威)則讓大部分人口未被登記。有許多被排除的群體,例如出生在父母國籍以外之國家的難民兒童,以及因宗教或意識形態理由而成為無國籍者的群體。

而如果你以為這是第三世界的問題:有幾個美國州正用繁瑣的登記程序讓黑人更難投票;而在「疾風世代(Windrush)」醜聞中,人們發現英國政府驅逐了一批本自動有權取得公民身分的外國出生英國居民——因為他們沒有維持一份好到足以滿足日益排外之部長們的公民身分紙本軌跡。

簡言之,關於政府與人民姓名之間關係的隱藏假設,以各種方式限制系統設計,並在假設被跨越國界搬運時造成意料之外的失敗。

工程師必須永遠警覺:服務導向的 ID 是一回事,法定身分或公民身分證明是另一回事。政府永遠在試圖把兩者糾纏起來,而這帶來各式各樣的痛苦。

名字的語意內容、唯一性與穩定性#

從一種名字換到另一種可能有危險。

一家銀行在把客戶資料的儲存方式從帳號改成姓名地址後被告了。他們寫了一支程式把每位客戶操作的所有帳戶連起來,希望這能更精準地投放垃圾郵件。對一位客戶的效果很嚴重:他為情婦所開帳戶的對帳單被寄給了他的妻子,於是她跟他離婚了。

名字的語意會隨時間改變。 在許多運輸系統中,車票與收費標籤可以用現金購買,這化解了隱私顧慮;但把它們連到銀行帳戶更方便,而這些連結會隨時間累積。英國退休人士用來免費搭公車的卡也是從匿名開始,但實務上公車公司會試圖把卡號連到其他乘客識別符。

唯一性:人名在我們住在小社群時演化出來。我們一開始只有名,但到中世紀晚期,旅行的成長導致政府逼迫人們採用姓氏。

那個過程花了一個世紀左右,並與紙張引進歐洲有關——紙作為羊皮紙的低成本、更防篡改的替代品,讓人們過去用於道路通行費等場合的徽章、封印與其他持有人憑證,得以被提及其姓名的信函取代。

另一個極端也許是密碼式名字:名字是公鑰或被命名物件其他穩定屬性的雜湊。各式各樣的機制被提出,把真實世界的名字、地址甚至文件內容不可磨滅且永恆地映射到雜湊函數的位元串輸出上。加密貨幣與區塊鏈的世界大量使用基於雜湊的識別符。

這類機制能讓名字無法被重複使用;由於過期的網域名常被壞人買走並利用,這有時很重要。

一個「唯一性放錯地方」的銀行事故

在交易處理中,「給所有東西和所有人一個號碼」早已常見。但如果你沒把唯一性放在對的地方,就可能失敗。

一家英國銀行把唯一序號印在用來擷取交易的文具上,以此指派交易序號。有一次,他們想匯 2000 萬英鎊到海外,操作員誤打成 1000 萬。於是第二筆 1000 萬的付款被下單——但它從紙本文件上取得了同一個交易序號。

結果是兩筆日期、收款人、金額與序號都相同的付款被送到 SWIFT,而第二筆被當成重複而丟棄。

穩定性:許多名字含有某種位址,然而位址會改變。

劍橋還有電話簿的時候,大約每年有四分之一的地址改變;工作用電子郵件的周轉率大概更高。1990 年代末我們試著建立一份「使用加密郵件的人及其金鑰」目錄時,發現條目變更的主因是郵件地址改變。(有些人原本假設會是金鑰的遺失或遭竊;來自這個來源的貢獻恰恰是零。)

現在情況或許穩定些。多數人試圖保留個人手機號碼,所以它們傾向長壽,個人郵件地址也日益如此。Google 與微軟這類大型服務商一般不會把同一個郵件地址發兩次,但其他公司仍會。

分散式系統的先驅認為把位址放進名字是壞事。但階層式命名系統可能涉及多層抽象,每一層的部分位址資訊構成上一層名字的一部分。 一個命名空間扁平與否是否較好,也取決於應用。

名字是複合的系統也有類似問題。例如有些線上業者靠「郵件地址 + 信用卡號」的組合認出作者——這顯然是壞做法:撇開他有好幾個郵件地址不談,他也有好幾張信用卡。

許多人也不時更換郵件地址以躲避垃圾郵件。另一方面,警方與其他機關會希望人們不要使用化名——這把我們帶進線上可追溯性的整個問題。

名字使用的限制#

有些名字只能在受限情況下使用。 這可能由法律規定(如美國社會安全號碼及其他國家的對應物),有時是行銷考量:相當一部分客戶會避開索取太多資訊的網站。

最後,當我們談到法律與政策時,名字的定義會拋出全新且意想不到的陷阱。

例如允許警方蒐集通聯資料(誰在何時打給誰的紀錄)的規範,通常比規範監聽的寬鬆得多;在許多國家,警方只要開口就能取得通聯資料。

這導致了關於 URL 地位的角力——URL 含有傳給搜尋引擎的參數這類資料。顯然有些警察會想要一份「所有點擊過 http://www.google.com/search?q=cannabis+cultivation 這種 URL 的人」的清單;而同樣顯然地,許多人會認為這種大規模拖網是不可接受的隱私侵犯。

英國法律的解方是把流量資料定義為「足以識別被通訊之機器」的資料,用白話說就是「第一個斜線之前的一切」。

名字的類型#

不只命名在所有層次上都複雜——從技術層、經過組織層到政治層——有些真正棘手的議題還會跨越層次。

名字不只可以指涉人(與代表他們行動的機器),也可以指涉:

  • 組織
  • 角色(「當值官」)
  • 群組
  • 複合構造
    • 擔任角色的主體——Alice 作為經理
    • 委任——Alice 代表 Bob
    • 連言——Alice 與 Bob

而這只是開始。名字也適用於服務(如 NFS 或公鑰基礎建設)與通道(可能指電線、通訊埠或密碼金鑰)。同一個名字也可能指涉不同角色:「作為電腦遊戲玩家的 Alice」應該比「作為系統管理員的 Alice」權限更少。

資安文獻中通常的抽象方式,是把它們當成不同的主體。所以名字與主體之間沒有簡單的對應,尤其當人們自帶裝置上班、或把工作裝置帶回家,因而可能在同一平台上有多個衝突的名字或角色時。

許多組織已開始仔細區分「Alice 本人」、「跑在 Alice 家用筆電上、代表 Alice 的程式」與「代表 Alice 跑在企業雲上的程式」。

企業主要想收到錢,而政府想唯一地識別人。實質上,企業想要你的信用卡號,政府想要你的護照號碼。 基於誘因的分析,有時能指出一個命名系統是開放還是封閉、本地還是全域、有狀態還是無狀態較好——以及維護它的人是否就是那些會承擔失敗成本的人。

最後,雖然作者用「人」來說明許多命名問題(因為那讓問題更即時、更有說服力),同樣的許多問題也以各種方式出現在密碼金鑰、唯一產品碼、文件 ID、檔名、URL 與更多東西上。

當我們深入現代企業網路的內部,可能會發現:DNS 輪詢指向多台各有自己 IP 位址、藏在單一名字後面的機器;或 Anycast 指向多台共用同一 IP 位址、藏在單一名字後面的機器;或 Cisco 的 HSRP 協定,其中 IP 位址與乙太網路 MAC 位址會從一台路由器移到另一台。

你必須仔細界定命名的範圍、理解誰控制你所倚賴的名字、弄清楚它們有多滑溜,並把系統設計成即使有它們的限制也仍然可靠。

小結#

許多安全分散式系統之所以付出巨大成本、或發展出嚴重漏洞,是因為設計者忽略了「如何建造(與如何不要建造)分散式系統」的基本功。 而這些基本功多數已經在電腦科學教科書裡待了一個世代。

  • 許多安全漏洞是某種形式的並行失敗:系統使用舊資料、以不一致或錯誤的順序做更新、或假設資料一致而其實不然甚至不可能一致。用時間為交易排序或許有幫助,但知道正確的時間比看起來難。
  • 容錯與故障復原至關重要。 提供「從安全失效、以及從隨機的實體與軟體失效中復原」的能力,是許多組織保護預算的主要目的。
    • 技術層次上,保護與韌性機制之間有顯著的互動。拜占庭失效——有缺陷的行程會串通而非隨機失效——是個議題,而它與我們對密碼工具的選擇互相作用。
    • 備援有許多不同的風味,我們必須使用正確的組合。我們不只要防護失效與蓄意操弄,也要防護「可能是更大攻擊計畫一部分」的蓄意阻斷服務。
  • 許多問題源自試圖讓一個名字做太多事,或對它做出「在某個特定系統、文化或司法管轄區之外並不成立」的假設。

例如,應該要能靠取消使用者名稱來撤銷其系統存取權,而不會因為其他功能一併被撤銷而被告。

最簡單的解法往往是給每個主體一個不作他用的唯一識別符,例如銀行帳號或系統登入名。但當合併兩個使用不相容命名方案的系統時,許多問題就冒出來了——有時甚至是意外發生的。

研究問題#

本章觸及了從安全時間協定到命名複雜性的許多技術議題。但也許最重要的研究問題是:如何設計出在惡意面前有韌性、能優雅降級、且在攻擊過去後能簡單地恢復其安全性的系統。

過去人們推銷過各式各樣的解藥,從「讓政府發給每個人 ID」到「把它全都放上區塊鏈」。然而這些魔法子彈似乎一隻妖精也沒殺死。

工程師研究失敗總是好主意;我們從那一座塌掉的橋學到的,比從一千座沒塌的橋學到的更多。 我們現在有越來越多失敗的 ID 系統,例如英國政府的 Verify 方案——一次為公共服務建立聯邦登入系統的嘗試,2019 年被放棄。也有研究社群在研究較不已開發國家 ID 系統的失敗。

也許我們該更仔細地研究「在什麼條件下我們能俐落地從腐敗的安全狀態中復原」。惡意程式與釣魚攻擊意味著任一時間都有一小(但非零)比例的客戶銀行帳戶處於犯罪控制之下,然而銀行系統仍然運轉下去。 受感染的筆電與手機比例在各國差異相當大,其效應也許值得更仔細的研究。

古典電腦科學理論把分散式系統中的收斂視為本質上的技術問題,其解法取決於技術性質(一個層次上是 ACID;另一個層次上是數位簽章、雙人控制與稽核)。

也許我們需要一個更高層次的視角:問我們如何取得對世界狀態的充分共識,並且不只納入技術韌性機制與保護技術,也納入「詐欺受害者取得補償」的機制。

純技術的機制若試圖免除對穩健補償的需求,實際上可能讓事情更糟。