waf 引擎 雲原生平台tproxy 實現調研


了解了基本 雲原生架構,不清楚的查看之前的文章:https://www.cnblogs.com/codestack/p/13914134.html

現在來看看雲原生平台tproxy waf引擎串聯實現:也就是 報文劫持轉發到對應的接口------本地socket捕獲數據包

tproxy方式

iptables -t mangle -N DIVERT #在nat表上新建名為DIVERT自定義鏈
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT #已建立的socket且被tproxy標記過的數據包執行DIVERT
iptables -t mangle -A DIVERT -j MARK --set-xmark 0x10000000/0xf0000000 #進入DIVERT設置標記
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -N MY_TCP
iptables -t mangle -p tcp -A MY_TCP -j TPROXY --on-port 8081 --tproxy-mark 0x10000000/0xf0000000
#MY_TCP執行TPROXY轉發為8081端口並進行標記
iptables -t mangle -A MY_TCP -j ACCEPT
iptables -t mangle -N MYMANGLE
iptables -t mangle -A PREROUTING -p tcp -j MYMANGLE #MYMANGLE鏈加入到PREROUTING
iptables -t mangle -A MYMANGLE -p tcp -m multiport --dports 80 -j MY_TCP #80端口的包執行MY_TCP
ip rule add fwmark 0x10000000/0xf0000000 table 200 pref 200 #對標記過的數據包執行序號為200的規則
ip route add local default dev lo table 200 #200規則:數據包發送到本地回環

 

那么問題來了,應用程序怎么編寫?假如需要連接1.1.1.1:80這個端口,就算數據包到了本地,但是本地並沒有1.1.1.1這個IP地址啊,程序是怎么能拿到數據的?不是應該直接丟棄這個數據包么?

  Linux提供了一個選項IP_TRANSPARENT,可以讓程序bind一個不屬於本機的地址,作為客戶端,它可以使用一個不屬於本機地址的IP地址作為源IP發起連接,作為服務端,它可以偵聽在一個不屬於本機的IP地址上,而這正是透明代理所必須的
setsockopt(fd,SOL_IP, TRANSPARENT,&opt,sizeof(opt));
setsockopt之后,作為代理服務器bind真實服務器addr,作為代理客戶端bind真實客戶端addr。

而由於TPROXY模式並沒有改變數據包,所以直接通過getsockname獲取到原始的IP端口信息:

 //Socket is bound to original destination
    if(getsockname(sockfd, (struct sockaddr*) orig_dst, &addrlen)
            < 0){
        perror("getsockname: ");
        return -1;
    } else {
        if(orig_dst->ss_family == AF_INET){
            inet_ntop(AF_INET,
                    &(((struct sockaddr_in*) orig_dst)->sin_addr),
                    orig_dst_str, INET_ADDRSTRLEN);
            fprintf(stderr, "Original destination %s\n", orig_dst_str);
        } else if(orig_dst->ss_family == AF_INET6){
            inet_ntop(AF_INET6,
                    &(((struct sockaddr_in6*) orig_dst)->sin6_addr),
                    orig_dst_str, INET6_ADDRSTRLEN);
            fprintf(stderr, "Original destination %s\n", orig_dst_str);
        }

參考:

https://www.kernel.org/doc/Documentation/networking/tproxy.txt


免責聲明!

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



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