iRules LX – AFM/APM Dynamic Firewall Rules

One of the iRules LX projects I’ve been working on is the ability to dynamically open firewall rules based upon a user’s APM Access Session.  In this example the user is external trying to access internal server resources but is blocked by AFM’s default firewall policies.  The user then logs into an APM policy and upon successful login AFM allows that external user access to internal resources.  See the video below for a demo:

iRules do not have direct access to control plane settings.  So prior to TMOS 12.1 this wasn’t easily doable without some serious iRule foo around sideband connections. However, with the introduction of iRules LX we can leverage Node.js to help us interact with the control plane via API calls.

So how does it work?

You still leverate iRules in iRules LX but a new set of commands allow you to pass data from TMM (data plane) to Node.js (control plane) and process that data via javascript – more information in the Getting Started With iRules LX series on DevCentral.

So what does this look like?

Your iRules do not change much except for the addition of the ILX commands:

  • ILX::init – invokes the specified node methods
  • ILX::call – establishes a communication path from an iRules to the node process
  • ILX::notify  – sends a message to the specified node method but does not wait for a response

As an example I’ve included the  iRule used in the AFM/APM dynamic firewall rule project below:


#
# AFM/ASM dynamic address list iRulesLX RPC.
#
# add the address to the address list
when ACCESS_POLICY_COMPLETED {
set ilx_handle [ILX::init "dynamic_address_list_plugin" "dynamic_address_list"]
# set IP address
set ip_address [ACCESS::session data get session.user.clientip]
if {[info exists ip_address]} {
# create a random secret
if {[catch {set res [ILX::call $ilx_handle "addAddress" $ip_address]} result]} {
log local0.error "Client – [IP::client_addr], ILX failure: $result"
return
}
} else {
log local0.error "Can not add address list, client IP not defined"
return
}
}
# remove the address from the address list
when ACCESS_SESSION_CLOSED {
set ilx_handle [ILX::init "dynamic_address_list_plugin" "dynamic_address_list"]
# set IP address
set ip_address [ACCESS::session data get session.user.clientip]
if {[info exists ip_address]} {
# create a random secret
if {[catch {set res [ILX::call $ilx_handle "deleteAddress" $ip_address]} result]} {
log local0.error "Client – $ip_address, ILX failure: $result"
return
}
} else {
log local0.error "Can not delete address list, client IP not defined"
return
}
}

Notice the ILX::init on line 7 – this is configured with the iRules LX plugin name and the iRules LX extension inside our workspace.

irules_lx_workspace

What about Node.js

Next, you provide the Node.js methods your iRule calls in the index.js file


/*
* iRulesLX RPC for AFM/APM Dynmanic Address List
*
*/
/* Import the f5-nodejs module. */
var f5 = require('f5-nodejs');
var afm = require('./f5_afm');
/* Create a new rpc server for listening to TCL iRule calls. */
var ilx = new f5.ILXServer();
/**
* add address to AFM address list
*
* @params {String} address
* @return {Boolean} result
*/
ilx.addMethod('addAddress', function(req, res) {
afm.addAddress(req.params()[0], function(result) {
if(typeof result !== undefined) {
res.reply(true);
} else {
res.reply(false);
}
});
});
/**
* remove address from AFM address list
*
* @ params {String} address
* @ return {Boolean} result
*/
ilx.addMethod('deleteAddress', function(req, res) {
afm.deleteAddress(req.params()[0], function(result) {
if(typeof result !== undefined) {
res.reply(true);
} else {
res.reply(false);
}
});
});

view raw

index.js

hosted with ❤ by GitHub

Not too hard and it offers a world of possibilities with the inclusion of NPM modules.

Where’s the rest of the code?

For a complete view of the iRules LX code please visit the Github repository.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.