早前写过一篇《哪吒监控 V1 使用唯一域名开启 CDN 和反向代理配置教程》详细说明了怎样使用唯一域名开启 Cloudflare CDN 并利用 1Panel 配置反向代理。很多朋友使用了这个方法搭建了哪吒监控 V1 面板。

上周,所有使用了 Cloudflare CDN 的哪吒 V1 面板小鸡突然全部掉线,经过排查,事情与 Cloudflare 升级 gRPC 配置有关。虽然在故障大约 1 天后,Cloudflare CDN 已修复问题,但我还是重新写了一篇《哪吒监控 V1 使用唯一域名关闭 CDN 改用直连后的配置修改》给出了使用唯一域名关闭 CDN 改用直连后的配置。

那么,既然关闭和开启 CDN,每次都要更改反代配置,有没有方法直接使用同一套配置,不用做任何更改?这样下次出现 CDN 问题,只需要去 Cloudflare 的 DNS 里面关闭域名的小黄云就行?

答案是有的,以下就是终极懒人配置:

1Panel 域名证书

如果你使用的是 Cloudflare 的 15 年自签证书,现在需要更换为公开 CA 签发的免费证书(1Panel 自带申请免费证书并自动续签的功能),这样在关闭 CDN 后就不会出现证书链的问题(Cloudflare 的 SSL/TLS 加密模式更改为【完全】)。

1Panel 域名配置文件

打开 1Panel 你添加的哪吒面板域名——配置文件,在最后面加上代码:

# 定义真实 IP 变量
map $http_x_real_ip $temp_ip {
    ""      $http_cf_connecting_ip;
    default $http_x_real_ip;
}
map $temp_ip $temp_ip2 {
    ""      $http_x_forwarded_for;
    default $temp_ip;
}
map $temp_ip2 $real_ip {
    ""      $remote_addr;
    default $temp_ip2;
}

# 允许头部包含下划线
underscores_in_headers on; 

# 定义上游服务器
upstream dashboard {
    keepalive 512; 
    server 127.0.0.1:8008; 
}

如果你使用的是其它面板(比如宝塔)或程序,完整的配置文件结构应该是这样的:

http {
    # 其他全局配置...
    
    # 真实 IP 获取
    map $http_x_real_ip $temp_ip {
      ""      $http_cf_connecting_ip;
      default $http_x_real_ip;
    }
    map $temp_ip $temp_ip2 {
      ""      $http_x_forwarded_for;
      default $temp_ip;
    }
    map $temp_ip2 $real_ip {
      ""      $remote_addr;
      default $temp_ip2;
    }
    
    # 允许头部包含下划线
    underscores_in_headers on;
    
    # 定义上游服务器
    upstream dashboard {
        keepalive 512;
        server 127.0.0.1:8008;
    }
    
    # 其他全局配置...
    
    server {
        # server配置...
        
        # 反向代理配置(location块)...
    }
}

1Panel 域名反向代理源文

域名——反向代理——源文,使用下面的配置替换:

location ^~ / {
    proxy_pass http://127.0.0.1:8008;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $real_ip;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_http_version 1.1;
    proxy_read_timeout 1800s;
    proxy_send_timeout 1800s;
    proxy_buffer_size 128k;
    proxy_buffers 4 128k;
    proxy_busy_buffers_size 256k;
    proxy_max_temp_file_size 0;
    add_header X-Cache $upstream_cache_status;
    add_header Cache-Control "private, no-store";
    proxy_ssl_server_name on;
}

# gRPC 服务
location ^~ /proto.NezhaService/ {
    grpc_set_header Host $host;
    grpc_set_header X-Real-IP $real_ip;
    grpc_read_timeout 600s;
    grpc_send_timeout 600s;
    grpc_socket_keepalive on;
    client_max_body_size 10m;
    grpc_buffer_size 4m;
    grpc_pass grpc://dashboard;
}

# WebSocket 服务
location ~* ^/api/v1/ws/(server|terminal|file)(.*)$ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $real_ip;
    proxy_set_header Origin https://$host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 1800s;
    proxy_send_timeout 1800s;
    proxy_pass http://127.0.0.1:8008;
}

面板后台设置

  • 前端真实 IP 请求头设置为 X-Real-IP
  • Agent 真实 IP 请求头设置为 X-Real-IP

无论是否开启 CDN 都无需修改任何设置,因为我们通过 Nginx 的 map 指令动态确定了 X-Real-IP 头部的值。

至此,所有设置完成。

这个统一配置的好处是简化了管理,不需要在切换 CDN 状态时手动修改 Nginx 配置和哪吒面板设置,系统会自动选择正确的 IP 来源。