Class: SSHScan::Worker
- Inherits:
-
Object
- Object
- SSHScan::Worker
- Defined in:
- lib/ssh_scan_worker/worker.rb
Instance Method Summary collapse
-
#initialize(opts = {}) ⇒ Worker
constructor
A new instance of Worker.
- #perform_work(work) ⇒ Object
- #post_results(results, job) ⇒ Object
- #retrieve_work ⇒ Object
- #run! ⇒ Object
- #setup_logger(logger) ⇒ Object
Constructor Details
#initialize(opts = {}) ⇒ Worker
Returns a new instance of Worker.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/ssh_scan_worker/worker.rb', line 8 def initialize(opts = {}) raise ArgumentError.new("API server not specified") unless ENV['sshscan.api.host'] || opts["server"] @server = ENV['SSHSCAN_API_HOST'] || opts["server"] raise ArgumentError.new("API scheme not specified") unless ENV['sshscan.api.host'] || opts["scheme"] @scheme = ENV['SSHSCAN_API_SCHEME'] || opts["scheme"] raise ArgumentError.new("API verify not specified") unless ENV['sshscan.api.verify'] || opts["verify"] @verify = ENV['SSHSCAN_API_VERIFY'] || opts["verify"] raise ArgumentError.new("API port not specified") unless ENV['sshscan.api.port'] || opts["port"] @port = ENV['SSHSCAN_API_PORT'] || opts["port"] raise ArgumentError.new("API auth token not specified") unless ENV['sshscan.api.token'] || opts["token"] @auth_token = ENV['SSHSCAN_API_TOKEN'] || opts["token"] @logger = setup_logger(opts["logger"]) @poll_interval = opts["poll_interval"] || 5 # in seconds @poll_restore_interval = opts["poll_restore_interval"] || 5 # in seconds @worker_id = SecureRandom.uuid end |
Instance Method Details
#perform_work(work) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ssh_scan_worker/worker.rb', line 98 def perform_work(work) @logger.info("Started job: #{work["uuid"]}") work["sockets"] = [work["target"] + ":" + work["port"].to_s] scan_engine = SSHScan::ScanEngine.new work["fingerprint_database"] = File.join(File.dirname(__FILE__),"../../data/fingerprints.yml") work["policy"] = File.join(File.dirname(__FILE__),"../../config/policies/mozilla_modern.yml") work["timeout"] = 5 results = scan_engine.scan(work) @logger.info("Completed job: #{work["uuid"]}") return results end |
#post_results(results, job) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/ssh_scan_worker/worker.rb', line 110 def post_results(results, job) uri = URI( "#{@scheme}://#{@server}:#{@port}/api/v1/\ work/results/#{@worker_id}/#{job["uuid"]}" ) http = Net::HTTP.new(uri.host, uri.port) if @scheme == "https" http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify == false = OpenSSL::SSL::OP_NO_SSLv2 + OpenSSL::SSL::OP_NO_SSLv3 + OpenSSL::SSL::OP_NO_COMPRESSION http. = end request = Net::HTTP::Post.new(uri.path) request.add_field("SSH_SCAN_AUTH_TOKEN", @auth_token) unless @auth_token.nil? request.add_field("Content-Type", "application/json") request.body = results.to_json http.request(request) @logger.info("Posted job: #{job["uuid"]}") end |
#retrieve_work ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/ssh_scan_worker/worker.rb', line 68 def retrieve_work (Net::HTTP::SSL_IVNAMES << :@ssl_options).uniq! (Net::HTTP::SSL_ATTRIBUTES << :options).uniq! Net::HTTP.class_eval do attr_accessor :ssl_options end uri = URI( "#{@scheme}://#{@server}:#{@port}/api/v1/\ work?worker_id=#{@worker_id}" ) http = Net::HTTP.new(uri.host, uri.port) if @scheme == "https" http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify == false = OpenSSL::SSL::OP_NO_SSLv2 + OpenSSL::SSL::OP_NO_SSLv3 + OpenSSL::SSL::OP_NO_COMPRESSION http. = end request = Net::HTTP::Get.new(uri.path) request.add_field("SSH_SCAN_AUTH_TOKEN", @auth_token) unless @auth_token.nil? response = http.request(request) JSON.parse(response.body) end |
#run! ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ssh_scan_worker/worker.rb', line 41 def run! loop do begin response = retrieve_work if response["work"] work = response["work"] results = perform_work(work) post_results(results, work) elsif response["error"] @logger.info("Error: #{response["error"]}") sleep @poll_interval next else @logger.info("No jobs available from #{@server}:#{@port} (waiting #{@poll_interval} seconds)") sleep @poll_interval next end rescue Errno::ECONNREFUSED @logger.error("Cannot reach API endpoint #{@server}:#{@port}, waiting #{@poll_restore_interval} seconds") sleep @poll_restore_interval #rescue RuntimeError => e @logger.error(e.inspect) end end end |
#setup_logger(logger) ⇒ Object
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ssh_scan_worker/worker.rb', line 30 def setup_logger(logger) case logger when Logger return logger when String return Logger.new(logger) end return Logger.new(STDOUT) end |