|
利用iptables TPROXY target,可以在skb進(jìn)入到協(xié)議棧之前,將skb關(guān)聯(lián)到一個(gè)本地監(jiān)聽(tīng)的socket,并且設(shè)置skb的fwmark。可以利用fwmark配置高級(jí)路由功能將非本地流量送到本地lo interface,從而能進(jìn)入本地協(xié)議棧的處理。skb隨后通過(guò)ip_rcv進(jìn)入本地協(xié)議棧處理后,可以直接利用已關(guān)聯(lián)的socket進(jìn)行處理,而不需像普通的處理流程那樣,使用skb中的tcp 4-tuples來(lái)查找listening socket或者established socket。這樣可以把去往任意目的IP和目的端口的skb,關(guān)聯(lián)到本地代理程序監(jiān)聽(tīng)的socket上。本地代理程序通過(guò)accept返回的socket中包含的local address和local port仍然為原始連接的信息。關(guān)聯(lián)到哪個(gè)本地監(jiān)聽(tīng)的socket,可以通過(guò)on-port和on-ip option來(lái)指定,并且本地監(jiān)聽(tīng)的socket需要設(shè)置IP_TRANSPARENT option,否則TPROXY target會(huì)當(dāng)做找不到指定的本地socket,將skb丟棄。 使用TPROXY的三個(gè)步驟:
A:0.0.0.0 B: 127.0.0.1 C: 任意本地接口的IP地址 D: 其它IP地址 選擇使用哪種IP來(lái)監(jiān)聽(tīng),都是可以的,只要TPROXY target配置中的on-ip配置匹配就好了。
FAQ Question1:已匹配iptables規(guī)則,使用TPROXY target的報(bào)文,還會(huì)繼續(xù)匹配后續(xù)規(guī)則么? Answer1:不會(huì)。TPROXY target返回NF_DROP(報(bào)文不能匹配找到本地已設(shè)置IP_TRANSPARENT option的established或者listening socket)或者NF_ACCEPT(報(bào)文可以匹配找到本地已設(shè)置IP_TRANSPARENT option的established或者listening socket)
Question2:TPROXY target對(duì)已建立連接的報(bào)文生效么? Answer2:生效。TPROXY target checks whether there is an established socket for the incoming skb (using the tcp 4-tuples in the skb to search the established sockets), if there is a such socket and the socket has set IP_TRANSPARENT, it sets the fwmark for the skb and associates the skb with the socket and return NF_ACCEPT. If no established socket found, it looks for listening socket using laddr and lport. It checks the configured ip address with --on-ip option, the dev ip, and the destination ip of the skb one by one, and the first non-zero one will be used as the laddr. The port configured with --on-port option will be used as lport, if not configured, the destination port of the skb is used as lport. If a listening socket is matched, and the socket has enabled IP_TRANSPARENT, it sets the mark/mask for the skb and associates the skb with the socket and returns NF_ACCEPT. Otherwise it returns NF_DROP.
Question3:既然TPROXY target對(duì)已經(jīng)建立連接的報(bào)文也生效,那么Linux kernel文檔https://www./doc/Documentation/networking/tproxy.txt中,下面這段配置是必須的么? # iptables -t mangle -N DIVERT # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT # iptables -t mangle -A DIVERT -j MARK --set-mark 1 # iptables -t mangle -A DIVERT -j ACCEPT Answer3:不是必須的,但加些配置性能稍微會(huì)提高些。對(duì)于可以匹配本地Established的報(bào)文,設(shè)置fwmark,配合高級(jí)路由配置確保這些報(bào)文在路由結(jié)束時(shí)可以送到本地的lo接口。這些報(bào)文不會(huì)再經(jīng)過(guò)TPROXY target處理。(MARK target性能會(huì)略高于TPROXY target) 另外這個(gè)配置在調(diào)試過(guò)程中也會(huì)更安全一些,對(duì)于報(bào)文屬于某個(gè)已經(jīng)建立的連接(包括到本地的連接,如ssh)將直接accept,不會(huì)走到TPROXY的規(guī)則。比如通過(guò)ssh登錄到一臺(tái)機(jī)器增加規(guī)則使用TPROXY target,但是配置時(shí)忘記exclude本地流量,這樣包括ssh到這臺(tái)機(jī)器的報(bào)文也將使用TPROXY target,而TPROXY target發(fā)現(xiàn)ssh的報(bào)文能匹配上本地established的socket,但是該socket未設(shè)置IP_TRANSPARENT,則會(huì)返回NF_DROP,導(dǎo)致ssh連接斷開(kāi)。
|
|
|
來(lái)自: just_person > 《待分類(lèi)》