为F5-LTM上的业务添加x-forward-for功能

最近拿到一个旧设备:BIG-IP LTM 6400,玩的人不在,文档又不足;只能自己玩了~

SNAT模式下,走HTTP代理,往http header中的x-forwarded-for加入源IP,以便让后端设备取得源IP

万事不懂先问谷歌

感谢以下:

1、F5官方解答:可以通过两种方式,一是通过http
profile插入;二是通过编写irule插入

http://support.f5.com/kb/en-us/solutions/public/4000/800/sol4816.html


2、一位熟悉F5 irule的大神

http://blog.sina.com.cn/s/blog_444ee46f0100mwzk.html


3、测试中nginx的accesslog抓不到x-forwarded-for

http://blog.itpub.net/27043155/viewspace-734234/

首先要谢谢web开发同事写了一个小页面给我放到服务器上测试,可以打印出服务器端接收到的所有http
header信息

   1:  <%@page import="java.util.Set"%>
   2:  <%@page import="java.util.HashMap"%>
   3:  <%@page import="java.util.Map"%>
   4:  <%@page import="java.util.Enumeration"%>
   5:  <%@page import="java.util.ArrayList"%>
   6:  <%@page import="java.util.List"%>
   7:  <%@page import="java.net.UnknownHostException"%>
   8:  <%@page import="java.net.InetAddress"%>
   9:  <%@ page language="java" contentType="text/html; charset=UTF-8"
  10:      pageEncoding="UTF-8"%>
  11:  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  12:  <html>
  13:  <head>
  14:  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  15:  <title>header参数</title>
  16:  </head>
  17:  <body>
  18:                  <center>
  19:                  <br/>
  20:                  <%
  21:                          Enumeration enumeration =       request.getHeaderNames();
  22:                          Map<String, String> requestHeaders = new HashMap<String, String>();
  23:                          //遍历出获得的请求头信息的名称和值
  24:                          while(enumeration.hasMoreElements()){
  25:                                  String headerName = (String)enumeration.nextElement();
  26:                                  String headerValue = request.getHeader(headerName);
  27:                                  requestHeaders.put(headerName, headerValue);
  28:                          }
  29:                  %>
  30:                          <h2>header参数</h2>
  31:                          <table border="1" width="400px" align="center">
  32:                                  <tr>
  33:                                          <td>
  34:                                                  参数名
  35:                                          </td>
  36:                                          <td>
  37:                                                  参数值
  38:                                          </td>
  39:                                  </tr>
  40:                                  <%
  41:                                                  if (requestHeaders != null && requestHeaders.size() > 0) {
  42:                                                          Set<String> headers = requestHeaders. keySet();
  43:                                                          for(String header : headers) {
  44:                                  %>
  45:                                          <tr>
  46:                                                  <td>
  47:                                                          <%=header%>
  48:                                                  </td>
  49:                                                  <td>
  50:                                                          <%=requestHeaders.get(header)%>
  51:                                                  </td>
  52:                                          </tr>
  53:                                  <%
  54:                                                          }
  55:                                                  }
  56:                                          %>
  57:                          </table>
  58:                  </center>
  59:  </body>
  60:  </html>

LTM6400要想在http header中插入信息,首先必须得是http代理啦,其次也得是SNAT模式(同LVS的NAT)

废话了~

有两种方式可以在http header中插入x-forwarded-for信息

一、Http Profile

二、iRule

两种方式不能共用,在下就吃憋了,没有好好看文档的结果。

一、使用http profile插入x-forwarded-for非常简单

只要在Local Traffic中的Profiles里新建一个即可,新的profile会继承自带的http设置;也可以修改原设置的http

不过不建议修改原有的http配置,没有技术上的问题,管理起来较为麻烦罢了

新的profile里只需要将insert xforwardedfor 打上钩,改为enable就好了

二、接下来是使用iRule配置x-forwarded-for

官方已经给了我们一套简单的模板

   1:  when HTTP_REQUEST {  
   2:  HTTP::header insert X-Forwarded-For [IP::remote_addr] 
   3:  }

但是不知道如果客户端提前在http
header中插入了x-forwarded-for的话,这个动作会不会将原有的x-forwarded-for的值覆盖掉?

