Wie man die echte IP des Clients über Nginx/Apache-Proxy erhält

Wenn Nginx/Apache als Proxy für Workerman verwendet wird, fungiert Nginx/Apache tatsächlich als Client von Workerman. Daher ist die IP, die in Workerman als die des Clients erfasst wird, die IP des Nginx/Apache-Servers und nicht die tatsächliche IP des Clients. Um die echte IP des Clients zu erhalten, können Sie die folgende Methode verwenden.

Prinzip:

Nginx/Apache überträgt die echte IP des Clients über die HTTP-Header, zum Beispiel durch das Hinzufügen von proxy_set_header X-Real-IP $remote_addr; in die Nginx-Konfiguration im Location-Block. Workerman liest diesen Header-Wert und speichert ihn im $connection-Objekt, (GatewayWorker kann ihn in der $_SESSION-Variablen speichern), und kann beim Nutzung einfach auf die Variable zugreifen.

Hinweis:

Die folgenden Konfigurationen sind für die Protokolle http/https und ws/wss geeignet. Für andere Protokolle ist die Methode zur Erfassung der Client-IP ähnlich, wobei der Proxy-Server einen Abschnitt mit IP-Daten in das Datenpaket einfügen muss, um die echte Client-IP durchzuleiten.

Nginx-Konfiguration sieht ungefähr so aus:

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";
    # Dieser Teil nutzt den HTTP-Header, um die echte Client-IP durchzuleiten
    proxy_set_header X-Real-IP $remote_addr;
  }

  # location / {} Weitere Konfigurationen der Seite...
}

Workerman liest die Client-IP aus dem von Nginx gesetzten Header

<?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 beim Websocket-Handschlag des Clients
 * In der onWebSocketConnect-Callback-Funktion wird der von Nginx über den HTTP-Header erhaltene Wert X_REAL_IP abgerufen
 */
$worker->onWebSocketConnect = function(TcpConnection $connection, $request){
    /**
     * Das connection-Objekt hat an sich noch kein realIP-Attribut. Hier wird dynamisch ein realIP-Attribut zum connection-Objekt hinzugefügt.
     * Denken Sie daran, dass PHP-Objekte dynamisch Attribute hinzufügen können, und Sie können auch einen von Ihnen bevorzugten Attributnamen verwenden.
     */
    //$connection->realIP = $_SERVER['HTTP_X_REAL_IP']; // Verwendung in Workerman v4
    $connection->realIP = $request->header('x-real-ip'); // Verwendung in Workerman v5
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
    // Wenn die echte Client-IP verwendet wird, kann einfach $connection->realIP verwendet werden
    $connection->send($connection->realIP);
};
Worker::runAll();

GatewayWorker erhält die Client-IP aus dem von Nginx gesetzten Header

Fügen Sie folgenden Code zu Events.php hinzu

class Events
{
   public static function onWebsocketConnect($client_id, $data)
   {    
        $_SESSION['realIP'] = $data['server']['HTTP_X_REAL_IP'];
   }
   // .... Andere Codes überspringen....
}

Nachdem Sie den Code hinzugefügt haben, müssen Sie GatewayWorker neu starten.

Auf diese Weise können Sie in den Methoden onMessage und onClose in Events.php die echte IP des Clients über $_SESSION['realIP'] abrufen.

Hinweis: In Events.php können onWorkerStart, onConnect und onWorkerStop nicht direkt $_SESSION['realIP'] verwenden.