प्लगइन्स के साथ एक HTTP प्रॉक्सी सर्वर लिखना

छवि एक समय, एक विषय सामने आया कि एक ऑनलाइन गेम में कैप्चा जैसी कोई कष्टप्रद बात थी। अपने आप से, कैप्चा दर्ज करने के लिए खेल से विचलित होने से बहुत अच्छे परिणाम नहीं हो सकते हैं, खासकर यदि आप इसे पहली बार दर्ज करते हैं, तो दुश्मन भी नाराज हो सकते हैं। लेकिन यह बात नहीं है। विशेष रूप से उन लोगों के लिए बुरी बात है जो स्थानीय बॉट्स का उपयोग करते हैं। उन छोटे लोगों ने कैप्चा पर ठोकर खाई, और इसके लिए खेल तुरन्त इकाइयों और संसाधनों के नुकसान के साथ उन्हें जुर्माना करता है। एक अप्रिय बात कहने के लिए।



तो, कार्य:

मैं कैप्चा दर्ज नहीं करना चाहूंगा। हालांकि अगर आप अपने आप से खेलते हैं, भले ही बॉट आपके लिए खेलता है, अगर आप सोते हैं।

अतिरिक्त स्थिति: 40 घंटे का समय (जहाज पर घबराहट के लिए)।

पसंदीदा स्थिति: विंडोज के लिए इंस्टॉलेशन फ़ाइल।

एक और वांछनीय स्थिति: परिणाम मेगाबाइट से अधिक नहीं होना चाहिए।





मैं तुरंत कहूंगा कि मैं गेमर नहीं हूं, और इसके विपरीत भी, मैं ऑनलाइन गेम के कुछ प्रतिद्वंद्वी हूं, और मैंने इस उद्योग में अतिरिक्त प्रवेश को जोड़ने के लिए इस व्यवसाय को लेने का फैसला किया। मामला, शायद कैप्चा और इस से जुड़े आतंक की उपस्थिति के मद्देनजर कुछ लाभ ला सकता है, लेकिन यह कुछ कारणों से नहीं लाया गया।



तो क्या करें?



प्रयास 1


एक सिस्टम टूल लिखें जो सभी स्थापित कार्यक्रमों से HTTP अनुरोधों और प्रतिक्रियाओं को स्वीकार करता है, और उन प्रतिक्रियाओं को फ़िल्टर करता है जिन्हें कैप्चा कैप्चर करने की आवश्यकता होती है। कार्यक्रम के दौरान, जो अन्य बातों के अलावा, इस समस्या को हल करने वाला था, लगभग दो महीने दो बेलारूसी प्रोग्रामर जमा हो रहे थे, प्लेटफ़ॉर्म को C से C # में बदल रहे थे, और फिर Java में सामंजस्य स्थापित कर रहे थे और उन्हें मशीन पर स्थापित OpenSSL की आवश्यकता हो सकती थी। हर बार कार्य अनावश्यक विवरणों से घिरा हुआ था। खैर, सामान्य तौर पर, यह काम नहीं करता था।



प्रयास 2: अपने आप को, सब खुद को




यह बिल्कुल स्पष्ट है कि कई तरीके नहीं हैं, और विकल्प केवल SOCKS प्रॉक्सी और HTTP प्रॉक्सी के बीच आया है। कुछ समय बाद, यह स्पष्ट हो गया कि सभी उपयोगकर्ता एप्लिकेशन SOCKS प्रॉक्सी का समर्थन नहीं करते हैं, और विकल्प अस्पष्ट हो गया है।



मंच का चयन


चुनाव मुश्किल नहीं था, विशेष रूप से प्रयास को देखते हुए 1. सी और सी # को जल्दी से चिह्नित किया गया था, अनुभव की पूरी कमी को देखते हुए। निम्नलिखित पुस्तकालय, आवश्यक पुस्तकालयों में समृद्ध, पहचाने गए:



जावा यह मान लेना मुश्किल है कि इतनी छोटी उपयोगिता को स्थापित करने के लिए, उपयोगकर्ता एक जेवीएम स्थापित करना चाहते हैं, यह कहने के लिए डरावना है कि कितने मेगाबाइट हैं। जावा गिर गया।



अजगर जैसा कि आप जानते हैं, यह हर जगह काम करता है और इसमें सब कुछ शामिल है (बैटरी शामिल हैं)। इसका वजन 7Mb ​​है। आधुनिक मानकों से, ज़ाहिर है, थोड़ा, लेकिन फिर भी मैं अधिक कॉम्पैक्ट चाहता था। प्रश्न यह है कि इस इंस्टॉलर को मेरी उपयोगिता के इंस्टॉलर में कैसे लागू किया जाए। मुझे नहीं पता कि यह पायथन अनुप्रयोगों में कैसे किया जाता है, यह बहुत सरल हो सकता है, लेकिन किसी तरह मैंने पहले ही इंस्टॉलर में इंस्टॉलर किया था और मैं नहीं चाहता।



