当前位置:网站首页>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:内部代理
无特殊需求可无需配
边栏推荐
- KT6368A蓝牙芯片的主从机之前透传功能说明,2.4G跳频自动连接
- TKKC round#3
- 磁盤的結構
- 985 test engineer is hanged. Who is more important in terms of education and experience?
- Docker installs MySQL 8.0. Detailed steps
- Publicity of the second batch of shortlisted enterprises! Annual Top100 smart network supplier selection
- YGG 近期游戏合作伙伴一览
- Yida technology signed a contract with seven wolves to help the digital transformation of "Chinese men's wear leader"
- In the era of industrial Internet, there is no Internet in the traditional sense
- Development trend and path of SaaS industry in China
猜你喜欢

理想L9,智能座舱新潮流

Description of transparent transmission function before master and slave of kt6368a Bluetooth chip, 2.4G frequency hopping automatic connection

系统测试主要步骤

Rotate the square array of two-dimensional array clockwise by 90 °

如何比较两个或多个分布:从可视化到统计检验的方法总结

NIO、BIO、AIO

Servlet details

一个女孩子居然做了十年硬件。。。

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

虚拟人的产业发展现状
随机推荐
字符串习题总结2
Collapse code using region
系统测试主要步骤
Redis+caffeine two-level cache enables smooth access speed
Development of live broadcast software app, and automatic left-right sliding rotation chart advertising
想当测试Leader,这6项技能你会吗?
Opengauss kernel: simple query execution
Several schemes of traffic exposure in kubernetes cluster
网上立案流程
Two implementation methods of stack
The process from troubleshooting to problem solving: the browser suddenly failed to access the web page, error code: 0x80004005, and the final positioning: "when the computer turns on the hotspot, the
磁盤的結構
first-order-model实现照片动起来(附工具代码) | 机器学习
YGG 近期游戏合作伙伴一览
进程的通信方式
Notes on writing questions (18) -- binary tree: common ancestor problem
Binary search tree template
NIO、BIO、AIO
KT6368A蓝牙双模透传芯片软件版本选型说明
Practice of hierarchical management based on kubesphere