跳到主要内容

IP地址

IP 地址在 HTTP 中起着基础性的作用;它用于访问控制、审计、基于地理位置的访问分析等。Slim 为此提供了方便的方法 Context#RealIP() 轻松获取。

但是,从请求中检索真实 IP 地址并非易事,尤其是在我们使用了某些代理技术时。在这种情况下,需要在 HTTP 层将代理程序中的真实 IP 中继到我们的应用程序上,所以我们不能无条件地信任 HTTP 报头,否则可能得到虚假地址,产生安全风险!

若要可靠且安全地检索 IP 地址,必须让应用程序了解基础架构的整个体系结构。 在 Slim 中,可以通过适当配置 Slim#IPExtractor 来完成,本指南向您展示了原因和方法。

注意

如果我们不显式地为 Slim 实例属性 Slim#IPExtractor 设置值,Slim 会回退到旧行为(即使用报头来完成解析),这可能取不到真正的 IP 地址。

让我们从两个问题开始:

  1. 我们是否使用了代理程序代理我们的应用程序?
    • 如云解决方法(如 AWS 等)或者 OSS 方案(如 Nginx、Envoy 或 Istio 入口网管)。
  2. 我们的代理使用哪一个 HTTP 报头?又是怎样将客户端 IP 传递给应用程序的?

问题 1:没有代理

如果你没有放置代理(例如:面向互联网的目录),你只需要(并且必须)看到的只是网络层的IP地址。 任何 HTTP 标头都是不可信的,因为客户端可以完全控制要设置的标头。

在这种情况下,请使用 .echo.ExtractIPDirect()

s.IPExtractor = slim.ExtractIPDirect()

问题 2:使用使用 X-Forwarded-For 标头的代理

X-Forwared-For (XFF) 是用于中继客户端 IP 地址的常用标头。 在代理上的每一跃点,它们都会在标头末尾附加请求 IP 地址。

以下示例关系图演示了此行为:


┌──────────┐ ┌──────────┐ ┌──────────┐
───────────>│ Proxy 1 │───────────>│ Proxy 2 │───────────>│ Your app │
│ (IP: b) │ │ (IP: c) │ │ │
└──────────┘ └──────────┘ └──────────┘

Case 1.
XFF: "" "a" "a, b"
~~~~~~
Case 2.
XFF: "x" "x, a" "x, a, b"
~~~~~~~~~
↑ What your app will see