Microsoft Office 365 IP intelligence
Problem this snippet solves: This snippet adds Microsoft Office 365 IP intelligence. This snippet parses the O365IPAddresses.xml file that Microsoft supplies to help identify Microsoft URLs and IP address ranges. With this snippet you can check if an IP address belongs to Microsoft and let the BIG-IP decide to allow or deny traffic. For more info see: Office 365 URLs and IP address ranges DISCLAIMER: This code has never been tested outside a lab environment. Consider this snippet to be a proof-of-concept. How to use this snippet: Prepare BIG-IP Create LX Workspace: office365_ipi Add iRule: office365_ipi_irule Add Extension: office365_ipi_extension Add LX Plugin: office365_ipi_plugin -> From Workspace: office365_ipi Install node.js modules # cd /var/ilx/workspaces/Common/office365_ipi/extensions/office365_ipi_extension # npm install xml2js https repeat lokijs ip-range-check --save office365_ipi_irule ### ### Name : office365_ipi_irule ### Author : Niels van Sluis, (niels@van-sluis.nl) ### Version: 0.1 ### Date : 2017-07-25 ### when RULE_INIT { # set table timeout to 1 hour set static::office365_ipi_timeout 3600 set static::office365_ipi_lifetime 3600 } when CLIENT_ACCEPTED { # Valid product names are: # o365, LYO, Planner, Teams, ProPlus, OneNote, Yammer, # EXO, Identity, Office365Video, WAC, SPO, RCA, Sway, # EX-Fed, OfficeMobile, CRLs, OfficeiPad, EOP # # Use 'any' to match an IP address in all products. set productName "o365" set ipAddress [IP::client_addr] set key $productName:$ipAddress set verdict [table lookup -notouch $key] if { $verdict eq "" } { log local0. "Need to retrieve verdict via iruleslx" set rpc_handle [ILX::init office365_ipi_plugin office365_ipi_extension] if {[catch {ILX::call $rpc_handle checkProductIP $productName $ipAddress} verdict]} { log local0.error "Client - [IP::client_addr], ILX failure: $verdict" return } log local0. "The verdict for $ipAddress: $verdict"; # cache verdict table set $key $verdict $static::office365_ipi_timeout $static::office365_ipi_lifetime } # verdict is 0 (reject) or 1 (allow) if { !($verdict) } { log local0. "rejected IP address: $ipAddress" reject } } Code : /** *** Name : office365_ipi_extension *** Author : Niels van Sluis, *** Version: 0.1 *** Date : 2017-07-25 **/ 'use strict'; // Import the f5-nodejs module and others. var f5 = require('f5-nodejs'); var parseString = require('xml2js').parseString; var https = require('https'); var repeat = require('repeat'); var loki = require('lokijs'); var ipRangeCheck = require('ip-range-check'); // Create (in-memory) LokiJS database. var db = new loki('db.json'); var products = db.addCollection('products'); // Create a new rpc server for listening to TCL iRule calls. var ilx = new f5.ILXServer(); // URL to Microsoft Office 365 XML file. var url = "https://support.content.office.net/en-us/static/O365IPAddresses.xml"; // Function to get XML file and convert to JSON object. function xmlToJson(url, callback) { var req = https.get(url, function(res) { var xml = ''; res.on('data', function(chunk) { xml += chunk; }); res.on('error', function(e) { callback(e, null); }); res.on('timeout', function(e) { callback(e, null); }); res.on('end', function() { if(res.statusCode == 200) { parseString(xml, function(err, result) { callback(null, result); }); } }); }); } // Function that uses the data in the XML file to create a database // that can be used to perform IP address and URL lookups. function getOffice365() { xmlToJson(url, function(err,data) { if(err) { console.log("Error: xmlToJson failed"); return; } // if xml happens to be empty due to an error, do not continue. if(!data) { console.log("Error: No data in XML file"); return; } // Get date updated: 7/13/2017 var productsUpdated = data.products.$.updated; // Only update if version changed var versionCheck = products.findObject({'name':'any'}); if(versionCheck && versionCheck.version == productsUpdated) { console.log("Info: product version didn't changed; No update required"); return; } var allIpAdresses = []; var allUrls = []; data.products.product.forEach(function (product) { var ipAddresses = []; var urls = []; product.addresslist.forEach(function (addresslist) { if(addresslist.$.type == "IPv4" || addresslist.$.type == "IPv6") { if ( typeof addresslist.address !== 'undefined' && addresslist.address ) { addresslist.address.forEach(function (address) { ipAddresses.push(address); allIpAdresses.push(address); }); } } else if(addresslist.$.type == "URL") { if ( typeof addresslist.address !== 'undefined' && addresslist.address ) { addresslist.address.forEach(function (address) { urls.push(address); allUrls.push(address); }); } } }); var p = products.findObject({'name':product.$.name.toLowerCase()}); if(!p) { products.insert({ name: product.$.name.toLowerCase(), ipAddresses: ipAddresses, urls: urls, version: productsUpdated }); } else { p.ipAddresses = ipAddresses; p.urls = urls; p.version = productsUpdated; } }); var p = products.findObject({'name':'any'}); if(!p) { products.insert({ name: 'any', ipAddresses: allIpAdresses, urls: allUrls, version: productsUpdated }); } else { p.ipAddresses = Array.from(new Set(allIpAdresses)); p.urls = Array.from(new Set(allUrls)); p.version = productsUpdated; } console.log("Info: update finished; " + products.data.length + " product records in database."); }); } // refresh Microsoft Office 365 XML every hour repeat(getOffice365).every(1, 'hour').start.now(); // ILX::call to check if an IP address is part of Office365 ilx.addMethod('checkProductIP', function(objArgs, objResponse) { var productName = objArgs.params()[0]; var ipAddress = objArgs.params()[1]; // fail-open = true, fail-close = false var verdict = true; var req = products.findObject( { 'name':productName.toLowerCase()}); if(req) { verdict = ipRangeCheck(ipAddress, req.ipAddresses); } // return AuthnRequest to Tcl iRule objResponse.reply(verdict); }); // Start listening for ILX::call and ILX::notify events. ilx.listen(); Tested this on version: 13.0906Views0likes5CommentsF5 BIG IQ VE suddenly unreachable
Hi, I gathered qkview from our BIG IQ VE then I uploaded it on ihealth. But after a few minutes, it becomes unreachable. I don't have access with the VM application and will coordinate with the VM application team to check this. But there is a log i saw on qkview /var/log/ltm Feb 6 23:39:01 uldcp-bigiqve01 notice mcpd[6090]: 01070410:5: Removed subscription with subscriber id qkview is that somewhat related with this issue?433Views0likes1CommentHow to apply the same iRule to multiple application with AS3 declaration?
Hi, I need to apply a single dynamic iRule (already configured on the BIGIP) to multiple application. Each time that there is a new change request the playbook (ansible), in conjunction with templates, must associates that iRule with the new application. For the moment I have tried in this way: [ { "op": "add", "path": "/{{ Layer }}/TEST_{{ ServiceName }}", "value": { "class": "Application", "template": "generic", "{{ ServiceName }}": { "class": "Service_HTTP", "iRules": ["dynamic_irule"], "virtualPort": {{ virtualPort| int }}, "virtualAddresses": ["{{ IPvirtualServer }}"], "persistenceMethods": ["{{ metodoPersistenza }}"], "pool": "{{ Pools.0.nomePool }}" }, "{{ Pools.0.nomePool }}": { "class": "Pool", "monitors": {{ Pools.0.monitor }}, "members": [{ "servicePort": {{ Pools.0.membersPort|int }}, "serverAddresses": {{ Pools.0.IPmembers|list }} }] }, "dynamic_irule": { "class": "iRule", "iRule": { "url": "/Frontend/TEST_{{ ServiceName }}/dynamic_irule" } } } } ] I only need to find a precise way to declare the iRule, ansible returns this error: ["/Frontend/TEST_Test_Var_With_iRule/dynamic_irule/iRule: url /Frontend/TEST_Test_Var_With_iRule/dynamic_irule for /Frontend/TEST_Test_Var_With_iRule/dynamic_irule/iRule must include host"], "message": "declaration is invalid"} TEST_Test_Var_With_iRule is the name of my app (it's all placed in variables), can you suggest me something to address this issue? Thanks405Views0likes0Commentsdelete port i rule with specific address
Hi i use an i rule for deleting ports on application servers. But the problem is when i called the ip address:port of an application server i rule deletes the ports of application server. So i want to write an exception for the specific ip address. here is my i rule: when HTTP_RESPONSE { if {[HTTP::header exists "Location"]}{ set org_location [HTTP::header "Location"] set http_part [substr $org_location 0 "//"] if {$http_part eq "http:"}{ set remain_part [findstr $org_location $http_part 5] } elseif {$http_part eq "https:"}{ set remain_part [findstr $org_location $http_part 6] } set port_str [findstr $remain_part ":"] set port_num [substr $port_str 1 4] deletes the ports between 9080 and 9199 if {($port_num >= 9080) and ($port_num <= 9199)} { set the_port [substr $port_str 0 5] set part1 [substr $org_location 0 $the_port] set part2 [findstr $org_location $the_port 5] if {$org_location contains $the_port}{ set org_location "$part1$part2" HTTP::header replace Location $org_location} } } } I want to modify this irule so; if the url contains the ip address, i rule wouldn't delete the ports. Thanks for your help196Views0likes1CommentExplicit forward proxy for HTTP(S), FTP(S), SFTP and SOCKS
Hi folks, I wanna setup a BIG-IP as a simple explicit forwarding proxy for several services: HTTP(S) FTP(S) SFTP SOCKS There is no need for caching, URL filtering or authentication just IP Intelligence should be used. So to my understanding LTM and an IPI license are sufficienct. Moreover the encrypted protocols (HTTPS, SFTP, FTPS) shouldnt be intercepted. I have read a few implementation guides for SWG which gave me an idea what to do: First of all I think I need 4 virtual servers to use as forward proxy servers (they act as listeners for the client proxy connections): VS_Forward_8080 (for receiving and forwarding the client HTTP(S) requests) VS_Forward_2121 (for receiving and forwarding the client FTP(S) requests) VS_Forward_22 (for receiving and forwarding the client SFTP requests) VS_Forward_1080 (for receiving and forwarding the client SOCKS requests) Moreover 4 tunnels are needed: tunnel_http tunnel_ftp tunnel_sftp tunnel_socks And last but not least I need six virtual servers who finally handle the client requests (name resolution, IPI check via iRule, SNAT and routing to the Internet): VS_HTTP_80 VS_HTTPS_443 VS_FTP_21 VS_FTPS_990 VS_SFTP_22 VS_SOCKS_1080 The tunnels link the forwarding proxy severs. A high level overwiew looks like that: My questions regarding that sceanrio: Does it work in principal? Is there a better/easier way to achieve what I want? Is it possible to avoid interception of the encrypted connections? If yes, how is name resolution possible for the destination hosts? Shall Fast L4 or Standard VS be used? Many thanks for your ideas and comments!1.2KViews0likes2CommentsIP intelligence feed list for ASM/WAF?
Hi all, Just started learning about ASM and AFM via documentation. AFM seems to allow importing of external ip list into IP intelligence database, but ASM/WAF seems to use Webroot for its database. Can ASM use external feeds like AFM? OR Can ASM use another source besides webroot feed? Thanks in advance for helping the noob!1.6KViews0likes11CommentsIs there F5 ip intelligence based on domain/FQDN (domain intelligence)?
I ask this question because for example for email security an email can be blocked if the source IP and/or source domain (DNS FQDN) are in a blacklist. From what I read the F5 Ip intelligence provides only a feed for bad IP addresses but there are attackers that use DYNAMIC DNS: DATA EXFILTRATION can change the domain related ip addresses very often and this could a usefull feature if not present at the moment.Solved1KViews0likes4CommentsConfiguring VIP through Ansible playbook by leveraging F5 AS3 declarative approach
Hi,I need to configure a VIP with Ansible playbook by leveraging the AS3's declaration, my target is to eliminate jinja templates, in this way I will be able to have one playbook for all the tasks required. Is there someone that can help me? Thanks in advance564Views1like1Comment