Position actuelle: Accueil> Derniers articles> Comment limiter le nombre maximum de connexions à socket_accept () pour éviter les attaques DOS

Comment limiter le nombre maximum de connexions à socket_accept () pour éviter les attaques DOS

M66 2025-06-03

Lorsque vous utilisez PHP pour la programmation réseau, socket_accept () est la fonction principale qui accepte les connexions client. Face aux attaques DOS (Denial of Service), les attaquants utilisent généralement un grand nombre de demandes de connexion malveillantes, épuisant les ressources du serveur, ce qui fait que le serveur est incapable de répondre aux demandes d'utilisateurs légitimes normalement. Cet article expliquera comment empêcher efficacement le serveur d'être traîné malicieusement vers le bas en limitant le nombre maximal de connexions acceptées par socket_accept () .

1. Comprendre les attaques DOS et les limites de connexion

Dans les attaques DOS, un attaquant crée un grand nombre de connexions simultanées qui remplissent les connexions simultanées du serveur du serveur, ce qui fait que le serveur ne peut pas traiter de nouvelles demandes normales. Limiter le nombre maximal de connexions et garantir que le serveur ne gère qu'un certain nombre de connexions client dans la plage d'autorisation des ressources peut réduire efficacement l'impact de cette attaque.

2. Idées à utiliser PHP Socket_Accept () pour limiter le nombre maximum de connexions

  • Utilisez des variables pour compter le nombre de connexions actuellement établies.

  • Lorsqu'une nouvelle connexion est reçue, il est déterminé si le numéro de connexion actuel dépasse la limite.

  • Rejeter la connexion lorsque la limite est dépassée (fermer la nouvelle connexion) et socket_accept () ne sera plus appelée à traiter.

  • Lorsque la connexion est fermée, réduisez le nombre de connexions dans le temps.

3. Exemple de code

Le code suivant montre comment implémenter une limite de connexion maximale basée sur socket_accept () dans PHP, en supposant que la connexion maximale est de 100:

 <?php
set_time_limit(0);
error_reporting(E_ALL);

$address = '0.0.0.0';
$port = 12345;
$maxConnections = 100;
$currentConnections = 0;

// créer TCP Socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $address, $port) or die('La reliure a échoué');
socket_listen($sock);

echo "Startup de serveur,moniteur {$address}:{$port}\n";

$clients = [];

while (true) {
    // Déterminer si le nombre maximum de connexions est dépassé
    if ($currentConnections < $maxConnections) {
        // Le mode non bloquant accepte de nouvelles connexions
        socket_set_nonblock($sock);
        $client = @socket_accept($sock);

        if ($client !== false) {
            // Une nouvelle connexion a réussi,Compter un
            $currentConnections++;
            $clients[] = $client;

            // Configuration du clientsocketNe pas bloquer
            socket_set_nonblock($client);

            echo "NOUVEAU CONNEXION CLIENT,Numéro de connexion actuel: $currentConnections\n";
        }
    } else {
        // Nombre maximum de connexions dépassées,Rejeter une nouvelle connexion(Temps d&#39;attente facultatif)
        usleep(100000); // 100ms
    }

    // Sondage pour traiter les données des clients connectés
    foreach ($clients as $key => $clientSocket) {
        $data = @socket_read($clientSocket, 2048, PHP_NORMAL_READ);

        if ($data === false) {
            // Coupure,Supprimer le client
            socket_close($clientSocket);
            unset($clients[$key]);
            $currentConnections--;
            echo "Client déconnecté,Numéro de connexion actuel: $currentConnections\n";
            continue;
        } elseif ($data !== '') {
            $data = trim($data);
            if ($data === 'quit') {
                // Le client se déconnecte activement
                socket_close($clientSocket);
                unset($clients[$key]);
                $currentConnections--;
                echo "Le client est déconnecté activement,Numéro de connexion actuel: $currentConnections\n";
                continue;
            }

            // Données de traitement envoyées par le client
            $response = "Serveur reçu: {$data}\n";
            socket_write($clientSocket, $response, strlen($response));
        }
    }

    usleep(50000); // réduireCPUOccupation
}
?>

4. Description du code

  • Utilisez $ CurrentConnections pour enregistrer le nombre actuel de connexions actives.

  • Appelez socket_accept () uniquement pour recevoir de nouvelles connexions lorsque le nombre maximum de connexions n'est pas dépassé.

  • Une fois la nouvelle connexion créée, enregistrez le socket client sur le tableau $ des clients et définissez en mode non bloquant.

  • En interrogeant $ les clients , lisez les données des clients et continuez à écouter après la réponse.

  • Si le client déconnecte ou envoie une commande QUIT , fermez la prise et réduisez le nombre de connexions.

  • Utilisez usleep () pour réduire la sur-occupation du processeur.

5. Autres suggestions de protection

  • Définir le délai d'expiration : détecter le temps d'inactivité de la connexion du client et le délai d'expiration se déconnecte automatiquement.

  • Limitez le nombre de connexions IP uniques : empêchez une seule IP de fabriquer un grand nombre de connexions.

  • Utilisation du pare-feu : limitez les connexions d'exception au niveau du serveur.

  • Utilisez l'équilibrage de la charge : disperser la pression de demande.

  • Journal de surveillance : découvrez un trafic anormal dans le temps.

6. Conclusion

En limitant le nombre maximum de connexions dans PHP Socket Server, vous pouvez résister efficacement à un certain degré d'attaques DOS et éviter l'épuisement malveillant des ressources du serveur. Combiné avec d'autres mesures de sécurité, il peut fournir une protection plus solide pour le serveur et assurer le fonctionnement stable des services.