用c#編寫socksProxy 伺服器,大白話細述協議的最重要部分。

來源:互聯網
上載者:User

由於我是個粗人,是個菜鳥,只會講大白話,只想知道咱老百姓想聽的內容。

 

不知道為什麼那些網文作者都說socks代理比http代理複雜,http代理和socks代理我都做了,明顯感覺http代理比socks代理要複雜很多,因為http代理要自己解析http協議,這是我的http代理http://blog.csdn.net/laotse/archive/2010/09/24/5903651.aspx

而socks代理除了開頭那一點點外,其他就是什麼不管就轉寄轉寄就行了。

我做的那個http代理可謂很失敗,用著用著就cpu100%佔用了,應該就是解析http協議頭做的不好,出現死迴圈了或者別的,那麼多http頭實在不想再分析了,ccproxy我也sniffer了,結果是看到它也出現了許多錯誤的解析,ccproxy都多少年了,都解析不好,說明解析http協議確實不容易啊。

所以我很懷疑那些網文作者到底做沒做過http代理就信口開河說http代理比socks代理簡單。

 

socks代理裡面,有socks4 socks4a socks5,也有叫sock4 sock4a sock5的,都是一回事。

socks4 socks4a和socks5的tcp部分極其簡單。

這又出現一個怪現象了,網文中除了一個人說道udp比tcp複雜,其他的全都說udp簡單,只說tcp部分,把udp都一筆帶過了。

而我就明顯感到udp比tcp複雜很多。

 

socks的rfc是rfc1928和rfc1929,別看了,打個比方,某人看到一本書,當他看了目錄,準備往後翻看內容時,發現已經到底了,原來這不是“目錄”它就是內容,這就是rfc1928,話說rfc是幹什麼的啊,寫成這樣就算交活了啊,還有王法嗎,還有法律嗎。中文翻譯的就像是機器翻譯一樣,不是人類語言。所以造成網文上全都是連蒙加猜,沒有一個對的,這兩天我連續翻看那些網文,又用現成的帶socks的程式然後sniffer,算是知道了個大概,其公用程式編寫出來很簡單,關鍵就是rfc的協議說的不明不白的,所以造成本來很簡單的事情,弄得大家全都一知半解。

 

 

socks4和socks4a只代理tcp。

socks4

比如ie可以直接用socks代理,但是ie只能用sock4代理,即使我現在用最新的ie9仍然如此。比如ie要用sock4訪問百度,那麼ie就先用本地的dns把百度轉成ip比如202.108.22.5,然後向sock4伺服器發送

04 01 00 50 CA 6C 16 05  41 64 6D 69 6E 69 73 74 72 61 74 6F 72 00

1、其中開頭04 01是固定的

2、00 50是ie要串連網站的連接埠號碼,這裡是80連接埠,十六進位就是00 50

3、CA 6C 16 05就是202.108.22.5的十六進位

4、41 64 6D 69 6E 69 73 74 72 61 74 6F 72是Administrator的acsii碼

5、最後一個00也是固定的

這就是socks4的固定格式04 01+連接埠2位元組+ip4位元組+id+00,其中的id,這裡是Administrator是可有也可以沒有,因為我現在win7用的賬戶是Administrator所以ie就把帳號名給發過去了,我試了一下最新的Firefox4.0,他發送MOZ,有的就直接省略掉了

04 01 00 50 CA 6C 16 05 00 所以發成這樣也行,隨便寫什麼都行,只要最後一個是0中間沒有0就行了。

如果Proxy 伺服器允許代理,比如驗證一下那個id,比如你想只允許id是administrator後,允許代理了,就發回8個位元組

04 5A 00 50 CA 6C 16 05

看到了嗎,區別就是第二個位元組是5A而且最後沒有00,那麼就是允許代理。其實根據協議5A這裡可以換其他的反饋位元組,但是我們就不要管了,如果你做的代理程式不允許他用,那麼直接就在程式中中斷連線就行了。

如果允許串連了,然後就把用戶端的所有資料原封不動的發到遠程主機,把收到遠程主機的內容原封不動發回用戶端就行了,以下我就簡稱交換交換就行了。

 

socks4a

細心的人會發現一個問題,在sock4中,用戶端比如ie要用sock4代理訪問百度,ie會在本地dns解析出百度的ip202.108.22.5,而不是通過sock4代理的那個機器的dns解析的,這樣就會出現一個問題,比如你的那個機器是個受限制的網路dns不給你解析網域名稱,只讓你以ip方式訪問網路,那麼怎麼辦呢?就沒辦法了對吧,你知道百度的ip沒用啊,網路上都以網域名稱形式存在的,其他的你都能知道嗎對吧。那麼ie為什麼要在本地dns解析而不再sock4代理機器上解析呢?因為sock4協議就這樣的,否則就不叫sock4協議了。

