压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

記一次對GFW防火墻的探究

今日openVPN連不上了,抓包發現剛一握手結束便收到了一個RST包,導致一直連不上。

1

可以看到,三次握手剛完畢,客戶端發送第一個控制消息到服務端,便收到了服務端發送的RST數據包,一直如此。

應該是有中間設備搞的鬼,于是我又到服務器端抓取了些數據:

2

果然的,服務器也收到了RST數據包,于是兩者的連接便斷開了。

再仔細分析下客戶端的RST數據包:

3

IP包的序號是12345,TTL是120。再看正常的數據包:

4

IP包的序號是0,TTL是46。很明顯RST數據包的TTL比正常的要大,而且每次RST的IP序號都是12345,應該是GFW沒錯了。

正常情況下初始的TTL是64,正常收到的TTL是46,跳數是15,說明我的電腦到服務器之間經過了15個路由設備。

為了證明這點,查看服務端收到的正常數據包:

5

服務器收到的TTL是50,因為我的電腦還要經過內部的一個路由器,所以TTL差了1。

同時查看服務端RST數據包的TTL值:

6

TTL值為117,因此得到的信息如下:

客戶端->服務器:15、GWF->服務器:117、GFW->客戶端:120。

假設GFW每次發送的TTL值都固定不變且為x,則有:x-117+x-120=15;得x=126。

所以GFW和我的電腦的跳數應該是6:

7

圖示的應該就是GFW的位置。

接下來問題來了,她是怎么識別出openVPN流量的呢?

我猜測是根據數據包的特征來識別的,那么我單獨發送單個數據包,應該也會返回RST數據,根據這一理論,我用scapy發送了單個的數據包,內容和三次握手之后客戶端發送的第一個數據包一樣,但結果是失望的,并沒有收到RST數據包。

于是進一步猜測,TCP連接之后再發送相應的數據包,應該能收到RST,于是又根據這一理論,寫下了如下代碼:

from?scapy.all?import?*
vpn_payload?=?"\x00\x0e\x38\x24\x5d\x21\xaa\x3a\x11\x2f\xb3\x00\x00\x00\x00\x00"
conf.verb?=?0
vpn_s?=?IP(dst="yovey.me",id=12345)/TCP(sport=58620,dport=1194,flags="S",seq=0)
print?"sending?syn"
vpn_s.show()
ans0,unans0?=?sr(vpn_s)
print?"recv?packet,seq?=?",ans0[0][1].seq
ans0[0][1].show()
vpn_sa?=?IP(dst="yovey.me",id=12346)/TCP(sport=58620,dport=1194,flags="A",seq=1,ack=ans0[0][1].seq+1)
print?"sending?ack"
vpn_sa.show()
ans1,unasn1?=?sr(vpn_sa,timeout=1)
vpn?=?IP(dst="yovey.me",id=12347)/TCP(sport=58620,dport=1194,flags="PA",seq=1,ack=ans0[0][1].seq+1)/vpn_payload
print?"sending?vpn?payload"
ans2,unasn2?=?sr(vpn)
ans2[0][1].show()

運行程序,還是沒有收到RST數據包。

于是我打開tcpdump,抓取了發包過程的數據包,發現了問題:

在服務器返回syn+ack之后,客戶端居然發送了RST到服務器,導致連接斷開。經過短暫的思考,才明白客戶端網卡在收到來自服務器的syn+ack之后,發現并沒有進程在監聽該數據包的端口,于是發送了RST數據包給服務器。

必須讓客戶端不發送RST數據包才行,想到可以通過iptable來過濾數據包,于是在iptable中添加如下規則:

iptables?-t?filter?-A?OUTPUT?-p?tcp?--tcp-flags?RST?RST?-j?DROP

再運行程序,一切都在計劃之中:

8

還是熟悉的IP序號,還是熟悉的TTL,看來GFW已經可以根據連接來識別流量了,真是下了血本啊。

想到建立連接,我立馬聯想到不用建立連接的UDP,是不是UDP數據只需要根據單個數據包就能識別了?于是將服務器配置成UDP模式,再次打開openVPN,特么的居然連上了!于是問題解決了,將配置改成UDP就能正常連接了。

上一篇:如何保護網絡個人隱私

下一篇:保利中環購物中心與銳捷網絡達成戰略合作