रूबी मेरी खोज की शुरुआत में विंडोज के लिए एक-कदम इंस्टॉलर नहीं था। पूरी तरह से और पूरी तरह से। अब, यह एक उपयोगकर्ता को स्थापित करते समय MinGW, MSYS और अन्य चीजों की स्थापना का तात्पर्य है जो भयभीत कर सकता है। वजन 7Mb।

इंस्टॉलर में इंस्टॉलर के बारे में, सवाल बना हुआ है।



लुआ C ++ गेम स्क्रिप्टर्स के बीच एक बहुत पुरानी और लोकप्रिय भाषा। सुस्त समुदाय, पुस्तकालयों को अलग करना। आवश्यक पुस्तकालयों में कस्टम वीएम असेंबली का वजन केवल 800Kb है। इंस्टॉलर प्रदान नहीं किया गया है, एक्सई फाइलों का एक सेट है, जिसमें इसे चलाने के लिए एक स्क्रिप्ट के रूप में लुआ स्क्रिप्ट को पारित किया जाता है। आपको जो भी चाहिए वह विन, मैकओएस, लिनक्स के लिए संकलित है, उनमें से प्रत्येक संस्करण 32 और 64 अलग-अलग हैं। आपको क्या चाहिए



इसलिए, मैंने लुआ का अध्ययन शुरू किया (एक नए साल की इच्छा सच हुई, मैंने एक नई प्रोग्रामिंग भाषा सीखी)।

भाषा में अद्भुत गुण हैं, जैसे:

- सैंडबॉक्सिंग (माणिक में केवल संस्करण 1.8.5 के लिए एक पैच था): आपको तीसरे पक्ष के कोड को चलाने की अनुमति देता है, इसके पर्यावरण को सीमित करता है;

- कोरआउट (जैसे 1.9 से रूबी फाइबर): आपको बहुत हल्के सहकारी मल्टीटास्किंग करने की अनुमति देता है;

- एक बहुत ही सरल (अधिक सटीक, सरल - केवल एक साहचर्य सरणी है) डेटा संरचना, जो, जैसा कि यह पता चला है, अधिकांश डेटा प्रोसेसिंग कार्यों को करने के लिए पर्याप्त है;

... बहुत अधिक, एक पोस्ट में इतना कठिन।



सबसे आसान तरीका एक HTTP प्रॉक्सी सर्वर के फ़िल्टरिंग अनुरोधों और प्रतिक्रियाओं के रूप में ऐसी प्रणाली बनाना था, जिसे करने का फैसला किया गया था (अच्छे से बुरे, अच्छे नहीं)।



यह विचार सरल है: टीसीपी सर्वर को लटकाएं, ग्राहक जो मांगता है उसे सुनें, HTTP हेडर को पार्स करें, HOST देखें, HTTP हेडर "प्रॉक्सी-कनेक्शन" को हटा दें, उस व्यक्ति को अनुरोध भेजें, जिस पर उसका इरादा था, प्रतिक्रिया प्राप्त करें, उसे क्लाइंट को भेजें, आदि।



सर्वर प्रतिक्रिया को फ़िल्टर करने की आवश्यकता होती है, और यह तब किया जा सकता है यदि सर्वर HTTPS का उपयोग नहीं करता है, लेकिन सौभाग्य से यह नहीं करता है। ऐसा करने के लिए यह काफी सरल निकला, रूबी के लिए रूबी के अनुरूप एनालॉग मैकेनाइज लिखने के लिए यह पर्याप्त निकला, जो लुआ की 190 पंक्तियों के साथ होता है, जो कुछ भी वह हेडर और अनुरोध के शरीर के साथ लेता है, आपको HTTP अनुरोधों के लिए जो भी फिल्टर चाहिए उसे लिखने की अनुमति देता है।



खैर, इस मामले में, हमें हानिकारक reCAPTCHA से छुटकारा पाना था, जिसके लिए केवल यह निर्धारित करना आवश्यक था:

- मूल अनुरोध ट्रूकॉलर के पेज पर क्लिक किया गया (और HTML पेज का अनुरोध किया गया था):

string.find(request.uri(), 'travian') and mimetype and string.find(mimetype, 'text/html')







- क्या "उपयोगी" गेम डेटा के बजाय परिणामी पृष्ठ पर एक कैप्चा था:

local captcha, captcha_key = string.match(response.body(), '<iframe src="(http://api.recaptcha.net/noscript??(k=[%a%d_]+&lang=en))')









