কম্পিউটার

রুবিতে একটি পোর্ট স্ক্যানার কীভাবে লিখবেন

কেন আপনি একটি পোর্ট স্ক্যানার লিখতে চান?

একটি পোর্ট স্ক্যানার লেখা টিসিপি প্রোটোকলের মূল বিষয়গুলি শেখার একটি দুর্দান্ত উপায়, যা হল পরিবহন স্তর বেশিরভাগ ইন্টারনেট প্রোটোকল দ্বারা ব্যবহৃত হয় (HTTP এবং SSH সহ)।

রুবি নেটওয়ার্ক প্রোগ্রামিং কীভাবে কাজ করে সে সম্পর্কে আরও জানার জন্য এটি একটি ভাল অনুশীলন৷

চলুন শুরু করা যাক পোর্ট সম্পর্কে কথা বলে!

বন্দর কি?

যখন আমরা বন্দর সম্পর্কে কথা বলি তখন আমরা আসলে কী সম্পর্কে কথা বলি? O.S-এ একটি বন্দর (অপারেটিং সিস্টেম) স্তরটি একটি প্রক্রিয়ার সাথে যুক্ত একটি "ফাইল বর্ণনাকারী"।

একটি ফাইল বর্ণনাকারী শুধুমাত্র একটি সংখ্যা যা একটি খোলা 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 (ইন্টারনেট অ্যাসাইনড নম্বর অথরিটি) দ্বারা বরাদ্দ করা হয়।

এবং 3য় রেঞ্জটি "ডাইনামিক" বা "এফিমেরাল" পোর্টের জন্য ব্যবহৃত হয়, এগুলি সার্ভার থেকে ডেটা গ্রহণের জন্য সংযোগের ক্লায়েন্ট সাইড দ্বারা ব্যবহৃত পোর্ট।

TCP কমিউনিকেশনের মূল বিষয়গুলি

এখন আপনার পোর্টগুলির সাথে আরও পরিচিত হওয়া উচিত, কিন্তু আমরা এখনও আমাদের পোর্ট স্ক্যানার লিখতে প্রস্তুত নই৷

প্রথমত, একটি বন্দর খোলা থাকার অর্থ কী তা নিয়ে আলোচনা করতে হবে। তারপরে আমরা নেটওয়ার্ক স্তরে একটি খোলা পোর্ট এবং একটি বন্ধ পোর্ট উভয়ের আচরণ পরীক্ষা করব যাতে আমরা তাদের পার্থক্য করতে পারি৷

একটি বন্দর খোলা থাকলে আপনি কিভাবে জানবেন?

একটি ওপেন পোর্ট বলতে বোঝায় যে অন্য প্রান্তে একটি অ্যাপ্লিকেশন শোনা যাচ্ছে এবং আমাদের এটিতে অ্যাক্সেস রয়েছে (ফায়ারওয়াল দ্বারা অবরুদ্ধ নয়)৷

আসুন দেখি কিভাবে একটি নতুন TCP সংযোগ শুরু হয়।

রুবিতে একটি পোর্ট স্ক্যানার কীভাবে লিখবেন

একটি SYN দিয়ে একটি নতুন TCP সংযোগ শুরু হয়েছে৷ প্যাকেট এই প্যাকেটটি একটি নতুন সংযোগ শুরুর প্রতীক৷

তিনটি সম্ভাব্য ফলাফল আছে :

  • সার্ভার একটি SYN/ACK দিয়ে উত্তর দেয় – এর মানে হল এটি একটি সংযোগ স্থাপনের জন্য প্রস্তুত
  • সার্ভার একটি RST দিয়ে উত্তর দেয় প্যাকেট - এর মানে হল সংযোগ প্রত্যাখ্যান করা হয়েছে
  • সার্ভার মোটেই উত্তর দেয় না (কিছু ফায়ারওয়াল এটিকে DROP নীতি হিসাবে প্রয়োগ করে)

যদি ক্লায়েন্ট একটি SYN/ACK পায় প্যাকেট তারপর এটি একটি ACK পাঠিয়ে সংযোগ স্থাপন শেষ করতে পারে প্যাকেট।

একে বলা হয় “তিন-মুখী হ্যান্ডশেক "।

দ্রষ্টব্য :tcpdump বা wireshark এর মত একটি নেটওয়ার্কিং টুল ব্যবহার করে এই ঘটনাটি দেখার একটি দুর্দান্ত উপায়। এই সরঞ্জামগুলি আপনাকে আপনার সিস্টেমের ভিতরে এবং বাইরে আসা প্রতিটি প্যাকেট দেখতে দেয়৷

এখানে tshark থেকে সংযোগের একটি উদাহরণ (wireshark এর কমান্ড-লাইন ইন্টারফেস):

রুবিতে একটি পোর্ট স্ক্যানার কীভাবে লিখবেন

এখন যেহেতু আপনি একটি টিসিপি সংযোগ কীভাবে প্রতিষ্ঠিত হয় সে সম্পর্কে প্রাথমিক ধারণা পেয়েছেন আমরা একটি সাধারণ পোর্ট স্ক্যানার লিখতে পারি।

আসুন একটি পোর্ট স্ক্যানার লিখি!

আমাদের স্ক্যানার লেখার সবচেয়ে সহজ উপায় হল 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 সংযোগ শুরু করা হয় (তিন-মুখী হ্যান্ডশেক) এবং রুবি ব্যবহার করে কীভাবে একটি মৌলিক পোর্ট স্ক্যানার লিখতে হয়৷

আপনি যদি এই পোস্টটি উপভোগ করেন তবে এটিকে শেয়ার করতে ভুলবেন না যাতে আরও লোকেরা এটি উপভোগ করতে পারে 🙂


  1. রুবিতে পরিবেশের ভেরিয়েবলগুলি কীভাবে ব্যবহার করবেন

  2. একটি ম্যাট্রিক্স কি এবং রুবিতে এটি কীভাবে ব্যবহার করবেন?

  3. রুবিতে স্ট্রাকট এবং ওপেনস্ট্রাক্ট কীভাবে ব্যবহার করবেন

  4. রুবিতে ফাইলগুলি কীভাবে পড়তে এবং লিখতে হয় (উদাহরণ সহ)