1

次のコードを使用して、ユーザーがプロキシ/VPN の背後にいるかどうかを検出します。

function checkUser()
{
    $proxy = null;
    $check = null;
    $proxy = ($_SERVER['HTTP_ACCEPT_ENCODING'] != 'gzip, deflate') ? true : false;
    if(empty($_SERVER['HTTP_CONNECTION']) || strtolower($_SERVER['HTTP_CONNECTION']) != 'keep-alive' || $_SERVER['HTTP_CACHE_CONTROL'] != 'max-age=0')
    {
        $check = ($proxy === true) ? 'proxy' : 'vpn';
    }
    return $check;
}
$connection = checkUser();
switch($connection)
{
    case 'proxy': $var = 'It seems you are behind Proxy.'; break;
    case 'vpn': $var = 'It seems you are using VPN.'; break;
    default: $var = 'No Proxy or VPN detected.'; break;
}
echo $var;

ただし、私が持っている古いサーバーでは問題なく機能しますが、新しいサーバーでは機能しません。新しいサーバーはリバース プロキシ サーバー (nginx) を使用しています。それがnginxと関係があるかどうか、および構成で何を調整する必要があるかを誰かに教えてもらえますか。ありがとう!

- - 編集: - -

#user  nginx;
worker_processes  4;
worker_rlimit_nofile 950000;


#error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

#pid        /var/run/nginx.pid;


events {
    worker_connections  45000;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  5;
    #tcp_nodelay        on;

    #gzip  on;
    #gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    server_tokens off;

    include /etc/nginx/conf.d/*.conf;

        fastcgi_buffers 8 16k;
        fastcgi_buffer_size 32k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
}
4

1 に答える 1

1

あなたのコードは、プロキシが gzip/deflate および/またはキープアライブ セッションの使用を無効にするという前提に基づいているようです。これは正確な仮定ではありません。これらの機能がオフになっている場合はプロキシを実装する方が簡単ですが、仕様によれば、これらの機能がオンの状態でプロキシが正しく動作することを妨げるものは何もありません。

そうです、nginx はおそらくより優れたプロキシであり、上記のコードの作成者が行った仮定は現在間違っています。

HTTP プロキシを確認する正しい方法は、X-Forwarded-For ヘッダーの存在を探すことです。このようなもので十分です:

function isProxied() {
    $headers = array_change_key_case(apache_request_headers());
    return isset($headers["x-forwarded-for"]);
}

技術的には、プロキシはその存在を宣伝せずに (X-Forwarded-For ヘッダーを追加せずに) 実装できます。これを行うオプションがあるものもありますが、その場合、これを実際に検出することはできません。しかし、ほとんどのプロキシはあなたに協力します。

独自のサーバー スタックでプロキシを使用している場合 (つまり、Apache の前で Varnish、Nginx などを実行している場合)、X-Forwarded-For ヘッダーも追加される可能性があるため、すべてがプロキシされているように見えることに注意してください。 (これによると、nginxはデフォルトで「X-Real-IP」を使用しているように見えるので、これについて心配する必要はありません)。この場合、Varnish/Nginx/whatever でそのオプションをオフにするか、X-Forwarded-For ヘッダーを解析して、1 つではなく 2 つの IP があるかどうかを確認します。

VPN 接続に関しては、着信 HTTP 接続だけからユーザーが VPN を使用しているかどうかを検出する信頼できる方法を見つけることはできないと思います。彼の発信元 IP をチェックして、彼が既知の TOR アドレスまたはそのようなものから来ているかどうかを確認することを検討することもできます. それをどこまで気にするかによる。

于 2013-09-30T04:34:21.967 に答える