You are here: 首頁

飛朵啦學習手札

本網站建議使用Firefox2.0以上,或是使用Goole瀏覽器來瀏覽,並使用1024x768解析度來觀看.

JA slide show

新聞公告

歡迎來到飛朵啦學習手札

16

PHP執行外部程式因selinux 限制apache exec 而無法執行

E-mail 列印 PDF

以下說明轉自http://emn178.pixnet.net/blog/post/72463845-php%E5%9F%B7%E8%A1%8C%E5%A4%96%E9%83%A8%E7%A8%8B%E5%BC%8F

 


 

How to execute an external program in PHP

說明PHP如何執行外部程式,以及可能造成無法成功執行的原因,包含SELinux、php.ini設定、Sudoer、環境變數路徑和參數問題。

在php中可以使用shell_exec(), exec(), system()等函式執行外部程式,但是要注意有些設定可能會限制而無法執行,這裡以Linux系統為主要討論,要注意的地方如下:

1. SELinux

這是加強系統安全的模組,但沒有特別去設定的話時常會無法讓程式正常運作,而且在php端沒有任何訊息,例如執行shell_exec("ls"),沒有任何訊息。不過如果被SELinux封鎖的話,在/var/log/messages裡面會有類似以下的訊息:

 

你可以輸入以下指令來查詢目前針對httpd的設定

1
# /usr/sbin/getsebool -a | grep httpd

例如會輸出

allow_httpd_anon_write -- off
allow_httpd_mod_auth_pam -- off
allow_httpd_sys_script_anon_write -- off
httpd_builtin_scripting -- on
httpd_can_network_connect -- off
httpd_can_network_connect_db -- off
httpd_can_network_relay -- off
httpd_disable_trans -- off
httpd_enable_cgi -- on
httpd_enable_ftp_server -- off
httpd_enable_homedirs -- on
httpd_rotatelogs_disable_trans -- off
httpd_ssi_exec --off
httpd_suexec_disable_trans -- off
httpd_tty_comm -- off
httpd_unified -- on

你可以依據需求更改,根據網路上找到的資料,設定httpd_ssi_exec為on可以解決掉這問題,輸入

1
# setsebool -P httpd_ssi_exec 1

停用SELinux

除此之外,你也可以直接關閉SELinux,修改SELinux設定檔,不同系統可能會不同位置,以我用到的CentOS為例是在/etc/selinux/config,有的系統在/etc/sysconfig/selinux

1
# vi /etc/selinux/config

SELINUX的值改成disabled

1
SELINUX=disabled

然後還要的要重開機

暫時停用

或者也可以暫時的停用啟用SELinux,不同系統有不同方式,Fedora和Red Hat使用setenforce開關

停用

1
# setenforce 0

啟用

1
# setenforce 1

有些則用以下方是

停用

1
echo 0 >/selinux/enforce

啟用

1
echo 1 >/selinux/enforce

2. php.ini

safe_mode

另外php.ini的safe_mode如果被啟用的話,shell_exec()就無法使用,而exec()則只能執行在safe_mode_exec_dir下的檔案

disable_functions

有些版本的php.ini會預設將shell_exec()等函式放到這下面,顧名思義在這之下的函式就無法使用,確認shell_exec()等沒有被設定在這項目之下

3. Sudoer

網頁的執行身分通常是apache,你可以在php中使用以下方式查看

1
2
3
<?php
echo shell_exec("whoami");
?>

所以php當然只能執行apache有權限執行的指令,如同Linux一般系統帳號的權限設定一樣,要使用sudoer設定apache允許執行的指令,你可以使用以下指令來編輯

1
# visudo

1
# vi /etc/sudoers

apache沒有密碼同時避免輸入密碼的過程,使用NOPASSWD的屬性,例如我們給root權限來測試如下

1
apache  ALL=(ALL)       NOPASSWD: /sbin/ifconfig

由於apache沒有tty,註解requiretty設定

1
#requiretty

最後再php中可使用sudo取得權限,例如

1
2
3
<?php
echo shell_exec("sudo /sbin/ifconfig");
?>

4. 環境變數

由於php執行外部程式的環境變數不太一樣,所以有時候必須要使用絕對路徑才能正確執行程式。

5. escapeshellarg

如果呼叫的程式會帶入動態的參數,應該要使用escapeshellarg()函式來檢驗,尤其是參數會由使用者輸入的內容來決定的時候,例如

1
2
3
<?php
echo shell_exec('ls ' . escapeshellarg($dir));
?>

6. 其他

