2013-02-10 73 views
3

我想要做的是運行一個簡單的PHP腳本來檢查遊戲服務器是否在線,並從中獲取一些信息。我在WAMP服務器的本地盒子上運行完全相同的腳本,其中我剛剛取消註釋php_openssl.dll和php_sockets.dll,並且 - 瞧 - 它按預期工作。Php套接字,Apache和CentOS 6.3授予權限被拒絕

但後來我們的生產環境!我通常與Debian合作,但是我們的主機決定在我們的專用服務器上安裝CentOS,因爲NIC在Debian中失敗了,從此以後它一直是個麻煩。

我克服了一些問題,並且留下了這個問題:我該如何修復PHP套接字?我讀,我需要的PHP常見,所以我安裝了這個用:

# yum install php-common 

然後我檢查phpinfo()和我得到這個

'./configure' '--with-openssl' '--enable-sockets' ... 

因此,這看起來不錯,如果你問我,無論是OpenSSL和套接字已安裝並且應該正常工作,但事實並非如此。我發現這個劇本在這裏堆棧溢出:

<?php 
//just in case 
if (!extension_loaded('sockets')) { 
die('The sockets extension is not loaded.'); 
} 
echo '<p><strong>Establishing connection...</strong></p>'; 
$socket = socket_create(AF_INET,SOCK_STREAM,0); 
if (!socket_connect($socket, "stackoverflow.com", 80)) 
{ 
die('Socket error : '.socket_strerror(socket_last_error())); 
} 

echo '<p><strong>Connection successful!</strong></p>'; 

$request = join("\n",array(
"GET/HTTP/1.1", 
"Connection: close", 
"Host: stackoverflow.com", 
"User-Agent: Mozilla/5.0 (Windows NT 6.1)", 
"Accept: text/html,*/*;q=0.8", 
"")); 
socket_write($socket,$request,strlen($request)); 

$response = socket_read($socket,2048); 


echo "<p><strong>This is the received data : </strong></p>"; 
echo '<pre>'.htmlentities($response).'</pre>'; 

socket_close($socket); 

這是什麼驚喜輸出我徹底:

Establishing connection... 

Connection successful! 

This is the received data : 

HTTP/1.0 408 Request Time-out 
Cache-Control: no-cache 
Connection: close 
Content-Type: text/html 

<html><body><h1>408 Request Time-out</h1> 
Your browser didn't send a complete request in time. 
</body></html> 

但儘管如此,我的腳本不能正常工作? :( 我有殘疾iptables在

# service iptables stop 

公正,以確保它不是一個防火牆的問題會發生什麼情況如下,當我打開網頁,而不是一個遊戲服務器的名字,我得到這樣的:

警告:socket_connect():無法連接[13]:權限/var/www/test.php否認第9行< < <

這是我使用的代碼,它是開源FR om xPaw,所以我不記得它:

<?php 
function queryserver($IP, $Port = 25565, $Timeout = 2) 
{ 
$Socket = Socket_Create(AF_INET, SOCK_STREAM, SOL_TCP); 
Socket_Set_Option($Socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => (int)$Timeout, 'usec' => 0)); 
Socket_Set_Option($Socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => (int)$Timeout, 'usec' => 0)); 
if($Socket === FALSE || Socket_Connect($Socket, $IP, (int)$Port) === FALSE) 
{ 
return FALSE; 
} 
Socket_Send($Socket, "\xFE\x01", 2, 0); 
$Len = @Socket_Recv($Socket, $Data, 256, 0); 
Socket_Close($Socket); 
if($Len < 4 || $Data[ 0 ] !== "\xFF") 
{ 
return FALSE; 
} 
$Data = SubStr($Data, 3); 
$Data = iconv('UTF-16BE', 'UTF-8', $Data); 

if($Data[ 1 ] === "\xA7" && $Data[ 2 ] === "\x31") 
{ 
$Data = Explode("\x00", $Data); 
return Array(
'HostName' => $Data[ 3 ], 
'Players' => IntVal($Data[ 4 ]), 
'MaxPlayers' => IntVal($Data[ 5 ]), 
'Protocol' => IntVal($Data[ 1 ]), 
'Version' => $Data[ 2 ] 
); 
} 
$Data = Explode("\xA7", $Data); 
return Array(
'HostName' => SubStr($Data[ 0 ], 0, -1), 
'Players' => isset($Data[ 1 ]) ? IntVal($Data[ 1 ]) : 0, 
'MaxPlayers' => isset($Data[ 2 ]) ? IntVal($Data[ 2 ]) : 0, 
'Protocol' => 0, 
'Version' => '1.3' 
); 
} 

$test = queryserver('SERVERADDRESSHERE'); // (i tried multiple, which are all working @wamp) 
$echo = $test['HostName'] . "<<< <br />"; 
echo $echo; 
+0

爲什麼使用套接字? – Blacksonic 2013-02-10 15:43:51

回答

17

在你的linuxbox(以root身份)試試這個命令。

setsebool -P httpd_can_network_connect 1 
+0

我希望我能給你更多的讚揚! – 2016-04-21 23:17:22

+0

拯救我的一天!謝謝 – KaKa 2017-09-01 07:07:23

0

我有類似的問題,所以我想我會在這裏下一個答案,也爲下一個遇到這個問題的人。在不禁用/限制SELinux的情況下,改變圍繞你的httpd的策略是一種方法。

希望這爲下一個讀者節省了2天時間。大聲笑

chcon -R -t httpd_sys_content_t /var/www 
chcon -R -t httpd_sys_content_rw_t /var/www/html 
0

(發表代表OP)。

我找到了答案。似乎SELinux正在阻止套接字連接。使用'#setenforce Permissive'禁用SE Linux並且它現在可用。以防萬一有人遇到同樣的陌生。