当前位置:网站首页>envoy获取客户端真实IP
envoy获取客户端真实IP
2022-06-24 19:35:00 【Mr.Cylon】
在envoy作为前端代理时,用户ip的获取很重要,一般获取ip的方式。都是通过Header中的 X-Forward-For、 X-Real-IP或 Remote addr 等属性获取,但是如果确保Envoy可以获取到的ip是真实的用户ip呢?本篇继续解密!
概念说明
Remote Address
是nginx与客户端进行TCP连接过程中,获得的客户端真实地址。Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。
一般情况下,在Envoy作为最外层代理时,此IP为真实的IP客户端IPX-Real-IP
是一个自定义头。X-Real-Ip 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。X-Real-Ip 目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息。X-Forwarded-For
X-Forwarded-For 是一个扩展头。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP,现在已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中。通常,X-Forwarded-For可被伪造,并且使用CDN会被重写
Envoy中如何获取真实IP
在Envoy中,涉及到客户端IP的配置如下:
use_remote_address: 默认值false,设置为true,使用客户端连接的真实远程地址,false是使用x-forwarded-for
skip_xff_append: 设置为true,则不会将远程地址附加到x-forwarded-for中
request_headers_to_add 添加请求头
request_headers_to_remove 删除一个请求头
实验环境配置准备
admin:
access_log_path: /dev/null
address:
socket_address: {
address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_80
address:
socket_address: {
address: 0.0.0.0, port_value: 80 }
access_log:
filter_chains:
- filters:
- name: envoy_http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
access_log:
- name: envoy.listener.accesslog
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /var/log/envoy.log
log_format:
text_format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\n"
http_filters:
- name: envoy.filters.http.router
use_remote_address: true
skip_xff_append: false
xff_num_trusted_hops: 0
stat_prefix: local_route
codec_type: AUTO
route_config:
name: local_route
#request_headers_to_remove: "X-Forwarded-For"
request_headers_to_add:
header:
key: "X-Forwarded-For"
value: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"
#value: "%REQ(REMOTE_ADDR)%"
append: true
virtual_hosts:
- name: split_traffic
domains: [ "*" ]
routes:
- match:
prefix: "/"
route:
cluster: version_v1
request_mirror_policies:
cluster: version_v2
runtime_fraction:
default_value:
numerator: 10
denominator: HUNDRED
runtime_key: routing.request_mirror.version
clusters:
- name: version_v1
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: version_v1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: {
address: version1, port_value: 90 }
health_checks:
timeout: 3s
interval: 30s
unhealthy_threshold: 2
healthy_threshold: 2
http_health_check:
path: /ping
expected_statuses: {
start: 200, end: 201 }
- name: version_v2
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: version_v2
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: {
address: version2, port_value: 90 }
health_checks:
timeout: 3s
interval: 30s
unhealthy_threshold: 2
healthy_threshold: 2
http_health_check:
path: /ping
expected_statuses: {
start: 200, end: 201 }
docker-compose
version: '3'
services:
envoy:
image: envoyproxy/envoy-alpine:v1.15-latest
environment:
- ENVOY_UID=0
ports:
- 80:80
- 443:443
- 82:9901
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
networks:
envoymesh:
aliases:
- envoy
depends_on:
- webserver1
- webserver2
- webserver3
- webserver4
webserver1:
image: cylonchau/envoy-end:latest
networks:
envoymesh:
aliases:
- version1
environment:
- VERSION=v1
- COLORFUL=blue
expose:
- 90
webserver2:
image: cylonchau/envoy-end:latest
networks:
envoymesh:
aliases:
- version1
environment:
- VERSION=v1
- COLORFUL=blue
expose:
- 90
webserver3:
image: cylonchau/envoy-end:latest
networks:
envoymesh:
aliases:
- version2
environment:
- VERSION=v2
- COLORFUL=red
expose:
- 90
webserver4:
image: cylonchau/envoy-end:latest
environment:
- VERSION=v2
- COLORFUL=red
networks:
envoymesh:
aliases:
- version2
expose:
- 90
networks:
envoymesh: {
}
实际使用Envoy作为代理时的外在环境
环境1:客户端直接和Envoy通信
当一个正常请求时,此处可以正常获得客户端IP,实际上envoy拿的值是 X-Forwarded-For

后端日志

在伪造或者重写X-Forwarded-For后实际上是获取的伪造的值。



在Envoy直接作为外层代理时,可以使用如下参数,在不管如何伪造,都可以拿到对应的参数。
name: local_route
request_headers_to_remove: "X-Forwarded-For" # 怕X-Forwarded-For为伪造值,可以删除此值,
request_headers_to_add: # 删除后还需要向后端传递,故还需要添加上此值
header:
key: "X-Forwarded-For"
value: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%" # 获取 remote_addr,此值无法伪造,为Envoy变量,表示 下游主机真实IP不加端口,即remote_addr 无端口
append: true # 表面值是追加还是重写



可以看到envoy获取的为真实的ip并非伪造的请求
环境2:Envoy前段存在代理(无CDN)
此环境下,前端存在代理,如f5、nginx等。这种情况下不能使用remote_addr 这样获取的为前端代理的IP并非真实IP
前端存在f5或nginx,可以在f5中配置irule传递真实的remote_addr,替换为真实的客户端IP,又前端代理重写配置,可自定义值。
request_headers_to_remove: "X-Forwarded-For"
request_headers_to_add:
header:
key: "X-Forwarded-For"
value: "%REQ(custom_header)%"
环境3:Envoy前段存在代理(单CDN)
此环境下,前端存在代理,并且使用了CDN,应为每个CDN厂商获取客户真实IP的方式并不一致,这里需要找到cdn厂商找到获取真实IP的方法,在按照步骤2进行。
环境4:Envoy前段存在代理(多CDN)
由于各CDN的带宽、价格、使用场景等因素,在实际情况下,可能使用多种CDN;如:正常情况下使用cdn加速,遇到攻击时切换安全防御高的CDN。一般仅加速的CDN价格比带防御的要便宜很多。
此处Enovy待更新,后端应用可根据CDN的http头正常获取IP
环境5:内部代理
无特殊需求可无需配
边栏推荐
- The ktp900f mobile download program of the fail safe mobile panel prompts that the download cannot be performed, and the target device is running or not in the transmission mode
- 直播软件app开发,左右自动滑动的轮播图广告
- Stl+ tree
- 短视频商城系统,scroll-view如何自适应页面剩余高度
- A girl has been making hardware for ten years. 。。
- Notes on writing questions (18) -- binary tree: common ancestor problem
- Double linked list implementation
- socket done
- AQS source code analysis
- Publicity of the second batch of shortlisted enterprises! Annual Top100 smart network supplier selection
猜你喜欢

socket done

PostMan工具介绍及安装使用

KT6368A蓝牙芯片的主从机之前透传功能说明,2.4G跳频自动连接

Detailed explanation of agency mode

I really can't do it. After 00, I collapsed and wanted to leave

How to refine permissions to buttons?

socket(1)

Description of software version selection of kt6368a Bluetooth dual-mode transparent chip

Heartless sword Chinese English bilingual poem 003 The sea of books

Machine learning: linear regression
随机推荐
MySQL gets fields and comments by indicating
波卡生态发展不设限的奥义——多维解读平行链
These map operations in guava have reduced my code by 50%
NIO 零拷贝
故障安全移动面板KTP900F Mobile下载程序提示无法下载,目标设备正在运行或未处于传输模式的解决办法
Find the maximum value in each tree row [extension of one of the hierarchical traversals]
Redis+caffeine two-level cache enables smooth access speed
系统测试主要步骤
Implementation of heap sort and quick sort principle
Publicity of the second batch of shortlisted enterprises! Annual Top100 smart network supplier selection
Docker installs redis-5.0.12. Detailed steps
seven
Learning notes 23-- basic theory of multi-sensor information fusion (Part I)
KT6368A蓝牙芯片的主从机之前透传功能说明,2.4G跳频自动连接
Servlet详解
Notes on writing questions (18) -- binary tree: common ancestor problem
How to grab the mobile phone bag for analysis? Fiddler artifact may help you!
Industrial development status of virtual human
Servlet details
The leader of ERP software in printing industry