ruby
23 TopicsMitigating Ruby YAML.load Universal RCE Deserialization Gadget with BIG-IP ASM
Recently a new YAML deserialization gadget was published that may lead to arbitrary code execution when deserialized by supplying it to Ruby'sYAML.load function as input. Prior to this new gadget it was known that calling YAML.load on user supplied input is a bad idea, but this was only relevant to applications that are based on the Ruby on Rails web framework. In this case the published gadget is universal, meaning it will only depend on the existence of classes that are shipped with the default installation of Ruby, and thus it will be able to execute code in any Ruby application that deserializes YAML documents using the YAML.load function. Mitigating the vulnerability with BIG-IP ASM BIG-IP ASM customers under any supported BIG-IP version are already protected against this vulnerability. The exploitation attempt will be detected by existing Ruby code injection attack signatures which can be found in signature sets that include the “Server Side Code Injection” attack type or “Ruby” System. Figure 1: Exploit blocked with attack signature 200004159 Additional Reading https://staaldraad.github.io/post/2019-03-02-universal-rce-ruby-yaml-load/753Views0likes0Commentsdoes iControl GTM pool create_v2 method actually work as documented?
I am trying to create a GTM pool using the create_v2 method as described here:https://devcentral.f5.com/wiki/iControl.GlobalLB__Pool__create_v2.ashx which says to pass in a type of VirtualServerID. This type includes only parameters, name-the virtual server name, and server-the name of the server object that hosts the virtual server. when i try run this method passing in the paramters described I get back this error message: Exception: Common::OperationFailed primary_error_code: 17236515 (0x01070223) secondary_error_code: 0 error_string: 01070223:3: Pool Member must contain VS IP and Pool Name this is surprising since the method documentation doesn't indicate it needs an IP address at all. i've tried this against a GTM-VE running 11.0 and 11.4.0HF4 with the same results. I'm using the ruby icontrol gem for 11.x. I tried using wsdls from 11.0 and 11.4 with no change. I'm going to go back and use the original create method, but i was hoping someone has had more success using the create_v2 method?303Views0likes3CommentsRuby Web Accelerator Policy Switcher Class
Problem this snippet solves: The WAPolicySwitcher class will connect to two BIG-IPs and allow for Web Accelerator application policies to be added and removed from a Web Accelerator. In our testing, we use this class to adjust how the web accelerator is dealing with traffic. Important: This class must be called from within a Ruby program. Configuration The following files need to be changed: Edit the bigip-config.ylm and bigip2-config.ylm files to include the addresses and credentials for the two BIG-IPs. Edit the WebAccelerator.Applications.wsdl and WebAccelerator.Applications2.wsdl files to include the correct IP addresses for the two BIG-IPs. (4th to last line in each file) How to use this snippet: Methods: deleteAppPolicy Requires the name of the application to delete. createPolicy Takes the name for the application, the local policy name, the remote policy name, and a list of domain names to use for the application. makePolicySymmetric Takes the name for the application, a single policy name, and a list of one or more host domain names to use for the application. Calls createPolicy. Will use the specified policy for both the local and remote policies. makePolicyAsymmetric Takes the name for the application, a single policy name, and a list of one or more host domain names to use for the application. Calls createPolicy. Will use the specified policy for the local policy and “Symmetric Deployment” for the remote policy. Code : # missing file291Views0likes0CommentsSSL Certificate Report
Problem this snippet solves: This is a script will generate a report of all or some of the certificates managed by a BIG-IP. It will output a multitude of information including: subject and issuers properties, serial, public key bit-length, and expiration dates. How to use this snippet: Requirements Ruby Ruby Gems F5 iControl for Ruby library (http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx) other dependencies will be installed with the iControl gem Installation Steps Install Ruby, Ruby's OpenSSL library, Ruby Gems, and the Ruby iControl libraries http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx Copy this code to /usr/local/bin and chmod +x to make the script executable Run it! ssl-certificate-report.rb -b 192.168.1.245 -u admin -p admin -v Code : #!/usr/bin/ruby require "rubygems" require "f5-icontrol" require "getoptlong" options = GetoptLong.new( [ "--bigip-address", "-b", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-user", "-u", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-pass", "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--cert-name", "-n", GetoptLong::OPTIONAL_ARGUMENT ], [ "--cert-list", "-l", GetoptLong::NO_ARGUMENT ], [ "--watermark-days", "-d", GetoptLong::OPTIONAL_ARGUMENT ], [ "--no-color", "-c", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::OPTIONAL_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) def usage puts $0 + " -b -u " puts " -b (--bigip-address) BIG-IP management-accessible address" puts " -u (--bigip-user) BIG-IP username" puts " -p (--bigip-pass) BIG-IP password (will prompt if left blank" puts " -n (--cert-name) name of certificate to display (display all by default)" puts " -l (--cert-list) list of certificates managed by the BIG-IP" puts " -d (--watermark-days) certificates expiring inside this number of days will" puts " be marked as \"expiring soon\", default is 30 days" puts " -c (--no-color) disable color coding for the shell (useful if piping" puts " output to less or are using Windows)" puts " -v (--verbose) show all certificate information (brief by default)" puts " -h (--help) shows this help/usage dialog" exit end # initial parameter values bigip_address = '' bigip_user = '' bigip_pass = '' cert_name = '' cert_list = false watermark_days = 30 verbose = false # the color_code variable must be global to be read within the format_text method $color_code = true options.each do |option, arg| case option when "--bigip-address" bigip_address = arg when "--bigip-user" bigip_user = arg when "--bigip-pass" bigip_pass = arg when "--cert-name" cert_name = arg when "--cert-list" cert_list = true when "--watermark-days" arg = arg.to_i watermark_days = arg when "--no-color" $color_code = false when "--verbose" verbose = true when "--help" usage end end usage if bigip_address.empty? or bigip_user.empty? if bigip_pass.empty? puts "Please enter the BIG-IPs password..." print "Password: " system("stty", "-echo") bigip_pass = gets.chomp system("stty", "echo") end bigip = F5::IControl.new(bigip_address, bigip_user, bigip_pass, ["Management.KeyCertificate"]).get_interfaces def format_text(text, code) if $color_code "#{code}#{text}\e[00m" else text end end def red(text) format_text(text, "\e[01;31m") end def green(text) format_text(text, "\e[01;32m") end def yellow(text) format_text(text, "\e[01;33m") end def bold(text) format_text(text, "\e[1m") end def underline(text) format_text(text, "\e[4m") end def bold_underline(text) format_text(text, "\e[4;1m") end def cert_validity_label(expire_text) case expire_text when "VTYPE_CERTIFICATE_VALID" green("valid") when "VTYPE_CERTIFICATE_EXPIRED" red("expired") when "VTYPE_CERTIFICATE_WILL_EXPIRE" yellow("expiring soon") when "VTYPE_CERTIFICATE_INVALID" red("invalid") else yellow("unknown") end end def key_strength_label(key_length) case(key_length) when 0..1023 red("low") when 1024..2047 yellow("medium") else green("strong") end end def key_type_label(key_type) case key_type when "KTYPE_RSA_PRIVATE" "RSA private key" when "KTYPE_RSA_PUBLIC" "RSA public key" when "KTYPE_DSA_PRIVATE" "DSA private key" when "KTYPE_DSA_PUBLIC" "DSA public key" else "Unkown" end end # collect certificate properties certs = {} bigip["Management.KeyCertificate"].get_certificate_list("MANAGEMENT_MODE_DEFAULT").each do |cert| id = cert['certificate']['cert_info']['id'] certs[id] = {} # general properties certs[id]['expires'] = Time.at(cert['certificate']['expiration_date']).strftime("%b %e, %Y") certs[id]['version'] = cert['certificate']['version'] certs[id]['serial'] = cert['certificate']['serial_number'] certs[id]['serial'] = 'unavailable' if certs[id]['serial'].empty? # subject and issuers properties ['subject', 'issuer'].each do |x| certs[id][x] = {} ['common_name', 'organization_name', 'division_name', 'locality_name', 'state_name', 'country_name'].each do |y| certs[id][x][y] = cert['certificate'][x][y] end end certs[id]['key'] = {} certs[id]['key']['length'] = cert['certificate']['bit_length'] certs[id]['key']['length_text'] = key_strength_label(cert['certificate']['bit_length'].to_i) certs[id]['key']['type'] = key_type_label(cert['certificate']['key_type']) end # collect certificate validity information validity_states = bigip["Management.KeyCertificate"].certificate_check_validity('MANAGEMENT_MODE_DEFAULT', certs.keys, ([watermark_days] * certs.keys.size)) x = 0 certs.each do |id,cert| cert['expire_text'] = cert_validity_label(validity_states[x]) x += 1 end # display BIG-IP information puts bold("\nConnected to BIG-IP at #{bigip_address} with user '#{bigip_user}'...") # if user only wants list, display it and exit if cert_list puts puts underline("Available certificates\n") puts certs.keys.sort.collect { |id| id = " " + id } puts exit end unless cert_name.empty? if certs.key? cert_name certs = { cert_name => certs[cert_name] } else puts "Error: could not locate a certificate by that name, try '-l' for a list" exit end end puts bold_underline(" " * 80) puts certs.keys.sort.each do |id| puts underline("General Properties") puts "\t" + bold("Name: ") + id puts "\t" + bold("Certificate Subject(s): ") + certs[id]['subject']['common_name'] + ", " + certs[id]['subject']['organization_name'] + "\n\n" puts underline("Certificate Properties") puts "\t" + bold("Expires: \t") + certs[id]['expires'] + " (" + certs[id]['expire_text'] + ")" puts "\t" + bold("Version: \t") + certs[id]['version'].to_s puts "\t" + bold("Serial: \t") + certs[id]['serial'] if verbose ['subject', 'issuer'].each do |section| puts "\t" + bold(section.capitalize) + ":" subsections = { 'Common Name' => 'common_name', \ 'Organization' => 'organization_name', \ 'Division' => 'division_name', \ 'Locality' => 'locality_name', \ 'State (Prov)' => 'state_name', \ 'Country' => 'country_name' } \ subsections.each do |key, subsection| puts "\t\t\t" + key + ": \t" + certs[id][section][subsection] unless certs[id][section][subsection].empty? end end puts end puts underline("Public Key Properties") puts "\t" + bold("Key Type: ") + certs[id]['key']['type'] puts "\t" + bold("Size: ") + certs[id]['key']['length'].to_s + " (" + certs[id]['key']['length_text'] + ")" puts puts bold_underline(" " * 80) puts end288Views0likes0CommentsRuby VIP Maker
Problem this snippet solves: This is a utility created for the purpose of producing large numbers of virtual servers, including pools. This was created to make our testing efforts easier. Configuration For MakeVips and DeleteVips to work, the following files need the following edits: ltmbigip-config.yml needs to be updated with the correct IP address of the LTM and the username and password. LocalLB.Pool.wsdl needs to have the IP address on the second to last line of the file updated to the correct IP of the LTM LocalLB.VirtualServer.wsdl needs to have the IP address on the second to last line of the file updated to the correct IP of the LTM How to use this snippet: Tool Usage Add Virtual Servers MakeVips.rb namePrefix numberOfVIPs vipStartIP port ipsPerPool poolStartIP This will create numberOfVIPs virtual servers on the BIG-IP. These virtual servers will have names that begin with namePrefix. Each VIP will answer on its own IP address beginning with vipStartIP and counting up. The IP addresses roll over at their boundaries. Every VIP will answer on the specified port. Every VIP will have its own unique pool containing ipsPerPool number of IP addresses as members. These nodes begin at poolStartIP IP address and count up just as the VIP IP addresses do. There will be numberOfVips multiplied by ipsPerPool number of nodes created by this utility. Delete Virtual Servers DeleteVips.rb namePrefix numberOfVIPs This will delete the first numberOfVIPs virtual servers from the BIG-IP beginning with namePrefix, along with the pools associated with those virtual servers, assuming that they were created with the same utility as described above.286Views0likes0CommentsiControlREST: Ruby: To Output a List of Virtual Servers and their Associated Pools and Pool Members.
Problem this snippet solves: This script enumerates virtual servers and their associated pools and pool members and their status, each virtual server on a line of its own in the ";' delimited format. Essentially, the code shows a way to parse the 'ltm/virtual' object and get the information required. It had a specific need to address when it was written, and it can be modified to suit other similar requirements. How to use this snippet: This code has been tested with Ruby 2.3.1p112. Code : #!/usr/local/bin/ruby -w # # This script enumerates virtual servers and their associated pools and # pool members and their status, each virtual server on a line of its own # in the ";' delimited format. # #------------------------------------------------------------------------- require 'rubygems' require 'rest-client' require 'json' # define program-wide variables BIGIP_ADDRESS = 'mgmt_IP_addr' BIGIP_USER = 'admin' BIGIP_PASS = 'admin' SLEEP_TIME = 20 bigip = RestClient::Resource.new( "https://#{BIGIP_ADDRESS}/mgmt/tm/", :user => BIGIP_USER, :password => BIGIP_PASS, :headers => { :content_type => 'application/json' }, :verify_ssl => false ) # Get virtual servers: vservers = bigip['ltm/virtual'].get vservers_obj = JSON.parse(vservers) # Get pools: pools = bigip['ltm/pool?expandSubcollections=true'].get pools_obj = JSON.parse(pools) # Output header: puts "Virtual Server Name;Virtual Server Destination;Virtual Server Partition;Pool Name;Pool LB Mode;Pool Member Name (address)(state)" $output = '' # Process data: vservers_obj.each do |vserver_obj| vserver_obj.each do |vserver_obj_element| if vserver_obj_element.is_a?(Array) vserver_obj_element.each do |vserver_obj_element_property| if vserver_obj_element_property.is_a?(Hash) if vserver_obj_element_property.has_key?("name") vs_name = vserver_obj_element_property.fetch("name") $output = $output + vs_name + ';' end if vserver_obj_element_property.has_key?("destination") vs_destination = vserver_obj_element_property.fetch("destination") $output = $output + vs_destination + ';' end if vserver_obj_element_property.has_key?("partition") vs_partition = vserver_obj_element_property.fetch("partition") $output = $output + vs_partition + ';' end if vserver_obj_element_property.has_key?("pool") pool_name_from_vs = vserver_obj_element_property.fetch("pool") pools_obj.each_pair do |key, val| next if key == "kind" next if key == "selfLink" for x in 0..(val.length-1) if val[x]["fullPath"] == pool_name_from_vs $output = $output + val[x]["name"] + ";" + val[x]["loadBalancingMode"] if val[x].has_key?("membersReference") val[x]["membersReference"].each_pair do |mrefkey,mrefval| next if mrefkey == "link" next if mrefkey == "isSubcollection" for i in 0..(mrefval.length-1) if i == 0 $output = $output + ";" + mrefval[i]["name"] + "(" + mrefval[i]["address"] + ")(" + mrefval[i]["state"] + ")," else $output = $output + mrefval[i]["name"] + "(" + mrefval[i]["address"] + ")(" + mrefval[i]["state"] + ")," end if i == mrefval.length-1 $output.chop! $output += "\n" end end end else $output = $output + ";;\n" end break end end end else $output = $output + ";;\n" end end end end end end puts $output #---END--- Tested this on version: 11.6265Views0likes0CommentsRuby iControl throwing non-descript soap fault on NodeAddressV2.create
So I'm receiving a soap fault when I try and create a node. If anyone could help me out with a diagnosis I'd really appreciate it!! bigip = F5::IControl.new('*******', '*******', '*******', ['LocalLB.Pool', 'LocalLB.NodeAddressV2']) interfaces = bigip.get_interfaces interfaces['LocalLB.NodeAddressV2'].create ['test'], ['test.test.com'], [0] Throws the error: SOAP::FaultError: Exception caught in LocalLB::urn:iControl:LocalLB/NodeAddressV2::create() Common::InvalidArgument249Views0likes1CommentSSLKeyAndCSRCreator
Problem this snippet solves: This is a script will generate a private key and output a certificate signing request. This is all done from a workstation command line and communicated to the BIG-IP via iControl. How to use this snippet: Requirements Ruby Ruby Gems F5 iControl for Ruby library other dependencies will be installed with the iControl gem Installation Steps Install Ruby, Ruby's ""OpenSSL"" library, Ruby Gems, and the Ruby iControl libraries Getting-Started-With-Ruby-and-iControl.aspx Copy this code to /usr/local/bin and chmod +x to make the script executable Run it! minimal options: ssl-key-and-csr-creator.rb -b 192.168.1.245 -u admin -i test-key-001 full options: ssl-key-and-csr-creator.rb -b 192.168.1.245 -u admin -p admin -i test-key-001 -t RSA -l 4096 -s fips --common-name=www.example.com --country=US --state=Washington --locality=Seattle --organization="Example Company, Inc." --division="Information Technology" -o /my-ssl-directory/ -k -c Code : #!/usr/bin/ruby require "rubygems" require "f5-icontrol" require "getoptlong" options = GetoptLong.new( [ "--bigip-address", "-b", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-user", "-u", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-pass", "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--key-id", "-i", GetoptLong::REQUIRED_ARGUMENT ], [ "--key-type", "-t", GetoptLong::OPTIONAL_ARGUMENT ], [ "--key-bit-length", "-l", GetoptLong::OPTIONAL_ARGUMENT ], [ "--key-security", "-s", GetoptLong::OPTIONAL_ARGUMENT ], [ "--common-name", GetoptLong::OPTIONAL_ARGUMENT ], [ "--country", GetoptLong::OPTIONAL_ARGUMENT ], [ "--state", GetoptLong::OPTIONAL_ARGUMENT ], [ "--locality", GetoptLong::OPTIONAL_ARGUMENT ], [ "--organization", GetoptLong::OPTIONAL_ARGUMENT ], [ "--division", GetoptLong::OPTIONAL_ARGUMENT ], [ "--output-dir", "-o", GetoptLong::OPTIONAL_ARGUMENT ], [ "--key-output", "-k", GetoptLong::NO_ARGUMENT ], [ "--csr-output", "-c", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) def usage puts $0 + " -b -u -i " puts puts "BIG-IP connection parameters" puts "-" * 20 puts " -b (--bigip-address) BIG-IP management-accessible address" puts " -u (--bigip-user) BIG-IP username" puts " -p (--bigip-pass) BIG-IP password (will prompt if left blank" puts puts "Private key parameters" puts "-" * 20 puts " -i (--key-id) key ID: must be unique and should be indicative of the purpose (required)" puts " -t (--key-type) key type: [RSA|DSA] (default is 'RSA')" puts " -l (--key-bit-length) key bit length: should be a minimum of 1024-bit (default is 2048; most CAs won't sign weaker keys)" puts " -s (--key-security) key security: [normal|fips|password] (default is 'normal' with no passphrase)" puts puts "X.509 data parameters (if blank, you'll be prompted for the answers)" puts "-" * 20 puts " (--common-name) common name: FQDN for virtual server (www.example.com)" puts " (--country) country: two letter country abbreviation (US, CN, etc.)" puts " (--state) state: two letter state abbreviation (WA, OR, CA, etc.)" puts " (--locality) locality: locality or city name (Seattle, Portland, etc.)" puts " (--organization) organization: organization or company name (F5 Networks, Company XYZ, etc.)" puts " (--division) division: department or division name (IT, HR, Finance, etc.)" puts puts "Output options" puts "-" * 20 puts " -o (--output-dir) CSR/key output directory: location to output private key and CSR files (defaults to current working directory)" puts " -k (--key-output) key output: save private key to a local file (saved as key_id.key)" puts " -c (--csr-output) CSR output: save certificate signing request to a local file (saved as key_id.csr)" puts puts "Help and usage" puts "-" * 20 puts " -h (--help) shows this help/usage dialog" puts exit end # set STDOUT buffer to synchronous STDOUT.sync = true # global variables KEY_TYPES = { "RSA" => "KTYPE_RSA_PRIVATE", "DSA" => "KTYPE_DSA_PRIVATE" } KEY_SECURITIES = { "normal" => "STYPE_NORMAL", "fips" => "STYPE_FIPS", "password" => "STYPE_PASSWORD" } # initial parameter values overwrite_key = false # key/CSR default output file values key_output = false csr_output = false output_dir = Dir.pwd # BIG-IP connection parameters bigip = {} bigip['address'] = '' bigip['user'] = '' bigip['pass'] = '' # private key parameters key_data = {} key_data['id'] = '' key_data['key_type'] = KEY_TYPES["RSA"] key_data['bit_length'] = 2048 key_data['security'] = KEY_SECURITIES["normal"] # X.509 data parameters x509_data = {} x509_data['common_name'] = '' x509_data['country_name'] = '' x509_data['state_name'] = '' x509_data['locality_name'] = '' x509_data['organization_name'] = '' x509_data['division_name'] = '' # loop through command line options options.each do |option, arg| case option when "--bigip-address" bigip['address'] = arg when "--bigip-user" bigip['user'] = arg when "--bigip-pass" bigip['pass'] = arg when "--key-id" key_data['id'] = arg when "--key-type" if KEY_TYPES.keys.include? arg.upcase key_data['key_type'] = KEY_TYPES[arg.upcase] else puts "Error: Invalid key type. Exiting." exit 1 end when "--key-bit-length" key_data['bit_length'] = arg.to_i when "--key-security" if KEY_SECURITIES.keys.include? arg.downcase key_data['security'] = KEY_SECURITIES[arg.downcase] else puts "Error: Invalid key security type. Exiting." exit 1 end when "--common-name" x509_data['common_name'] = arg when "--country" if arg =~ /[a-z]{2}/i x509_data['country_name'] = arg.upcase else puts "Error: Use exactly two letters for the country code. Exiting." exit 1 end when "--state" x509_data['state_name'] = arg when "--locality" x509_data['locality_name'] = arg when "--organization" x509_data['organization_name'] = arg when "--division" x509_data['division_name'] = arg when "--output-dir" if File.directory? arg output_dir = arg else puts "Error: Invalid directory for output. Exiting." end when "--key-output" key_output = true when "--csr-output" csr_output = true when "--help" usage end end # we need at least the BIG-IP's address, user, and a key ID to proceed usage if bigip['address'].empty? or bigip['user'].empty? or key_data['id'].empty? if bigip['pass'].empty? puts "Please enter the BIG-IPs password..." print "Password: " system("stty", "-echo") bigip['pass'] = gets.chomp system("stty", "echo") puts end # set up connection to BIG-IP and Management.KeyCertificate interface bigip = F5::IControl.new(bigip['address'], bigip['user'], bigip['pass'], ["Management.KeyCertificate"]).get_interfaces #grab a list of existing keys and confirm overwrite if a conflict exists existing_keys = bigip["Management.KeyCertificate"].get_key_list('MANAGEMENT_MODE_DEFAULT').collect { |key| key["key_info"]["id"] } if existing_keys.include? key_data['id'] print "A key with an ID of '#{key_data['id']}' already exists. Overwrite it? (yes/no) " answer = gets.chomp if answer !~ /^yes$/i puts "Will not overwrite existing key. Exiting." exit else overwrite_key = true end end # time to play 20 questions with the X.509 data if x509_data.values.delete_if { |value| !value.empty? }.size > 0 puts "Please fill in the following X.509 data parameters..." end x509_data.sort.each do |key, value| if value.empty? print key.capitalize.gsub('_', ' ') + "? " x509_data[key] = gets.chomp end end bigip["Management.KeyCertificate"].key_generate('MANAGEMENT_MODE_DEFAULT', [key_data], [x509_data], true, overwrite_key) # write private key to local file if specified by user if key_output key_output_file = output_dir + "/" + key_data['id'] + ".key" key = bigip["Management.KeyCertificate"].key_export_to_pem('MANAGEMENT_MODE_DEFAULT', [key_data['id']])[0] File.open(key_output_file, 'w') { |file| file.write(key) } end # display subject information for CSR as well as the CSR puts "Certificate Request" puts "-" * 20 puts "Subject: C=#{x509_data['country_name']}, ST=#{x509_data['state_name']}, L=#{x509_data['locality_name']}, O=#{x509_data['organization_name']}, OU=#{x509_data['division_name']}, CN=#{x509_data['common_name']}" csr = bigip["Management.KeyCertificate"].certificate_request_export_to_pem('MANAGEMENT_MODE_DEFAULT', [key_data['id']]) # write csr key to local file if specified by user if csr_output csr_output_file = output_dir + "/" + key_data['id'] + ".csr" File.open(csr_output_file, 'w') { |file| file.write(csr) } end puts puts csr248Views0likes0CommentsPool Member Update By A Record
Problem this snippet solves: This is a script will do an A record lookup for a hostname and populate the specified pool with all available A records. The script will not change the existing pool member(s) or modify their connections if the next A record matches. Only changes to the associated A record will result in changes to the pool members. The script will error out and print a help message if any of the following conditions are met: 6 arguments are not provided (BIG-IP address, BIG-IP user, BIG-IP password, A record query, pool name, pool member port), the port is an invalid integer (valid ports: 1-65535), BIG-IP connection cannot be made, the pool does not exist, or no A record returned. How to use this snippet: Requirements Ruby Ruby Gems F5 iControl for Ruby library (https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx) other dependencies will be installed with the iControl gem Installation Steps Install Ruby, Ruby's OpenSSL library, Ruby Gems, and the Ruby iControl libraries https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx Copy this code to /usr/local/bin and chmod +x to make the script executable Run it! change-pool-member-to-a-record-result <BIG-IP address> <BIG-IP user> <BIG-IP password> < A record query> < pool name> < pool member port> Code : #!/usr/bin/ruby require 'rubygems' require 'f5-icontrol' require 'resolv' def usage puts $0 + ' ' exit end # make sure enough arguments have been provided usage if $*.size < 6 $*[5] = $*[5].to_i # create iControl interface bigip = F5::IControl.new($*[0], $*[1], $*[2], ['LocalLB.Pool']).get_interfaces # test iControl connectivity begin bigip['LocalLB.Pool'].get_version rescue puts "Error: could not establish a connection to the BIG-IP. Check the hostname, user, and password." exit 1 end # ensure that the pool member port is an integer and in the valid range unless $*[5].between?(1, 65535) puts "Error: please provide a valid integer for the pool member port." exit 1 end # make sure that the provided pool exists unless bigip['LocalLB.Pool'].get_list.include? $*[4] puts "Error: could not locate #{$*[4]} pool. If using version 11, make sure to prepend the folder, e.g. /Common/my_pool" exit 1 end # attempt to resolve the hostname resources = Resolv::DNS.new.getresources($*[3], Resolv::DNS::Resource::IN::A) # check if we received a response, exit on empty responses if resources.size == 0 puts "Error: could not resolve #{$*[3]}. Please verify the name, ensure that it is fully qualified, and verify setting in /etc/resolv.conf" exit 1 end # grab a list of current pool members old_members = bigip['LocalLB.Pool'].get_member([ $*[4] ])[0].collect do |member| { 'address' => member.address, 'port' => member.port } end # create an array to hold new member records and new_members = [] # add each of the returned a records to the pool resources.each do |record| new_member = { 'address' => record.address.to_s, 'port' => $*[5] } if old_members.include? new_member old_members.delete new_member puts "Info: preserving pool member: #{new_member['address']}:#{new_member['port']}" else new_members << new_member end end # delete old members that are no longer used old_members.each do |member| puts "Info: removing pool member: #{member['address']}:#{member['port']}" end bigip['LocalLB.Pool'].remove_member([ $*[4] ], [ old_members ]) # add new members to pool new_members.each do |member| puts "Info: adding new pool member: #{member['address']}:#{member['port']}" end bigip['LocalLB.Pool'].add_member([ $*[4] ], [ new_members ])235Views0likes0CommentsInstallSoftwareImage
Problem this snippet solves: This script will transfer the BIG-IP software image to the target system and execute the installation. How to use this snippet: Requirements Ruby Ruby Gems F5 iControl for Ruby library other dependencies will be installed with the iControl gem Installation Steps Install Ruby, Ruby's ""OpenSSL"" library, Ruby Gems, and the Ruby iControl libraries http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx Install Net::SCP and progressbar Ruby Gems ""gem install -r net-scp progressbar"" Copy this code to /usr/local/bin and chmod +x to make the script executable Run it! minimal options: ""install-bigip-image.rb -b 192.168.1.245 -f BIGIP-10.2.1.297.0.iso -h HD1.1"" full options: ""install-bigip-image.rb -b 192.168.1.245 -u admin -s root -p admin --bigip-shell-pass default -f BIGIP-10.2.1.297.0.iso -h HD1.1"" Code : #!/usr/bin/ruby require "rubygems" require "f5-icontrol" require "net/scp" require "progressbar" require "getoptlong" STDOUT.sync options = GetoptLong.new( [ "--bigip-address", "-b", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-web-user", "-u", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-web-pass", "-p", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-shell-user", "-s", GetoptLong::REQUIRED_ARGUMENT ], [ "--bigip-shell-pass", GetoptLong::REQUIRED_ARGUMENT ], [ "--install-image", "-f", GetoptLong::REQUIRED_ARGUMENT ], [ "--hd-slot", "-h", GetoptLong::REQUIRED_ARGUMENT ], [ "--skip-upload", "-x", GetoptLong::NO_ARGUMENT ], [ "--help", GetoptLong::NO_ARGUMENT ] ) def usage puts $0 + " -b -u " puts " -b (--bigip-address) BIG-IP management-accessible address" puts " -u (--bigip-web-user) BIG-IP web interface username (must have administrator privileges; defaults to 'admin')" puts " -p (--bigip-web-pass) BIG-IP web interface user password (will prompt if not specified)" puts " -s (--bigip-shell-user) BIG-IP Secure Shell (SSH) username (must have root privileges; defaults to 'root')" puts " (--bigip-shell-pass) BIG-IP Secure Shell user password (will prompt if not specified)" puts " -f (--install-image) path of ISO image for BIG-IP install image" puts " -x (--skip-upload) skip uploading of ISO image (already on BIG-IP in /shared/images)" puts " -h (--hd-slot) installation slot (HD slot) to install to" puts " (--help) shows this help/usage dialog" exit end # initial command argument values bigip_address = '' bigip_web_user = 'admin' bigip_web_pass = '' bigip_shell_user = 'root' bigip_shell_pass = '' install_image = '' skip_upload = false hd_slot = '' verbose = false # the color_code variable must be global to be read within the format_text method options.each do |option, arg| case option when "--bigip-address" bigip_address = arg when "--bigip-web-user" bigip_web_user = arg when "--bigip-web-pass" bigip_web_pass = arg when "--bigip-shell-user" bigip_shell_user = arg when "--bigip-shell-pass" bigip_shell_pass = arg when "--install-image" if File.exists? arg install_image = arg else puts "ERROR: install image does not exist - #{arg}" exit end when "--skip-upload" skip_upload = true when "--hd-slot" hd_slot = arg when "--help" usage end end usage if bigip_address.empty? or install_image.empty? or hd_slot.empty? # prompt for web interface and shell users' password(s) if not provided if bigip_web_pass.empty? print "Web user's (#{bigip_web_user}) password: " system("stty", "-echo") bigip_web_pass = gets.chomp system("stty", "echo") puts end unless skip_upload if bigip_shell_pass.empty? print "Shell user's (#{bigip_shell_user}) password: " system("stty", "-echo") bigip_shell_pass = gets.chomp system("stty", "echo") puts end puts "Copying #{File.basename(install_image)} to #{bigip_address}..." Net::SCP.start(bigip_address, bigip_shell_user, :password => bigip_shell_pass.chomp, :auth_methods =>["keyboard-interactive" ] ) do |scp| # upload a file to a remote server pbar = ProgressBar.new(File.basename(install_image), 100) scp.upload!(install_image, "/shared/images/.") do |chunk, image, sent, total| pbar.set((sent*100)/total) end pbar.finish end end puts "Install image details" puts "-" * 20 install_image_details = install_image.scan /(\w+)-(\d+\.\d+\.\d+)\.(\d+.\d+)/ puts "Product: #{install_image_details[0][0]}" puts "Version: #{install_image_details[0][1]}" puts "Build: #{install_image_details[0][2]}" bigip = F5::IControl.new(bigip_address, bigip_web_user, bigip_web_pass, ["System.SoftwareManagement", "System.Failover"]).get_interfaces answer = '' if bigip["System.Failover"].get_failover_state == "FAILOVER_STATE_ACTIVE" question = "\nWARNING: you are installing on an ACTIVE unit! Are you sure you want to proceed? (no/yes) " else question = "\nAre you sure you want to proceed with installation of this image? (no/yes) " end print question STDOUT.flush answer = gets.chomp exit unless answer == "yes" puts "\nInstalling #{File.basename(install_image)} on #{bigip_address}...\n" bigip["System.SoftwareManagement"].install_software_image(hd_slot, install_image_details[0][0], install_image_details[0][1], install_image_details[0][2]) puts "#{install_image_details[0][0]} version #{install_image_details[0][1]}, build #{install_image_details[0][2]} has been successfully installed on #{bigip_address}..."232Views0likes0Comments