api
6 TopicsIntegrate F5 SSL VPN with CheckPoint Identity Awareness
Problem this snippet solves: Goal This snippet allows you to use "identity based" rules on a CheckPoint firewall to manage the permissions for users connected by SSL VPN with F5 APM. Context Usually, when deploying SSL VPN with F5 APM, you need to use F5 ACL to manage the permissions for the VPN users defining which user or group is allowed to reach which servers or networks. These rules may be duplicates of existing rules implemented in the core firewall of the company. Since the mappings (username, assigned VPN IP) is known only by F5, it is impossible for the core firewall to apply the proper filtering based on users identity. The idea with this snippet is to be able to manage all the rules centrally on the CheckPoint firewall such as the following : User "Paul Anderson" is allowed to reach the network 10.10.1.0/24 User "Robert Schmitt" is allowed to go everywhere except 10.10.2.0/24 Active Directory group "Admins" is allowed to go everywhere on TCP ports 443 and 22 This snippet allows this kind of rules defined in a CheckPoint gateway to work also when the users are connected with F5 APM SSL VPN. How it works We are using the new CheckPoint R80 Web API to spread the association (username, assigned VPN IP) to the CheckPoint gateway. Indeed, the VPN connection follows the following steps : The user "Paul Robert" connects the F5 SSL VPN (through the Edge Client or the browser helper) The user "Paul Robert" is given an IP by F5 within the "lease pool" : let's say 192.168.1.13 F5 sends an HTTP request to the CheckPoint Identity Awareness Web API containing the association : 192.168.1.13 --> "Paul Robert" When Paul generates traffic through the VPN, this traffic is seen as coming from the source IP 192.168.1.13 from the CheckPoint firewall point of view. The firewall is able to apply the proper "identity based rules" because it knows that 192.168.1.13 is actually "Paul Robert" How to use this snippet: Requirements APM module provisioned on F5 SSL VPN service already configured with APM Import the iRule "HTTP Super Sideband Requestor" on your F5 Download here This iRule must be named "HSSR" and must be in the partition "Common" CheckPoint Gateway R80 with the blade Identity Awareness enabled Existing firewall rules based on identity CheckPoint Identity Awareness Web API By default, the WebAPI is not enabled in a CheckPoint gateway, you need to first configure it. The configuration is simply setting up which source IP are allowed to use the API and defining a secret for each client. It is done in the gateway object from the Smart Console : Here I configured my F5 as a WebAPI client with the secret "Fr38N....." Once the configuration is done, you need to install the policy on the gateway to apply the configuration. To validate the WebAPI is working, you can use the following bash command on F5 : curl -k -v --data '{ "shared-secret":"<api_secret>", "ip-address":"1.2.3.4", "user":"testuser1" }' https://<checkpoint_gw_ip/_IA_API/v1.0/add-identity This command sends the association (IP : "1.2.3.4" --> User: "testuser1"). If successful, you should get the following message from the gateway : { "ipv4-address" : "1.2.3.4", "message" : "Association sent to PDP." } F5 configuration Once you've validated the CheckPoint WebAPI is working and the F5 SSL VPN is ready, the needed configuration to integrate F5 with CheckPoint is composed of the 4 following steps : Create a new pool Pool member: CheckPoint gateway IP / port 443 Monitoring TCP Create a new local virtual server Type: standard Destination : A fake, non existing IP address (such as 1.1.1.1 for example)* Port : 443 Server SSL profile : serverssl-insecure-compatible Pool : previously created pool Source address translation: Automap (if needed) Import the iRule in this snippet with the following adaptations : Change <secret_api> with your WebAPI secret Change <vs_name> with the name of the previously created virtual server Add this iRule to your existing SSL VPN virtual server Testing After having applied the iRule, every new VPN connection should append the following line in the log file /var/log/ltm on F5 : VPN : Publishing VPN IP in CheckPoint identity - SUCCESS Moreover, all your existing "identity based rules" in CheckPoint must now work with clients connected through the F5 VPN. Notes For this configuration we made two assumptions : The "network access" object for the VPN is not doing any SNAT (SNAT Pool: none). Indeed, if we are using "Automap" for the network access, all the connected clients are hidden behind the same IP, so there is no way to identify the users outside of F5. In the iRule, we suppose the username to send to CheckPoint is present in the APM variable "session.logon.last.username". If it's not your case, you need to adapt the iRule by changing this variable name. Code : when RULE_INIT { ## Secret configured on CheckPoint to authenticate the F5 to the Web API set static::checkpoint_api_secret " " } when CLIENT_ACCEPTED { ACCESS::restrict_irule_events disable } when HTTP_REQUEST { # Thx to John Alam for this way to get assigned VPN IP # https://devcentral.f5.com/s/questions/how-do-i-record-the-ip-assigned-to-a-client-after-login if { [HTTP::uri] starts_with "/myvpn?sess=" } { after 5000 { set api_username [ACCESS::session data get session.logon.last.username] set vpn_ip [ACCESS::session data get session.assigned.clientip] set jsonBody "{ \"shared-secret\":\"$static::checkpoint_api_secret\", \"ip-address\":\"$vpn_ip\", \"user\":\"$api_username\" }" set sts [call /Common/HSSR::http_req -virt /Common/ -uri "http://checkpoint.webapi.local/_IA_API/v1.0/add-identity" -method POST -body $jsonBody -rbody apiResp] if { $apiResp contains "Association sent to PDP" } { log local0. "VPN : Publishing VPN IP in CheckPoint identity - SUCCESS" } else { log local0. "VPN ERROR : Failed to publish the VPN IP in CheckPoint Identity : $apiResp" } } } } Tested this on version: 13.02.3KViews0likes2CommentsGet all certificates and their virtual servers and SSL profiles via API calls
Problem this snippet solves: Summary F5 will give you a decent report of all your certificates and their expiration dates. However I have not found a way to pull what Virtual Server or SSL Profile the certificates are applied to (or if they are used at all). What this code does is grabs all the virtual servers, all SSL profiles, and all certificates. Then it loops through them to find where a certificate is applied. Then it returns the certificate and virtual server info. I wrote this in C# but the logic can be used anywhere as the API calls are independent of language. How to use this snippet: You will need some way to compile C#. Easiest way is to use Visual Studio. Simply add your API credentials and IP addresses and run the code through a C# compiler. Code : https://github.com/matthewwedlow/F5_Scripts/blob/master/GetCerts.cs2.3KViews1like3CommentsPwned Passwords Check
Problem this snippet solves: This snippet makes it possible to use Troy Hunt’s ‘Pwned Passwords’ API. By using this API one can check if the password being used was exposed in earlier data breaches. You can use this information to deny access to highly secure resources or to force a user to first change it’s password to one that isn’t known to be exposed to earlier data breaches. Or you could choose to just to inform a user that it would be wise to change it’s password. It’s good to note that the password itself will not be shared while using this API. This snippet uses a mathematical property called k-anonymity. For more information about k-anonymity and Troy Hunt’s ‘Pwned Passwords’ API see: https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/ This snippet also uses Patt-tom McDonnell’s hibp-checker node package. How to use this snippet: Prepare the BIG-IP Provision the BIG-IP with iRuleLX. Create LX Workspace: hibp Add iRule: hibp-irule Add Extension: hibp-extension Add LX Plugin: hibp-plugin -> From Workspace: hibp Install the node.js hibp-checker module # cd /var/ilx/workspaces/Common/hibp/extensions/hibp-extension/ # npm install hibp-checker --save /var/ilx/workspaces/Common/hibp/extensions/hibp-extension └── hibp-checker@1.0.0 # irule To make it works, you need to install the irule on the Virtual Server that publish your application with APM authentication. access profile If you already have an existing access profile, you will need to modify it and include some additionnal configuration in your VPE. If you have no access profile, you can starts building your own based on the description we provide below. Configuring the Visual Policy Editor The printscreen below is an example Visual Policy Editor on how you can use the Pnwed Password snippet. VA – Force Password Change This is a Variable Assignment agent that triggers APM to show a Change Password window. Set variable: session.logon.last.change_password to Custom Expression: expr { 1 } VA – Get Password This is a Variable Assignment agent that copies the password to a session variable that can be read by the hibp irule. Set variable: session.custom.hibp.password to Custom Expression: return [mcget -secure {session.logon.last.password}] IE - HIBP This is an irule event with the ID set to ‘hibp’. This will trigger the hibp_irule to come into action. EA – HIBP Verdict This is an Empty Action with two branches. The branch named "Not Pwned" contains the following expression : expr { [mcget -nocache {session.custom.hibp.status} ] == 0 } MB – Exposed Password This is a message box that will inform the user that it’s password was exposed in earlier data breaches and a password change is needed. The message could be something like this: The password you are using was found in %{session.custom.hibp.status} data breaches. In order to be compliant with our security policy, you must change your password. hibp_irule when ACCESS_POLICY_AGENT_EVENT { if { [ACCESS::policy agent_id ] eq "hibp" } { set password [ACCESS::session data get session.custom.hibp.password] set failonerror 0 if { $password eq "" } { log local0. "Error: no password set" ACCESS::session data set session.custom.hibp.status $failonerror return } set rpc_handle [ ILX::init hibp-plugin hibp-extension ] if {[ catch { ILX::call $rpc_handle -timeout 12000 hibpCheck $password } result ] } { log local0. "hibpCheck failed. ILX failure: $result" ACCESS::session data set session.custom.hibp.status $failonerror return } ACCESS::session data set session.custom.hibp.status [expr { $result }] } } Code : var f5 = require('f5-nodejs'); const checkPassword = require('hibp-checker'); // Create a new rpc server for listening to TCL iRule calls. var ilx = new f5.ILXServer(); ilx.addMethod('hibpCheck', function(req, res) { var password = req.params()[0]; var breachCount = checkPassword(password); breachCount.then(function(result) { return res.reply(result); }, function(err) { return res.reply(err); }); }); // Start listening for ILX::call and ILX::notify events. ilx.listen(); Tested this on version: 13.01.6KViews3likes15CommentsAutomated Nagios monitoring for F5 BigIP devices
Problem this snippet solves: Complete Nagios solution for automated monitoring of F5 BigIP using API & SNMP in Ruby. Generates Nagios config automatically. How to use this snippet: Readme here: https://github.com/anordby/plugins/blob/master/nagios/f5/README.md Ideally I would have this code linked up as Ruby code sample on these pages: https://devcentral.f5.com/wiki/iControl.System__Session.ashx https://devcentral.f5.com/wiki/iControl.System__Failover__get_failover_state.ashx https://devcentral.f5.com/wiki/iControl.System__Session__get_active_folder.ashx https://devcentral.f5.com/wiki/iControl.System__Session__set_active_folder.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__Pool.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__Pool__get_list.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__Pool__get_object_status.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__Pool__get_member_v2.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__Pool__get_member_object_status.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__VirtualServer.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__VirtualServer__get_list.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__VirtualServer__get_object_status.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__NodeAddressV2.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__NodeAddressV2__get_list.ashx https://devcentral.f5.com/wiki/iControl.LocalLB__NodeAddressV2__get_object_status.ashx Code : https://github.com/anordby/plugins/tree/master/nagios/f5405Views0likes0CommentsBig-IQ bulk licensing of Big-IP using REST API
Problem this snippet solves: Attached is a link to github which provides the user with an comprehensive example of how to license many BIGIP devices via BIGIQ CM REST API into an existing license pool. Script bulkLicensePool.pl is a standalone script installed directly in the BIGIQ shell. Suggested recommendations: 1. Create a /shared/scripts/. directory 2. scp file to BIGIQ, 3. Usage below. This automation will invoke a task to license many BIGIP's as defined in a bulk_license.csv file. This happens sequentially and is very useful when administrator's goal is to license many BIGIP devices in a programmatic manner. ** tested with perl distribution present on bigiq v5.8.8 How to use this snippet: Usage: ./bulkDiscovery -c bulk_discovery.csv Program: bulkLicensePool.pl Version: v2.00.00 ##### License multiple BIG-IP devices. -r Root credentials for every BIG-IP (such as root:default) - overrides root creds in CSV -a Admin credentials for every BIG-IP (such as admin:admin) - overrides any creds in CSV -v Verbose screen output -s Discover ASM -l Discover LTM -p Discover APM -c Path to CSV file with all BIG-IP devices - REQUIRED -u Update framework if needed -h Help -k Keep the CSV file after this finishes (not recommended if it contains creds) -q BIG-IQ admin credentials in form admin:password - REQUIRED if not using default -g access group name if needed -f Discover AFM csv format: ip, user, pw, cluster-name, framework-action, root-user, root-pw ip: ip address of the BigIP to discover. user, pw: username & password of the BigIP. Will be overridden if -a is specified on the command line. configuration csv example format 1.2.3.4, admin, pw, base-reg-key Code : https://github.com/carldubois/bigiq-cm-restapi-bulk Tested this on version: 12.0373Views0likes0CommentsAdd Pwned Passwords HTTP Headers
Problem this snippet solves: This is an example snippet which uses Troy Hunt’s ‘Pwned Passwords’ API that can be used to intercept a request passing the BIG-IP. It looks at POST requests and extracts a field called password and checks it against Troy Hunt’s service. It then adds an HTTP request header F5-Password-Pwned , with either the value Yes or No depending on whether the password being handled is found in the database or not. It also adds an additional HTTP header F5-Password-Pwned-Score . This header will hold an integer that represents the number of different date breaches in which this password was found. The POST request is then passed on to the origin server for handling, with the extra headers inserted. This could, for example, be used on a signup page to check whether the password a user is hoping to use has already been found in a leak. The server would simply look at the header. It’s good to note that the password itself will not be shared while using this API. This snippet uses a mathematical property called k-anonymity. For more information about k-anonymity and Troy Hunt’s ‘Pwned Passwords’ API see: https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/ This idea for making this example snippet was inspired by this blog article by John Graham-Cumming: https://blog.cloudflare.com/using-cloudflare-workers-to-identify-pwned-passwords/ This snippet also uses Patt-tom McDonnell’s hibp-checker node package. Examples In the example below you see that the 'topsecret' password has been found in the database. $ curl -X POST -d 'password=topsecret' http://10.23.98.35/headers.php HTTP headers received: User-Agent: curl/7.40.0 Host: 10.23.98.35 Accept: */* Content-Length: 18 Content-Type: application/x-www-form-urlencoded X-Forwarded-For: 10.23.92.2 F5-Password-Pwned: Yes F5-Password-Pwned-Score: 15279 $ The next example shows a more secure password that isn't in the database. $ curl -X POST -d 'password=llo5lFvXCEc4ZYruQmmt' http://10.23.98.35/headers.php HTTP headers received: User-Agent: curl/7.40.0 Host: 10.23.98.35 Accept: */* Content-Length: 29 Content-Type: application/x-www-form-urlencoded X-Forwarded-For: 10.23.92.2 F5-Password-Pwned: No F5-Password-Pwned-Score: 0 $ How to use this snippet: Prepare the BIG-IP Provision the BIG-IP with iRuleLX. Create LX Workspace: Local Traffic > LX Workspaces Name: workspace_hibp-headers Add Extension: extension_hibp-headers Create LX Plugin: Local Traffic > iRules > LX Plugins Name: plugin_hibp-headers From Workspace: workspace_hibp-headers Create iRules LX Profile: Local Traffic > Profiles > Other > iRules LX Name: ilx_hibp-headers Plugin: plugin_hibp-headers Install the node.js hibp-checker, querystring and utf8 module # cd /var/ilx/workspaces/Common/workspace_hibp-headers/extensions/extension_hibp-headers/ # npm install hibp-checker querystring utf8 --save /var/ilx/workspaces/Common/workspace_hibp-headers/extensions/extension_hibp-headers/ ├── hibp-checker@1.0.0 ├── querystring@0.2.0 └── utf8@3.0.0 # Add iRules LX Profile to Virtual Server Select Virtual Server: Local Traffic > Virtual Servers > some_vs Select Advanced Configuration. Select ilx_http-headers as iRule LX Profile. Code : var f5 = require('f5-nodejs'); var plugin = new f5.ILXPlugin(); var qs = require('querystring'); var utf8 = require('utf8'); var hibpChecker = require('hibp-checker'); plugin.on("connect", function(flow) { var hibpEngineEnable = 0; var body = ''; flow.client.on("requestStart", function(request) { if ((request.params.method == "POST") && (request.params.headers['content-length'] > 0) && (request.params.headers['content-length'] <= 1048576)) { hibpEngineEnable = 1; } }); flow.client.on("readable", function() { while (true) { var buffer = flow.client.read(); if (buffer !== null) { if (hibpEngineEnable == 1) { body += buffer; } else { flow.server.write(buffer); } } else { break; } } }); flow.client.on("requestComplete", function(request) { if ( hibpEngineEnable == 1 ) { var post = qs.parse(body); if( post.password ) { const password = utf8.encode(post.password); var breachCount = hibpChecker(password); breachCount.then(function(result) { if(result > 0) { request.setHeader('F5-Password-Pwned', 'Yes'); } else { request.setHeader('F5-Password-Pwned', 'No'); } request.setHeader('F5-Password-Pwned-Score', result); flow.server.write(body); request.complete(); }, function(err) { console.log('ERROR: ' + err); flow.server.write(body); request.complete(); }); } } else { request.complete(); } }); // Register callbacks for error events. Errors events must be caught. flow.client.on("error", function(errorText) { console.log("client error event: " + errorText); }); flow.server.on("error", function(errorText) { console.log("server error event: " + errorText); }); flow.on("error", function(errorText) { console.log("flow error event: " + errorText); }); }); // Start listening for new flows. var options = new f5.ILXPluginOptions(); options.handleServerData = false; options.handleServerResponse = false; plugin.start(options); Tested this on version: 13.0264Views1like0Comments