所以sock4a協議就是為了彌補這個問題的,可以讓客戶把網域名稱發到sock4a代理機器上,用這個代理機器上的dns解析出ip,這樣就克服了用戶端不方便解析網域名稱的情況,而且有的網站比如google在本地解析和在Proxy 伺服器解析網域名稱得到的ip是不一樣的,在Proxy 伺服器解析網域名稱得到的ip更好,一般連線速度更快也更像就是從Proxy 伺服器發起的。

socks4a是這樣的,截取我用flashfxp通過socks4a代理登入sourceforge的sftp

04 01 00 16 00 00 00 01  6C 61 6F 74 73 65 00 65 62 2E 73 6F 75 72 63  65 66 6F 72 67 65 2E 6E  65 74 00

1、04 01是固定的

2、00 16是連接埠22的十六進位

3、00 00 00 01是原本ip地址的地方,這裡前3個位元組必須為0,最後一個必須不能為0,一般都是1

4、6C 61 6F 74 73 65是laotse的ascii,我設的flashfxp代理的命名,可以沒有,和sock4一樣

5、00 固定的,和sock4一樣,如果第四步的id沒有,這個00也不能省略

6、65 62 2E 73 6F 75 72 63 65 66 6F 72 67 65 2E 6E 65 74 就是網域名稱web.sourceforge.net的ascii了

7、00 固定的。

這樣就可以看出,就是把sock4的ip那地方換成00 00 00 xx這樣的假ip,然後再sock4後面多了網域名稱+00

這樣socks4a代理首先把web.sourceforge.net解析成216.34.181.70(D8 22 B5 46),並且和216.34.181.70串連上,再向用戶端發送

04 5A 00 16 D8 22 B5 46

和sock4一樣的,依然是04 5A+連接埠+IP共8位元組。

然後就和sock4一樣就是轉寄轉寄了,如果不允許代理直接斷開就行了也不用發送什麼反饋了。

所以明顯socks4a比socks4要好,這樣避免了本地對網域名稱解析帶來的問題,話說如果你要上些不和諧的站呢,總是用本地dns解析那些網域名稱……是吧。所以能用socks4a就不要用socks4,但是杯具的是ie只能用sock4,ie9也如此,Firefox也是。

 

看到了吧socks4和socks4a就是這麼簡單,簡單的不能再簡單了。

 

 

socks5

socks5代理和socks4 socks4a比,多了一個驗證功能和udp代理的功能。

socks5的tcp代理幾乎和socks4 socks4a一樣簡單,但是udp卻比較複雜一點,但是再複雜也沒有http代理那麼複雜。

首先說驗證,不管是要代理tcp還是udp,開始驗證都是要一個tcp串連的,而且驗證過程一樣,驗證完了才分tcp和udp的實際代理過程,有好幾種驗證,別管了,其他的都用不到太小眾化了,那些協議是什麼都沒聽說過,也沒處實驗去,信我的,就記住3種就行

如果一個客戶想通過socks5代理,那麼開始他會發送以下3種內容

05 01 00 共3位元組,這種是要求匿名代理

05 01 02 共3位元組,這種是要求以使用者名稱密碼方式驗證代理

05 02 00 02 共4位元組,這種是要求以匿名或者使用者名稱密碼方式代理

 

如果socks5代理允許匿名那麼就返回05 00兩個位元組,如果要求驗證就返回05 02兩個位元組。

這裡匿名等一下,先說要求密碼驗證的,因為要求驗證就比匿名多了一步而已,後頭是一樣的,所以先說密碼驗證。

當上面socks5返回05 02兩個位元組後

用戶端發送01 06 6C 61 6F  74 73 65 06 36 36 36 38 38 38

1、01固定的

2、06這一個位元組這是指明使用者名稱長度,說明後面緊跟的6個位元組就是使用者名稱

3、6C 61 6F 74 73 65這就是那6個是使用者名稱,是laotse的ascii

4、又一個06共1個位元組指明密碼長度,說明後面緊跟的6個位元組就是密碼

5、36 36 36 38 38 38就是這6個是密碼,666888的ascii。

6、假如這後面還有位元組,一律無視。

這時socks5代理就驗證了使用者名稱laotse密碼666888對不對啊,如果不對直接關閉串連就可不用反饋了。

如果這個使用者名稱和密碼通過了,可以進行代理,那麼就發送01 00給用戶端。那麼下面就和匿名是一樣的了,匿名就是省略了這一步而已。

這時無論匿名或者通過了密碼驗證的用戶端向socks5發送下列三種方式

先說tcp的

第一種

05 01 00 03 13 77  65 62 2E 73 6F 75 72 63  65 66 6F 72 67 65 2E 6E  65 74 00 16

1、05固定

2、01說明是tcp

3、00固定

4、03說明後面跟著的是網域名稱而不是ip地址,由socks5伺服器進行dns解析

5、13前面指明了是網域名稱,那麼0x13(19位元組)是網域名稱字元長度

6、77 65 62 2E 73 6F 75 72 63 65 66 6F 72 67 65 2E 6E 65 74 就這19個是網域名稱web.sourceforge.net的ascii。

7、00 16連接埠,即為22連接埠。

第二種

05 01 00 01 CA 6C 16 05 00 50

1、05固定

2、01說明tcp

3、00固定

4、01說明是ip地址

5、CA 6C 16 05就是202.108.22.5了,百度ip

6、00 50連接埠,即為80連接埠

看到了嗎,tcp的可以本地解析出ip來,只讓socks5代理去連,也可以發過網域名稱去讓socks5去用它的dns去解析ip再串連

 

這時Proxy 伺服器收到了上面的請求後,如果是網域名稱的,先解析出ip來串連,如果直接是ip的就用一個tcp串連去串連那個ip和連接埠,如果和遠程主機串連成功了,就向客戶發送什麼呢

05 00 00 01 C0 A8  00 08 16 CE共10個位元組

無論上面兩種哪一種都是這樣

1、05 00 00 01固定的

2、後面8個位元組可以全是00,也可以發送socks5伺服器串連遠程主機用到的ip地址和連接埠,比如這裡C0 A8 00 08,就是192.168.0.8,這是我socks5伺服器的ip地址,16 CE即5838連接埠,即是socks5伺服器用5838連接埠去串連百度的80連接埠。也可以05 00 00 01 00 00 00 00 00 00,只告知客戶串連成功不告訴他細節,但是0不要省略。

 

後面就是在客戶和遠程主機之間轉寄轉寄啊的,是不是很容易啊,比http代理簡單太多了。

 

然後說udp的,udp的要複雜不少。首先要說下原理,udp和tcp不一樣,不是一個串連中一口氣下來的,上面說了不管tcp還是udp上面的那個tcp協商部分都是一樣的,而且如果是udp的話會佔用socks5代理一個tcp串連一個udp。

第三種udp的

用戶端如qq發送(仍在剛才的tcp中發送)

05 03 00 01 00  00 00 00 E5 F0

1、05固定

2、03說明是要代理udp

3、00固定

4、01固定,只能制定後面跟著的是ip地址

5、00 00 00 00這裡可以由用戶端如qq發送客戶的ip,也可全是0,因為這個ip地址沒用。

6、E5 F0最重要的一條,用戶端比如qq,向socks5代理說明它預備開放的udp連接埠,這裡是58864。

那麼socks5怎麼回答呢?如果不同意代理直接關閉串連就可以了不用反饋了。如果同意的話,socks5要這麼做,首先準備一個ip和一個udp連接埠,比如我用192.168.0.8這個ip上開放58865udp連接埠給客戶轉寄用。然後返回

05 00 00 01 C0 A8  00 08 E5 F1

1、05 00 00 01固定

2、C0 A8 00 08預備開放udp連接埠開放給客戶的ip,這裡是192.168.0.8,如果多ip機器,那麼返回下面開放udp連接埠綁定的那個ip。

3、E5 F1返回給客戶說明預備開放哪個連接埠,這裡是58865。

 

好了tcp協商部分完成了,注意這個tcp串連一定不要關閉,要一直開著,雖然再也不會發送和接受資料了,但是要一直開著,如果這個串連一關,那麼客戶就認為串連被斷開了,因為這就是socks5協議,所以說socsk5轉寄udp不但要佔用一個udp還要佔用一個tcp串連。麻煩吧。

 

