資安

Dsm as deepin mate(3):離線編輯初始鏡像,讓skynas本地驗證啟動安裝/升級

本文關鍵字:啥是真正的黑群,壓縮skynas磁盤佈局為5G內

在《dsm as Deepin mate(2)》中,我們講到了使skynas鏡像脫離aliyun ecs真正能運行起來的方法。但是我們用的是倒敘的手法,我們還沒到得到安裝鏡像,這裡繼續。講解離線創建和編輯純淨鏡像,使之能像普通黑群一樣啟動,完成安裝/升級的方法。

Ps:啥是真正的黑群

————
所謂黑群暉,是由於群暉基於linux gpl要求開源了早期內核和toolchain在sourceforge:http://sourceforge.net/projects/dsgpl/files/,而它的rd.gz,pat升級/安裝包是很容易解包打包的https://github.com/andy928/synochecksum。因此。各種黑群技術有機會修改zImage,rd.gz和重新打包定製pat。你可以在這裡定製內核插入你的驅動,作各種腳本增強,使群暉適用於更多機型,甚至通用硬盤。
故,其實正真被黑的部分並不是bootloader。正真被黑的應該是部分內核zImage與位於initrd ramdisk中的各種外掛模塊。至於系統中的安裝包/升級包中的正常具體邏輯,是不需要破解的。雖然如此,大部分黑群版本命名大都是xxxboot之類。
具體技術方面,(1)破解的第一關是rd.gz中的synobios:群暉是通過一個叫做synobios.ko的外掛模塊集中處理硬件綁定問題的。一旦破解了它,很容易解除硬件綁定關係。所謂的破解,主要就是改一下這個接口的代碼,使他在黑群暉的硬件上也能返回一個合法的機型代碼(例如DS3612xs的代碼是42)。因此,大家現在所安裝的黑群暉,實際上synobios.ko文件已經修改過了,鏡像pat也用的是重新打包過的pat,synochecksum-emu1 hda1.tgz rd.gz updater VERSION zImage >checksum.syno這裡有一個對pat內文件驗證打包的過程。(2)破解的第二關,群暉在sourcefourge的開源內核驅動僅支持官方,本身也是有點錯誤的,需要一定定製,加入自己的驅動,直接編譯後在引導系統的時候會出現很多錯誤,例如加載synobios時候出現找不到符號的錯誤、synoacl實現並沒有完全開放等等。因此,需要對synology開放的內核代碼做一些修改,目前網上能夠找到的對內核的修改只有舊內核的(3.2.11等)。加入自己的驅動,等等。(3)還有一些邊角的破解或增強,如修改u盤vid和pid,填寫正確的U盤 VID和PID可以在DSM界面隱藏U盤,修改sn和mac地址可以用於"洗白”。可見sn破解是無關緊要的,除非你要用上官方的服務如quickconnect,ffmpeg縮略生成等(見前文後面,本地驗證版黑群,官方只是沒有對這些假sn開刀而已)。
http://xpenology.com/wiki/en/building_xpenology可以說是一篇最詳細和權威的資料(編譯內核的內容,還包括了synobios的破解和rd.gz的製作,etc..),不過它是是針對4.1的老版本的。不過其用於指導黑群製作的思路是不變的。
視上面二方面,加入了不同驅動,作了不同增強,因此有很多黑群版本,雖然定製synobios是不可避免的,但有的版本,如gnoboot支持使用官方的PAT文件(依然是xpenology的思路),gnoboot編寫了一組腳本,巧妙的實現了在rd.gz引導系統後自動替換需要破解的文件,不僅如此,gnoboot還包含了大量的驅動,並且可以很方便的加載和卸載驅動。
—————

問題回到出發點,對於skynas,破解目標是什麼?對應上面提到的(1)(2)(3)有哪些地方需破解呢?第一個問題,不經過破解直接運行的結果,就是用你提取的安裝鏡像換機安裝時,不會啟動sda5中的系統安裝無法繼續,而是進入web assit重裝界面(即用當初收費鏡像機dd出來的機器鏡像,換機後也有綁定過期驗證不通過退回webassit重裝界面),這個綁定在哪?是不是驗證?這就是第二個問題。

作初步猜想,可能在grub的那個checksum(zimage,rd.gz,update.pat/hda1.tgz三個都是阿里雲綁定的因為其內都有aliyun_xxx相關的腳本文件,不排除是這個原因導致的安裝驗證不通過。rd.gz/synobios應該不需要破解因為都是阿里雲機。那麼那個checksum呢?),也有可能在sn綁定(因為skynas是個在線機器,有先sn網絡驗證後安裝的條件,不過群暉並不常用sn驗證安裝過程,物理機上的黑群boot通過了就通過了)。

