多层代理下如何获取客户端请求真实ip
  yx99X8RMvAE0 2023年11月13日 27 0

需求背景:

研发发了一张redis查看信息截图,说sdk服务没有获取到用户真实ip

多层代理下如何获取客户端请求真实ip_uwsgi

他想要能获取到用的真实请求ip


sdk服务访问架构

多层代理下如何获取客户端请求真实ip_header_02


思路:

这里犯了致命失误 ,没有问清楚,上面那个redis信息是从那个代码上获取,怎么获取到的,虽然在语言方面运维天然劣势,不过可以问研发嘛,那些代码是干什么作用的,如果不去当面问清楚,恐怕自以为解决后但实质研发的问题并没有解决会让你的研发伙伴感觉你是不专业的,后面了解到研发通过获取请求头信息中的REMOTE_ADDR来作为用户真实请求ip存入redis中的,那么我们想下是不是研发拿错了请求头信息了,因为一般remote_addr只是代表服务上一层客户端的ip地址,而请求头信息中的X-Forwarded-For才会有包含客户端真实请求ip,为了验证这个想法

第一步:需要准备一个测试域名,服务器架构要和正式sdk服务架构一致

第二步:需要一个假的sdk http服务,使用django 中request.META去获取全部的请求头信息


演示1:

在不了解清楚的情况下,我是直接通过nginx  启用 ngx_http_realip_module 模块来尝试解决这个问题

nginx -V |grep http_realip_module     # 尝试查看nginx配置是否有这个模块

如果没有这个模板的话,因为我nginx是编译安装的,所以我这里直接重新编译,如果nginx其他方式安装的话,请自行搜索解决方法

cd tengine-2.3.3/   # 切换到软件下载目录
./configure --with-stream --with-http_realip_module
make && make install
 /usr/local/nginx/sbin/nginx -V  # 查看realip模板是否安装好了


然后编辑nginx配置文件

# 启用 ngx_http_realip_module 模块
real_ip_header X-Forwarded-For;
set_real_ip_from IP_address;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
log_format  nbwl_access '$remote_addr – $remote_user [$time_local] "$request" "$request_body" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"url=$http_host" "rt=$request_time" "us=$upstream_status" "uaddr=$upstream_addr" "urt=$upstream_response_time"';

access_log  /data/logs/nginx/access.log nbwl_access;

加入以上配置

我们通过设置 real_ip_header 指令来告诉 Nginx 使用 X-Forwarded-For 请求头来获取真实 IP 地址。通常,代理服务器会将客户端的真实 IP 地址放置在 X-Forwarded-For 请求头中。

然后,我们使用 set_real_ip_from 指令指定允许从任何 IP 地址获取真实 IP。你可以根据需要进行适当的配置,以限制允许获取真实 IP 的 IP 地址范围,比如负载均衡ip地址段和高防ip地址段,多个ip地址段用逗号分隔

proxy_set_header 这个很好就是设置头信息, X-Real-IP        多层代理下如何获取客户端请求真实ip_header_03remote_addr


修改完成后重载nginx

nginx -t    # 查看配置语法是否正常
nginx -s reload  # 重载

上述步骤可以提前现在测试环境中测试

然后我通过观察日志文件/data/logs/nginx/access.log,发现第一个列就是客户端真实请求ip,然后我就跟研发说,这个问题处理好了,结果研发试了,根本没好,因为此时我并不知道研发是从哪里获取到的用户真实ip

演示2:

按照上面思路的提示,我需要提前准备一个sdk测试域名,服务架构和正式sdk服务搞一样的,需要高防接入域名,添加dns解析,sdk服务器中添加nginx配置,还需要提前准备一个假的sdk服务(用django编写的)部署到sdk服务器上去

第一步:

本地用pycharm新建一个django项目

第二步:

修改项

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
]
DEBUG = False
ALLOWED_HOSTS = ["*", ]


urls.py

from django.contrib import admin
from django.urls import path
from index import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]


在项目根目录下创建index包

多层代理下如何获取客户端请求真实ip_django_04

index包下views.py

from django.http import HttpResponse


def index(request):  # 定义视图函数index()
    s = ""
    for k, v in request.META.items():
        s += "{}:{}\n\n".format(k, v)

    response = HttpResponse(content=s, content_type='text/plain')
    return response


生成requirements.txt依赖包文件

多层代理下如何获取客户端请求真实ip_真实ip_05


第三步:将上面的项目目录给打包,上传到sdk测试服务器上


第四步:使用uwsgi启动项目

uwsgi是一个快速的,纯c语言开发的,自维护的,对开发者友好的wsgi服务器,旨在实现专业的python web应用开发和发布

unzip djangoProject.zip   # 解压压缩包
mv djangoProject /var/www/  # 放入/var/www目录下
cd /var/www/djangoProject/ # 切入目录下
pip3 install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple # 安装virtualenv
virtualenv venv # 生成虚拟环境目录
source venv/bin/activate # 激活虚拟环境
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 安装依赖包
pip install uwsgi  # 安装uwsgi
ln -s /var/www/djangoProject/venv/bin/uwsgi /usr/bin/uwsgi

配置uwsgi配置文件

多层代理下如何获取客户端请求真实ip_uwsgi_06

[uwsgi]
http=0.0.0.0:8001
chdir=/var/www/djangoProject
wsgi-file=/var/www/djangoProject/djangoProject/wsgi.py
uid=root
gid=root
master=true
processes=4
buffer-size=65535
vacuum=true
pidfile=/var/www/djangoProject/uwsgi.pid
daemonize=/var/www/djangoProject/uwsgi.log


启动项目

uwsgi --ini /var/www/djangoProject/uwsgi.ini


多层代理下如何获取客户端请求真实ip_django_07

本地测试

 curl http://localhost:8001/index/

多层代理下如何获取客户端请求真实ip_nginx_08


添加nginx配置文件

多层代理下如何获取客户端请求真实ip_uwsgi_09


然后将测试域名接入高防,添加dns解析,负载均衡进行80配置转发,就不多说了


第五步:通过访问测试域名/index 获取所有的请求头信息

多层代理下如何获取客户端请求真实ip_真实ip_10

通过头信息得知,要获取客户端真实ip的话可以拿HTTP_X_REAL_IP或HTTP_X_FORWARDED_FOR列表左边第一个值就是真实ip

不能拿REMOTE_ADDR这个值作为真实ip


解决

了解到研发从请求头REMOTE_ADDR这个值作为真实ip,我通过上面测试域名得到的结论建议研发去取HTTP_X_REAL_IP这个头部信息的值,如果这个头部信息的值没有的话,可以拿HTTP_X_FORWARDED_FOR ip列表第一个值就是真实ip,最后搞定了

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  4JlQwvcFgfj9   2023年12月11日   23   0   0 djangoldap
  P3nxyT0LRuwj   2023年11月28日   25   0   0 nginxhtmlWeb
  jnZtF7Co41Wg   2023年12月11日   29   0   0 nginx客户端服务端
  jnZtF7Co41Wg   2023年11月28日   19   0   0 nginx文件名linux命令
  stLBpDewCLT1   2023年12月08日   28   0   0 nginx
  jnZtF7Co41Wg   2023年12月10日   22   0   0 nginx客户端服务端NFS
  eHipUjOuzYYH   2023年12月06日   26   0   0 nginxHTTP
  eHipUjOuzYYH   2023年12月06日   22   0   0 nginx加载IPV6
yx99X8RMvAE0