上面那個tcp不要關,下面就是客戶和socks5的2個udp連接埠之間進行資料交換了,這裡udp麻煩的一方面又體現出來了,它就是不需連線的,它不像tcp那樣因為tcp協議部分就保證了資料的可靠性,這麼說吧比如tcp串連qq發送abcdef,這些資料太大了一次發送不完,那麼就會分區,那麼socks5可能會收到ab第二次c第三次def這樣的,雖然不知道能一次收多少,但是只要連起來還是abcdef的順序,而且不會出現資料丟失而發送方不知道的情況。udp就不一樣,可能第一次就接到了def,第二次才接到a,bc可能直接就丟了還不知道,所以要保證udp資料的完整,不能靠udp協議這一層了,得自己手動指定,那麼在socks5裡就有一個udp分包的概念,就是在頭幾個位元組指定這是1號包還是2號包,socks5程式必須自己弄個排序,比如第一次接到標記為3號的包,那麼先存起來等著1號2號來了把3號放後面再發,所以說是很麻煩的,而且rfc也說了應用程式盡量不要弄這種分包,而且rfc說了,socks5程式可以選擇拒絕這種分包方式接到後直接丟棄而不通知用戶端,所以既然那麼麻煩,咱也不用去實現這用不大上的功能,因為即使你這socks5程式實現了,對於應用程式比如qq來說還是不可靠的,而使用udp的應用程式在它應用程式本身就有個完整性和排序的功能,比如丟包了,qq之間自己就知道了,qq之間自己會去想辦法重發還是排序的什麼的,所以我們就不用去管分包了,讓應用程式自己去解決吧,我們只實現轉寄不分包的那種就行了。

 

 

 既然只實現不分包的,那麼格式就固定了

用戶端qq的58864udp連接埠向socks5的58865udp連接埠發送什麼呢,仍然是ip+連接埠或者網域名稱+連接埠方式

00 00 00 01 70 5F F0 3C  1F 40 +實體資料          

比如這個,00 00 00 01開頭,那麼後面4個就是ip地址70 5F F0 3C即112.95.240.60,1F 40 即連接埠8000,後面的全都是實體資料了。那麼socks5伺服器就用58865udp連接埠向qq的伺服器112.95.240.60的8000連接埠發送後面的實體資料而不要發送前面那些封裝內容,那麼會受到qq伺服器返回58865udp連接埠的資料,返回的都是實體資料,因為代理嘛,就像是socks5那台機器在用qq一樣,所以收到的資料沒有前面的封裝都是實體資料。那麼socks5就要返回給用戶端,還不能直接返回,得封裝一下

00 00 00 01 70 5F F0 3C  1F 40 +收到遠程主機返回的資料

把這個返回給用戶端的58864udp連接埠

是不是前麵包裝內容都是一樣的啊,是一樣的,因為用戶端已經指明了ip,所以肯定是一樣的。

 

還一種是這樣網域名稱的,qq的58864udp連接埠發送給socks5的58865udp連接埠
00 00 00 03 12 67 72 6F  75 70 63 6C 69 65 6E 74  2E 71 71 2E 63 6F 6D 23  29+實體資料

00 00 00 03開頭說明後面跟的是網域名稱,緊跟著的12說明後面0x12(十進位18)位元組就是網域名稱,解出來就是groupclient.qq.com

後面23 29即連接埠9001。那麼socks5伺服器就要先把groupclient.qq.com的ip給dns出來58.251.62.164(3A FB 3E A4 ),用58865up連接埠向58.251.62.164的9001udp發送後面的實體資料,返回來後和上面一樣向客戶qq的58864udp發送

00 00 00 01 3A FB 3E A4 23 29 +收到遠程主機返回的資料,03變01了,直接就ip+連接埠了

 

大家注意到了沒,客戶和socks5tcp協商後,socks5開放的udp連接埠,既和客戶開放的udp連接埠聯絡,也和需要串連的遠程主機之間聯絡,都用一個連接埠所以有點亂,這樣就得判斷了,如果發現像這個連接埠如58864udp發送資料的ip和udp連接埠,是之前協商的那個,就說明是客戶的資料,這時就要把客戶要發送的遠程主機的ip和連接埠記錄下來,比如上例的58.251.62.164的9001udp連接埠,如果發現是從58.251.62.164的9001udp發送過來的資料,那麼說明是遠程主機發回的,那麼需要轉寄給協商好的客戶,還有一種情況,既不是客戶也不在遠程主機列表中的機器發過來的資料,就要丟棄,而且比如說客戶發過來一條資料是要發送給遠程A的a連接埠,那麼發送出去接收到返回給客戶,客戶又繼續發過來一條,這次要發給遠程B的b連接埠,那麼就要發出去接收返回給客戶,那麼這時遠程主機就要有個列表了,現在有2條記錄,只要接收到的udp在這2條中,就要轉寄給客戶,如果客戶又要發給C的c,那麼列表就3條記錄了,那麼可能4條5條。

 

 

