摘要: 你是否也在用 1Panel 部署 Docker 应用,并套上了 CDN?你是否发现应用日志里记录的永远是内网 IP,而且时间还和你对不上?本文将以 2FAuth 应用为例,带你一步步排查并完美解决这两个最常见的“拦路虎”,让你的自托管服务既安全又准确!


大家好,我是一名热衷于自托管(Self-Hosted)的开发者。最近,我使用广受好评的 1Panel 服务器运维面板 在我的服务器上部署了一个 Docker 版本的 2FAuth(一款优秀的二步验证应用)。为了提升访问速度和安全性,我还在前面套上了一层腾讯云 CDN

我的访问链路是这样的:
用户 -> 腾讯云 CDN -> 我的服务器 (1Panel) -> Nginx 反向代理 -> 2FAuth Docker 容器

然而,部署完成后,两个令人头疼的问题接踵而至。这篇文章,就是我解决这两个问题的完整复盘。

第一大坑:迷失在代理网络中的真实IP

当我首次登录应用并查看日志时,我震惊地发现,所有的访问记录,来源 IP 都是清一色的 172.18.0.1!

这意味着基于 IP 的安全功能(如登录失败锁定、异地登录提醒)完全失效,这对于一个安全应用来说是不可接受的。

探寻原因

在多层代理架构中,后端应用看到的是上一层代理的 IP。为了传递真实用户 IP,我们需要建立一个从 CDN 到 Nginx 再到应用的“信任链”,通过 X-Forwarded-For 请求头来接力传递 IP 信息。

三步搞定:让真实IP“重见天日”

登录腾讯云 CDN 控制台,在“回源配置”中找到“客户端 IP 头部”选项,确保它已开启,并且头部名称为 X-Forwarded-For。

进入 1Panel 的“网站” -> “反向代理”,编辑你的站点配置文件。核心是要让 Nginx 信任 CDN 并继续向下传递 IP。

这是我的优化后配置,你可以直接参考:codeNginx

location ^~ / {
    proxy_pass http://127.0.0.1:8000; # 你的应用容器端口
    proxy_set_header Host $host;

    # --- 核心配置开始 ---
    # 1. 信任 CDN 并从中解析真实 IP
    # 建议将 0.0.0.0/0 替换为腾讯云官方的 CDN IP 段,更安全
    set_real_ip_from 0.0.0.0/0; 
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    # 2. 将解析出的真实 IP 传递给后端应用
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    # --- 核心配置结束 ---

    # 其他配置...
}

应用本身也需要被告知“请信任代理”。对于 2FAuth (Laravel 框架),这需要一个特定的环境变量。

进入 1Panel -> 应用 -> 编辑 2FAuth,在“环境变量”中,添加以下配置:

  • 变量名 (Key): TRUSTED_PROXIES
  • 变量值 (Value): *

重要提示: * 表示信任所有代理,最简单有效。更安全的方式是设为 Docker 网关 IP 段,如 172.18.0.0/16。

配置完成后,保存并让 1Panel 重新部署应用。当我再次登录时,我收到了应用发来的安全邮件,IP 地址赫然显示为我自己的公网 IP!问题解决!

第二大坑:慢了8小时的“美国时间”

解决了IP这个心头大患,我心满意足地泡了杯茶,准备欣赏我的完美部署。然而,当我再次审视日志时,一个新的问题浮出水-——时间不对

日志里的时间是 05:34,而我手表上的时间是 13:34。很明显,容器正在使用 UTC 时间,而我身处东八区(CST),这8个小时的时差在排查问题时会造成极大的困扰。

探寻原因

Docker 容器默认使用 UTC 时间,这是一个为了保持全球一致性的标准实践。我们需要做的,就是强制让容器的时区与我们的宿主机(服务器)保持一致。

一行挂载搞定:让容器与我们同步

最直接、最可靠的方法就是通过文件挂载,将宿主机的时区配置“共享”给容器。

  1. 首先,确保你的宿主机时区是正确的。你可以SSH登录服务器,执行 date 命令查看,确认显示的是北京时间。
  2. 进入 1Panel -> 应用 -> 编辑 2FAuth 应用。
  3. 找到 “文件挂载” 或 “卷” (Volumes) 的设置。
  4. 点击 “添加” 一个新的挂载,配置如下:
    • 宿主机路径 (Host Path): /etc/localtime
    • 容器路径 (Container Path): /etc/localtime
    • 权限 (Permissions): 设置为只读 (ro)
  1. 保存并重新部署容器。

原理揭秘:/etc/localtime 是 Linux 系统中存储当前时区信息的核心文件。通过这个挂载,我们把宿主机正确的时区文件直接映射到了容器内部,覆盖了容器默认的 UTC 配置,从而强制容器与宿主机保持时区一致。这种方法简单粗暴且非常有效。

(当然,也可以通过添加一个 TZ 环境变量来实现,但文件挂载的方式确保了与宿主机的绝对同步。)

操作完成后,我查看最新的日志:

时间正确了,时区也显示为 +0800。第二个问题,完美解决!

总结

在 CDN + 反向代理 + Docker 的现代 Web 架构下,获取真实 IP 和同步时区是两个绕不开的基础问题。幸运的是,借助 1Panel 强大的图形化界面,我们只需要:

  1. 在 Nginx 配置中,建立起 IP 的“传递链”。
  2. 在应用配置中,通过 TRUSTED_PROXIES 环境变量和一行 /etc/localtime 文件挂载,就能解决应用层面的信任和时区问题。

希望我的这次踩坑和填坑经验,能帮助到每一位热爱折腾、追求完美的你!

转载请注明原文链接:首页 > 日常 > 从踩坑到完美:腾讯云CDN + 1Panel + Docker下获取真实IP与同步时区的终极指南
  • 微信打赏微信打赏

AnHui.HuaiNan

我很感谢那些爱过我的人.