后面大神还提供了两个模板

   1:  when HTTP_REQUEST {
   2:        HTTP::header remove X-Forwarded-For
   3:        HTTP::header insert X-Forwarded-For [IP::client_addr]
   4:  }

从大神的指导看,最后这个应该最好,但是运算量有些大,在下线上业务压力不小,所以没有使用

相关xff伪造的文章可以看看这位,非常不错:http://yzs.me/1952.html

   1:  when HTTP_REQUEST {

   2:    if {[HTTP::header exists X-Forwarded-For]}{

   3:        set old_xff   [HTTP::header values X-Forwarded-For]

   4:       HTTP::header remove X-Forwarded-For

   5:        HTTP::header insert X-Forwarded-For_Org  "[IP::client_addr], $old_xff"

   6:    } else { 

   7:        HTTP::header insert X-Forwarded-For [IP::client_addr]

   8:    }

   9:  }

在Local Traffic – iRules里新建一个即可~

填上,直接finish/update~搞定

Virtual Servers里想要引用iRule配置,要选择转发类型为http

然后在resource里添加已经新建的irules到左边框框,搞定

无论是使用http profile,还是自己编写irule;最终的效果都是一致的,采取哪种方法并不重要,最好还是根据实际情况和使用习惯决定~

Nginx放到F5后面,日志记录有问题,先描述一下网络情况

代理IP:192.168.1.1

nginx IP:192.168.2.1

client IP:192.168.3.1

LTM 6400后有一台nginx的日志中,只能获取到LTM的IP地址,无法获得X-Forwarded-For过来的IP

nginx.conf中的log配置为

   1:  log_format  ‘$remote_addr - $remote_user [$time_local] "$request" ‘
   2:           ‘$status $body_bytes_sent "$http_referer" ‘
   3:           ‘"$http_user_agent" $http_x_forwarded_for‘;

打印出来的日志为

   1:  192.168.1.1 - - [09/May/2014:15:04:52 +0800] "GET / HTTP/1.1" 200 798 "-" "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"

其中$http_x_forward_for理论上应该获得的是X-Forwarded-For的值

那我们来查看http header信息

x-forwarded-for:192.168.3.1

x-real-ip:192.168.1.1

这里看完全是无异常的,另一台也是硬件负载均衡到此台nginx的请求日志中$http_x_forward_for显示为x-forwarded-for的IP地址

但是两台代理的http header中并无差异之处

万事谷歌

找到nginx有一个real ip module,随即做了以下测试

nginx重新编译,configure参数加上选项:--with-http_realip_module

在原nginx.conf配置中添加:

   1:  server
   2:  {
   3:      ...
   4:      set_real_ip_from 192.168.0.0/16;    #许可此网段过来的访问可以修改real_ip;这里放的比较宽,测试用不要在意细节
   5:      real_ip_header X-Forwarded-For;     #将$x-forward-for的值替换掉real_ip
   6:      ...
   7:      #我的日志格式如下
   8:      log_format  ‘$remote_addr - $remote_user [$time_local] "$request" ‘
   9:               ‘$status $body_bytes_sent "$http_referer" ‘
  10:               ‘"$http_user_agent" $http_x_forwarded_for‘;
  11:      ...
  12:  }

通过这样的配置,日志的内容变成了

   1:  192.168.3.1 - - [09/May/2014:15:05:35 +0800] "GET / HTTP/1.1" 200 800 "-" "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"

可以看得到$remote_addr参数已经变成了x-forwarded-for的值

同时查看web页面打印出来的http header,其中

x-forwarded-for:192.168.3.1

x-real-ip:192.168.3.1

感觉靠谱吗

不好说,虽然功能上,nginx的access
log里面已经实现了抓取客户端IP的需求,但是$http_x_forwarded_for这个参数的问题仍未解决

目前求助各大神群未果,谷歌无结果,只能等着看看哪一天可以解决了

全剧终~

时间: 2024-08-08 18:56:25

为F5-LTM上的业务添加x-forward-for功能的相关文章

js在table指定tr行上或底下添加tr行