看出來了吧,socks5代理udp比起tcp來是很麻煩很麻煩的,不但要佔用一個tcp一直維持串連,而且還要手動搞這種列表,但是話說回來了,雖然麻煩,但是比起編寫http代理去解析http還是要容易多了。

 

socks5還有一種bind的tcp方式,說是ftp協議中有一種主動模式是一個tcp連上ftp伺服器的21後,經過協商,伺服器的某連接埠會反向主動串連用戶端的某連接埠,很早以前好像見過,現在這種模式基本沒用,ftp伺服器和主機協商有什麼用啊,現在的機器要麼是在防火牆後,要麼是在區域網路中,ftp伺服器反向串連怎麼能連上客戶呢是吧,所以現在的ftp幾乎都用的是客戶主動串連ftp伺服器的被動模式,socks5的bind就適用於那種老的主動模式,用處很小很小,所以咱不去考慮。

 

 

 ie9隻能用sock4,4a和5不行

Firefox4可以用sock4, 4a不行,可以用sock5,但是是個半殘,不支援使用者名稱和密碼驗證,而且sock5中我上面說了可以發網域名稱過去讓sock5代理去dns解析,但是Firefox4卻非要在本地解析網域名稱,只用sock5的ip模式,無法達到徹底隱藏的目的,話說如果你想上某些不和諧站,如果被人發現你老是在本地dns解析那些網域名稱……是吧。rfc管這叫dns泄露。

 

 

轉寄轉寄,怎麼實現客戶和遠程主機之間的轉寄呢?

看我寫的這一篇,有代碼,很簡單!http://blog.csdn.net/laotse/archive/2010/09/10/5874778.aspx

 

 

逾時怎麼做啊?

我覺得,無論4 4a 還是5,對於tcp的代理,如果發現無論遠程還是客戶只要5分鐘內沒有資料轉送,就把遠程和客戶的這2條tcp串連斷開就行了,對於5的udp也是,如果發現udp連接埠5分鐘都沒有客戶的udp資料包發過來,就把這個udp連接埠關閉,把那個和客戶維持的tcp斷開。而不論4 4a 還是5,只要客戶主動斷開,那麼就把為這個客戶開的一切資源全都關閉掉。不用擔心,一般程式都會定時發送維持性串連資訊的,不會在那連著不收不發就那麼耗著不管了的,所以5分鐘都沒資料,就可以認為已經斷開了,就關閉就行。

這個問題很嚴重,如果不做好不一會就會把伺服器的連接埠全部佔滿,親身體會,其實早斷開了,但就是不釋放,好幾天都顯示ESTABLISHED,等到4294967295秒後才會自動關閉,所以這個問題要謹慎,保守一點好。

 

 

socks代理仍然是明文,就開頭幾個位元組後面全是明文,並不能真正達到隱藏的目的。而且socks代理不支援加密串連。所以我是這樣做的。 肉雞讀取到網路上的某個固定網站上面的某個ip,就串連到我了,是以rsa+aes加密串連的,所以在我的某連接埠和我的肉雞某連接埠之間建立了一條加密隧道,ie等程式通過這個加密隧道來到肉雞上面,串連到那裡的socksProxy 伺服器,通過socks代理串連網路伺服器。這樣串連過程是絕對安全的,而且當初我編寫反向串連伺服器中的aes設的加密位元和密鑰初始化向量都是用最大號的最變態的那種。以前我是把http代理放肉雞上通過這個加密隧道上網,但是由於http代理只能http協議瀏覽網頁用,而且我一開始說了,那個http代理我做的比較失敗,經常不明原因就死迴圈了。現在好了,全都能用了, 應用程式願sock4就sock4,願sock5就sock5,各取所需,多線程同時串連,互不干擾,而且全都是通過反連過來的加密隧道,而且這種不用分析tcp之上高層協議只轉寄的速度快,不會因為解析協議的邏輯錯誤而出現死迴圈的情況,試了兩天很好,cpu佔用率基本為0左右,記憶體16兆左右。

 

 

對了忘記說明重要的一點了,以上我只是用qq舉例說明代理udp的過程,我是不用qq的,有的同志看到我的文章後和我發郵件聯絡就一句話“希望交流某某某 qq:xxxxxx",我是不用qq的,qq我一年也開不了2、3次,只是我在做這個socks程式,才開了開qq進行測試用的,我聊天都是泡論壇。有想交流的,要麼發郵件,最好能光臨我的網站發帖。

 

http://blog.csdn.net/laotse/article/details/6296573

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.