當前位置: 首頁> 最新文章列表> socket_accept() 服務中實現IP 白名單過濾機制

socket_accept() 服務中實現IP 白名單過濾機制

M66 2025-05-28

在使用PHP 編寫基於Socket 的服務端程序時, socket_accept()是用於接受客戶端連接的關鍵函數。儘管這個函數非常實用,但它本身並不具備訪問控制的功能。如果你希望你的服務只允許特定的IP 地址進行連接,就需要自己實現IP 白名單的過濾機制。

本文將詳細介紹如何在使用socket_accept()的服務中添加IP 白名單功能,提升服務的安全性和控制能力。

基本Socket 服務結構

首先,我們來看一個典型的使用socket_accept()的基本Socket 服務結構:

 $host = '0.0.0.0';
$port = 12345;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);

echo "服務器已啟動,監聽端口 $port...\n";

while (true) {
    $clientSocket = socket_accept($socket);
    // 此處將添加 IP 白名單過濾邏輯
}

默認情況下,以上代碼將無限接受所有客戶端的連接請求。為了加入IP 白名單控制,我們需要在socket_accept()之後,使用socket_getpeername()獲取客戶端IP,然後判斷該IP 是否在白名單中。

添加IP 白名單過濾邏輯

以下是修改後的代碼,加入了簡單的白名單機制:

 $host = '0.0.0.0';
$port = 12345;

// IP 白名單
$whitelist = [
    '192.168.1.100',
    '203.0.113.45',
    '198.51.100.23'
];

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);

echo "服務器已啟動,監聽端口 $port...\n";

while (true) {
    $clientSocket = socket_accept($socket);
    
    if ($clientSocket === false) {
        continue;
    }

    socket_getpeername($clientSocket, $clientIp);

    if (!in_array($clientIp, $whitelist)) {
        echo "拒絕來自 $clientIp 的連接。\n";
        socket_close($clientSocket);
        continue;
    }

    echo "接受來自 $clientIp 的連接。\n";

    // 此處處理客戶端請求邏輯
    $welcomeMsg = "歡迎訪問 m66.net 的服務。\n";
    socket_write($clientSocket, $welcomeMsg, strlen($welcomeMsg));

    socket_close($clientSocket);
}

關鍵說明

  1. socket_getpeername() :該函數用於獲取已連接客戶端的IP 地址。

  2. 白名單數組:你可以將允許訪問的IP 地址放入$whitelist數組中。

  3. 連接控制:對於不在白名單中的IP,我們直接使用socket_close()斷開連接。

安全提示

  • 不建議將白名單硬編碼在代碼中,實際部署時可以從數據庫或配置文件中動態加載。

  • 可以考慮添加日誌記錄功能,追踪非法連接嘗試。

總結

通過在socket_accept()之後添加IP 白名單驗證邏輯,可以有效限制非授權的訪問,提升PHP Socket 服務的安全性。上述示例展示了一種最基礎的實現方法,開發者可以根據實際需求進行擴展,例如加入CIDR 範圍、支持IPv6 地址等。

在搭建對外提供服務的PHP Socket 程序時,務必把好“第一道防線”,不要讓不受信任的客戶端輕易接入你的系統。希望本文對你有所幫助!