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,onWorkerStopdi Events.php non è possibile utilizzare direttamente$_SESSION['realIP'].