為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配置,沒有技術上的問題,管理起來較為麻煩罷了

QQ圖片20140509172657

新的profile里只需要將insert xforwardedfor 打上鈎,改為enable就好了

$XWGMBS91QQW_UVL]5I}FVF

 

二、接下來是使用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里新建一個即可~

50R4HD~D3_XMQ0I[4$8]VNT

填上,直接finish/update~搞定

Virtual Servers里想要引用iRule配置,要選擇轉發類型為http

](%Q]H]2P%)DRZGC5BQYD5J

然后在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這個參數的問題仍未解決

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

全劇終~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM