国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

獲取客戶端真實(shí) IP 地址的最佳實(shí)踐

這篇具有很好參考價(jià)值的文章主要介紹了獲取客戶端真實(shí) IP 地址的最佳實(shí)踐。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、背景

1. 業(yè)務(wù)上云帶來(lái)性能收益

公司從去年全面推動(dòng)業(yè)務(wù)上云,而以往 IDC 架構(gòu)部署上,接入層采用典型的 4 層 LVS 多機(jī)房容災(zāi)架構(gòu),在業(yè)務(wù)高峰時(shí)期,擴(kuò)容困難(受限于物理機(jī)資源和 LVS 內(nèi)網(wǎng)網(wǎng)段的網(wǎng)絡(luò)規(guī)劃),且抵擋不住 HTTPS 卸載引發(fā)的高 CPU 占用。

而經(jīng)過(guò)壓力測(cè)試發(fā)現(xiàn),使用騰訊云 7 層 CLB 負(fù)載均衡進(jìn)行 HTTPS 卸載,性能得到極大提升。測(cè)試數(shù)據(jù)也表明,IDC 舊架構(gòu)中,啟用 HTTPS 會(huì)帶來(lái) 90% 以上的性能損耗。

2. 架構(gòu)調(diào)整引發(fā)多次故障

引入騰訊云 7 層 CLB 負(fù)載均衡產(chǎn)品,帶了了巨大的性能提升,卻也給業(yè)務(wù)帶來(lái)了痛苦,主要核心問(wèn)題是獲取客戶端的真實(shí) IP 上。

當(dāng)前現(xiàn)狀是業(yè)務(wù)語(yǔ)言異構(gòu)(PHP + Go),多數(shù)業(yè)務(wù)已經(jīng)歷服務(wù)化改造,但缺乏服務(wù)發(fā)現(xiàn)機(jī)制,服務(wù)與服務(wù)之間的調(diào)用依賴域名和 DNS 解析,大部分都是 HTTP 服務(wù)。

在架構(gòu)調(diào)整后,由于未能 100% 覆蓋測(cè)試,導(dǎo)致漏測(cè)的服務(wù)經(jīng)常拿到錯(cuò)誤的客戶端 IP 地址,造成的后果是損失大量的用戶。這些用戶會(huì)因?yàn)槎绦膨?yàn)證碼發(fā)送限制、IP 登錄頻次過(guò)高而無(wú)法登錄、充值,給公司帶來(lái)巨大損失。

3. 未來(lái)的路應(yīng)該怎么走?

更進(jìn)一步講,當(dāng)前業(yè)務(wù)如何抵擋外界的 DDoS 攻擊、請(qǐng)求機(jī)器人、SQL 注入等等,最簡(jiǎn)單的是接入高防 IP、WAF 應(yīng)用防火墻,而請(qǐng)求經(jīng)過(guò)多輪轉(zhuǎn)發(fā),同樣也有獲取客戶端真實(shí) IP 的問(wèn)題。

再者,業(yè)務(wù)也在逐步容器化,享受 Kubernetes 彈性擴(kuò)容的便利,怎么平滑遷移也是非常值得深思的。

假設(shè)有一天某個(gè)同學(xué),不小心配置有誤——應(yīng)用層拿到的,很有可能是高防 IP 或者 WAF 的 IP,業(yè)務(wù)絕對(duì)無(wú)法忍受。

顯然,確定一個(gè)業(yè)務(wù)無(wú)感知的方案并成功落地迫在眉睫。

然而翻遍整個(gè)互聯(lián)網(wǎng),幾乎沒(méi)有文章能把這些看起來(lái)很簡(jiǎn)單的事情捋清楚、講明白,更不用說(shuō)最佳實(shí)踐。

大多數(shù)人都是抄抄配置,潦潦草草上線,方案并沒(méi)有普適性。

這篇文章也是我在這段時(shí)間的研究中總結(jié)出來(lái)的寶貴經(jīng)驗(yàn),希望對(duì)讀者能有些許幫助。文章篇幅較長(zhǎng),難免有錯(cuò)誤之處,還請(qǐng)各位看官斧正,感激不盡:)

