作者lance70176 (十三夜)
看板Soft_Job
標題[心得] PHP 7.1 沒人修?自己把修補編進 RPM
時間Sun Oct 25 04:12:30 2026
PHP2Shell 那篇有人問:sury 的回補套件只有 Debian/Ubuntu 能用,那 CentOS 怎麼辦?
這篇就是答案。我們手上有二十幾台 CentOS 7,跑的是 Webtatic 的 php71w 7.1.33。
Webtatic 早就不維護了,其中一套系統光評估升 PHP 8 就要 6 到 8 人天。
所以就自己打包了。網路上找不到有人針對 Webtatic 做過,順手記下來。
先講結論:
rpmbuild 大約 35 分鐘,每台主機上線含檢查 2 到 7 分鐘,php-fpm 只停 6 秒左右。
修補從哪來
官方給舊版本的最小修補是 php-src 的 commit 712e60f9ed(Avoid state corruption
via bailout),但它沒辦法直接套到 7.1。
GitHub 上有幾個社群做的 7.1 移植版,我拿四個去跟官方逐行比,最接近的是
Qsnh/php2shell-fixed,就用它。
sury 的 Debian patch 要先套他另一個 patch 才編得過,就沒拿來用。
這個修補大概做了幾件事:
- 記憶體爆掉時直接讓 worker 結束(_exit),不再帶著做到一半的狀態跳回去繼續跑
- 關掉 upload_progress
- 解析上傳表單時只留必要的欄位,另外加了上傳欄位數量上限
- 請求結束時把幾個全域變數清乾淨
我自己只改了一行。
移植版裡把陣列初始容量設成 1,但 7.1 的雜湊表索引大小跟 7.3 以後不一樣,設 1
會讓記憶體對不齊。這是我請 Codex 看 diff 時它抓到的,我再回去翻 7.1 原始碼確認,
改成 2:
#define array_init_singleton(arg) do { \
array_init(arg); \
- Z_ARRVAL_P(arg)->nTableSize = 1; \
+ Z_ARRVAL_P(arg)->nTableSize = 2; \
} while (0)
很小的一行,但沒改的話是那種平常不會出事、哪天突然掛掉也查不出原因的坑。
怎麼編
用 podman 開一個 centos:7 容器,套件來源指到 vault 的封存 repo。
先驗 Webtatic SRPM 的簽章,再確認裡面的原始碼壓縮檔跟 php.net 官方的
sha256 一樣。
spec 只改四個地方:Release 後面加 .php2shell1、加一行 Patch400、加一行
%patch400、補一筆 changelog。
接著:
yum-builddep -y --define 'dist .w7' SPECS/php71.spec
rpmbuild -bb --define "dist .w7" SPECS/php71.spec
第一次跑就死在 make: command not found,因為 yum-builddep 不會幫你裝 make。補
裝之後再跑,大約 35 分鐘編完。Webtatic 的 spec 會編好幾種 SAPI,所以不算快。
編出來 33 個 RPM,版本都是 7.1.33-1.w7.php2shell1。版本號排序比原本的 1.w7 新,
以後就算有人手滑 yum update,也不會被蓋回去。
怎麼驗
我沒有拿網路上的攻擊程式去打,自己寫了一個不會造成破壞的檢查,五項:
1. 送 3000 個欄位的上傳表單,要被數量上限擋下
2. 正常上傳 1MB 檔案,要完整收到
3. 上傳進度不能被寫進 session
4. memory_limit 設 32M 讓它爆掉,worker 要直接結束(沒修補的版本只會報 Allowed
memory size,然後繼續活著)
5. 爆掉之後的請求還是要正常回 200
結果:原版 2/5,修補版 5/5,降回原版又變 2/5。
另外跑了 php.net 官方測試,9,454 項:
原版 通過 8,751 失敗 34
修補版 通過 8,742 失敗 43
多出來的 9 個失敗都是預期內的:8 個是上傳進度相關的 session 測試,1 個是在檢查
舊的記憶體錯誤訊息。移植版作者回報的也是同樣這 9 個。
怎麼上線
每台的流程:
1. 先記下 rpm -qa,再從 Webtatic 的鏡像把原本的套件抓回來,當作退路
2. yum --assumeno 預覽,畫面只能出現「Upgrade N Packages」
3. 停 php-fpm,yum upgrade 本機的 RPM,php-fpm -t 檢查設定,再啟動
php-fpm 停大約 6 秒,一台含檢查 2 到 7 分鐘。要退回就用 yum downgrade 裝回剛剛
備份的原版。
踩到的兩個坑
1. 升級會把 /var/lib/php/session(還有 wsdlcache、opcache)的擁有者重設成
root:apache 770。我們的 php-fpm 不是用 apache 跑的,結果有一台 session_start()
壞了大約 4 分鐘,chown 回去才恢復。容器測試沒抓到,因為測試環境剛好就是用
apache 跑。升級前先把擁有者記下來。
2. WorkerMan 這種常駐的 CLI 程式,會繼續跑舊的執行檔,看 /proc/<pid>/exe 會顯
示 (deleted)。記得一起重啟。
7.4 呢
7.4 我沒有自己編。exception0x876 有一份 php74-el7,是拿 Remi 的 7.4.33 重新編,
帶的是同一個官方 commit。我驗過他簽章的 SHA256SUMS,也把他的 SRPM 跟 Remi 官方
的逐檔比過,才放心用。
最後講清楚:這只補了這兩個 CVE,7.1 還是 7.1。
它換到的是時間,讓我們能好好規劃真正的升級,不用在駭客敲門的時候硬升。
--
Key君:「哈哈哈哈哈哈,我就是後宮之王——杉崎鍵!
我是為了野心不惜傷害重要的人,
但同時為了讓她幸福也不怕萬苦的男人!」
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.116.54.124 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Soft_Job/M.1792872763.A.47C.html
1F:噓 ladyboy99: PO這什小AI文 語句順一下好嗎 10/25 14:40
2F:→ asdfghjklasd: 他會回你幾百億流水 10/25 15:09
3F:噓 encorek22554: 都用AI了直接升不就好了 10/25 16:17
4F:→ angusyu: 你煩不煩,是要幾篇 10/25 16:34
5F:推 TAKADO: 大家現在可以體會熱門套件維護者審山積的AI PR的心情了吧 10/25 17:22
6F:推 chan15: 我升級了好幾個專案,5.6 7.x 都有,先主要功能都寫 unitt 10/26 06:24
7F:→ chan15: est,開始修改程式碼,升級 8.4 後跑測試跟語法檢查,然後 10/26 06:24
8F:→ chan15: playwright-cli e2e,其中一個是功能極大的商城花了三個 10/26 06:24
9F:→ chan15: 小時,其他都兩小時內,全程 opus 5.5 10/26 06:24
10F:推 Romulus: 我懷疑這幾篇連續發文是來釣黑名單的 10/26 10:33
11F:→ Obama19: 就是個怪咖 不知道為何台灣軟體業一堆這種人 10/26 12:01
12F:→ superpandal: 浪費時間弄這些一點意思也沒有 我很久前也是一直在 10/26 20:44
13F:→ superpandal: rpmbuld dpkg-buildpackage 打補釘 最後發現這兩個編 10/26 20:45
14F:→ superpandal: 譯打包工具鏈都很垃圾 只是流行 用這些系統就更新就 10/26 20:48
15F:→ superpandal: 好 不是給你方便自定義和打安全補釘用的 其實一堆管 10/26 20:50
16F:→ superpandal: 理工具都是這樣 一堆web介面的管理工具更是 10/26 20:52
17F:→ superpandal: 現在的運維就是學一下基本的工具 然後拿流行開源出來 10/26 20:56
18F:→ superpandal: 的web介面工具用來管理 devops其實也差不多 有意思的 10/26 20:59
19F:→ superpandal: 真的很少 以前有創意有想法多了 10/26 21:01
20F:噓 mirror0227: AI 10/28 11:37
21F:噓 kevin9527: ai隨便用就好的東西 意義不明的文章 10/28 20:55
22F:推 holishing: 理論上這種事情選對發行版事半功倍,那麼喜歡自己打包的 11/02 20:08
23F:→ holishing: 話,只有 dpkg/rpm, dpkg-buildpackage/rpmbuild 也不夠 11/02 20:10
24F:→ holishing: (能chroot/容器化卻不做只會搞死自己), 所以...還是問 11/02 20:11
25F:→ holishing: AI吧 XDDD 11/02 20:11
26F:推 holishing: 合理的答案不會像你文章裡那種挖東牆補西牆,這一定有更 11/02 20:14
27F:→ holishing: 成熟的工具不會讓流程那麼混亂容易出錯 11/02 20:15