कैप्चा को कैसे हल किया जाए (बहुत आधुनिक और उच्च-प्रदर्शन वाले भारतीय नहीं, बल्कि बेहद सस्ते रहने वाले भारतीय) की मदद से हमारे विशुद्ध रूप से तकनीकी विषय से थोड़ा परे है, इसलिए कहीं और।



परिणामस्वरूप, कैप्चा चित्र डाउनलोड किया गया, भारतीयों को भेजा गया (केवल मामले में 2 बार), 5-10 सेकंड के बाद प्राप्त किए गए उत्तरों की तुलना की गई, और यदि वे समान थे, तो परिणाम एक अनुरोध के द्वारा HTTP POST के लिए भेजा गया था, जिसमें पीड़ित एक पृष्ठ जारी करता है, खुशी से रिपोर्टिंग करता है हम, यह पता चला है, लोग हैं, और "उपयोगी" खेल डेटा का एक गुच्छा। हम इस पृष्ठ को एक पहले से न दिखाने वाले ग्राहक को दिखाते हैं जो केवल एक मामूली विराम पर ध्यान दे सकता है। बेमेल के निराशावादी मामले में, चित्र फिर से भारतीयों को भेजा गया था, और इसी तरह, जब तक कम से कम दो समान समाधान प्राप्त नहीं किए गए थे, बाकी धनवापसी के लिए सहायता सेवा में भेजे गए (भारतीयों के लिए लगभग कोई मुफ्त नहीं)।



तो, यहाँ यह है, समाधान है।



हालाँकि, कुछ ऐसा हुआ जिसकी किसी को उम्मीद नहीं थी। किसी कारण से, उपयोगकर्ताओं को अन्य साइटों तक पहुंच की आवश्यकता थी, यह अकल्पनीय है! उनमें से HTTPS के माध्यम से भी एक्सेस की गई साइटें थीं, और कुछ को नियमित प्रॉक्सी के बिना ऑन / ऑफ स्विचिंग के साथ किया जाना था।

और फिर भी यह आवश्यक था कि कई अनुरोध एक साथ स्वीकार किए जाते थे। यह अप्रिय था कि Google एनालिटिक्स कभी-कभी एक स्थायी मिनट बनाता है, जो सिंगल-थ्रेडेड प्रॉक्सी को स्टैंडबाय मोड में छोड़ देता है।



खैर, इसके लिए, एसिंक्रोनस टीसीपी सर्वर बनाने के लिए तीन अलग-अलग पुस्तकालयों के रूप में थे। वह है - हम एक आने वाले कनेक्शन की प्रतीक्षा कर रहे हैं, हम डेटा का एक टुकड़ा प्राप्त करते हैं, हम डिस्पैचर पर नियंत्रण स्थानांतरित करते हैं, हम देखते हैं कि क्या अभी भी आने वाले कनेक्शन हैं या खुले कनेक्शन हैं जिसके लिए डेटा (चयन / kpoll / epoll) है, हम बदले में नियंत्रण स्थानांतरित करते हैं।



काश और आह, चूंकि ऐसे सभी कनेक्शन स्थानीय मशीन पर होते हैं, यह सब लगभग तुरंत होता है। और धीमे कनेक्शन आउटगोइंग हैं। मौजूदा पुस्तकालयों ( कोपस , एसोक ) को पोक करना , जो आने वाले कनेक्शनों को मल्टीप्लेक्स करने के लिए डिज़ाइन किए गए हैं, अपने खुद के लिखने की तुलना में अधिक कठिन थे। और मैंने एक छोटी (272 पंक्तियाँ) लिखी। इस तथ्य के अलावा कि सभी इनकमिंग और आउटगोइंग कनेक्शन असिंक्रोनस रूप से काम करते हैं, आप एक सामान्य चक्र में काम करने वाले पूल में किसी भी अधिक कोरआउट्स (मुझे सही करें, विशेष शिक्षा वाले लोग) जोड़ सकते हैं।



ठीक है, सब कुछ समानांतर में काम करना शुरू कर दिया, और गति के मामले में यह केवल अप्रत्यक्ष रूप से पीछे रह गया कि यह प्रॉक्सी के बिना कैसे काम करता है।



जब मुझे हेडर के साथ सर्वर से एक पृष्ठ प्राप्त हुआ तो मेरा आश्चर्य कैसा था:

सामग्री-एनकोडिंग: gzip

स्थानांतरण-एन्कोडिंग: chunked

और वास्तव में जवाब के शरीर के रूप में पूर्ण krakozyabry।