有些程式雖然在ssh執行的時候是正常有輸出訊息,但是在php執行外部程式就是沒有,例如直接輸入/usr/bin/java會有使用說明,但php端看不到,不過直接執行jar程式還是可以正常運作,應該是shell_exec()只回傳stdout的資料,stderr看不到,要讓shell_exec()都看的到可以在指令後面加上'2>&1 1> /dev/null',例如

1
2
3
<?php
echo shell_exec('ls file_not_exist 2>&1 1> /dev/null');
?>
文章標籤
最近更新 ( 週一, 16 四月 2018 14:42 )
 
 
23

一個關於LINUX網路出問題的解決經驗

E-mail 列印 PDF

這天公司伺服器突然斷線了,這已經營運多年就這樣突然斷了,而斷線不外乎就那幾種問題。

網卡故障。

IP或mac因為寄發垃圾信被鎖。

網路線掛掉。

伺服器當機,導致系統設定跑掉。

在查了半天之後發現了一一過濾,直到輸入ip link list發現這個訊息。

eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT qlen 1000 link/ether 00:13:ef:b0:29:74 brd ff:ff:ff:ff:ff:ff

NO-CARRIER意旨實體網路斷掉。

 

為了保險起見,再輸入mii-tool,顯示以下資訊。

eth0: no link

eth1: negotiated 100baseTx-FD, link ok


真相已經快一浮出,接者輸入ifconfig,顯示eth0的廣播是BROADCAST MULTICAST而非 UP BROADCAST RUNNING MULTICAST。

至此真相大白,當及聯絡機櫃的負責人,果然是網路線鬆脫,就此結案。

網站參考:http://blog.163.com/lijiji_1515/blog/static/126877446201181611282283/

最近更新 ( 週四, 23 二月 2017 16:33 )
 
 
十二27

[轉]在舊版本Ubuntu系統中使用“apt-get update”出現“404 Not Found”錯誤的解決辦法

E-mail 列印 PDF

問題:我的電腦上安裝的是舊版本的Ubuntu 13.04(Raring Ringtail)。當我運行sudo apt-get update命令的時候,拋出了“404 Not Found”錯誤,並且我不能通過 apt-get or aptitude來更新包。由於這個錯誤,我甚至不能更新到最新發布版本的系統。我該如何解決這個問題呢?

每一個Ubuntu發布版本都有它的結束時間,通常,Ubuntu發布版本支持18個月,而LTS (Long Term Support)(長期支持)版本分別支持3年(服務器版)和5年(桌面版)。當一個Ubuntu發布版本到達結束期後,它的庫將不再能夠訪問,並且你也不會得到任何維護更新和安全補丁。當寫這個的時候,13.04版本已經到底了它的結束期。

 

如果你使用的是Ubuntu系統到達結束期了,你使用 apt-get or aptitude更新庫時會得到以下錯誤提示:

 

W: Failed to fetch http://us.archive.ubuntu.com/ubuntu/dists/raring-backports/multiverse/binary-i386/Packages  404  Not Found [IP: 91.189.91.13 80]

 

W: Failed to fetch http://extras.ubuntu.com/ubuntu/dists/raring/main/binary-amd64/Packages  404  Not Found

 

W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/raring-security/universe/binary-i386/Packages  404  Not Found [IP: 91.189.88.149 80]

 

E: Some index files failed to download. They have been ignored, or old ones used instead

對於那些使用舊版本的Ubuntu的用戶,Canonical會維護 old-releases.ubuntu.com ,這是一個過期庫的歸檔。因此,當Canonical支持的Ubuntu過期後,你必須把源切換到 old-releases.ubuntu.com(除非你想在過期前進行升級)。

 

下面的方法通過切換到舊版本的源來解決“404 Not Found”錯誤。

 

首先,使用舊版本的源來替換當前主源:

 

$ sudo sed -i -r 's/([a-z]{2}\.)?archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list

$ sudo sed -i -r 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list

然後使用文本編輯器打開 /etc/apt/sources.list ,找到 extras.ubuntu.com,這個庫也不再支持13.04。所以你需要使用 “#” 號注釋掉 extras.ubuntu.com。

 

#deb http://extras.ubuntu.com/ubuntu raring main

#deb-src http://extras.ubuntu.com/ubuntu raring main

現在,你應該能夠在舊版本的Ubuntu系統上進行安裝或者更新了。

--------------

本文參考:http://webres.wang/404-not-found-error-apt-get-update-ubuntu/

 
更多文章...
第 7 頁, 共 50 頁