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,onWorkerStopdoğrudan$_SESSION['realIP']kullanamaz.