二、名詞釋義

1. REMOTE-ADDR
  • Nginx + PHP 模式下,REMOTE-ADDR 為遠(yuǎn)端的 IP 地址,可通過(guò) $_SERVER['REMOTE-ADDR'] 獲?。?/li>
  • 它代表與上一層建立 TCP 連接的 IP 地址;
  • 網(wǎng)站無(wú)代理時(shí)(客戶端->服務(wù)端),WEB服務(wù)器(Nginx,Apache等)會(huì)設(shè)置該值為客戶端 IP;
  • 網(wǎng)站存在代理時(shí)(客戶端->代理->服務(wù)端),該值為代理的 IP。
proxy_set_header REMOTE-ADDR $remote_addr;
2. X-Forwarded-For

X-Forwarded-For 是一個(gè) HTTP 擴(kuò)展頭部。HTTP/1.1(RFC 2616)協(xié)議并沒(méi)有對(duì)它的定義,它最開(kāi)始是由 Squid 這個(gè)緩存代理軟件引入,用來(lái)表示 HTTP 請(qǐng)求端真實(shí) IP。如今它已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn),被各大 HTTP 代理、負(fù)載均衡等轉(zhuǎn)發(fā)服務(wù)廣泛使用,并被寫(xiě)入 RFC 7239(Forwarded HTTP Extension)標(biāo)準(zhǔn)之中。

  • 格式為英文逗號(hào) + 空格隔開(kāi),例如:X-Forwarded-For: IP0(client), IP1(proxy), IP2(proxy);

  • 中間經(jīng)過(guò)的代理,會(huì)逐層追加至末尾;

  • IP0 離服務(wù)端最遠(yuǎn),然后是每一級(jí)代理設(shè)備的 IP,IP2 直連服務(wù)端。

  • 如果客戶端偽造 IP 地址,格式為:X-Forwarded-For: 偽造的 IP 地址 1, [偽造的 IP 地址 2…], IP0(client), IP1(proxy), IP2(proxy)。

3. X-Real-IP

注:CLB <=> SLB,為騰訊云和阿里云不同產(chǎn)品的稱(chēng)呼,均為負(fù)載均衡。

典型的調(diào)用鏈路:

client --> ① [CLB-7]gateway --域名--> ② [CLB-7]server(③ nginx + ④ go/php)
  • X-Real-IP 為建立 TCP 連接的上一跳的 IP 地址;
  • 對(duì)于 ④ 而言,X-Real-IP 為 ① 網(wǎng)關(guān)的 NAT 公網(wǎng)出口 IP 地址,或 gateway 的內(nèi)網(wǎng) IP 地址,該結(jié)論通過(guò)生產(chǎn)環(huán)境 tcpdump 抓包驗(yàn)證得到;
  • 公網(wǎng)調(diào)用下,① 網(wǎng)關(guān) 調(diào)用 ② 7 層 CLB,再到應(yīng)用層 ③④,此時(shí) ④ 拿到的 X-Real-IP 為 ① 的 NAT 公網(wǎng)出口地址(7 層 CLB 會(huì)重寫(xiě) X-Real-IP 頭部,并追加 X-Forwarded-For 頭部);
  • 內(nèi)網(wǎng)環(huán)境中,原理相似,只不過(guò)拿到的是 gateway 的內(nèi)網(wǎng) IP 地址;
  • 中間可能被 ③ nginx 重寫(xiě),此時(shí)等同于 REMOTE-ADDR。

比如以下最常見(jiàn)的 nginx 配置:

proxy_set_header  REMOTE-ADDR     $remote_addr;
proxy_set_header  X-Real-IP       $remote_addr;
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

REMOTE-ADDR 和 X-Real-IP 都是 nginx 的 $remote_addr 變量,再傳遞給下游。

三、面臨困境

1. 運(yùn)維側(cè)
  • 業(yè)務(wù)線配置五花八門(mén),沒(méi)有統(tǒng)一。具體表現(xiàn)在 nginx.conf 和 vhost 配置在不同的業(yè)務(wù)線有很大區(qū)別;
  • vhost 成千上萬(wàn),nginx 內(nèi)部存在多重轉(zhuǎn)發(fā),外部也有網(wǎng)關(guān)轉(zhuǎn)發(fā)過(guò)來(lái)的流量,且網(wǎng)關(guān)不止一套,捋不清鏈路容易導(dǎo)致線上故障;
  • 缺乏完善的 QA 驗(yàn)證流程,變更沒(méi)辦法 100% 覆蓋測(cè)試,最終結(jié)果就是盡可能少變更,但這不是長(zhǎng)久之計(jì);
  • 存在開(kāi)發(fā)自行維護(hù)信任 IP 的情況,所以運(yùn)維不敢隨便變更,因?yàn)樽兏靶枰ㄖ_(kāi)發(fā)整改,開(kāi)發(fā)有自己的時(shí)間排期,處理起來(lái)效率極其低下;
  • 為了盡可能少修改原先的配置,部分機(jī)器組接入了騰訊云的 TOA 模塊,用來(lái)獲取客戶端真實(shí) IP 地址,而阿里云沒(méi)有相似的產(chǎn)品,如果沒(méi)有統(tǒng)一的方案,沒(méi)辦法上線阿里云,實(shí)現(xiàn)不了雙云雙活的目標(biāo)等等。
2. 開(kāi)發(fā)側(cè)

各個(gè)業(yè)務(wù)線使用的技術(shù)棧不統(tǒng)一,存在多種獲取客戶端 IP 的方案,需要找到一種盡可能少修改代碼,或者一點(diǎn)都不需要修改代碼的方案。

PHP 以 Laravel 框架為例(底層是 Symfony 框架),發(fā)現(xiàn)內(nèi)部取了 $_SERVER[‘REMOTE_ADDR’] 變量:

public function getClientIp()
{
    $ipAddresses = $this->getClientIps();
    return $ipAddresses[0]; // 1. 取第一個(gè) IP 地址。
}
public function getClientIps()
{
    $ip = $this->server->get('REMOTE_ADDR');
    if (!$this->isFromTrustedProxy()) {
        // 2. 程序在這里返回了 REMOTE_ADDR 頭部的值。
        return [$ip];
    }
    // 3. 永遠(yuǎn)到不了這個(gè)分支。
    return $this->getTrustedValues(self::HEADER_X_FORWARDED_FOR, $ip) ?: [$ip];
}
public function isFromTrustedProxy()
{
    // 4. 因?yàn)樯a(chǎn)環(huán)境中,$trustedProxies 沒(méi)有配置。
    return self::$trustedProxies && IpUtils::checkIp($this->server->get('REMOTE_ADDR', ''), self::$trustedProxies);
}

公司內(nèi)部有些業(yè)務(wù)自己實(shí)現(xiàn)函數(shù),依賴的是 X-Forwarded-For 頭部。

Go 以 Gin 框架為例,準(zhǔn)確的說(shuō)是 Gin@v1.6. 版本,它先取 X-Forwarded-For 的第一個(gè) IP,取不到就取 X-Real-IP 頭部:*

func (c *Context) ClientIP() string {
	// 1. ForwardedByClientIP 默認(rèn)為 true
	if c.engine.ForwardedByClientIP {
		// 2. 優(yōu)先獲取 X-Forwarded-For 頭部
		clientIP := c.requestHeader("X-Forwarded-For")
		// 3. 取 X-Forwarded-For 的第一個(gè) IP 地址
		clientIP = strings.TrimSpace(strings.Split(clientIP, ",")[0])
		// 4. 取不到就取 X-Real-Ip 字段
		if clientIP == "" {
			clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip"))
		}
		// 5. 拿到了就直接返回(正常的邏輯)
		if clientIP != "" {
			return clientIP
		}
	}
	// 6. 忽略,該值為 false,除非 build tags 包含 appengine 為 true
	if c.engine.AppEngine {
		if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
			return addr
		}
	}
	// 7. 以上都取不到的話,取 RemoteAddr 字段,走到這個(gè)邏輯,程序肯定不正常。
	// 參考 Go 標(biāo)準(zhǔn)庫(kù),該值為 TCP 建立連接的遠(yuǎn)端 IP 地址
	// go1.17.1/src/net/http/server.go:1003
	// req.RemoteAddr = *conn.remoteAddr
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

經(jīng)過(guò)調(diào)研發(fā)現(xiàn),業(yè)務(wù)取的是 X-Real-IP 字段,具體原因就不展開(kāi)了。

至于 Gin@1.7.* 版本,由于 Gin@1.6.* 的實(shí)現(xiàn)存在偽造客戶端 IP 的問(wèn)題,被爆 CVE-2020-28483 漏洞,官方為了修復(fù)這個(gè)問(wèn)題,換了一種實(shí)現(xiàn)修復(fù)該漏洞:

func (c *Context) ClientIP() string {
	// 1. 自定義 Header 的情況,可以忽略
	if c.engine.TrustedPlatform != "" {
		if addr := c.requestHeader(c.engine.TrustedPlatform); addr != "" {
			return addr
		}
	}
	if c.engine.AppEngine {
		if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
			return addr
		}
	}
	// 2. 獲取 IP 地址,并返回是否可以信任
	remoteIP, trusted := c.RemoteIP()
	if remoteIP == nil {
		return ""
	}
	// 3. 如果信任,檢查 IP 地址的合法性,合法就返回
	// 默認(rèn)值:ForwardedByClientIP=true,RemoteIPHeaders=[X-Forwarded-For(優(yōu)先), X-Real-IP]
	if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
		for _, headerName := range c.engine.RemoteIPHeaders {
			// c.requestHeader 在頭部有效的情況下,也是返回第一個(gè) IP 地址。
			ip, valid := validateHeader(c.requestHeader(headerName))
			if valid {
				return ip
			}
		}
	}
	// 4. 不能信任,那就用 TCP 連接遠(yuǎn)端 IP 兜底。
	return remoteIP.String()
}
func (c *Context) RemoteIP() (net.IP, bool) {
	ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr))
	if err != nil {
		return nil, false
	}
	remoteIP := net.ParseIP(ip)
	if remoteIP == nil {
		return nil, false
	}
	// remoteIP = TCP 連接遠(yuǎn)端 IP 地址
	// 由于業(yè)務(wù)沒(méi)有配置 engine.TrustedProxies,所以是不可信任的。
	return remoteIP, c.engine.isTrustedProxy(remoteIP)
}
func (e *Engine) isTrustedProxy(ip net.IP) bool {
	if e.trustedCIDRs != nil {
		for _, cidr := range e.trustedCIDRs {
			if cidr.Contains(ip) {
				return true
			}
		}
	}
	// 業(yè)務(wù)將會(huì)走到這里!
	return false
}
func (e *Engine) validateHeader(header string) (clientIP string, valid bool) {
	if header == "" {
		return "", false
	}
	items := strings.Split(header, ",")
	for i := len(items) - 1; i >= 0; i-- {
		ipStr := strings.TrimSpace(items[i])
		ip := net.ParseIP(ipStr)
		if ip == nil {
			return "", false
		}
		// X-Forwarded-For is appended by proxy
		// Check IPs in reverse order and stop when find untrusted proxy
		if (i == 0) || (!e.isTrustedProxy(ip)) {
			return ipStr, true
		}
	}
	return
}

