使用 apt-p2p 搭建本地 Debian 軟件包緩存
本人家里有好幾臺運行Debian GNU/Linux testing的計算機,共處于一個小局域網內。因為Debian testing是滾動更新的,所以我每隔幾天就要把它們全部更新一遍。但是一來中國家庭的網速還是說不上很快,每臺機器都要從上游軟件源的服務器上下載成百上千兆字節的軟件包要花不少時間;二來這樣操作也給軟件源的服務器造成不小的負擔。
后來我想起Debian曾開發過一個叫apt-p2p的軟件,它的設計初衷是緩存已下載的軟件包提供給其他同樣運行著apt-p2p的peers,作為從軟件源下載的補充。那么是否可以用這個軟件在局域網內搭建一個Debian軟件包緩存呢?
apt-p2p由Python寫成,安裝好后默認監聽于TCP和UDP的9977端口,可通過/etc/apt-p2p/apt-p2p.conf改變其行為。TCP端口同時用于本機apt下載軟件包,而UDP端口用于組建在p2p文件共享工具中常見的DHT網絡。只需要在/etc/apt/sources.list文件中軟件源的url,例如http://mirror.server/debian/的服務器域名前面插入localhost:9977,即成為http://localhost:9977/mirror.server/debian/,具體從互聯網上獲取軟件包的工作便交給apt-p2p負責了:
- 當收到來自本機apt的文件下載請求時,apt-p2p會先檢測文件是否已經存在于緩存的目錄樹中
- 如果已存在,則還要檢查是否為最新(通過向軟件源服務器發出HEAD請求來實現)
- 如果是,則直接返回緩存的文件
- 否則從互聯網上下載文件供給apt,同時存入緩存并記錄其散列值
- 下載文件會首先嘗試從peer處下載,不成再到軟件源服務器處下載
- 緩存下來的文件和散列值可供其他peer使用。可以通過apt-p2p的日志文件/var/log/apt-p2p.log深入觀測這一過程。
以下是我安裝了apt-p2p的主機mycastle的sources.list:
deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing main deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing main deb http://localhost:9977/mirrors.ustc.edu.cn/debian-security/ testing/updates main deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian-security testing/updates main deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb http://localhost:9977/mirrors.ustc.edu.cn/debian/ unstable main deb-src http://localhost:9977/mirrors.ustc.edu.cn/debian/ unstable main
然而apt-p2p的緩存只能給本機使用,其他主機若試圖直接訪問9977端口只會得到404錯誤。因此還需要在安裝apt-p2p的主機上架設一個http反向代理,使得在apt-p2p看來,所有的請求均來自本機。
我使用的反向代理是Pound,它在安裝好后默認是禁用的。在/etc/pound/pound.cfg中配置好服務器后再到/etc/default/pound中啟用它,然后使用service啟動服務器即可。
我使用的配置如下:
...(keep default) ListenHTTP Address 0.0.0.0 Port 9978 ## allow PUT and DELETE also (by default only GET, POST and HEAD)?: xHTTP 0 Service BackEnd Address 127.0.0.1 Port 9977 End End End
監聽于9978端口,后臺服務器在本機的9977端口。
這樣一來,其他主機便也可以通過9978端口使用apt-p2p的緩存了。我的做法是在打算使用緩存的其他主機上將/etc/apt/sources.list移動到/etc/apt/sources.list.d/50_main.list,然后仿照緩存主機的軟件源列表建立/etc/apt/sources.list.d/10_apt-p2p-home.list,只是要把url中的localhost:9977換成<hostname-of-cache-server>.local:9978即可,當然最好保持軟件源服務器相同。這樣apt會優先通過反向代理使用apt-p2p的緩存,當緩存不可用時仍可直接連接軟件源服務器獲取軟件包:
10_apt-p2p-home.list:
deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing main deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing main deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian-security/ testing/updates main deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian-security testing/updates main deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ unstable main deb-src http://mycastle.local:9978/mirrors.ustc.edu.cn/debian/ unstable main
50_main.list:
deb http://mirrors.ustc.edu.cn/debian/ testing main deb-src http://mirrors.ustc.edu.cn/debian/ testing main deb http://mirrors.ustc.edu.cn/debian-security/ testing/updates main deb-src http://mirrors.ustc.edu.cn/debian-security testing/updates main deb http://mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb-src http://mirrors.ustc.edu.cn/debian/ testing-proposed-updates main deb http://mirrors.ustc.edu.cn/debian/ unstable main deb-src http://mirrors.ustc.edu.cn/debian/ unstable main
如安裝了apt-transport-https,可以將50_main.list中的http換成https。
這種以主機名加“.local”的域名格式是mDNS/DNS-SD協議提供的一種在廣播域內定位主機和發布服務的方法,主要實現有Avahi和Mac OS X的Bonjour。
這樣一來,在局域網內,任何一臺主機都優先通過apt-p2p獲取軟件包,一臺更新可以惠及全家;即使短時間內更新多臺主機,也只需要向軟件源索取一次;而且大規模的數據流動發生在帶寬很高的局域網內,更縮短了更新時間,提高了效率。
只是這樣一來相當于在非緩存主機上配置了兩個軟件源,而當這兩個軟件源重復部分的信息不同步時(如筆記本計算機在局域網外更新了直連軟件源服務器的軟件包列表),apt-get source是無法使用的,因為apt對源碼包的檢查更嚴格。