पहला विचार अनुरोध में स्वीकार-एनकोडिंग को अक्षम करना था, ताकि सर्वर डेटा को पैक करने की कोशिश न करे, और HTTP 1.1 को HTTP 1.0 में बदल दे ताकि यह "विखंडू" न भेजे। लेकिन मैंने गति में गिरावट और यातायात में वृद्धि के बारे में सोचा, और उपयोगकर्ताओं पर दया की।

यह इस तरह निकला:

if headers(pipe, target)['Transfer-Encoding'] == 'chunked' then

target.body = dechunk(target.body)

end



function dechunk(chunkie)

local chunk_size

local chunk

local chunks = {}

chunkie, chunk_size = readline(chunkie)



while chunk_size and tonumber(chunk_size, 16) > 0 do

chunkie, chunk = readbytes(chunkie, tonumber(chunk_size, 16))



table.insert(chunks, chunk)

chunkie, chunk_size = readline(chunkie)

if not chunk_size or chunk_size == '' then -- sometimes there's a crlf, sometimes not

chunkie, chunk_size = readline(chunkie)

end

end



return table.concat(chunks)

end









मैं मैटरियल पढ़ने गया था। भगवान का शुक्र है, प्रलेखन के ये आइटम सभ्य हैं।

"चंक्स" को गोंद करें, हमें एक gzip फ़ाइल मिलती है (कभी-कभी अपस्फीति होती है, लेकिन मैंने इसे अभी तक नहीं देखा है)। अनपैक ( पुस्तकालय के लिए डेविड मानुरा का धन्यवाद)।

अनपैक करना और भी आसान हो गया:

if headers(pipe, target)['Content-Encoding'] == 'gzip' and #target.body > 0 then

local decoded = {}

gzip.gunzip {input=target.body, output=function(byte) table.insert(decoded, string.char(byte)) end}

target.body = table.concat(decoded)

end









थोड़ा बचा

HTTPS साइटों के लिए HTTPS टनलिंग बनाएं (भगवान का शुक्र है, आपको OpenSSL को टक्कर देने की आवश्यकता नहीं है, बस पारदर्शी रूप से डेटा को आगे और पीछे स्थानांतरित करें):

if request.method() == 'CONNECT' then

local sent_to_server, err = client.send("HTTP/1.0 200 Connection established\r\nProxy-agent: BotHQ-Agent/1.2\r\n\r\n")

print('https transparent connection')

https(client, server)

return

end



local function https(client, server)

close_callback = function()

client.close()

server.close()

end



client.receive_subscribe(function(data)

server.send(data)

end, close_callback)



server.receive_subscribe(function(data)

client.send(data)

end, close_callback)

end









- इंस्टॉलर में डालें:

सामान्य तौर पर, हरोकू पर 7zip sfx के लॉन्च के साथ रोमांच एक अलग पोस्ट के लायक है। जीत की खुशी विकास के किसी भी मुश्किल क्षण की देखरेख करती है।



वैसे, मैं आपके बारे में नहीं जानता, लेकिन मेरे लिए ऐसा करना दिलचस्प और दिलचस्प था। मुझे समय व्यतीत करने का पछतावा नहीं है।



संक्षेप में:

प्रॉक्सी सर्वर यहां लाइन 71 पर है

यहां अतुल्यकालिक लाइब्रेरी टीसीपी-सर्वर-क्लाइंट 272 लाइनों पर।

190 लाइनों के लिए HTTP क्लाइंट के कुछ एनालॉग।

यहां 150 लाइनों के लिए कैप्चा को हल करने के लिए फ़िल्टर करें

स्थापना फ़ाइल आकार में मेगाबाइट से कम है।



मुझे यकीन है कि इस चीज़ के लिए बहुत सारे उपयोगी अनुप्रयोग हैं, न कि बहुत अच्छे लोगों से, जैसे "स्वचालित" कैप्चा सॉल्विंग के साथ स्पैमलॉक, उपयोगी लोगों के लिए, जब आपको स्क्रिप्ट के साथ उपयोगकर्ता ट्रैफ़िक को लचीले ढंग से फ़िल्टर करने की आवश्यकता होती है। यहाँ एक सरल स्क्रिप्ट है जो उपयोगकर्ताओं को प्रॉक्सी के माध्यम से vk.com से जुड़ने की अनुमति नहीं देती है:

module(..., package.seeall)

function filter(request, response)

response.set_body('')

end



function pre(request, response)

return string.find(request.uri(), 'vk.com')

end









लुआ 5.2 की आगामी रिलीज के साथ, कोरटाइन से मेटामेथोड्स को कॉल करने पर प्रतिबंध हटा दिया जाएगा, और पुस्तकालयों को और अधिक सुंदर बनाया जा सकता है, उदाहरण के लिए, http.set_body तरीके चले जाएंगे, और बहुत कुछ।



All Articles