官方的手法也是簡(jiǎn)單粗暴,以前是將錯(cuò)就錯(cuò),這次一下子修復(fù)好了,搞得很多人翻車(chē)了(https://github.com/gin-gonic/gin/issues/2697)。

原因是新的實(shí)現(xiàn)沒(méi)有兼容 1.6 版本,導(dǎo)致升級(jí)框架后獲取不到客戶端的真實(shí) IP,1.7.7 才解決該問(wèn)題。

四、三大原則

分析完整個(gè)事情的來(lái)龍去脈,想必讀者們對(duì)現(xiàn)狀有一定的了解。

我把這套方案,抽象為三大原則,只要理解它,獲取客戶端真實(shí) IP 的問(wèn)題,就跟喝水一樣簡(jiǎn)單!

1. 代理必須向下傳遞客戶端 IP 地址

原因:從入口流量開(kāi)始,經(jīng)過(guò) N 層代理,如果代理中間不傳遞客戶端的 IP 地址,底層業(yè)務(wù)必然獲取不到客戶端的真實(shí) IP 地址

2. 統(tǒng)一使用 nginx 的 realip 模塊獲取客戶端 IP 地址
# nginx.conf
# ...
set_real_ip_from 騰訊云/阿里云 NAT 出口網(wǎng)段;
set_real_ip_from 騰訊云/阿里云高防 IP 網(wǎng)段;
set_real_ip_from 騰訊云/阿里云 WAF 網(wǎng)段;
set_real_ip_from CDN 網(wǎng)段;
set_real_ip_from 內(nèi)網(wǎng)地址網(wǎng)段; # 按需配置,對(duì)于網(wǎng)關(guān)進(jìn)來(lái)的請(qǐng)求通過(guò)內(nèi)網(wǎng)到業(yè)務(wù)機(jī)器,需要配置上這個(gè)網(wǎng)段。
set_real_ip_from 127.0.0.1;  # 按需配置,主要作用在 nginx 的內(nèi)部轉(zhuǎn)發(fā)。
real_ip_header X-Forwarded-For;
real_ip_recursive on;        # 必須打開(kāi)該選項(xiàng),原因見(jiàn)下面分析。
access_by_lua '
    ngx.req.set_header("X-REAL-IP",       ngx.var.remote_addr)
    ngx.req.set_header("X-FORWARDED-FOR", ngx.var.remote_addr)
';

# vhost/*.conf
location ^~ /foo {
    access_log         logs/api_foo.access.log main;
    proxy_pass         http://api_foo;
    proxy_redirect     off;
    proxy_http_version 1.1;
    proxy_set_header   Host            $http_host;
    proxy_set_header   X-NginX-Proxy   true;
    proxy_set_header   Connection      "";
}

此時(shí),X-Real-IP、REMOTE-ADDR、X-Forwarded-For 均統(tǒng)一為 realip 模塊重寫(xiě)后的 $remote_addr 變量,業(yè)務(wù)就可以取到真實(shí)的客戶端 IP 地址,無(wú)需考慮 PHP、Go 等不同語(yǔ)言、同種語(yǔ)言不同框架下的差異。

那問(wèn)題來(lái)了,客戶端 IP 是否會(huì)被偽造?答案是不會(huì)的。

按照 X-Forwarded-For 的定義,該頭部每經(jīng)過(guò)一層就追加一個(gè) IP 地址:

X-Forwarded-For: 客戶端偽造 IP 地址, IP0(client), IP1(proxy), IP2(proxy)

那么,我們只需啟用 realip 模塊的 real_ip_recursive 遞歸模式,將從右往左逐步剔除 IP2,IP1 等信任代理,最后會(huì)獲取到真實(shí)的客戶端 IP 地址。

問(wèn)題二:網(wǎng)上有一種邊緣節(jié)點(diǎn)的方案,為什么不采用?

邊緣節(jié)點(diǎn),指的就是接入層,直接連接客戶端的那一層。經(jīng)過(guò)邊緣節(jié)點(diǎn)轉(zhuǎn)發(fā)到下游的,統(tǒng)稱(chēng)為非邊緣節(jié)點(diǎn)。

按照這個(gè)思路,如果邊緣節(jié)點(diǎn)拿到了客戶端 IP,重置 X-FORWARDED-FOR 頭部為客戶端 IP 地址,并轉(zhuǎn)發(fā)到下游,業(yè)務(wù)只獲取第一個(gè) IP 地址,理論上也不會(huì)被偽造,業(yè)務(wù)也簡(jiǎn)單,為什么不采用?

因?yàn)檫吘壒?jié)點(diǎn)方案最大的缺點(diǎn)在于失去了靈活性,譬如你想接入高防 IP 或者 WAF 防火墻,此時(shí)它已不再是邊緣節(jié)點(diǎn),而是接收高防服務(wù)器或 WAF 防火墻清洗的流量,將會(huì)拿到錯(cuò)誤的 IP 地址。

