Module: Paloalto::Ngfw
- Defined in:
- lib/paloalto/ngfw.rb
Class Method Summary collapse
-
.commit(pan_address = nil, key = nil) ⇒ Object
Commits a candidate configuration.
- .create_dags(pan_address = nil, key = nil, device_name = nil, vsys_name = nil, tags_element = nil) ⇒ Object
- .create_tags(pan_address = nil, key = nil, device_name, vsys_name, tags_element) ⇒ Object
-
.curlRequest(url) ⇒ Object
Curls a request to a specified URL.
- .curlRequestWithFile(url, filename) ⇒ Object
- .generate_add_asset_xml(ip_addresses_details = []) ⇒ Object
-
.generate_dag_xml(dag_name, dag_filter, dag_tag_member) ⇒ Object
Generates PAN API formatted XML for adding a DAG.
- .generate_remove_asset_xml(ip_addresses_details = []) ⇒ Object
-
.generate_tag_xml(tag_name, tag_colour, tag_comments) ⇒ Object
Generates PAN API formatted XML for adding a TAG.
-
.log_message(message) ⇒ Object
Logs a message.
-
.login(url = nil, pan_username = nil, pan_password = nil) ⇒ Object
Performs login using URL, pan_username, pan_password.
-
.parse_device_name(device_config_xml = nil) ⇒ Object
Parse the device config and return the device name.
-
.parse_existing_dags(device_config_xml = nil) ⇒ Object
Parse the device config and return the existing DAGs.
-
.parse_existing_tags(device_config_xml = nil) ⇒ Object
Parse the device config and return the existing tags.
-
.parse_vsys_name(device_config_xml = nil) ⇒ Object
Parse the device config and return the vsys name.
-
.post_dag_file(pan_address = nil, filename = nil, key = nil) ⇒ Object
Posts a XML formatted file to PAN.
- .register_dag_devices(pan_address = nil, key = nil, dag_parsed_details = nil) ⇒ Object
- .register_devices(pan_address = nil, key = nil, asset_details = nil, site_id = nil) ⇒ Object
-
.retrieve_device_config(pan_address = nil, key = nil, device_name = nil, vsys_name = nil) ⇒ Object
Queries the Firewall for it’s configuration (device and vsys names etc) Returns Nokogiri::XML::Document.
- .unregister_devices(pan_address = nil, key = nil, asset_details = nil, site_id = nil) ⇒ Object
Class Method Details
.commit(pan_address = nil, key = nil) ⇒ Object
Commits a candidate configuration. TODO: Handle invalid command/key. Validate before commit and check commit job status.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/paloalto/ngfw.rb', line 65 def self.commit(pan_address=nil, key=nil) raise 'Need to login first.' if key.nil? raise 'Need to define a PAN URL.' if pan_address.nil? url="https://#{pan_address}/api/?type=commit&key=#{key}&cmd=<commit></commit>" response_xml = curlRequest(url) #Get job id job_id=response_xml.at_xpath('//job').child url = "https://#{pan_address}/api/?type=op&key=#{key}&cmd=<show><jobs><id>#{job_id}</id></jobs></show>" 6.times do response = curlRequest(url) complete = response.at_xpath('/response[@status="success"]/result/job/result') if complete.nil? ("Commit response <#{response}>") raise 'Error trying to parse commit response! See log for details.' end complete = complete.child ("Current commit status <#{complete}>") (complete.to_s == 'OK') ? break : sleep(20) end return response_xml end |
.create_dags(pan_address = nil, key = nil, device_name = nil, vsys_name = nil, tags_element = nil) ⇒ Object
173 174 175 176 177 |
# File 'lib/paloalto/ngfw.rb', line 173 def self.create_dags(pan_address=nil, key=nil, device_name=nil, vsys_name=nil, =nil) raise 'Options and key must be set' if pan_address.nil? || key.nil? || device_name.nil? || vsys_name.nil? || .nil? url="https://#{pan_address}/api/?type=config&action=set&key=#{key}&xpath=/config/devices/entry[@name='#{device_name}']/vsys/entry[@name='#{vsys_name}']/address-group&element=#{}" return curlRequest(url) end |
.create_tags(pan_address = nil, key = nil, device_name, vsys_name, tags_element) ⇒ Object
167 168 169 170 171 |
# File 'lib/paloalto/ngfw.rb', line 167 def self.(pan_address=nil, key=nil, device_name, vsys_name, ) raise 'Options and key must be set' if pan_address.nil? || key.nil? || device_name.nil? || vsys_name.nil? || .nil? url="https://#{pan_address}/api/?type=config&action=set&key=#{key}&xpath=/config/devices/entry[@name='#{device_name}']/vsys/entry[@name='#{vsys_name}']/tag&element=#{}" return curlRequest(url) end |
.curlRequest(url) ⇒ Object
Curls a request to a specified URL. Returns Nokogiri::XML::Document
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/paloalto/ngfw.rb', line 9 def self.curlRequest(url) raise 'Need a URL to curl a request' if url.nil? ("Sending request to URL") curlReq = Curl::Easy.new(url) curlReq.multipart_form_post = true curlReq.ssl_verify_peer = false curlReq.ssl_verify_host = false curlReq.perform ("Request response <#{curlReq.body}>") return Nokogiri::XML(curlReq.body) end |
.curlRequestWithFile(url, filename) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/paloalto/ngfw.rb', line 25 def self.curlRequestWithFile(url, filename) raise 'Need a URL and a file to curl a request' if url.nil? || filename.nil? ("Sending request to URL <#{url}> with file <#{filename}>") curlReq = Curl::Easy.new(url) curlReq.multipart_form_post = true curlReq.ssl_verify_peer = false curlReq.ssl_verify_host = false curlReq.http_post(Curl::PostField.file("fileupload",filename)) ("Request response <#{curlReq.body}>") return Nokogiri::XML(curlReq.body) end |
.generate_add_asset_xml(ip_addresses_details = []) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/paloalto/ngfw.rb', line 179 def self.generate_add_asset_xml(ip_addresses_details = []) raise 'Need asset details to generate add asset xml.' if ip_addresses_details.nil? xml = '' ip_addresses_details.each do |ip_address, | xml << "<entry ip=\"#{ip_address}\"><tag>" .split(/<(.*?)>/).each do |tag| xml << "<member>#{tag}</member>" unless tag.empty? end xml << "</tag></entry>" end #return URI.escape(xml) return xml end |
.generate_dag_xml(dag_name, dag_filter, dag_tag_member) ⇒ Object
Generates PAN API formatted XML for adding a DAG. Returns PAN API formatted XML String ready for sending
148 149 150 |
# File 'lib/paloalto/ngfw.rb', line 148 def self.generate_dag_xml(dag_name, dag_filter, dag_tag_member) return URI.escape("<entry name=\"#{dag_name}\"><dynamic><filter>#{dag_filter}</filter></dynamic><tag><member>#{dag_tag_member}</member></tag></entry>") end |
.generate_remove_asset_xml(ip_addresses_details = []) ⇒ Object
194 195 196 197 198 199 200 201 202 |
# File 'lib/paloalto/ngfw.rb', line 194 def self.generate_remove_asset_xml(ip_addresses_details = []) raise 'Need asset details to generate remove asset xml.' if ip_addresses_details.nil? xml = '' ip_addresses_details.each do |ip_address| xml << "<entry ip=\"#{ip_address}\"></entry>" end return xml end |
.generate_tag_xml(tag_name, tag_colour, tag_comments) ⇒ Object
Generates PAN API formatted XML for adding a TAG. Returns PAN API formatted XML String ready for sending
142 143 144 |
# File 'lib/paloalto/ngfw.rb', line 142 def self.generate_tag_xml(tag_name, tag_colour, tag_comments) return URI.escape("<entry name=\"#{tag_name}\"><color>#{tag_colour}</color><comments>#{tag_comments}</comments></entry>") end |
.log_message(message) ⇒ Object
Logs a message
42 43 44 45 46 47 48 49 50 |
# File 'lib/paloalto/ngfw.rb', line 42 def self.() require 'logger' logger_file = File.join(File.dirname(__FILE__), './logs/rapid7_palo_alto.log') directory = File.dirname(logger_file) FileUtils.mkdir_p(directory) unless File.directory?(directory) @log = Logger.new(logger_file, 'monthly') @log.level = Logger::INFO @log.info() end |
.login(url = nil, pan_username = nil, pan_password = nil) ⇒ Object
Performs login using URL, pan_username, pan_password. Returns Nokogiri::XML::Element TODO: Handle invalid login.
55 56 57 58 59 60 61 |
# File 'lib/paloalto/ngfw.rb', line 55 def self.login(url=nil, pan_username=nil, pan_password=nil) raise 'URL, Username and Password must be set in environment variables.' if url.nil? || pan_username.nil? || pan_password.nil? url="https://#{url}/api/?type=keygen&user=#{pan_username}&password=#{pan_password}" response_xml = curlRequest(url) return response_xml.at_xpath('//key').child end |
.parse_device_name(device_config_xml = nil) ⇒ Object
Parse the device config and return the device name. Returns device name
110 111 112 113 |
# File 'lib/paloalto/ngfw.rb', line 110 def self.parse_device_name(device_config_xml=nil) raise 'Need to pass device config to parse device name!' if device_config_xml.nil? return device_config_xml.at_xpath('/response/result/devices/entry').values.first end |
.parse_existing_dags(device_config_xml = nil) ⇒ Object
Parse the device config and return the existing DAGs. Returns an array containing existing DAGs
133 134 135 136 137 138 |
# File 'lib/paloalto/ngfw.rb', line 133 def self.parse_existing_dags(device_config_xml=nil) raise 'Need to pass device config to parse existing DAGs!' if device_config_xml.nil? existing_dags=[] device_config_xml.xpath('//address-group/entry').each {|tag| existing_dags << tag.values if tag.to_s.include?("<dynamic")} return existing_dags end |
.parse_existing_tags(device_config_xml = nil) ⇒ Object
Parse the device config and return the existing tags. Returns an array containing existing tags
124 125 126 127 128 129 |
# File 'lib/paloalto/ngfw.rb', line 124 def self.(device_config_xml=nil) raise 'Need to pass device config to parse existing tags!' if device_config_xml.nil? =[] device_config_xml.xpath('//tag/entry').each {|tag| << tag.values} return end |
.parse_vsys_name(device_config_xml = nil) ⇒ Object
Parse the device config and return the vsys name. Returns device vsys name
117 118 119 120 |
# File 'lib/paloalto/ngfw.rb', line 117 def self.parse_vsys_name(device_config_xml=nil) raise 'Need to pass device config to parse vsys name!' if device_config_xml.nil? return device_config_xml.at_xpath('/response/result/devices/entry/vsys/entry').values.first end |
.post_dag_file(pan_address = nil, filename = nil, key = nil) ⇒ Object
Posts a XML formatted file to PAN. Options is a hash with: ‘pan_address’ : PAN URL. ‘filename’ : File with XML to post. TODO: Handle error codes.
157 158 159 160 161 162 163 164 165 |
# File 'lib/paloalto/ngfw.rb', line 157 def self.post_dag_file(pan_address = nil, filename = nil, key=nil) raise 'Options and key must be set' if pan_address.nil? || key.nil? || filename.nil? c = Curl::Easy.new("https://#{pan_address}/api/?type=user-id&key=#{key}&action=set") c.multipart_form_post = true c.ssl_verify_peer = false c.ssl_verify_host = false c.http_post(Curl::PostField.file('thing[file]', filename)) end |
.register_dag_devices(pan_address = nil, key = nil, dag_parsed_details = nil) ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/paloalto/ngfw.rb', line 247 def self.register_dag_devices(pan_address=nil, key=nil, dag_parsed_details=nil) raise 'Options and key must be set' if pan_address.nil? || key.nil? || dag_parsed_details.nil? #Createa folder to hold the files folder = "./paloalto/logs" FileUtils.mkdir_p(folder) unless File.directory?(folder) add_file_list=[] #Add devices xml="<uid-message><version>1.0</version><type>update</type><payload><register>#{generate_add_asset_xml(asset_details)}</register></payload></uid-message>" add_file =File.open("#{folder}/dag_#{dag_details[0]}_add.xml", 'w') add_file.puts(xml) add_file_list << add_file.path add_file.close add_file_list.each do |filename| puts curlRequestWithFile("https://#{pan_address}/api/?type=user-id&action=set&key=#{key}&client=wget&&file-name=\"#{filename}\"", filename) end end |
.register_devices(pan_address = nil, key = nil, asset_details = nil, site_id = nil) ⇒ Object
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/paloalto/ngfw.rb', line 227 def self.register_devices(pan_address=nil, key=nil, asset_details=nil, site_id=nil) raise 'Options and key must be set' if pan_address.nil? || key.nil? || asset_details.nil? || site_id.nil? #Createa folder to hold the files folder = "./paloalto/logs" FileUtils.mkdir_p(folder) unless File.directory?(folder) add_file_list=[] #Add devices xml="<uid-message><version>1.0</version><type>update</type><payload><register>#{generate_add_asset_xml(asset_details)}</register></payload></uid-message>" add_file =File.open("#{folder}/#{site_id}_add.xml", 'w') add_file.puts(xml) add_file_list << add_file.path add_file.close add_file_list.each do |filename| curlRequestWithFile("https://#{pan_address}/api/?type=user-id&action=set&key=#{key}&client=wget&&file-name=\"#{filename}\"", filename) end end |
.retrieve_device_config(pan_address = nil, key = nil, device_name = nil, vsys_name = nil) ⇒ Object
Queries the Firewall for it’s configuration (device and vsys names etc) Returns Nokogiri::XML::Document
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/paloalto/ngfw.rb', line 91 def self.retrieve_device_config(pan_address=nil, key=nil, device_name=nil,vsys_name=nil) raise 'Need to login first.' if key.nil? raise 'Need to define a PAN URL.' if pan_address.nil? if (!device_name.nil?) if(!vsys_name.nil?) url="https://#{pan_address}/api/?type=config&action=show&key=#{key}&xpath=/config/devices/entry[@name='#{device_name}']/vsys/entry[@name='#{vsys_name}']" else url="https://#{pan_address}/api/?type=config&action=show&key=#{key}&xpath=/config/devices/entry[@name='#{device_name}']" end else url="https://#{pan_address}/api/?type=config&action=show&key=#{key}&xpath=/config/devices" end response_xml = curlRequest(url) return response_xml end |
.unregister_devices(pan_address = nil, key = nil, asset_details = nil, site_id = nil) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/paloalto/ngfw.rb', line 204 def self.unregister_devices(pan_address=nil, key=nil, asset_details=nil, site_id=nil) raise 'Options and key must be set' if pan_address.nil? || key.nil? || asset_details.nil? || site_id.nil? #Extract a list of IPs from the asset details ip_list=[] asset_details.each {|ip_addess, | ip_list << ip_addess} #Createa folder to hold the files folder = "./paloalto/logs" FileUtils.mkdir_p(folder) unless File.directory?(folder) remove_file_list=[] xml="<uid-message><version>1.0</version><type>update</type><payload><unregister>#{generate_remove_asset_xml(ip_list)}</unregister></payload></uid-message>" remove_file = File.open("#{folder}/#{site_id}_remove.xml", 'w') remove_file.puts(xml) remove_file_list << remove_file.path remove_file.close remove_file_list.each do |filename| curlRequestWithFile("https://#{pan_address}/api/?type=user-id&action=set&key=#{key}&client=wget&file-name=\"#{filename}\"", filename) end end |