無論如何,skynas用的並不是嚴格普通黑群的那套(不是synobios過了,pat就會過)。而是隻有zimage,rd.gz,update.pat三個都過了,才過,所以破解會是(1),(3)我們需要測試驗證,下面會講到。

鏡像及鏡像離線編輯測試環境

我們先來嘗試建立一個純淨鏡像,去阿里雲開一臺系統盤為20g的skynas615-15254(選擇可卸載)按量機器作測試環境(為什麼不在本地虛擬機測試呢?因為我們還沒有精力去考慮因換本地可能帶來的其它情況),開機後關機,恢復系統盤初始狀態為skynas615-15254選擇不重啟,建立快照。 —— 這樣我們就得到了一個初始skynas61515254的快照。重置系統為ubuntu18,並啟動,為只有一個系統盤的系統建立一個20G的數據區,建立時恢復skynas快照並mount。

反轉數據區與系統區啟動邏輯(為什麼要反轉呢,因為我們未來要在系統區安裝skynas運行測試鏡像,啟動到數據區上安裝的ubunt18裡離線編輯,grub1,2可以互通),在ubt18中初步編輯skynas/vda/boot/grub.cfg建立啟動到第二硬盤的菜單,像這樣:

timeout由15改為1500,如果這個不改,從vnc重啟,如果過快,會默認啟動到skynas。
加一個菜單boot ubt
set root=(hd1,msdos1) 這裡是vdb中的ubt,從grub1 chainload grub2,反之需要insmod ext2
linux /initrd
initrd /vmlinux
boot

刪掉原來快照重新建立數據區的新快照 ——— 這樣我們得到一個初步修正了的skynas的快照。同時,系統區也做快照。—— 這樣我們得到了一個ubuntu18的快照。

現在,使用阿里雲最新的功能卸載系統盤和數據盤,為沒有任何盤的系統重新建立一個20G的系統和50G的數據(這裡為什麼先前要卸載系統盤呢,因為不是新建的盤不可以從快照中恢復,我們也不想使用鏡像功能因為那會涉及到計費),建立時恢復新skynas的鏡像,如上所述,我們將在這個ubunt18裡離線編輯(為什麼ubuntu18裡面不同時裝我們以前文章中處處使用到的tinycorelinuxpevirtio呢因為tcpe畢竟有些工具版本有限不太方便),在skynas盤運行測試鏡像(為什麼不在數據盤裡運行skynas呢,因為skynas kernel的root必須是sda系列,而ubt怎麼都可以),這樣我們就得到一個離線編輯運行鏡像的測試環境了。

vnc重啟,進入skynas的菜單,選擇啟動到vdb上的ubuntu,在ubunt裡,dd( + status=progress可看進度)數據區到系統區root下形成img.gz文件。得到一體化灌裝好的一個初始鏡像615-15254.gz,這也是阿里雲初始sky nas 鏡像用的方式,(並非用任意pat通過webassit直裝),mount /vdb5可以看到它是如下這樣組織的,像這樣:

.SynoUpgradeIndexdb.txz
.SynoUpgradePackager 猜出現在package center的是丟在pat/package升級包中提取出來的
.SynoUpgradeSynohdpackImg.tcz
.NormalShutdown
…..
然後是hda1.tgz釋放到整個sda5中的內容

其實不嫌麻煩,你可以利用前幾篇文章中的方法或重新建立分區,研究手動釋放DSM_SkyNAS_15254.pat升級包到vdb5得到如上組織的方式。

繞過驗證邏輯

這樣三者(kernel,rd.gz,pat)都有了,synobios略過,來看grub中的checksum,它相當於物理機中pat中的checksum,checksum是check rd.gz+zimage的。如果修改rd.gz,checksum會failed,但它會不會影響rd.gz中的邏輯呢。如果驗證邏輯主要在rd.gz中呢?(這個在gui桌面環境下用7z就能打開查看,裡面有大量的可能驗證邏輯),不論如何,先驗證一下修改rd.gz使checksum失效吧,看會有什麼影響。

我們首先測試來為rd.gz中的root去掉內置默認密碼,以證實我們的想法和利於接下來的分析,:etc/passwd去掉第一對::中的x,/etc/shadow去掉第一對::中的*,如下作重新打包即可:

(我們現在在/root,mount /dev/vdb2 mnt/vdb2, cd mnt/vdb2,vdb2空間足夠,可以直接在這裡修改和重打包,首先把rd.gz改名為rd.gz.xz,不然接下來xz解壓不成功)

(解壓)
mkdir rd.dir
cd rd.dir
xz -d -c -k ../rd.gz.xz  | cpio -id

(壓縮)
cd rd.dir
find . | cpio -o -H newc | xz -9 --format=lzma > ../rd.gz

(測試1)
重啟測試新的rd.gz,即boot sda2啟動菜單中去掉checksum和vendor。此時進去/sda5/etc/會發現大部分rc都是加密的。原來checksum只夠影響這裡。

(測試2)
重啟測試新的rd.gz,即boot sda2啟動菜單中保留checksum和vendor。此時進去/sda5/etc/會發現rc都是正常的,只是顯示checksum處顯示failed,而且linuxrc.syno failed on 4。但此時系統依然無法啟動。,啟動後。依然如意料只會停留在web assit界面。

看來checksum並不是最終驗證或唯一的過程。使得這個升級過程不能繼續。我們需要探索更多rd.gz中的地方。接下來就是初步分析整個rd.gz,去得到繞過驗證的邏輯,然後動態修改rd.gz,並用新的rd.gz用在系統區中啟動。一點一點測試,這是我們的新思路。

我們結合dmesg,從linuxrc.syno來一步一步分析。這裡的流程是rd.gz/linuxrc.syno(rd.subr)->/etc/synogrinst.sh(rd.gz/usr/syno/sbin/installer.sh,update.sh)->sda5/usr/syno/etc.default/aliyun_sn_init.sh,sn_generater在第一次啟動後(無論成功或失敗)會自刪掉

我們從上面找到了,從rd.gz到sda5 privot root的地方(rd.gz/linuxrc.syno,rd.gz/etc/rc中的mount /dev/root /)。

貌似在upgrade輸出,準備升級開始的地方。
如果找不到/dev/root就找不到/tmp/root等
如果找不到分區,就找不到/dev/sda
找不到/dev/sda,針對sda就全盤cfgen不了,就導致linuxrc.syno啟動失敗(upgrade過程)
如果upgrade不了,就形成不了整個有效可啟動的/dev/sda5

正是這裡導致了linuxrc.syno failed on 4,最終就只能進入rd.gz

因此,所有的問題都變成,如何觸發 讓rd.gz過程找到/dev/root(就會啟動/dev/sda,事實上繞過了驗證)

(最終成功測試)
解發能找到分區的關鍵是,安裝過程中要有一個/dev/sdb,跟前文一個思路和技術。

(最後來說那個sn)

其實那個序列號只是系統內一個叫sn_generater的本地工具隨機生成的。有沒有那個sn沒關係,系統可以以空sn安裝啟動
那個aliyun_sn_init.sh和aliyun_sn_generater是臨時生成的。

封裝和後期離線編輯過程

最後是封裝:dd到ubut分區中,及後期離線編輯:

(沒有kpartx,我們可以用loop)
losetup -f
losetup -o 1048576 /dev/loop0 skynasinit
mount /dev/loop0 /mnt/volume1
losetup -o 17825792 /dev/loop1 skynasinit
mount /dev/loop1 /mnt/volume2
losetup -o 122715648 /dev/loop2 skynasinit
mount /dev/loop2 /mnt/volume5
umount /volume5
losetup -d /dev/loop2
上面-o 之後的數據就是skynas的四個分區開始乘於512得到的

(如果volume5 umount不了,我們可以找出佔用volume1的在執行進程並終止它們)
lsof +f -- /volume5
Kill -s 9 pid

——————

dsm的web後臺技術做得很流暢很輕量不費資源,還有webassit在線安裝升級是syno的二個特色(從這裡我們可以分析得到其邊分區邊升級、安裝的技術)。結合前文《Dsm as deepin mate(2):在阿里雲上真正實現單盤安裝運行skynas》,甚至你還可以壓縮skynas磁盤佈局為5G內,這樣鏡像做出來也會更小,集成更多內置spk和一個叫move_syno_pkgs.sh的腳本,etc…..前文遺留問題:有一些spk如vide,photo只能在有單獨hd as volume的情況下安裝,把sdb1改成sda4


(此處不設回覆,掃碼到微信參與留言,或直接點擊到原文)

qrcode.png

Leave a Reply

Your email address will not be published. Required fields are marked *