3. 運(yùn)維維護(hù)信任 IP 列表,開(kāi)發(fā)代碼不做處理

由 2 可知,三個(gè)頭部均為統(tǒng)一的值,對(duì)開(kāi)發(fā)可以保證最大的兼容性。原因是不同的語(yǔ)言,同個(gè)語(yǔ)言的不同開(kāi)發(fā)框架,同個(gè)框架的不同版本,獲取客戶端 IP 的方式也就這幾種。

對(duì)開(kāi)發(fā)而言,確實(shí)沒(méi)必要關(guān)心自己的代碼需要引入 NAT 網(wǎng)關(guān) IP 配置、高防 IP 配置等,并且每個(gè)工程可能都要修改,這是不現(xiàn)實(shí)的。

本質(zhì)上,這也是運(yùn)維的工作。舉個(gè)例子,如果真的遇到 DDoS 攻擊,切換高防 IP 抵御 DDoS 攻擊的操作人是運(yùn)維,開(kāi)發(fā)這個(gè)時(shí)候去將所有工程配置上高防 IP 地址是一件極其痛苦的事情。一旦加漏、加錯(cuò)將直接引發(fā)故障。

五、最佳實(shí)踐

(1) 虛擬機(jī)部署
  1. SRE 維護(hù)信任的 IP 池,X-Real-IP、REMOTE-ADDR、X-Forwarded-For 均統(tǒng)一為 realip 模塊重寫(xiě)后的 $remote_addr 變量,開(kāi)發(fā)不感知;
  2. 開(kāi)發(fā)無(wú)需修改代碼,因?yàn)樯鲜鋈齻€(gè)變量讀取出來(lái)的值是一致的,無(wú)任何風(fēng)險(xiǎn)。
(2) 容器化部署

a. PHP 無(wú)需改動(dòng),可以平滑切換上容器。因?yàn)?PHP 容器上層依然有 nginx.conf,平移該配置即可;

b. GO 容器化,有 2 種方案:

注:最終采用方案 2,去除了 Pod 內(nèi)部的 nginx 轉(zhuǎn)發(fā),Pod 的上層使用了 nginx-ingress,做到了業(yè)務(wù)無(wú)感知容器上云。

  1. 如果保留虛擬機(jī)架構(gòu),即 Go 服務(wù)上層有 nginx,也是平移就可以了,跟 PHP 一樣;

  2. 如果 Go 服務(wù)上游去除 nginx 轉(zhuǎn)發(fā):

    流量入口使用 7 層騰訊云 CLB / 阿里云 SLB 進(jìn)行 HTTPS 卸載后轉(zhuǎn)發(fā)到容器集群的 nginx-ingress,業(yè)務(wù)代碼無(wú)感知。實(shí)現(xiàn)原理和虛擬機(jī)方案相似,均為配置 realip 模塊和統(tǒng)一 X-Real-IP、REMOTE-ADDR、X-Forwarded-For 頭部,詳情可以參考以下資料:

    • https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-proxy-protocol
    • https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#proxy-real-ip-cidr
    • https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#server-snippet
    • https://help.aliyun.com/document_detail/86533.html

還有個(gè)容易忽略的點(diǎn)——ingress 選型。

如果使用 Pod 直連,也就是不使用 nginx-ingress:

PHP / Go 上層都需要有一層 nginx 并配置好 nginx.conf,配置 realip 模塊和統(tǒng)一 X-Real-IP、REMOTE-ADDR、X-Forwarded-For 頭部。

此時(shí) PHP / Go 架構(gòu)統(tǒng)一,但對(duì) Go 容器來(lái)說(shuō)多了一層 nginx,會(huì)造成資源浪費(fèi)(每個(gè) Pod 都需要部署一個(gè) nginx,再轉(zhuǎn)發(fā)到 Go)。

具體用哪個(gè) ingress,就要看怎么取舍了。

nginx 存在的意義在于阻止業(yè)務(wù)直接感知到信任代理 IP 列表的存在,如果對(duì)于你的業(yè)務(wù)而言,各個(gè)業(yè)務(wù)線去維護(hù)這個(gè)配置列表成本極低,那 nginx 確實(shí)是沒(méi)有存在的必要性。


