आप पोर्ट स्कैनर क्यों लिखना चाहेंगे?
पोर्ट स्कैनर लिखना TCP प्रोटोकॉल की मूल बातें सीखने का एक शानदार तरीका है, जो अधिकांश इंटरनेट प्रोटोकॉल (HTTP और SSH सहित) द्वारा उपयोग की जाने वाली ट्रांसपोर्ट लेयर है।
यह रूबी नेटवर्क प्रोग्रामिंग कैसे काम करती है, इसके बारे में अधिक जानने का भी एक अच्छा अभ्यास है।
आइए पोर्ट्स के बारे में बात करके शुरू करते हैं!
पोर्ट क्या है?
जब हम पोर्ट्स के बारे में बात करते हैं तो हम वास्तव में किस बारे में बात कर रहे हैं? ऑपरेटिंग सिस्टम स्तर पर एक पोर्ट केवल एक प्रक्रिया से जुड़ा एक "फाइल डिस्क्रिप्टर" होता है।
एक फाइल डिस्क्रिप्टर केवल एक संख्या है जिसका उपयोग खुले I/O चैनल को संदर्भित करने के लिए किया जाता है, जैसे stdout (मानक आउटपुट), एक नेटवर्क सॉकेट या एक फाइल।
जब OS को एक TCP/IP पैकेट प्राप्त होता है तो यह डेस्टिनेशन पोर्ट को देखता है और एक ऐसी प्रक्रिया खोजने का प्रयास करता है जो इस पोर्ट पर सुन रही हो।
फिर यदि कोई सुनने वाली प्रक्रिया है तो पैकेट को उस तक पहुंचा दिया जाता है।
पोर्ट रेंज
कुल 65,535 पोर्ट उपलब्ध हैं, लेकिन व्यवहार में उनमें से सभी का नियमित रूप से उपयोग नहीं किया जाता है।
पोर्ट्स को 3 समूहों में विभाजित किया जा सकता है:
| रेंज | नाम | उदाहरण |
|---|---|---|
1-1023 | वेल-नोन पोर्ट्स | 22 (SSH), 80 (HTTP), 443 (HTTPS) |
1024-49151 | रजिस्टर्ड पोर्ट्स | 3306 (MySQL), 5432 (PostgreSQL) |
49152-65535 | एफेमरल पोर्ट्स | Chrome, Firefox |
दूसरी रेंज में पोर्ट्स IANA (इंटरनेट असाइन्ड नंबर्स अथॉरिटी) द्वारा असाइन किए जाते हैं।
और तीसरी रेंज "डायनामिक" या "एफेमरल" पोर्ट्स के लिए उपयोग की जाती है, ये क्लाइंट साइड द्वारा सर्वर से डेटा प्राप्त करने के लिए उपयोग किए जाने वाले पोर्ट हैं।
TCP कम्युनिकेशन की मूल बातें
अब आप पोर्ट्स से अधिक परिचित हो चुके हैं, लेकिन हम अभी भी अपना पोर्ट स्कैनर लिखने के लिए तैयार नहीं हैं।
पहले, हमें चर्चा करने की आवश्यकता है कि किसी पोर्ट के खुले होने का क्या अर्थ है। फिर हम नेटवर्क स्तर पर खुले पोर्ट और बंद पोर्ट दोनों के व्यवहार की जांच करेंगे ताकि हम उन्हें अलग कर सकें।
आप कैसे जान सकते हैं कि कोई पोर्ट खुला है?
एक खुला पोर्ट केवल इसका मतलब है कि दूसरे छोर पर एक एप्लिकेशन सुन रहा है और हमारे पास उस तक पहुंच है (फायरवॉल द्वारा अवरुद्ध नहीं)।
आइए देखें कि एक नया TCP कनेक्शन कैसे शुरू किया जाता है।

एक नया TCP कनेक्शन SYN पैकेट के साथ शुरू होता है। यह पैकेट एक नए कनेक्शन की शुरुआत का प्रतीक है।
तीन संभावित परिणाम हैं:
- सर्वर
SYN/ACKके साथ जवाब देता है – इसका मतलब है कि यह कनेक्शन स्थापित करने के लिए तैयार है - सर्वर
RSTपैकेट के साथ जवाब देता है – इसका मतलब है कि कनेक्शन अस्वीकार कर दिया गया है - सर्वर बिल्कुल भी जवाब नहीं देता (कुछ फायरवॉल इसे DROP पॉलिसी के रूप में लागू करते हैं)
यदि क्लाइंट को SYN/ACK पैकेट प्राप्त होता है तो यह ACK पैकेट भेजकर कनेक्शन स्थापित करना समाप्त कर सकता है।
इसे "थ्री-वे हैंडशेक" कहा जाता है।
नोट: इसे होते हुए देखने का एक शानदार तरीका tcpdump या Wireshark जैसे नेटवर्किंग टूल का उपयोग करना है। ये टूल आपको अपने सिस्टम में आने और जाने वाले हर पैकेट को देखने की अनुमति देते हैं।
यहां tshark (Wireshark का कमांड-लाइन इंटरफेस) से एक उदाहरण कनेक्शन है:

