Rails Insights

Создание сканера портов на Ruby

Сканеры портов — это полезные инструменты для сетевых администраторов и специалистов по безопасности, позволяющие проверять открытые порты на удаленных хостах. В этой статье мы рассмотрим, как создать простой сканер портов на языке Ruby. Мы будем использовать стандартные библиотеки Ruby, чтобы сделать процесс максимально простым и понятным.

Что такое сканер портов?

Сканер портов — это программа, которая проверяет доступность портов на удаленном хосте. Порты — это точки доступа, через которые приложения обмениваются данными. Если порт открыт, это может означать, что на нем работает служба, готовая принимать соединения. Сканирование портов может помочь в выявлении уязвимостей и обеспечении безопасности сети.

Зачем использовать Ruby для создания сканера портов?

Ruby — это мощный и удобный язык программирования, который позволяет быстро разрабатывать приложения. Он имеет простую синтаксис и множество встроенных библиотек, что делает его отличным выбором для создания сетевых инструментов. Кроме того, Ruby поддерживает асинхронное программирование, что позволяет эффективно обрабатывать множество соединений одновременно.

Подготовка окружения

Перед тем как начать, убедитесь, что у вас установлен Ruby. Вы можете проверить это, выполнив следующую команду в терминале:

ruby -v

Если Ruby не установлен, вы можете скачать его с официального сайта ruby-lang.org и следовать инструкциям по установке.

Основы сканирования портов

Сканирование портов можно реализовать несколькими способами. В этой статье мы создадим простой сканер, который будет проверять, открыты ли порты на заданном хосте. Мы будем использовать метод TCP-соединения для проверки доступности портов.

Создание простого сканера портов

Давайте начнем с написания кода для нашего сканера. Мы создадим файл с именем port_scanner.rb и добавим в него следующий код:

require 'socket'

def scan_ports(host, ports)
  ports.each do |port|
    begin
      socket = Socket.new(:INET, :STREAM)
      socket.connect(Socket.sockaddr_in(port, host))
      puts "Порт #{port} открыт"
    rescue Errno::ECONNREFUSED
      puts "Порт #{port} закрыт"
    rescue SocketError
      puts "Ошибка подключения к #{host}: #{port}"
    ensure
      socket.close if socket
    end
  end
end

host = ARGV[0] || '127.0.0.1'
ports = (1..1024).to_a

puts "Сканирование портов на #{host}..."
scan_ports(host, ports)

В этом коде мы используем библиотеку socket для создания TCP-соединений. Мы определяем метод scan_ports, который принимает хост и массив портов для сканирования. Для каждого порта мы пытаемся установить соединение и выводим результат.

Запуск сканера

Чтобы запустить сканер, откройте терминал и выполните следующую команду:

ruby port_scanner.rb <адрес_хоста>

Замените <адрес_хоста> на IP-адрес или доменное имя, которое вы хотите просканировать. Если вы не укажете адрес, сканер будет использовать 127.0.0.1 (локальный хост) по умолчанию.

Расширение функциональности

Теперь, когда у нас есть базовый сканер, давайте добавим несколько улучшений:

  • Параллельное сканирование: Мы можем использовать потоки для одновременного сканирования нескольких портов.
  • Настройка диапазона портов: Позволим пользователю задавать диапазон портов для сканирования.
  • Вывод результатов в файл: Добавим возможность сохранять результаты сканирования в файл.

Параллельное сканирование

Для реализации параллельного сканирования мы можем использовать библиотеку thread. Давайте изменим наш метод scan_ports:

require 'socket'
require 'thread'

def scan_ports(host, ports)
  threads = []
  ports.each do |port|
    threads << Thread.new do
      begin
        socket = Socket.new(:INET, :STREAM)
        socket.connect(Socket.sockaddr_in(port, host))
        puts "Порт #{port} открыт"
      rescue Errno::ECONNREFUSED
        puts "Порт #{port} закрыт"
      rescue SocketError
        puts "Ошибка подключения к #{host}: #{port}"
      ensure
        socket.close if socket
      end
    end
  end
  threads.each(&:join)
end

Теперь наш сканер будет проверять порты параллельно, что значительно ускорит процесс.

Настройка диапазона портов

Чтобы позволить пользователю задавать диапазон портов, мы можем изменить способ получения портов. Давайте добавим возможность передавать диапазон через аргументы командной строки:

host = ARGV[0] || '127.0.0.1'
port_range = ARGV[1] || '1-1024'
ports = (port_range.split('-').map(&:to_i).first..port_range.split('-').map(&:to_i).last).to_a

puts "Сканирование портов на #{host}..."
scan_ports(host, ports)

Теперь вы можете указать диапазон портов, например:

ruby port_scanner.rb <адрес_хоста> 20-80

Вывод результатов в файл

Чтобы сохранить результаты сканирования в файл, мы можем добавить параметр для указания имени файла:

def scan_ports(host, ports, output_file)
  File.open(output_file, 'w') do |file|
    ports.each do |port|
      begin
        socket = Socket.new(:INET, :STREAM)
        socket.connect(Socket.sockaddr_in(port, host))
        file.puts "Порт #{port} открыт"
      rescue Errno::ECONNREFUSED
        file.puts "Порт #{port} закрыт"
      rescue SocketError
        file.puts "Ошибка подключения к #{host}: #{port}"
      ensure
        socket.close if socket
      end
    end
  end
end

output_file = ARGV[2] || 'scan_results.txt'
scan_ports(host, ports, output_file)

Теперь вы можете указать имя файла для сохранения результатов:

ruby port_scanner.rb <адрес_хоста> 20-80 results.txt

Заключение

В этой статье мы создали простой сканер портов на Ruby, который может проверять открытые порты на удаленных хостах. Мы также добавили несколько улучшений, таких как параллельное сканирование, настройка диапазона портов и возможность сохранения результатов в файл. Теперь у вас есть базовый инструмент для анализа сетевой безопасности.

Не забывайте использовать сканеры портов ответственно и только на тех системах, на которые у вас есть разрешение. Сканирование без разрешения может быть незаконным и привести к серьезным последствиям.

Надеемся, что эта статья была полезной и вдохновила вас на создание собственных сетевых инструментов на Ruby!

Published: August 12, 2024

© 2024 RailsInsights. All rights reserved.