跳到主要內容

發表文章

Ubuntu 24.04 使用 PPA 建置 Apache+PHP-FPM:安裝步驟與實作心得

過去建置 Apache 網站時,多半使用 mod_php,讓 Apache 直接載入 PHP 模組。這次新主機改採 Apache event MPM 搭配 PHP-FPM,將 PHP 請求交由獨立的工作程序處理,作為後續新建站的施工方式。 PHP-FPM 可以管理 PHP 工作程序數量,也能透過不同的 pool,分別設定執行帳號與資源限制。這讓網站伺服器與 PHP 的設定、維護更有彈性;不過,各站的隔離程度仍取決於實際帳號、權限與 pool 配置,不是安裝後就自動完成隔離。 採用 PHP-FPM,是希望讓 Apache 連線處理與 PHP 工作量能分別管理,便於後續調整資源。 本次已完成新站建置與操作確認,以下整理實際使用的步驟;併發效能仍需依各站負載測試。 本文以 Ubuntu 24.04、Apache、PHP 8.4-FPM 為例,Apache 與 PHP 採用 Ondřej Surý 提供的第三方 PPA;資料庫與 phpMyAdmin 接續原有 SOP。安裝時請確認實際套件版本與安全更新狀態,既有主機則應先備份並安排維護時段。 0. 開工前核對 ```bash cat /etc/os-release apache2 -v 2>/dev/null || true php -v 2>/dev/null || true ``` - 預期為 Ubuntu 24.04 LTS。若不是 24.04,先調整套件版本及本 SOP。 - 若機器不是全新、已有 Apache/PHP,先記錄 `sudo apache2ctl -M`、`dpkg -l | grep -E 'apache2|php8\.'`,再決定是否要停用既有 handler;不要在未知站台上直接切換。 1. 使用 Ondřej Surý PPA 安裝套件來源與 Apache ```bash sudo apt update sudo apt install -y software-properties-common sudo add-apt-repository -y ppa:ondrej/apache2 sudo add-apt-repository -y ppa:ondrej/php sudo apt update apt-cache policy apache2 php8.4-f...
最近的文章

Ubuntu阻擋uploads目錄內PHP腳本的HTTP存取(403)

XOOPS 網站的 uploads 是各模組存放圖片、附件等檔案的地方。早期站台有時把目錄權限設為 777;若模組的前端上傳檢查不夠嚴謹,攻擊者便可能把 PHP 木馬混進來,再從網址呼叫木馬,讓後續污染擴大。 替 uploads 加一道 Apache 的 <Directory> 防線,就能讓圖片、附件照常上傳與讀取,卻不讓 uploads 及其子目錄內的 PHP 類檔案透過 HTTP 執行。若攻擊鏈是「上傳 PHP 木馬 → 呼叫木馬網址 → 擴散」,請求在第二步就會收到 403,鏈路因此中斷。這是很實用的止血補強,但不能代替上傳檢查、漏洞修補與清除已植入的檔案;新站也不要因為有這道鎖,就把 uploads 預設設為 777。 設定步驟 1. 到 /etc/apache2/sites-available/ 找出目前網站正在使用的設定檔,例如 000-default-le-ssl.conf;各站檔名不同,不能隨便挑一份 .conf。不確定時先執行 sudo apache2ctl -S 查看啟用的 vhost,並備份要修改的設定檔。 2. 確認網站實際的 uploads 路徑。在該網站的 <VirtualHost *:443> 區塊內加入下列設定。以下 /var/www/html/uploads 只是範例,現場路徑不同就要修改。 <Directory "/var/www/html/uploads">     AllowOverride None     Options -Indexes     <FilesMatch "(?i:\.(?:php[0-9]*|phtml|pht|phtm|phar)(?:\.|$))">         Require all denied     </FilesMatch> </Directory> <Directory> 會涵蓋 uploads 和所有子目錄;<FilesMatch> 會擋常見 PHP 類副檔名、大小寫變化與 .php.jpg 這類多重副檔名。AllowOverride None 會讓此目錄下的 .htacc...

修正 XOOPS 2.7 儲存頁尾註腳 HTML 會被自動過濾為純文字的問題

今天無意間又發現 XOOPS 2.7的一個BUG問題,就是儲存頁腳的資訊區塊,原本(XOOPS2.5.11)都還能支援HTML格式,現在貼入內容會被自動清除為純文字格式,這不處理會死人的呢!!頁腳聯絡資訊,網站資訊,還有AA標章,連CSS都沒辦法用,一堆HTML要放的,變成純文字能交差嗎。 經追查資料庫config存進去就已經被過濾成純文字了,研判因該是在儲存端的Xoops安全機制過濾的,於是再反查Xoops的modules/system/admin.php 最後在這裡找到 modules\system\admin\preferences 用筆記本打開找到約第439行 // Detect this and explicitly set an empty array instead. 吧下面整段註解掉 /* $multiFormTypes = ['select_multi', 'group_multi', 'user_multi', 'theme_multi']; if (in_array($formType, $multiFormTypes, true) && !Request::hasVar($confName, 'POST')) { $new_value = []; } else { $new_value = Request::getVar($confName, $config->getVar('conf_value'), 'POST'); }*/ 替換為 //修改儲存頁腳footer會被自動過成濾純文字的問題 $multiFormTypes = ['select_multi', 'group_multi', 'user_multi', 'theme_multi']; if (in_array($formType, $multiFormTypes, true) && !Request::hasVar($...

CSS LOGO 描邊陰影字工法(替換原 filter: drop-shadow)用法,解決行動瀏覽異常消電原問題(觸發 GPU 合成層)

之前寫過一篇【 用CSS做出來一個文字漸層+文字白框+文字陰影的LOGO區塊,CSS最終解法並符合無障礙 】的工作心得,但經過多次實際驗證,filter: drop-shadow方法雖然較為美觀,但在行動瀏覽或是平板,容易觸發 GPU 合成層,導致版面異常(畫面上下空白),裝置發燙等耗電等問題,因此經改良後,改用CSS LOGO 描邊陰影字工法能維持與原本 filter: drop-shadow相同的效果,且手機平版不會異常,方法如下: 以下是使用-webkit-text-stroke/text-shadow做出來的文字效果,幾乎能90%還原PSD設計效果 文字的PHP常數增加data-storke設定 define('_THEME_LOGO_02','<div class="logo_01_box" aria-hidden="true" tabindex="-1" data-storke="桃園市" >桃園市</div><div class="logo_02_box" aria-hidden="true" tabindex="-1" data-storke="快樂" >快樂</div><div class="logo_03_box" aria-hidden="true" tabindex="-1" data-storke="國民小學" >國民小學</div>'); 注意: aria-hidden="true":視覺文字不給讀報軟體讀。 - tabindex="-1":避免視覺文字進入 TAB 流。 data-storke:提供 CSS content:attr(data-storke); 使用。 外層已有可讀 aria-label 或 sr-only,不要讓同一段校名被讀兩次。 CSS 核心寫法 #toplogobox{ position:relative; width:980p...

修正 XOOPS 2.7 profile 模組編輯欄位時出現 Incorrect column name '' 問題

今天測試 XOOPS 2.7 的 profile 模組時,無意間發現後台欄位編輯有一個問題。 操作路徑:後台 → Profile 模組 → 欄位 → 編輯 只要修改任意一項後送出,就會出現錯誤: Errors field_name 為必填項 Incorrect column name '' MySQL 除錯訊息會看到類似這段: ALTER TABLE profile_profile ADD  varchar(255) NULL 一開始看起來很像資料表壞掉,因為 SQL 竟然要新增一個空白欄位名稱。但後來追程式才發現,真正原因不是資料表問題,而是表單送出時沒有把既有欄位的 id 傳回去。 XOOPS 2.7 的 modules/profile/admin/field.php 在儲存時會從 POST 讀取欄位 id: $fieldId = Request::getInt('id', 0, 'POST'); 如果 POST 沒有收到 id,系統就會誤判成「新增欄位」。但因為目前其實是在編輯既有欄位,表單中沒有 field_name 輸入框,最後就變成欄位名稱是空字串,進而產生: ADD  varchar(255) 修復方式 用文字編輯器打開:modules/profile/include/forms.php 找到 profile_getFieldForm() 裡建立表單的位置,大約在前段: $form = new XoopsThemeForm($title, 'form', $action, 'post', true); 在下方加入: if (!$field->isNew()) { $form->addElement(new XoopsFormHidden('id', $field->getVar('field_id'))); } 也就是讓所有「編輯既有欄位」的表單,都固定送出 hidden id。 修正後,送出欄位設定時,field.php 就能正常收到 POST id,不會再誤判成新增欄位,也不會產生空欄位名稱的 SQL。 修正後結果 經實測: - profile 欄位可正常編輯 - 欄位設定可正常儲存 - 不再出現 field_name ...

XOOPS 2.7 升級筆記:Smarty 4 不支援 <{php}> 的解決方法

 XOOPS 2.7 全面升級到 Smarty 4 後,舊佈景或舊模組最容易炸掉的地方,就是樣板裡的 `<{php}>...<{/php}>`。 原因很單純:Smarty 4 已經不支援在樣板中直接執行 PHP。也就是說,舊寫法如果還把 PHP 邏輯塞在 `.tpl` 裡,升級後就會出現 unknown tag、白畫面或 SmartyCompilerException。 目前比較穩的解法,不是去 hack Smarty,也不是讓 Smarty 重新開放任意 PHP,而是把原本散落在樣板中的 PHP 程式碼收回 PHP 檔案,整理成 function,再用 `$tpl->registerPlugin()` 註冊成 Smarty 標籤,最後在樣板中用新標籤取代原本的 `<{php}>`。 簡單說: 舊寫法: .tpl 直接寫 <{php}> PHP CODE <{/php}> 新寫法: PHP 檔建立 function → registerPlugin 註冊成 Smarty function → .tpl 改用 <{php_channel}> 這樣效果接近原本 `<{php}>`,但執行入口變乾淨,也比較符合 Smarty 4 的規則。 修改方法如下說明: 一、建立相容函式檔 建議先建立一個 PHP 檔,專門收納原本樣板裡的流浪 PHP,例如: modules/模組ID/function/tpl_smarty_compat.php 示例: <?php //Smarty 4 樣板流浪 PHP 收容區 function register_smarty_compat($tpl=""){ if(empty($tpl) || !is_object($tpl)) return; if(!method_exists($tpl,'registerPlugin')) return; static $registered=array(); $tplid=function_exists('spl_object_id') ? spl_object_id($tpl) : spl_object_hash($tpl); if(!empty($regist...

Apache 網站存取與嵌入防護設定(敏感檔案、目錄瀏覽、iframe 防護)

話說時間過得真快,轉眼間又收到上半年度局端的伺服器「弱點管制表」通報,其中當然免不了那些PHP/Apache需要升級項目,但本次多了三個新弱點項目,做個紀錄日後就能SOP處理! 弱點名稱:備份檔案洩漏 弱點概述:It is possible to retrieve file backups from the remote web server. 弱點名稱:Web 伺服器的目錄/資料夾可被瀏覽 弱點概述:Some directories on the remote web server are browsable. 弱點名稱:Web 應用程式具有點擊劫持(ClickJacking)的弱點 弱點概述:The remote web server may fail to mitigate a class of web application vulnerabilities. 這三個弱點可以一次解決,只需要找到 HTTPS vhost,也就是 <IfModule mod_ssl.c> 裡的 <VirtualHost *:443>。 該檔案通常由 certbot 自動產生,檔案名稱多為:000-default-le-ssl.conf(通常位於 sites-available 資料夾中,並連結到 sites-enabled 啟用) sudo nano /etc/apache2/sites-available/000-default-le-ssl.conf 打開編輯 <IfModule mod_ssl.c> <VirtualHost *:443> 略........................ ServerAdmin webmaster@localhost DocumentRoot /var/www/html #防護設定加在DocumentRoot 後面 #這段解決Web 伺服器的目錄/資料夾可被瀏覽問題 <Directory /var/www/html> Options -Indexes AllowOverride All Require all granted </Directory> #這段解決備份檔案洩漏 <FilesMatch "(?i)(~$|\.bak$|\.old$|\.or...