अब जब आपको TCP कनेक्शन कैसे स्थापित होता है, इसकी बुनियादी समझ है, तो हम एक साधारण पोर्ट स्कैनर लिख सकते हैं।
आइए पोर्ट स्कैनर लिखें!
हमारे स्कैनर को लिखने का सबसे सरल तरीका TCPSocket का उपयोग करके एक नया TCP कनेक्शन खोलना है और फिर इस तथ्य पर भरोसा करना है कि एक अस्वीकृत कनेक्शन Errno::ECONNREFUSED एक्सेप्शन उठाएगा।
यहां कोड है:
require 'socket' PORT = ARGV[0] || 22 HOST = ARGV[1] || 'localhost' begin socket = TCPSocket.new(HOST, PORT) status = "open" rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT status = "closed" end puts "Port #{PORT} is #{status}." इस कोड की कुछ सीमाएं हैं:
हम एक समय में केवल एक पोर्ट को स्कैन कर सकते हैं। अक्सर आप किसी विशिष्ट होस्ट पर उजागर सेवाओं का बेहतर अंदाजा लगाने के लिए पोर्ट्स की एक रेंज को स्कैन करना चाहते हैं।
इस कोड के साथ एक और सीमा यह है कि एक नॉन-रिस्पॉन्डिंग पोर्ट (जिसका मैंने पहले उल्लेख किया था तीसरा परिणाम) आपको लगभग 20 सेकंड तक इंतजार कराएगा जब तक कि कनेक्शन टाइम आउट न हो जाए।
इसे connect_nonblock, IO.select और Socket ( TCPSocket के बजाय, जो ऑब्जेक्ट बनाते ही कनेक्शन शुरू कर देता है) के संयोजन से हल किया जा सकता है।
उदाहरण:
require 'socket' TIMEOUT = 2 def scan_port(port) socket = Socket.new(:INET, :STREAM) remote_addr = Socket.sockaddr_in(port, 'www.example.com') begin socket.connect_nonblock(remote_addr) rescue Errno::EINPROGRESS end _, sockets, _ = IO.select(nil, [socket], nil, TIMEOUT) if sockets p "Port #{port} is open" else # Port is closed end end PORT_LIST = [21,22,23,25,53,80,443,3306,8080] threads = [] PORT_LIST.each { |i| threads << Thread.new { scan_port(i) } } threads.each(&:join) IO.select कॉल तब तक इंतजार करेगा जब तक कि सॉकेट डेटा प्राप्त करने के लिए तैयार न हो जाए (जिसका मतलब है कि यह खुला है) या TIMEOUT समय बीत चुका हो, जिसके बाद हम मान सकते हैं कि पोर्ट या तो बंद है या कनेक्शन अनुरोधों को अनदेखा कर रहा है।
तो, यह सब एक सीखने के अभ्यास के रूप में बहुत अच्छा है, लेकिन यदि आपको एक उचित पोर्ट स्कैनर की आवश्यकता है तो आपको nmap जैसी किसी चीज़ का उपयोग करना चाहिए।
Nmap ओपन सोर्स है और 15 वर्षों से अधिक समय से सक्रिय विकास में है।
यहां nmap आउटपुट जैसा दिखता है:

मुझे पता है कि यह बहुत सारी जानकारी है, इसलिए आपको याद रखने में मदद करने के लिए इस पोस्ट से सीखी गई 2 नई चीजों के साथ एक कमेंट लिखें 🙂
सारांश
इस पोस्ट में आपने सीखा कि पोर्ट क्या है, उपलब्ध विभिन्न पोर्ट रेंज, TCP कनेक्शन कैसे शुरू किया जाता है (थ्री-वे हैंडशेक) और रूबी का उपयोग करके एक बुनियादी पोर्ट स्कैनर कैसे लिखें।
यदि आपको यह पोस्ट पसंद आई तो इसे शेयर करना न भूलें ताकि अधिक लोग इसका आनंद ले सकें 🙂