You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX IMAP代理无法获取客户端真实IP的问题求助

问题描述

我编译了带有--with-http_realip_module的nginx/1.24.0作为IMAP代理,但遇到两个问题:

  • 无法在nginx的80_access.log日志中获取客户端真实IP;
  • 无法在index.php的$_SERVER["REMOTE_ADDR"]变量中获取客户端真实IP。

日志中始终显示服务器自身的内网或外网IP:

  • 当设置server_name为imap.example.com、auth_http为imap.example.com/index.php时,日志显示服务器外网IP;
  • 当设置server_name为imap、auth_http为imap/index.php时,日志显示服务器内网IP。

我尝试过配置real_ip_header X-Forwarded-For; set_real_ip_from 0.0.0.0/0;但无效果,附上当前配置:

user www;
worker_processes auto;
pid /var/run/nginx.pid;
worker_rlimit_nofile 20480;

events {
    use kqueue;
    worker_connections 10240;
    multi_accept on;
}

http {
    include /usr/local/etc/nginx/mime.types;
    default_type application/octet-stream;

    server_tokens off;

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

    access_log /var/log/nginx/nginx-access.log main;
    error_log /var/log/nginx/nginx-error.log warn;

    keepalive_timeout 30;
    keepalive_requests 200;

    server {
        listen 80;
        server_name imap.example.com;

        server_name_in_redirect on;

        access_log /var/log/nginx/gatewaymail.net/imap/80_access.log common;
        error_log /var/log/nginx/gatewaymail.net/imap/80_errors.log warn;

        root /usr/local/www/nginx/imap;
        index index.php;

        location / {
        }

        location = /favicon.ico {
            log_not_found off;
        }

        location ~ \.php$ {
            try_files $uri = 404;

            fastcgi_pass unix:/var/run/imap-php8.3-fpm.sock;

            fastcgi_send_timeout 300;
            fastcgi_read_timeout 300;

            include fastcgi_params;
            fastcgi_split_path_info ^(.+?\.php)(/.*)?$;

            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;

            fastcgi_buffer_size 1024k;
            fastcgi_buffers 4 1024k;
            fastcgi_busy_buffers_size 1024k;
            fastcgi_temp_file_write_size 1024k;

            set $path_info $fastcgi_path_info;
            fastcgi_param PATH_INFO $path_info;

            fastcgi_param SERVER_ADMIN support@gatewaymail.net;
            fastcgi_param SERVER_SIGNATURE nginx/$nginx_version;
            fastcgi_index index.php;
        }

    }

}

mail {

    proxy_pass_error_message  on;

    server {
        auth_http imap.example.com/index.php;
        listen 143;
        protocol imap;

        error_log /var/log/nginx/gatewaymail.net/imap/imap_proxy_errors.log warn;

    }
}
解决方案

核心问题是:Nginx的mail模块调用auth_http接口时,是作为客户端向自身http模块发起请求的,默认不会传递IMAP客户端的真实IP,导致http模块拿到的请求来源是服务器自身IP。需从以下几处调整:

1. 在mail模块中传递客户端真实IP到auth_http

修改mail块内的server配置,添加auth_http_header指令,将IMAP客户端IP通过自定义Header传给后端:

mail {
    proxy_pass_error_message  on;

    server {
        auth_http imap.example.com/index.php;
        # 新增:传递客户端真实IP到auth_http接口
        auth_http_header X-Client-IP $remote_addr;
        listen 143;
        protocol imap;

        error_log /var/log/nginx/gatewaymail.net/imap/imap_proxy_errors.log warn;
    }
}

2. 在http模块中配置real_ip识别真实IP

在http块中添加real_ip相关配置,指定从自定义Header获取真实IP,并信任服务器自身IP的请求:

http {
    # 原有配置...

    # 新增real_ip配置
    set_real_ip_from 127.0.0.1; # 服务器内网IP,可补充实际内网段
    set_real_ip_from 你的服务器外网IP; # 替换为实际外网IP
    real_ip_header X-Client-IP;
    real_ip_recursive off; # 无多层代理时保持off即可

    # 原有server配置...
}

注意:set_real_ip_from必须填写Nginx发起auth_http请求时使用的源IP(即服务器自身的内网/外网IP),否则Nginx不会信任该来源的Header。

3. 确保PHP能获取真实IP

检查PHP的location块,确保fastcgi_params包含REMOTE_ADDR参数(默认配置通常已包含):

fastcgi_param REMOTE_ADDR $remote_addr;

因为real_ip模块已将$remote_addr替换为客户端真实IP,只要传递该参数,PHP的$_SERVER["REMOTE_ADDR"]就能拿到真实IP。

4. 优化日志格式(可选)

若需同时记录原始请求IP和真实IP,可修改日志格式:

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

其中$realip_remote_addr是原始请求IP(服务器自身IP),$remote_addr是替换后的客户端真实IP。

内容的提问来源于stack exchange,提问作者scazy0rg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:02:19