Check all ports


#1

Yes I am new at this.

I’m trying to create an inSpec script to check the status of every port on a client/server. I can run the following with no issues, but it doesn’t run well if at all when I scale it to a large number of ports.

for port in 0..21
	describe port(port) do
		it { should_not be_listening }
	end
end

It seems to consume a large amount of memory and eventually dies when scanning the full port range. Any suggestions? I’d rather not manually parse output from SS.


#2

Maybe not the best from a presentation standpoint, but have you tried putting the loop within the it block?

If my understanding is correct, inspec will attempt to run each it in its own thread, in parallel (for obvious time-savings). If you try to do that for massive port ranges, that’s probably too much though. If you loop within the it, it should go through them sequentially.

For the best of both worlds, you could just loop over chunks of port ranges, and then have a nested loop within the it block.


#3

Makes sense, but I’m not understanding how to do the loop inside of the it block.


#4

Never had this but I got curious and found that the inspec docs actually have an example for port ranges:

describe port.where { protocol =~ /tcp/ && port > 22 && port < 80 } do
  it { should_not be_listening }
end

Taken from https://www.inspec.io/docs/reference/resources/port/


#5

Yes. I found that late yesterday afternoon and it works perfectly.

describe port.where { port > 30000 && port < 40000 } do
	it { should_not be_listening }
end

This runs in seconds where the other method would take ~10 minutes to check 10000 ports. I’m not sure why this method works so much better, but none the less it does.


#6

I’m still scratching my head on how/if it is possible to have a generic inspec script where I could load a csv file/yaml/etc… and that file determines which ports should or shouldn’t be listening.

Example of what I have…that doesn’t work for the same reason my initial question didn’t work. Anybody have any ideas of how to make this or something similar to this work?

YAML File

- port: 1
  status: closed
- port: 2
  status: closed

The inspec script looks like this -

# encoding: utf-8

title 'Port Looper'
openPorts = yaml(content: inspec.profile.file('openPorts.yaml')).params

# you add controls here
control 'portLoop' do                        # A unique ID for this control
		impact 0.7                                # The criticality, if this control fails.
		title 'Port Check'             # A human-readable title
		desc 'Check which ports are open/listening...'


	openPorts.each do |portNumber|
		describe port(portNumber['port']) do
			if portNumber['status'] == "closed"
				it { should_not be_listening }
			elsif portNumber['status'] == "open"
				it { should be_listening }
			end
		end
	end
end