Nginx/Apache Proxy Üzerinden İstemci Gerçek IP'si Nasıl Elde Edilir?

Nginx/Apache'yi Workerman proxy'si olarak kullanırken, nginx/apache aslında Workerman'ın istemcisi olarak davranır. Bu nedenle, Workerman üzerinde elde edilen istemci IP'si nginx/apache sunucusunun IP'sidir, gerçek istemci IP'si değildir. Gerçek istemci IP'sini elde etmenin yöntemleri aşağıda açıklanmıştır.

Prensip:

Nginx/Apache, istemcinin gerçek IP'sini http header aracılığıyla aktarır. Örneğin, nginx yapılandırmasında location içinde proxy_set_header X-Real-IP $remote_addr; ayarı yapmak gerekir. Workerman, bu header değeri okunarak bu değeri $connection nesnesine kaydeder, (GatewayWorker için bu değer $_SESSION değişkenine de kaydedilebilir), kullanırken değişkeni direkt okuyabilirsiniz.

Dikkat:

Aşağıdaki yapılandırmalar http/https ws/wss protokolleri için geçerlidir. Diğer protokollerde istemci IP'sini elde etme yöntemleri benzerdir; ihtiyaç duyulan proxy sunucusu, veri paketine gerçek istemci IP'sini ileten bir IP verisi eklemelidir.

Nginx Yapılandırması Aşağıdaki Gibidir:

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";
    # Bu kısım http header aracılığıyla gerçek istemci IP'sinin iletilmesini sağlar
    proxy_set_header X-Real-IP $remote_addr;
  }

  # location / {} Site'nin diğer yapılandırmaları...
}

Workerman Nginx'in Ayarladığı Header'dan İstemci IP'sini Okur

<?php

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

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

/**
 * İstemci websocket el sıkışırkenki geri çağırma onWebSocketConnect
 * onWebSocketConnect geri çağrısında nginx'in http header'ındaki X_REAL_IP değerini elde etmek
 */
$worker->onWebSocketConnect = function(TcpConnection $connection, $request){
    /**
     * connection nesnesinin aslında realIP özelliği yoktur, burada connection nesnesine dinamik olarak bir realIP özelliği ekliyoruz
     * Unutmayın ki php nesnelerine dinamik olarak özellik ekleyebilirsiniz, kendi tercih ettiğiniz özellik adını da kullanabilirsiniz
     */
    //$connection->realIP = $_SERVER['HTTP_X_REAL_IP']; // workerman v4 kullanımı
    $connection->realIP = $request->header('x-real-ip'); // workerman v5 kullanımı
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
    // Gerçek istemci ip'sini kullanırken, direkt olarak $connection->realIP kullanabilirsiniz
    $connection->send($connection->realIP);
};
Worker::runAll();

GatewayWorker Nginx'in Ayarladığı Header'dan İstemci IP'sini Alır

Events.php dosyasına aşağıdaki kodu ekleyin:

class Events
{
   public static function onWebsocketConnect($client_id, $data)
   {    
        $_SESSION['realIP'] = $data['server']['HTTP_X_REAL_IP'];
   }
   // .... Diğer kodlar atlandı....
}

Kod eklendikten sonra GatewayWorker'ı yeniden başlatmanız gerekir.

Artık Events.php içindeki onMessage ve onClose yöntemlerinde $_SESSION['realIP'] aracılığıyla istemcinin gerçek IP'sini elde edebilirsiniz.

Dikkat: Events.php içindeki onWorkerStart, onConnect, onWorkerStop doğrudan $_SESSION['realIP'] kullanamaz.