總之,我個(gè)人認(rèn)為:

  1. 業(yè)務(wù)完全不需要關(guān)心如何獲取客戶端的真實(shí) IP,這是最好的選擇;
  2. 千萬(wàn)不要封裝各種函數(shù)去獲取客戶端真實(shí) IP,這種問(wèn)題最好交給上層 SRE 基礎(chǔ)架構(gòu)的同學(xué)負(fù)責(zé),不然真的非常容易出問(wèn)題;
  3. 理解好三大原則,獲取客戶端真實(shí) IP 的問(wèn)題,就跟喝水一樣簡(jiǎn)單!

OK,文章終于寫(xiě)完了,花費(fèi)了好多天的時(shí)間整理,憋出來(lái)了。感謝你讀到這里,是時(shí)候吃晚飯了:)


文章來(lái)源于本人博客,發(fā)布于 2021-12-19,原文鏈接:https://imlht.com/archives/248/文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-753849.html

到了這里,關(guān)于獲取客戶端真實(shí) IP 地址的最佳實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • nginx獲取客戶端真實(shí)ip

    在nginx中獲取客戶端真實(shí)IP的方法有多種,以下是其中兩種常用的方法: 使用nginx的access_log模塊記錄請(qǐng)求日志,并在日志中包含客戶端的真實(shí)IP信息。例如: 在上述配置中,通過(guò)使用http_x_forwarded_for字段來(lái)獲取客戶端的真實(shí)IP地址。如果該字段不存在或不合法,則使用remote_ad

    2024年02月16日
    瀏覽(47)
  • kubernetes獲取客戶端真實(shí)ip

    kubernetes獲取客戶端真實(shí)ip

    大部分的業(yè)務(wù)場(chǎng)景都需要獲取客戶端的ip來(lái)審計(jì)或采取措施,文章從nodeport暴露方式獲取真實(shí)ip到ingress-nginx獲取真實(shí)ip 初學(xué)者用k8s創(chuàng)建時(shí)暴露方式一般采用nodeport,這樣方式暴露導(dǎo)致應(yīng)用負(fù)載和訪問(wèn)者并不是同一段網(wǎng)絡(luò),當(dāng)web服務(wù)獲取客戶端ip的時(shí)候會(huì)發(fā)現(xiàn)獲取到的ip是k8s網(wǎng)關(guān)的

    2024年02月01日
    瀏覽(21)
  • 獲取客戶端真實(shí)IP的方法

    獲取客戶端真實(shí)IP的方法

    獲取請(qǐng)求的IP很簡(jiǎn)單,可以直接使用request.getRemoteAddr()直接獲取。但由于請(qǐng)求在轉(zhuǎn)發(fā)到接口前,會(huì)經(jīng)過(guò)大量的反向代理,例如流程圖中,至少要經(jīng)過(guò)Nginx后,請(qǐng)求才會(huì)轉(zhuǎn)發(fā)到接口,因此需要對(duì)請(qǐng)求接口的IP做處理,提取客戶端真實(shí)IP地址。 配置Nginx的配置文件,需要反向代理服務(wù)

    2024年02月16日
    瀏覽(22)
  • k8s ingress獲取客戶端客戶端真實(shí)IP

    k8s ingress獲取客戶端客戶端真實(shí)IP

    在Kubernetes中,獲取客戶端真實(shí)IP地址是一個(gè)常見(jiàn)需求。這是因?yàn)樵谪?fù)載均衡架構(gòu)中,原始請(qǐng)求的源IP地址會(huì)被替換成負(fù)載均衡器的IP地址。 獲取客戶端真實(shí)IP的需求背景包括以下幾點(diǎn): 安全性:基于客戶端IP進(jìn)行訪問(wèn)控制和認(rèn)證授權(quán)可以提高系統(tǒng)安全性。 日志記錄與審計(jì):記

    2024年02月13日
    瀏覽(23)
  • Nginx(二十) 獲取真實(shí)客戶端IP

    ????????客戶端在訪問(wèn)互聯(lián)網(wǎng)應(yīng)用服務(wù)器時(shí),與真實(shí)的應(yīng)用服務(wù)器之間會(huì)因?yàn)橛卸鄬臃聪虼?,而?dǎo)致真實(shí)應(yīng)用服務(wù)器獲取的僅是最近一層的反向代理服務(wù)器 IP。為使 Nginx 后端的上游服務(wù)器可以獲得真實(shí)客戶端 IP,Nginx 提供了 ngx_http_realip_module 模塊用以實(shí)現(xiàn)真實(shí)客戶端

    2024年01月16日
    瀏覽(30)
  • nginx如何獲取真實(shí)客戶端ip

    nginx作為反向代理服務(wù)器,即代理我們的服務(wù)端,下面介紹下如何配置nginx獲取真實(shí)的客戶端ip 1、配置nginx.con 2、在java程序中可以通過(guò)如下方式獲取: 這樣就可以打印出真實(shí)ip了!即request.getHeader(\\\"X-Real-IP\\\")的值 引用: 查看端口占用及釋放所占用的端口_查詢谷歌瀏覽器的端口

    2024年02月11日
    瀏覽(14)
  • 學(xué)習(xí)NodeJs之【如何獲取客戶端真實(shí)IP】

    學(xué)習(xí)NodeJs之【如何獲取客戶端真實(shí)IP】

    ????????產(chǎn)品想要增加一個(gè)操作日志的模塊,重點(diǎn)記錄增刪改的操作ip。 ????????這塊業(yè)務(wù)其實(shí)需要按【是否代理】來(lái)分邏輯。首次開(kāi)發(fā)時(shí),并未考慮? 測(cè)試生產(chǎn)環(huán)境有統(tǒng)一代理? ,導(dǎo)致傳統(tǒng)的獲取ip方式取到了容器網(wǎng)關(guān)ip?!@然這樣是無(wú)法滿足產(chǎn)品想要區(qū)分操作

    2024年02月03日
    瀏覽(23)
  • 【全方位解析】如何獲取客戶端/服務(wù)端真實(shí) IP

    【全方位解析】如何獲取客戶端/服務(wù)端真實(shí) IP

    1.比如在投票系統(tǒng)開(kāi)發(fā)中,為了防止刷票,我們需要限制每個(gè) IP 地址只能投票一次 2.當(dāng)網(wǎng)站受到諸如 DDoS(Distributed Denial of Service,分布式拒絕服務(wù)攻擊)等攻擊時(shí),我們需要快速定位攻擊者 IP 3.在滲透測(cè)試過(guò)程中,經(jīng)常會(huì)碰到網(wǎng)站有 CDN(Content Distribution Network,內(nèi)容交付網(wǎng)絡(luò)

    2024年02月07日
    瀏覽(36)
  • k8s ingress 添加獲取客戶端真實(shí)ip配置

    k8s ingress 添加獲取客戶端真實(shí)ip配置

    本環(huán)境是一個(gè)互聯(lián)網(wǎng)ip服務(wù)器上的nginx轉(zhuǎn)發(fā)k8s集群內(nèi)的ingress域名,實(shí)現(xiàn)所有服務(wù)通過(guò)域名訪問(wèn), 默認(rèn)配置下,在pod內(nèi)獲取客戶端請(qǐng)求地址信息時(shí),獲取的是pod的ip和節(jié)點(diǎn)ip。要獲取客戶端ip,需要添加nginx配置中 除此之外還需要修改configmap ingress-nginx-controller ,增加如下配置

    2024年02月02日
    瀏覽(43)
  • Nginx+netty實(shí)現(xiàn)tcp負(fù)載均衡,獲取客戶端真實(shí)ip

    在nginx.conf文件中,events,http同級(jí)添加配置 啟動(dòng)nginx服務(wù) 啟動(dòng)2個(gè)服務(wù)netty服務(wù)設(shè)置nginx中8888,8889端口。 使用tcp工具連接并發(fā)送數(shù)據(jù)測(cè)試 參考博客 參考鏈接1 參考鏈接2

    2024年02月06日
    瀏覽(32)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包