nginx中配置使用proxy protocol协议的全过程

目录
  • 简介
  • proxy protocol在nginx中应用
  • 在nginx中配置使用proxy protocol
    • 在nginx中启用proxy protocol
    • 使用Real‑IP modules
    • 请求转发
    • 日志记录
  • 总结

简介

我们已经介绍了haproxy提出的proxy protocol协议,通过proxy protocol协议,服务器端可以获得客户端的真实IP地址和端口,从而可以进行一些非常有意义的操作。

为什么获得客户端的真实IP地址会非常有意义呢?

考虑一个藏在proxy背后的数据库,如果有多个客户端通过proxy进行数据库的连接,事实上因为都是通过代理进行连接,所以数据库中的所有的操作都是proxy服务器的IP地址,这在对数据库的性能监控和优化是不利的,因为我们不知道真实异常的服务器IP地址。

这种情况下就需要用到proxy protocol协议,让数据库可以反映出真实客户端的IP地址,从而便于数据库的监控和问题定位。

事实上,数据库只是一个特定的例子,我们在很多其他的情况下也可能需要知道客户端真实IP的情况。

以现在最流行的http服务器和代理服务器nginx为例,我们来看一下如何在nginx中配置proxy protocol。

proxy protocol在nginx中应用

我们知道nginx是一个web服务器和代理服务器,它一般工作在proxy server或者负载均衡软件(Haproxy,Amazon Elastic Load Balancer (ELB)的后面。

客户端首先请求proxy server或者LSB负载均衡软件,然后再到nginx进行真实的web访问。

因为经过了多层软件,所以客户端的一些信息比如ip地址,端口号等可能就会被隐藏,这对于我们问题分析,数据统计都是不利的。因为对于nginx来说,我们希望能够获得真实的客户端IP地址,这样才能获取真实的请求环境。

这种情况下就需要用到PROXY protocol了。

如果前面所说的proxy或者LSB都实现了PROXY protocol协议的话,不管是HTTP, SSL, HTTP/2, SPDY, WebSocket 还是 TCP协议,nginx都可以拿到客户端的原始IP地址,从而根据原始IP地址进行一些特殊的操作,比如屏蔽恶意IP的访问,根据IP不同展示不同的语言或者页面,或者更加简单的日志记录和统计等,都非常有效。

当然,如果想要支持PROXY protocol,对nginx的版本也是有要求的,具体版本需求如下:

  • 想要支持PROXY protocol v2,需要NGINX Plus R16或者NGINX Open Source 1.13.11。
  • 想要支持ROXY protocol for HTTP,需要NGINX Plus R3或者NGINX Open Source 1.5.12。
  • 想要支持TCP client‑side PROXY protocol,需要NGINX Plus R7或者 NGINX Open Source 1.9.3。
  • 想要支持PROXY protocol for TCP,需要NGINX Plus R11 或者 NGINX Open Source 1.11.4。

在nginx中可以通过下面的变量来获得对应的客户端信息,具体而言如下所示:

$proxy_protocol_addr和$proxy_protocol_port 分别表示的是原始客户端的IP地址和端口号。

$remote_addr 和 $remote_port表示的是load balancer的的IP地址和端口。

如果你使用了RealIP扩展模块,那么这个模块会重写$remote_addr 和 $remote_port这两个值,将其替换成原始客户端的IP地址和端口号。

然后使用$realip_remote_addr 和 $realip_remote_port来表示load balancer的的IP地址和端口。

在RealIP扩展模块中,$proxy_protocol_addr和$proxy_protocol_port 表示的含义不变,还是原始客户端的IP地址和端口号。

在nginx中配置使用proxy protocol

上面我们提到了nginx中proxy protocol的基本应用,下面来讲一下如何在nginx中进行具体的配置。

在nginx中启用proxy protocol

如果你的nginx已经是支持proxy protocol的版本,那么启用proxy protocol非常简单,只需要在server中的listen中添加proxy_protocol即可,如下所示:

http {
    #...
    server {
        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;
        #...
    }
}

stream {
    #...
    server {
        listen 112233 proxy_protocol;
        #...
    }
}

可能大家比较熟悉的是http block,这表示的是nginx对http/https的支持。stream模块可能大家比较陌生,这是nginx提供的对tcp/udp协议的支持。

通过上面的配置,nginx可以实现在tcp/udp协议和http/https协议同时支持proxy protocol。

使用Real‑IP modules

Real‑IP modules是nginx自带的一个模块,可以通过下面的命令来查看nginx是否有安装real-ip模块:

nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'

如果你当前使用的版本没有real ip,也不要急,这时候你可能需要从源代码进行编译。

在编译的过程中,我们需要执行一个configure命令,在这个configure命令中可以指定要开启的功能,比如stream或者http_ssl_module:

$ ./configure
--sbin-path=/usr/local/nginx/nginx
--conf-path=/usr/local/nginx/nginx.conf
--pid-path=/usr/local/nginx/nginx.pid
--with-pcre=../pcre-8.44
--with-zlib=../zlib-1.2.11
--with-http_ssl_module
--with-stream
--with-mail

如果要开启real-ip功能,则可以添加:

--with-http_realip_module

如果nginx是运行在SLB或者proxy之后的,那么可以通过set_real_ip_from命令来指定代理或者负载均衡服务器的IP范围,如下所示:

server {
    #...
    set_real_ip_from 192.168.1.0/24;
   #...
}

然后我们需要将proxy或者SLB的IP地址替换成为真实客户端的地址,那么可以这样使用:

http {
    server {
        #...
        real_ip_header proxy_protocol;
      }
}

请求转发

不管是http还是stream block,都可能遇到请求向后续的upstream进行转发的情况,对于upstream来说,他们希望收到的是真实客户端IP地址,而不是proxy或者slb的地址,那么可以通过下面的设置来解决:

http {
    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
stream {
    server {
        listen 12345;
        proxy_pass example.com:12345;
        proxy_protocol on;
    }
}

http和stream的设置方式是不同的。

日志记录

日志是一个非常重要的功能,对于定位问题,执行数据统计分析都非常有用,当然我们需要的是真实的客户端IP地址。

我们可以通过使用变量$proxy_protocol_addr在http和stream block中记录对应的日志,如下所示:

http {
    #...
    log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
}
stream {
    #...
    log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
                      '$protocol $status $bytes_sent $bytes_received '
                      '$session_time';
}

总结

通过上面的设置,nginx已经可以使用proxoy protocol了,这会让我们的后续分析工作变得更加轻松。

到此这篇关于nginx中配置使用proxy protocol协议的文章就介绍到这了,更多相关nginx使用proxy protocol协议内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在Nginx中增加对OAuth协议的支持的教程

    我们使用Nginx的Lua中间件建立了OAuth2认证和授权层.如果你也有此打算,阅读下面的文档,实现自动化并获得收益. SeatGeek在过去几年中取得了发展,我们已经积累了不少针对各种任务的不同管理接口.我们通常为新的展示需求创建新模块,比如我们自己的博客.图表等.我们还定期开发内部工具来处理诸如部署.可视化操作及事件处理等事务.在处理这些事务中,我们使用了几个不同的接口来认证: Github/Google Oauth 我们SeatGeek内部的用户系统 基本认证 硬编码登录 显然,实际应用

  • 全面了解Nginx中的HTTP协议相关模块配置

    要理解 HTTP 模块配置解析的过程,首先需要对 nginx 的配置文件结构做一个了解 nginx 的配置文件是用树状结构组织的,每个 NGX_CORE_MODULE 作为根统领着其下的所有配置项 而如下图所示,HTTP 模块的配置被分成了 main.server.location 三层 整个 nginx 配置解析的过程其实就是这棵树的深度遍历过程 而遍历 HTTP 子树的函数就是下面要介绍的 ngx_http_block 配置文件解析 -- http 配置块 当我们需要使用 http 模块的时

  • nginx中配置使用proxy protocol协议的全过程

    目录 简介 proxy protocol在nginx中应用 在nginx中配置使用proxy protocol 在nginx中启用proxy protocol 使用Real‑IP modules 请求转发 日志记录 总结 简介 我们已经介绍了haproxy提出的proxy protocol协议,通过proxy protocol协议,服务器端可以获得客户端的真实IP地址和端口,从而可以进行一些非常有意义的操作. 为什么获得客户端的真实IP地址会非常有意义呢? 考虑一个藏在proxy背后的数据库,如

  • Nginx中配置用户服务器访问认证的方法示例

    Nginx超级强大它可以单独为一个域名设置用户认证,方法也很简单我们只要生成用户认证的用户名和密码,然后再Nginx添加auth认证配置即可. Nginx可以为某一个域名单独加用户认证,具体做法如下: 1. 生成用户认证的用户名和密码: #wget -c soft.vpser.net/lnmp/ext/htpasswd.sh;bash htpasswd.sh 根据提示输入: 用户名: 密码: 文件名: 脚本会自动生成认证文件,auth.conf内容如下: /usr/local/nginx/con

  • Nginx中配置开启Nginx Status来查看服务器运行状态

    nginx和php-fpm一样内建了一个状态页,对于想了解nginx的状态以及监控nginx非常有帮助.为了后续的zabbix监控,我们需要先了解nginx状态页是怎么回事. 1. 启用nginx status配置 在默认主机里面加上location或者你希望能访问到的主机里面. server { listen *:80 default_server; server_name _; location /ngx_status { stub_status on; access_log off; #a

  • 在nginx中配置pathinfo模式支持thinkphp的URL重写

    最近一个项目中使用了ThinkPHP做为开发框架,URL上我们使用了PATHINFO模式,但是Nginx默认是不支持PATHINFO的,需要进行手动配置才可以,于是我们按照了以下方法进行了Nginx的PATHINFO支持配置:修改nginx.conf,找到server中的 location ~ .php${},修改为location ~ .php {},并在其中增加以下内容: 复制代码 代码如下: set $path_info "";set $real_script_name $fas

  • 在Nginx中配置image filter模块来实现动态生成缩略图

    先来看一下什么是nginx的image filter模块. HttpImageFilterModule用来裁剪过大的图片到指定大小,是nginx自带模块,默认不会开启 开启HttpImageFilterModule需要在编译要带上参数 --with-http_image_filter_module 该模块主要有两个指令: 语法: image_filter (test | size | resize width height | crop width height) 默认是: 无 可出现的上下文:

  • 如何在nginx中配置缓存静态文件

    这篇教程说明你应该怎样配置 nginx.设置 HTTP 头部过期时间,用 Cache-Control 中的 max-age 标记为静态文件(比如图片. CSS 和 Javascript 文件)设置一个时间,这样用户的浏览器就会缓存这些文件.这样能节省带宽,并且在访问你的网站时会显得更快些(如果用户第二次访问你的网站,将会使用浏览器缓存中的静态文件). 1.准备事项 我想你需要一个正常工作的 nginx 软件,就像这篇教程里展示的:在Ubuntu 16.04 LTS 上安装 Nginx,PHP 7

  • nginx中配置pathinfo模式示例

    缘由 很久不使用apache了,渐渐对apache感到陌生,因为朋友有个ZendFramework框架从apache移到nginx下,需要pathinfo模式支持. 网上海搜 于是开始搜索nginx+pathinfo相关文章,一开以为很容易就会配置好.因为搜索后发现有大量文章介绍nginx开启pathinfo模式,感觉不是什么难事.但是经过几个小时下来,还是没有配置好.并且大量文章的内容都极其相似,基本都是转载的. 开始有点急了!因为一天过去了没有配好. 继续摸索 没办法,继续搜索.为了验证方便

  • Nginx中配置过滤爬虫的User-Agent的简单方法

    过去写博客的时候经常出现服务器宕机,网页全部刷不出来,但是Ping服务器的时候又能Ping通.登录SSH看了下top,惊呆了,平均负载13 12 8.瞬间觉得我这是被人DDOS了么?看了下进程基本上都是php-fpm把CPU给占了,去看下日志吧... 一看不得了,基本上都是被一个User Agent叫"YisouSpider"的东西给刷屏了,一看就不知道是哪的蜘蛛,太没节操了. 找到根目录配置区,增加User Agent过滤判断语句,发现叫"YisouSpider"

  • 记一次nginx中proxy_pass的使用问题

    最近排查一个web服务的问题,webserver使用的nginx,最终发现是踩了nginx中proxy_pass的一个坑,这里记录下来. 踩坑经过 一个线上的http服务,示例nginx关键配置如下: server { listen 80; server_name ligang.gdemo.com; server_tokens off; keepalive_timeout 5; charset utf-8; include /home/ligang/devspace/gobox-demo/con

  • nginx中proxy_pass各种用法详解

    目录 代理转发规则 第一种: 第二种: 第三种: 第四种: 第五种: 代理转发规则 nginx中配置location代理转发规则的时候不同写法对应不同转发规则. 如果proxy_pass使用了URI,当传送请求到后端服务器时,规范化以后的请求路径与配置中的路径的匹配部分将被替换为指令中定义的URI(对应下文第一种情况). 如果proxy_pass没有使用URI,传送到后端服务器的请求URI一般客户端发起的原始URI(下文第二种情况). 访问地址:http://localhost/proxy/ab

随机推荐