ip_auditor 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ M2IxZmI1MzhmZGVhOWE0ZmE1MTNlNjMyYmM5NjdhNTdmNDQyNzlmZg==
5
+ data.tar.gz: !binary |-
6
+ MjMwZjM3YmNiMGM4ZjE3Y2U4MGJjYzVmOGRjODY5ZjgyNmEyMDA4ZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YmI1MmJiZDdkOGViY2ViMzZmMjBjMTUxN2E1ZjU2MGJkZDk4NzdmMTg5NmI4
10
+ MjMzYTFiYjRlYzViZThhZGIwNzcwODA2ZWQ3Y2VhZTY3YjdlNDBiZmJmZjNk
11
+ NjkwNWI3MGQ1MjczMWUzNDU2OWI2YmRhMDI5YWE4NmQzYWMxZWI=
12
+ data.tar.gz: !binary |-
13
+ YjRiOTU2NGNiZTg0M2I4ZGRjOGI2ZjBjNGMxNjM1MDA5NmNhMWM5NWQxYTQ1
14
+ YmRhYjFkYTZiYjA0NTZjNzhkOTI3NzE0ZTdmMWZlNjc3YzE0YmI4MDk3NjVm
15
+ ZTBiZDE2OWFhZDI2N2FhZDlhNDI0MjFjOGIwZDc1ZmVmMDdjMjM=
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ip_auditor.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 James Kurczodyna
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # IP Auditor
2
+
3
+ The IP Auditor looks through your Apache vhosts to compile a list of apps on the server, what domains are being listened for and what IP each domain is actually pointing to.
4
+
5
+ This allows you to quickly track which domains and apps are active and which are pointing elsewhere.
6
+
7
+ ## Installation
8
+
9
+ * clone this repo
10
+ * cd into the repo
11
+ * run `bundle install`
12
+
13
+ ## Usage
14
+
15
+ To use the Auditor, cd into the cloned repo and run the following command:
16
+
17
+ ruby ./lib/ip_auditor.rb [server name/IP] [user] [options]
18
+
19
+ Example:
20
+
21
+ ruby ./lib/ip_auditor.rb someserver.com myuser
22
+
23
+ ## Output
24
+
25
+ The Auditor will return a crude report for each VirtualHost in the following format.
26
+
27
+ ============
28
+ /path/to/vhost/vhostname: <VirtualHost [IP]:[port]>
29
+ ============
30
+ [domain-1]
31
+ [IP domain-1 is actually pointing to]
32
+ [domain-2]
33
+ [IP domain-2 is actually pointing to]
34
+ [/path/to/app/DocumentRoot]
35
+
36
+ ## Options
37
+
38
+ * -p [PORT NUMBER] : Specify a port number (default is 22)
39
+ * -c [FILE NAME (optional)]: Output to .csv file instead of terminal (can specify a name)
40
+ * -v : Output more information as to what's happening
41
+ * -e [prod|stage|dev|etc.]: Specify an environment to output (defaults to 'all'; determined by passenger config files, so non-rails site will always return)
42
+
43
+ ## License
44
+
45
+ MIT License
46
+
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of this software and associated documentation files (the
49
+ "Software"), to deal in the Software without restriction, including
50
+ without limitation the rights to use, copy, modify, merge, publish,
51
+ distribute, sublicense, and/or sell copies of the Software, and to
52
+ permit persons to whom the Software is furnished to do so, subject to
53
+ the following conditions:
54
+
55
+ The above copyright notice and this permission notice shall be
56
+ included in all copies or substantial portions of the Software.
57
+
58
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
59
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
60
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
61
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
62
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
63
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
64
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/audit_ips ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/ip_auditor.rb'
4
+
5
+ IpAuditor.audit
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ip_auditor/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "ip_auditor"
6
+ gem.version = IpAuditor::VERSION
7
+ gem.platform = Gem::Platform::RUBY
8
+ gem.authors = ["James Kurczodyna", "Kellen Hawley"]
9
+ gem.email = ["james@finedesigngroup.com"]
10
+ gem.description = "IP Auditor"
11
+ gem.summary = "Audits Apache vhosts and domain IPs"
12
+ gem.homepage = "https://github.com/jamesmkur/ip-auditor"
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = ['audit_ips']
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+ gem.bindir = 'bin'
19
+
20
+ gem.add_dependency "net-ssh", "~> 2.6.7"
21
+ end
data/lib/ip_auditor.rb ADDED
@@ -0,0 +1,284 @@
1
+ # require "ip_auditor/version"
2
+ require 'net/ssh'
3
+ require 'optparse'
4
+ require 'ostruct'
5
+ require 'yaml'
6
+
7
+ begin
8
+ require 'io/console'
9
+ rescue LoadError
10
+ end
11
+
12
+
13
+ module IpAuditor
14
+
15
+ def IpAuditor.set_options
16
+ @options = OpenStruct.new
17
+
18
+ @options.verbose = false
19
+ @options.environment = 'all'
20
+
21
+ # parse the options passed in through the terminal
22
+ OptionParser.new do |opts|
23
+ opts.banner = 'Usage: ip.auditor.rb [server name/IP] [username] [options]'
24
+
25
+ # get the port number
26
+ opts.on('-p', '--port [PORT NUMBER]', 'Port (default is 22)') do |p|
27
+ @options.port = p
28
+ end
29
+
30
+ # check whether to output data as csv, possibly get the name
31
+ opts.on('-c', '--csv [FILENAME]', 'Output data as CSV file') do |c|
32
+ @options.csv = true
33
+ @options.csv_name = c =~ /[^[:space:]]/ ? c : nil
34
+ end
35
+
36
+ # check whether output more information
37
+ opts.on('-v', '--verbose', 'Print out more information about what\'s happening') do |v|
38
+ @options.verbose = true
39
+ end
40
+
41
+ # specify the environment we're checking
42
+ opts.on('-e', '--environment [prod|stage|dev|etc.]', 'Print only the sites that have environment specified in their passenger files (default is all)') do |e|
43
+ @options.environment = e
44
+ end
45
+
46
+ end.parse!
47
+
48
+ # prompt for password
49
+ @options.pass = IpAuditor.get_password
50
+ puts "\n"
51
+
52
+ # set the connection variables
53
+ @options.server = ARGV[0] || ''
54
+ @options.user = ARGV[1] || ''
55
+ @options.port = @options.port || 22
56
+ @options.pass = @options.pass || ''
57
+ @options.csv_name = @options.csv_name || @options.server
58
+
59
+ end
60
+
61
+ # prompt for and return password
62
+ def IpAuditor.get_password
63
+ if STDIN.respond_to?(:noecho)
64
+ puts "Password: "
65
+ STDIN.noecho(&:gets).chomp
66
+ else
67
+ `read -s -p "Password: " password; echo $password`.chomp
68
+ end
69
+ end
70
+
71
+ # get and parse the yaml passenger config file if available, else return false
72
+ def IpAuditor.get_passenger_file(ssh,file_name)
73
+
74
+ puts "Getting passenger information for #{file_name}..." if @options.verbose
75
+
76
+ yaml_file = ssh.exec!("find /etc/passenger.d -name '#{file_name}.yml' -exec cat {} \\;")
77
+
78
+ # if blank, return false
79
+ if yaml_file !~ /[^[:space:]]/
80
+ return false
81
+ else
82
+ begin
83
+ content = YAML.load(yaml_file)
84
+ rescue ArgumentError
85
+ return false
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ # get the rails version for the site, else return nil
92
+ def IpAuditor.get_rails_version(ssh,gemset)
93
+
94
+ puts "Getting the rails version..." if @options.verbose
95
+ rails_version = ssh.exec!("/usr/local/rvm/bin/rvm #{gemset} do gem list")[/\nrails \((.*?)\)\n/,1]
96
+
97
+ end
98
+
99
+
100
+ # get the rails information using passenger, or return false
101
+ def IpAuditor.get_rails_information(ssh,file_name)
102
+
103
+ rails_info = get_passenger_file(ssh,file_name)
104
+
105
+ # only return info if we're looking for this environment. Return false if rails info exists but
106
+ # we should ignore this environment, nil if there is no rails info
107
+ if rails_info && (rails_info['environment'][@options.environment] || @options.environment == 'all')
108
+ rails_info['rails_version'] = get_rails_version(ssh,rails_info['rvm'])
109
+ return rails_info
110
+ elsif rails_info
111
+ return false
112
+ else
113
+ return nil
114
+ end
115
+
116
+ end
117
+
118
+ # use nslookup to get the IP of a given domain
119
+ def IpAuditor.check_site_status(domain)
120
+ lookup = `nslookup #{domain}`
121
+
122
+ # strip output to IPs only
123
+ output = lookup[/Non-authoritative answer:(.*)/m,1]
124
+ ip = !output.nil? ? output[/Address: (.*)/m,1] : false
125
+
126
+ # output IP address or message saying lookup failed
127
+ if ip
128
+ return ip
129
+ else
130
+ return 'DOMAIN LOOKUP FAILED'
131
+ end
132
+ end
133
+
134
+ # get and compile information from /etc/apache2/sites-enabled
135
+ def IpAuditor.get_site_information(ssh)
136
+ data = []
137
+ current_file_path = '--'
138
+ current_file = nil
139
+ directory = ''
140
+ virtual_host = ''
141
+ domain_statuses = []
142
+
143
+ # get all relevant lines from vhost files
144
+ domain_text = ssh.exec!("grep -r '<VirtualHost\\|DocumentRoot\\|<Directory\\|ServerName\\|ServerAlias' /etc/apache2/sites-enabled")
145
+
146
+ # parse each line for relevant data
147
+ domain_text.each_line do |line|
148
+
149
+ # if we're still looking at the same file, get information
150
+ if line[current_file_path]
151
+
152
+ domain = nil
153
+
154
+ # if line contains a domain, get its status
155
+ if line[/(ServerName|ServerAlias)(.*)/]
156
+ domain = line[/(ServerName|ServerAlias)(.*)/,2].strip
157
+ domain_statuses << [domain,IpAuditor.check_site_status(domain)]
158
+
159
+ elsif line[/<VirtualHost/]
160
+ virtual_host = line[/<VirtualHost (.*)>/,1].strip.split(" ").join(", ")
161
+
162
+ elsif line[/DocumentRoot/]
163
+ directory = line[/DocumentRoot\s*?"?(.*)"?/,1]
164
+ end
165
+
166
+ else
167
+ # if this is a new file, get rails info and push into data array before resetting variables
168
+ if !(current_file.nil?)
169
+ rails_info = IpAuditor.get_rails_information(ssh,current_file)
170
+
171
+ # if it has rails info an dit's for the relavant domains
172
+ if rails_info
173
+ data << [current_file, rails_info['environment'], rails_info['cwd'], rails_info['rvm'], rails_info['rails_version'], virtual_host,domain_statuses].flatten
174
+ elsif rails_info.nil?
175
+ data << [current_file,'',directory,'','',virtual_host,domain_statuses].flatten
176
+ end
177
+ end
178
+
179
+ # reset the per-file variables
180
+ current_file_path = line[/(.*?):/,1]
181
+ current_file = current_file_path[/.*\/(.*?\.com$)/,1]
182
+ virtual_host = line[/<VirtualHost/] ? line[/<VirtualHost (.*)>/,1].strip.split(" ").join(", ") : ''
183
+ directory = ''
184
+ domain_statuses = []
185
+
186
+ end
187
+ end
188
+
189
+ data
190
+
191
+ end
192
+
193
+
194
+ def IpAuditor.write_to_csv(headers,csv_data)
195
+ require 'csv'
196
+ CSV.open("IP Audit - #{@options.csv_name}.csv", "w") do |csv|
197
+ csv << headers
198
+ csv_data.each do |line|
199
+ csv << line
200
+ end
201
+ end
202
+ end
203
+
204
+ def IpAuditor.write_to_terminal(headers,site_data)
205
+ last_header_index = headers.length - 1
206
+
207
+ site_data.each do |site|
208
+
209
+ puts "\n\n============\n#{site[0]}\n============"
210
+
211
+
212
+ (1...site.length).each do |index|
213
+ if site[index] =~ /[^[:space:]]/
214
+
215
+ if !headers[index].nil? && index < last_header_index
216
+ puts "#{headers[index]}: #{site[index]}"
217
+
218
+ elsif index == last_header_index
219
+ puts "------------\n#{headers[index]}\n------------"
220
+ puts site[index]
221
+ else
222
+ puts site[index]
223
+ end
224
+ end
225
+ end
226
+
227
+ end
228
+ end
229
+
230
+
231
+ def IpAuditor.audit
232
+
233
+ # set the options for this instance
234
+ IpAuditor.set_options
235
+
236
+ puts "Opening SSH connection to #{@options.server}..."
237
+
238
+ begin
239
+
240
+ # open an ssh connection
241
+ Net::SSH.start(@options.server, @options.user, {port: @options.port, password: @options.pass}) do |ssh|
242
+
243
+ puts "Connection opened! Finding and parsing apache/passenger files (this may take a while)..."
244
+
245
+ # find lines of interest in vhosts, assumes location is /etc/apache2/sites-enabled
246
+ domain_text = ssh.exec!("grep -r '<VirtualHost\\|DocumentRoot\\|<Directory\\|ServerName\\|ServerAlias' /etc/apache2/sites-enabled")
247
+
248
+ headers = ['Site','Environment','Directory','Gemset','Rails Version','Virtual Host','Site Statuses']
249
+
250
+ puts "Parsing the vhosts files ..." if @options.verbose
251
+ site_data = IpAuditor.get_site_information(ssh)
252
+
253
+
254
+
255
+
256
+ # output to .csv file
257
+ if !@options.csv.nil? && @options.csv
258
+
259
+ puts "Writing to .csv file..." if @options.verbose
260
+ IpAuditor.write_to_csv(headers,site_data)
261
+
262
+ puts "File saved to ./IP Audit - #{@options.csv_name}.csv!"
263
+
264
+
265
+ # output to terminal
266
+ else
267
+ IpAuditor.write_to_terminal(headers,site_data)
268
+
269
+ end
270
+
271
+ end
272
+
273
+ # catch the basic errors
274
+ rescue SocketError => e
275
+ puts "Socket Error! Is your domain name correct?"
276
+ rescue Net::SSH::AuthenticationFailed
277
+ puts "Authentication Error! Did you correctly type in your username and password?"
278
+ rescue Exception => e
279
+ puts "Error! Have you specified the correct port? Or maybe there's a problem with the code..."
280
+ end
281
+
282
+ end
283
+
284
+ end
@@ -0,0 +1,3 @@
1
+ module IpAuditor
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ip_auditor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - James Kurczodyna
8
+ - Kellen Hawley
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: net-ssh
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: 2.6.7
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 2.6.7
28
+ description: IP Auditor
29
+ email:
30
+ - james@finedesigngroup.com
31
+ executables:
32
+ - audit_ips
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - .gitignore
37
+ - Gemfile
38
+ - LICENSE
39
+ - README.md
40
+ - Rakefile
41
+ - ip_auditor.gemspec
42
+ - lib/ip_auditor.rb
43
+ - lib/ip_auditor/version.rb
44
+ - bin/audit_ips
45
+ homepage: https://github.com/jamesmkur/ip-auditor
46
+ licenses: []
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.1.3
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Audits Apache vhosts and domain IPs
68
+ test_files: []