Intelligent Proxy Steering - Office365
Introduction
This solution started back in May 2015 when I was helping a customer bypass their forward proxy servers due to the significant increase in the number of client connections after moving to Office365. Luckily they had a BIG-IP in front of their forward proxy servers load balancing the traffic and F5 had introduced a new “Proxy Mode” feature in the HTTP profile in TMOS 11.5. This allowed the BIG-IP to terminate Explicit Proxy connections, instead of passing them through to the pool members. The original solution was a simple iRule that referenced a data-group to determine if the connection should bypass the forward proxy pool or reverse proxy and load balance the connection as normal.
Original iRule:
when HTTP_PROXY_REQUEST { # Strip of the port number set hostname [lindex [split [HTTP::host] ":"] 0] # If the hostname matches a MS 0ffice365 domain, enable the Forward Proxy on BIG-IP. # BIG-IP will then perform a DNS lookup and act as a Forward Proxy bypassing the Forward Proxy # Server Pool (BlueCoat/Squid/IronPort etc..) if { [class match $hostname ends_with o365_datagroup] } { # Use a SNAT pool - recommended snatpool o365_snatpool HTTP::proxy } else { # Load balance/reverse proxy to the Forward Proxy Server Pool (BlueCoat/Squid/IronPort etc..) HTTP::proxy disable pool proxy_pool } }
As more organisations move to Office365, they have been facing similar problems with firewalls and other security devices unable to handle the volume of outbound connections as they move the SaaS world. The easiest solution may have been just to create proxy PAC file and send the traffic direct, but this would have involved allowing clients to directly route via the firewall to those IP address ranges. How secure is that?
I decided to revisit my original solution and look at a way to dynamically update the Office365 URL list. Before I started, I did a quick search on DevCentral and found that DevCentral MVP Niels van Sluis had already written an iRule to download the Microsoft Office365 IP and URL database. Perfect starting point. I’ve since made some modifications to his iRulesLX and a new TCL iRule to support the forward proxy use case.
How the solution works
- The iRuleLX is configured to pull the O365IPAddresses.xml every hour. Reformat into JSON and store in a LokiJS DB.
- The BIG-IP is configured as an Explicit Proxy in the Clients network or browser settings.
- The Virtual Server has a HTTP profile attached with the Proxy Mode set to Explicit along we a few other settings. I will go in the detail later.
- An iRule is attached that executes on the HTTP_PROXY_REQUEST event to check if the FQDN should bypass the Explicit Proxy Pool.
- If the result is not in the Cache, then a lookup is performed in the iRuleLX LokiJS DB for a result. The result is retuned to the iRule to make a decision to bypass or not.
- The bypass result is Cached in a table with a specified timeout.
- A different SNAT pool can be enabled or disabled when bypassing the Explicit Proxy Pool
Configuration
My BIG-IP is running TMOS 13.1 and the iRules Language eXtension has been licensed and provisioned. Make sure your BIG-IP has internet access to download the required Node.JS packages.
This guide also assumes you have a basic level of understanding and troubleshooting at a Local Traffic Manager (LTM) level and your BIG-IP Self IP, VLANs, Routes, etc.. are all configured and working as expected.
Before we get started
The iRule/iRuleLX for this solution can be found on DevCentral Code Share.
- Download and install my Explicit Proxy iApp
- Copy the Intelligent Proxy Steering - Office365 iRule
- Copy the Microsoft Office 365 IP Intelligence - V0.2 iRuleLX
Step 1 – Create the Explicit Proxy
1.1 Run the iApp
iApps >> Application Services >> Applications >> “Create”
Supply the following:
- Name: o365proxy
- Template: f5.explicit_proxy
Explicit Proxy Configuration
- IP Address: 10.1.20.100
- FQDN of this Proxy: o365proxy.f5.demo
- VLAN Configuration - Selected: bigip_int_vlan
- SNAT Mode: Automap
DNS Configuration
- External DNS Resolvers: 1.1.1.1
- Do you need to resolve any Internal DNS zones: Yes or No
Select “Finished" to save.
1.2 Test the forward proxy
$ curl -I https://www.f5.com --proxy http://10.1.20.100:3128
HTTP/1.1 200 Connected
HTTP/1.0 301 Moved Permanently
location: https://f5.com
Server: BigIP
Connection: Keep-Alive
Content-Length: 0
Yep, it works!
1.3 Disable Strict Updates
iApps >> Application Services >> Applications >> o365proxy
- Select the Properties tab, change the Application Service to Advanced.
- Uncheck Strict Updates
Select “Update" to save.
1.4 Add an Explicit Proxy server pool
In my test environment I have a Squid Proxy installed on a Linux host listening on port 3128.
Local Traffic >> Pools >> Pool List >> “Create”
Supply the following:
- Name: squid_proxy_3128_pool
- Node Name: squid_node
- Address: 10.1.30.105
- Service Port: 3128
Select “Add" and “Finished” to Save.
Step 2 – iRule and iRuleLX Configuration
2.1 Create a new iRulesLX workspace
Local Traffic >> iRules >> LX Workspaces >> “Create”
Supply the following:
- Name: office365_ipi_workspace
Select “Finished" to save.
You will now have any empty workspace, ready to cut/paste the TCL iRule and Node.JS code.
2.2 Add the iRule
Select “Add iRule” and supply the following:
- Name: office365_proxy_bypass_irule
- Select OK
Cut / Paste the following Intelligent Proxy Steering - Office365 iRule into the workspace editor on the right hand side. Select “Save File” when done.
2.3 Add an Extension
Select “Add extension” and supply the following:
- Name: office365_ipi_extension
- Select OK
Cut / Paste the following Microsoft Office 365 IP Intelligence - V0.2 iRuleLX and replace the default index.js. Select “Save File” when done.
2.4 Install the NPM packages
- SSH to the BIG-IP as root
- cd /var/ilx/workspaces/Common/office365_ipi_workspace/extensions/office365_ipi_extension/
- npm install xml2js https repeat lokijs ip-range-check --save
2.5 Create a new iRulesLX plugin
Local Traffic >> iRules >> LX Plugin >> “Create”
Supply the following:
- Name: office365_ipi_plugin
- From Workspace: office365_ipi_workspace
Select “Finished" to save.
2.6 Verify the Office365 XML downloaded
SSH to the BIG-IP and tail -f /var/log/ltm
The Office365 XML has been downloaded, parsed and stored in the LokiJS:
big-ip1 info sdmd[5782]: 018e0017:6: pid[9603] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] Info: update finished; 20 product records in database.
2.7 Add the iRule and the Explicit Proxy pool to the Explicit Proxy virtual server
Local Traffic >> Virtual Servers >> Virtual Server List >> o365proxy_3128_vs >> Resources
Edit the following:
- Default Pool: squid_proxy_3128_pool
Select “Update" to save.
Select “Manage…” and move office365_proxy_bypass_irule to the Enabled section.
Select “Finished" to save.
Step 3 – Test the solution
SSH to the BIG-IP and tail -f /var/log/ltm
3.1 Test a non-Office365 URL first
$ curl -I https://www.f5.com --proxy http://10.1.20.100:3128
HTTP/1.1 200 Connected
HTTP/1.0 301 Moved Permanently
location: https://f5.com
Server: BigIP
Connection: Keep-Alive
Content-Length: 0
Output from /var/log/ltm:
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58190 --> 10.1.20.100:3128
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : ## HTTP Proxy Request ##
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : CONNECT www.f5.com:443 HTTP/1.1
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Host: www.f5.com:443
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : User-Agent: curl/7.54.0
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Proxy-Connection: Keep-Alive
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.f5.com not in cache - perform DB lookup
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.f5.com - bypass: 0
big-ip1 info tmm2[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58190 (10.1.30.245:24363) --> 10.1.30.105:3128
3.2 Test the same non-Office365 URL again to confirm the cache works
Output from /var/log/ltm:
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58487 --> 10.1.20.100:3128
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : ## HTTP Proxy Request ##
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : CONNECT www.f5.com:443 HTTP/1.1
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Host: www.f5.com:443
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : User-Agent: curl/7.54.0
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Proxy-Connection: Keep-Alive
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.f5.com found in cache
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.f5.com - bypass: 0
big-ip1 info tmm1[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58487 (10.1.30.245:25112) --> 10.1.30.105:3128
3.3 Test a Office365 URL and check it bypasses the Explicit Proxy pool
$ curl -I https://www.outlook.com --proxy http://10.1.20.100:3128
HTTP/1.1 200 Connected
HTTP/1.1 301 Moved Permanently
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Location: https://outlook.live.com/
Server: Microsoft-IIS/10.0
Connection: close
Output from /var/log/ltm:
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58692 --> 10.1.20.100:3128
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : ## HTTP Proxy Request ##
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : CONNECT www.outlook.com:443 HTTP/1.1
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Host: www.outlook.com:443
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : User-Agent: curl/7.54.0
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : Proxy-Connection: Keep-Alive
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.outlook.com not in cache - perform DB lookup
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : www.outlook.com - bypass: 1
big-ip1 info tmm3[12384]: Rule /Common/office365_ipi_plugin/office365_proxy_bypass_irule : 10.10.99.31:58692 (10.1.10.245:21666) --> 40.100.144.226:443
It works!
Conclusion
By combining Microsoft Office365 IP and URL intelligence with LTM, produces a simple and effective method to steer around overloaded Forward Proxy servers without the hassle of messy proxy PAC files.
- Jayvee_359603Altostratus
Hi Brett,
Thanks for this article. I followed your guide and already integrated the iRule to the VS, but i got this error when I used it as my proxy. Any idea why this came up? I checked the LX plugin but the extension is there.
Thanks!
- SmithyCirrostratus
Hi Jayvee,
It's hard to tell what has been miss configured based on the log file above. Check the spelling of the extension within the workspace and check it has been loaded in /var/log/ltm. You should see an entry similar to this:
Aug 2 21:02:17 big-ip1 info sdmd[16742]: 018e0017:6: pid[12328] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] Info: update finished; 20 product records in database. Aug 2 21:02:17 big-ip1 info sdmd[16742]: 018e0017:6: pid[12329] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] Info: update finished; 20 product records in database. Aug 2 21:02:17 big-ip1 info sdmd[16742]: 018e0017:6: pid[12330] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] Info: update finished; 20 product records in database. Aug 2 21:02:17 big-ip1 info sdmd[16742]: 018e0017:6: pid[12327] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] Info: update finished; 20 product records in database.
Cheers, Brett
- vu_tien_cuongNimbostratus
Hi Jayvee, You can try to reload the workspace from Local Traffic ›› iRules : LX Plugins ›› office365_ipi_plugin I did try and it worked.
Rgds Cuong
- Jayvee_359603Altostratus
Hi Cuong,
Will definitely try your workaround. Thank you for the assistance!
- f5support_at_sfNimbostratus
Hi Brett,
I work with vCMP environement, the test to forward proxy doesn't work from vcmp guest but work in vcmp host. Can you help me please.
rgds, Hedi.
- f5support_at_sfNimbostratus
Hi Brett,
Sep 7 12:40:27 slot1/pr-cha-px-o365-01 err sdmd[6245]: 018e0011:3: Received sigchld for unknown pid 12402 Sep 7 12:40:27 slot1/pr-cha-px-o365-01 err sdmd[6245]: 018e0018:3: pid[12416] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] /var/sdm/plugin_store/plugins/:Common:office365_ipi_plugin_44198_17/extensions/office365_ipi_extension/index.js:150 Sep 7 12:40:27 slot1/pr-cha-px-o365-01 err sdmd[6245]: 018e0018:3: pid[12416] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] for (let url of req.urls) { Sep 7 12:40:27 slot1/pr-cha-px-o365-01 err sdmd[6245]: 018e0018:3: pid[12416] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] ^^^ Sep 7 12:40:27 slot1/pr-cha-px-o365-01 err sdmd[6245]: 018e0018:3: pid[12416] plugin[/Common/office365_ipi_plugin.office365_ipi_extension] SyntaxError: Unexpected strict mode reserved word
I have un syntax error when I load plugin from workplace. Have you an idea?
Thanks, Hedi.
- APNimbostratus
Hi Jayvee,
Did you end up finding a solution to your error? I'm getting the same thing and naming is all correct.
Thanks, Andrew
- SmithyCirrostratus
If you are getting the following error: "Could not find ILX extension office365_ipi_extension in path office365_ipi_plugin", make sure you have installed all the NPM packages.
Go back and re-run this at root:
$ cd /var/ilx/workspaces/Common/office365_ipi_workspace/extensions/office365_ipi_extension/
$ npm install xml2js https repeat lokijs ip-range-check –save
Make sure you get this: /var/ilx/workspaces/Common/office365_ipi_workspace/extensions/office365_ipi_extension ├── https@1.0.0 ├─┬ ip-range-check@0.0.2 │ └── ipaddr.js@1.8.1 ├── lokijs@1.5.5 ├── repeat@0.0.6 └── xml2js@0.4.19
Check /var/log/ltm for any runtime compile errors.
- SmithyCirrostratus
Niels van Sluis, DevCentral MVP has re-written the Microsoft Office 365 IP Intelligence iRuleLX to support the new REST API: https://github.com/nvansluis/f5.office365_endpoints_extension
- Arnaud_LemaireEmployee
with the new ilx from Niels the node module instalmation must be completed with : npm uuid install unique-concat --save