Come ottenere l'IP reale del client attraverso un proxy nginx/apache?

Utilizzando nginx/apache come proxy per Workerman, nginx/apache funge effettivamente da client per Workerman, quindi l'IP del client ottenuto su Workerman sarà l'IP del server nginx/apache e non l'IP reale del client. È possibile fare riferimento ai metodi sottostanti per ottenere l'IP reale del client.

Principio:

nginx/apache trasmette l'IP reale del client tramite l'header HTTP, ad esempio, aggiungendo nel file di configurazione di nginx nella sezione location proxy_set_header X-Real-IP $remote_addr;. Workerman legge il valore di questo header e lo memorizza nell'$connection object, (GatewayWorker può memorizzarlo nella variabile $_SESSION), in modo da poterlo utilizzare direttamente.

Attenzione:

Le configurazioni seguenti si applicano ai protocolli http/https ws/wss. Per altri protocolli, il metodo per ottenere l'IP del client è simile; è necessario che il server proxy inserisca una parte di dati IP nei pacchetti per passare l'IP reale del client.

La configurazione di nginx è simile alla seguente:

server {
  listen 443;

  ssl on;
  ssl_certificate /etc/ssl/server.pem;
  ssl_certificate_key /etc/ssl/server.key;
  ssl_session_timeout 5m;
  ssl_session_cache shared:SSL:50m;
  ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

  location /wss
  {
    proxy_pass http://127.0.0.1:8282;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    # Questa parte utilizza l'header HTTP per passare l'IP reale del client
    proxy_set_header X-Real-IP $remote_addr;
  }

  # location / {} Altre configurazioni del sito...
}

Workerman legge l'IP del client dall'header impostato su nginx

<?php

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('websocket://0.0.0.0:7272');

/**
 * Callback onWebSocketConnect quando il client esegue l'handshake websocket
 * Nella callback onWebSocketConnect otteniamo il valore X_REAL_IP dall'header http impostato da nginx
 */
$worker->onWebSocketConnect = function(TcpConnection $connection, $request){
    /**
     * L'oggetto connection non ha di per sé un attributo realIP, qui aggiungiamo dinamicamente un attributo realIP all'oggetto connection
     * Ricorda che gli oggetti PHP possono avere attributi aggiunti dinamicamente, puoi anche usare un nome di attributo che ti piace
     */
    //$connection->realIP = $_SERVER['HTTP_X_REAL_IP']; // Utilizzo di workerman v4
    $connection->realIP = $request->header('x-real-ip'); // Utilizzo di workerman v5
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
    // Quando si utilizza l'IP reale del client, utilizzare direttamente $connection->realIP
    $connection->send($connection->realIP);
};
Worker::runAll();

GatewayWorker ottiene l'IP del client dall'header impostato su nginx

Aggiungere il codice seguente a Events.php

class Events
{
   public static function onWebsocketConnect($client_id, $data)
   {    
        $_SESSION['realIP'] = $data['server']['HTTP_X_REAL_IP'];
   }
   // .... Altre righe di codice omesse....
}

Dopo aver aggiunto il codice, è necessario riavviare GatewayWorker.

In questo modo è possibile ottenere l'IP reale del client tramite $_SESSION['realIP'] nei metodi onMessage e onClose in Events.php.

Attenzione: nei metodi onWorkerStart, onConnect, onWorkerStop di Events.php non è possibile utilizzare direttamente $_SESSION['realIP'].