所有拼圖都擺到桌面上之後,林劫發現一個被所有人忽略的問題——時間。三組DNS節點要同時過載,三組變電站要同步跳閘,通訊號中央協調要在電力波發的同一秒注邏輯炸彈。每一環都對度有要求,差出一秒就可能讓整個行從“癱瘓系統”變“幫系統做力測試”。而偏偏在這個要命的節點上,他發現網路端和理端走的不是同一個時鐘。
網路端用的是龍系統自己的NTP授時服務,所有聯網裝置強制同步到龍系統網的原子鐘叢集,度能到毫秒級。殭網路那兩百萬臺染的時候已經從宿主裝置上繼承了NTP對時資料,彼此的時鐘偏差最多不超過三十毫秒。但理端完全不是這回事。馬雄手下的人在鏽帶幹活用的是黑市上淘來的老舊裝置——老鬼改裝的那幾臺可程式設計電源本倒是帶了個溫補晶振,度撐死了能到每天漂移零點五秒左右,但發必須依賴林劫從網路端發過去的加脈衝,而加脈衝從林劫的跳板伺服到鏽帶變電站的接收端,中間要走七個纖節點。每個節點的轉發延遲林劫都用網路模擬逐段跑過,算下來大約四十到六十毫秒——網路端完全能接。真正棘手的不是網路延遲,是理端自的時鐘基線本不準。老鬼上次在二十毫安電流環上做時間標記的時候,用的參考時鐘是一臺從廢品站淘來的舊GPS授時模組,最近一週鏽帶上空電離層擾得厲害,GPS訊號抖得跟帕金森似的,那臺模組的時間誤差已經從幾十毫秒漂到了將近三秒。
三秒。在變電站跳閘這件事上,三秒意味著電尖峰和主網解列視窗之間會錯開整整三秒——要麼備用電源已經切完畢、斷路重新合閘,電網控制節點本不會進離線,要麼電尖峰還沒來,林劫的攻擊洪峰已經在網路層暴了意圖,龍系統的防AI有充足的時間把異常流量模式標記並下發到所有邊緣節點。
沈易把這個時間漂移的資料拿給林劫看的時候,林劫沉默了大概十秒鐘,然後說了一句:“不能用GPS。用系統自己的時鐘。”
這個想法乍一聽很荒謬。龍系統的NTP授時服務是封閉的,所有合法的時間同步請求必須經過PKI認證,客戶端需要有簽名的數字證書才能從原子鐘叢集同步時間。而林劫在殭網路裡對那些做的時鐘同步,本質上是用被染裝置自帶的系統時間在抗——沒有用龍系統的授時服務本,只是把所有裝置自己記錄的時間強行對齊,時鐘源是的,只是對齊之後得一致。但理端需要絕對時間,需要跟龍系統的原子鐘叢集對齊到毫秒級,否則三組變電站的跳閘訊號就會像響樂團沒了指揮一樣各自為政。
解決方案是林劫在天快亮的時候找到的。他在龍系統的部網路拓撲裡翻出了一臺次級授時伺服——這東西位於城東一個已經停用的舊通訊基站裡,理裝置還在機架上,供電也沒斷,但因為該基站三個月前被龍系統從主網裡除名,這臺授時伺服已經不在正規的NTP服務池裡了。不在服務池裡意味著不對外提供授時請求響應,卻仍然過纖直連從主幹原子鐘叢集同步自己的部時鐘。也就是說,這臺機自己知道準確時間,只是不對外說。
如果有人能理接這臺機——不需要認證,只要能到它的維護埠——就能從它的時鐘暫存裡直接讀取原子鐘授時資料,確到毫秒。然後再把這組資料手同步給老鬼改裝的那幾臺電源。
問題是那個基站在主城區。鏽帶的人進不去,進去了也不到機架——基站雖然停用,但理安保還在,巡捕的巡邏車每四十分鐘經過一次,門口還有一臺還在運轉的人臉識別攝像頭。沈易盯著林劫翻出來的那張基站結構圖,手指在螢幕了那個維護埠的位置:“從這裡到外牆大概十二米。如果能破開外牆的通風百葉窗,鑽進去,沿著電纜橋架走大概八米,就能到機櫃後面。維護埠就在機櫃背板的左下角,是一個RJ45介面。”
“百葉窗是什麼材質?”
“圖紙上標註的是鋁合金,但實際安裝的時候會不會工減料就不知道了。”
林劫沒再問。第二天凌晨他背了個工包,換了灰撲撲的工裝——就是那種通訊公司外勤維修工常穿的連工作服,口還印著個模糊的公司logo,是他從黑市上花五十塊買的二手貨。坐馬雄手下那輛破面包車到了基站外圍,貓在對面一棟廢棄居民樓的四樓窗戶後面,用夜視遠鏡盯著基站門口看了快一個鐘頭,把巡捕巡邏車的經過時間確記下來。三點二十七分一趟,四點零六分一趟,中間間隔三十九分鐘,誤差不超過一分鐘。攝像頭是舊型號,紅外夜視距離大概十五米,角度覆蓋基站大門和側面圍牆,但有一個盲區——它拍不到基站背面那堵牆和牆上的通風百葉窗,因為背面挨著一棟同樣廢棄的舊倉庫,兩棟建築之間只有一條不到一米寬的夾。
林劫從夾裡進去的時候,後背蹭著兩面牆的水泥面往前挪,挪到基站背面那堵牆下,抬頭看——百葉窗離地面大概三米高,鋁合金的,但固定螺鏽得厲害,有一顆已經鬆,歪在一邊。他用螺刀把那幾顆鏽螺挨個擰下來,手穩得像是擰自家水龍頭,擰完最後一顆,百葉窗往外一拉就開了。裡面是通風管,直徑大概六十公分,勉強夠一個人著肩膀爬進去。他把工包叼在裡,雙手撐著管壁往上蹭,蹭了大概兩米,到了電纜橋架的鐵質橫樑。沿著橫樑往右爬了大概八米,頭頂出現了他在地圖上看到的那個位置——機櫃背面。
機櫃的金屬背板冰冰涼涼,左下角果然有個RJ45介面,上面還著張泛黃的標籤,寫著“維護埠-未授權止接”。林劫把便攜終端接上去,從工包里拉出卷好的網線,上,終端螢幕亮起來。授時伺服的作業系統還是舊版本的Linux,核心沒打過最新的安全補丁,登介面也沒設碼——因為這個基站已經不在主網裡,運維人員早就把它忘了。他連Shell都不用提權,直接進了時鐘暫存的讀取介面——當前原子鐘授時時間以UTC格式顯示在螢幕上,確到毫秒,後面還跟著一連串跳的小數點後三位。他把這組資料儲存下來,用便攜終端上的一個小指令碼把UTC時間換算瀛海市的本地時間,又額外記錄了一個關鍵引數——這臺授時伺服的時鐘偏移量。從它最後一次與主幹原子鐘叢集同步到現在,時鐘偏移了大概四十七毫秒。四捨五,不到零點零五秒。夠用了。
他把資料打包加,用預先鋪好的低軌衛星短報文通道發給了沈易,發完之後把終端拔下來,網線卷好塞回工包,順著原路爬出去,再把百葉窗裝回去,螺一顆一顆擰。整個過程從鑽進夾到鑽出來,一共用了不到三十分鐘。巡邏車還沒來。沈易收到資料之後,立刻用纖直連跳板分發給三個變電站的接收端,老鬼在舊港區主變電站拿到授時資料之後用了不到十分鐘就手校準了那幾臺改裝電源的部時鐘,校準完之後還在加頻道里回了一條訊息,語氣不像是彙報工作,更像是自言自語:“誤差零點零三秒。老子這輩子對時都沒這麼準過。”
鏽帶北和鏽帶南分站也同步完了校準。馬雄親自守在鏽帶南那臺接收終端前面,看到螢幕上跳出來的同步功的提示,轉頭對旁邊蹲在地上菸的疤頭說了一句:“告訴兄弟們,時間對好了。誰手抖早按一秒,老子把他手指頭掰了。”疤頭把菸頭往地上一摁,笑了笑,沒說話。
同一天晚上,通訊號系統的邏輯炸彈注端也做了最後一次對時測試。沈易在墨影舊伺服上那套“綠波”專案的殘留程式碼裡埋了個帶時間發條件的補丁,用博士去年申請的一次授權金鑰簽了名。他自己反覆測了四次,每次都是在預設發時間到達後的四十毫秒完注,全部落在林劫要求的同步視窗。他盯著螢幕上第四次測試跑完的那行綠狀態碼,發現自己手心裡全是汗。不是張——是坐在螢幕前面連續跑測試跑太久了,手掌在鍵盤掌託上捂出來的。他把汗蹭在子上,截了張圖發給林劫。
網路端的時間校準要比理端更細。兩百萬臺,每臺裝置的本地時鐘都有自己的漂移量,雖然經過之前的集中同步已經對齊到彼此相差不到三十毫秒,但林劫還需要確保所有裝置在發起洪峰請求的那一秒完全同步——不是在絕對時間意義上,而是在行指令發的意義上。絕對時間由攻擊腳本里的發時間控制,時間本已經對齊到從授時伺服竊取的標準時間;指令發則由一個輕量級的同步脈衝完,脈衝本過殭網路建的P2P傳播協議以樹狀拓撲分發,從節點到所有葉子節點的最大延遲經過之前兩力測試,到了三百七十毫秒以。這個數字還差了一點——理想目標是二百毫秒以。
林劫花了一個下午重新優化了殭網路的同步脈衝分發拓撲,把樹狀結構改了多層星型結構,在關鍵節點上加了幾個專用的低延遲中繼伺服——說是伺服,其實就是幾臺從馬雄黑市上借來的高效能礦機,挖不了礦,但網路轉發效能一流。改完拓撲之後重新跑測試,最大延遲從三百七十毫秒降到了不足兩百毫秒。
至此,所有攻擊節點的時間基準全部對齊到龍系統的原子鐘叢集,最大同步誤差不超過零點三秒,遠小於三秒的行視窗。他把測試完的同步資料儲存下來,關了螢幕,靠在椅背上閉了會兒眼。黑暗裡,他能覺到那兩百萬臺沉睡的像無數拉滿的弓弦,只等一個訊號。窗外鏽帶的天又亮了,不知道是第幾個沒睡的夜晚。