js在table指定tr行上或下面添加tr行 function onAddTR(trIndex)         {             var tb = document.getElementById("tb1");             var newTr = tb.insertRow(trIndex);//添加新行,trIndex就是要添加的位置             var newTd1 = newTr.insertCell();             newTd1.

上传APP添加视频预览--精简点名

上传APP添加视频预览--精简点名 在为精简点名APP制作视频预览时的坑: 1.视频预览不能太长,也不能太短15-30s就好:我录制的是18s 2.视频的帧数不能太大,也就是说你在录制视频的时候,要慢点录制: 3.上传时可能会说文件的无法载入,请再次上传,这个多数是你网络不好造成的,找个网络好的时候,重新上传: 4.视频的尺寸是有限制的,需要不同设备的尺寸:这里有个技巧,想要不同的尺寸,那么使用不同的设备进行录制 5.采用什么样的软件,其实使用QuickTime+iphone就可以搞定,也不需要

ajaxFileUpload+struts2实现多文件上传(动态添加文件上传框)

上篇文章http://blog.csdn.net/itmyhome1990/article/details/36396291介绍了ajaxfileupload实现多文件上传, 但只是固定的文件个数,如果需求不确定是多少文件 则我们就需要动态的添加文件上传框,以实现灵活性. 基于上篇基本框架是不变的,主要修改以下几个方面 1.jQuery实现动态添加删除文件上传框 2.获取文件上传框的ID 3.ajaxfileupload.js里将ID数组转换为需要的Object数组 依次解决上面问题 一.实现动

phpcms 移植【添加相关文章】功能

添加相关文章功能相当有用,移植一个过来基本上可以实现比较复杂的页面内包含分类功能,做二次开发时可以省下不少力气. 用例:如果一个产品,属于一个厂家,而这个厂家是动态添加的,既不是一个分类,而是一个厂家的模型,这二者关联的时候使用这个添加相关的功能可以轻易实现. 学会使用phpcms中的类别管理和推荐位管理基本上可以满足文章管理的多数场景,如果能够理解mysql表的设计,可以使用模型管理这个大杀器, 基本上能够想到的功能都能实现,最后再对[添加相关文章]功能进行设计和移植,模型功能能够再次爆发威力

3D打印机如何添加自动调平功能

原理说明 Kossel/Rostock等Delta(并联/三角洲)类型的机器,可以参考:http://learn.makerlab.me/guides/11 3d打印打印时最重要的是第一层的效果,如果第一层能够很好的粘在打印平台上,后面的如果不出意外,都可以顺利完成.但是第一层的打印并没有那么容易,其中一个原因就是打印平台是否水平的问题.如果平台不水平,可能导致模型的第一层在一个位置非常牢固,在另一个位置却根本没有粘上.甚至会损坏打印头(平台不平,由低的位置运动到高的位置可能会撞坏打印头). 本

电商网站中添加商品到购物车功能模块2017.12.8

前言: 电商网站中添加商品到购物车功能模块实现: 根据前一篇博客的介绍,我们看到淘宝网站为了保证购物车数据的同步,直接是强制用户必须登录才可以将商品加入购物车.而京东网站是用户在未登录的状态下也可以将商品加入到购物车,此时这个是保存在了cookie中,然后用户登录后,根据商品的id判断商品是否存在,将两个购物车的商品合并,形成最终的购物车商品. 本篇文章分两个模块,分别看下这两个功能是如何实现的: 1.必须在用户登录的前提下,才可以将商品加入到购物车列表 我们今天先看下淘宝网站的状态下的添加商品

史上最简单的带流控功能的http server

s.py import time import SimpleHTTPServer import SocketServer BYTES_PER_SECOND=160*1024 class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): def do_GET(self): """Serve a GET request.""" f = self.send_head() i

PullToRefreshRecyclerView——带上拉刷新下拉加载功能的RecyclerView

PullToRefreshRecyclerView——带上拉刷新下拉加载功能的RecyclerView

Android高级控件(一)——ListView绑定CheckBox实现全选,添加和删除等功能

Android高级控件(一)--ListView绑定CheckBox实现全选,添加和删除等功能 这个控件还是挺复杂的.也是项目中应该算是比較经常使用的了,所以写了一个小Demo来讲讲,主要是自己定义adapter的使用方法.加了非常多的推断等等等等-.我们先来看看实现的效果吧! 好的,我们新建一个项目LvCheckBox 我们事先先把这两个布局写好吧,一个是主布局,另一个listview的item.xml.相信不用多说 activity_main.xml <LinearLayout xmlns: