|
Salesforce: Opening Trusted IP Ranges
August 27th, 2008
As you know, salesforce.com has taken many steps to ensure that their app is secure. The primary security features call for the use of a security token appended to the standard Salesforce login credentials or a confirmation message to enable login from specific computers/laptops. For most Salesforce customers these security features were a welcomed addition but to developers these security features caused some headaches.
Developers will often create a one-off Salesforce org to demonstrate some functionality that they have built or for illustrative purposes to assist with things such as training or sales. Without side-stepping the security features a developer will often have to begin a presentation with the instructions for getting through the Salesforce security and this makes for some unwanted downtime especially if the demonstration is with a prospective customer.
One of the ways to get around the security features is to list out specific IP addresses or IP ranges that have permission to access your org. Using the Salesforce app anyone with admin rights can go in and enter IPs that are trusted but the process is very manual. It would be easier to use the Salesforce API to load in a bunch of IP addresses directly into the table where this information is stored. However, the table for trusted IPs is currently unavailable via the API and that leaves only one way to get the IPs listed - manually.
When trusted IP functionality was initially released, salesforce.com allowed admins to simply enter the full range of possible IP addresses in one entry (0.0.0.0 through 255.255.255.255). This single entry was simple to make and didn't require more than a few seconds to setup. However, the app now limits the size of the IP range that can be entered and that means that the admin now has to create multiple entries to cover the same range (0.0.0.0 through 255.255.255.255).
Initial Trusted IP Functionality

Current Trusted IP Functionality

To be clear, most companies will not need to make trusted IP entries because they want to fully utilize the security features of the Salesforce application. But companies that sell AppExchange products will certainly need to add the full list of trusted IP ranges because they want to ensure that all people willing to demo their app can access it from wherever they might be on the planet. For this reason I decided to put together a simple sConrol that when accessed will populate the full range of possible IP addresses for an org. I use this sControl every time I create a developer edition org and when we create demonstration apps for our customers or for demos on the AppExchange. The full code is below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Update Network Access</title>
<!--
Created by: Greg Hacic
Last Update: August 27, 2008
Questions?: http://www.interactiveties.com/contact.php
Copyright (c) 2008 Interactive Ties LLC - All Rights Reserved
-->
<link href="/sCSS/13.0/Theme2/common.css" type="text/css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet">
<link href="/sCSS/13.0/Theme2/allCustom.css" type="text/css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet">
<link href="/sCSS/13.0/Theme2/dStandard.css" type="text/css" media="handheld,print,projection,screen,tty,tv" rel="stylesheet">
<script src="/js/functions.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
<!--
function initiatePage() {
var a = 0;
var docHTML = "<table class=\"list\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
docHTML += "<tr class=\"headerRow\">";
docHTML += "<th scope=\"col\" class=\"\">IP Start</th>";
docHTML += "<th scope=\"col\" class=\"\">IP End</th>";
docHTML += "<th scope=\"col\" class=\"\">Status</th>";
docHTML += "<th scope=\"col\" class=\"\"> </th>";
docHTML += "</tr>";
while (a<=254) {
docHTML += "<tr class=\"dataRow ";
if (a%2 == 0) {
docHTML += "even";
} else {
docHTML += "odd";
}
if (a == 254) {
docHTML += " last\"";
} else if (a == 0) {
docHTML += " first\"";
} else {
docHTML += "\"";
}
docHTML += " onmouseout=\"if (typeof(hiOff) != 'undefined'){hiOff(this);}\" onfocus=\"if (typeof(hiOn) != 'undefined'){hiOn(this);}\" onblur=\"if (typeof(hiOff) != 'undefined'){hiOff(this);}\" onmouseover=\"if (typeof(hiOn) != 'undefined'){hiOn(this);}\">";
docHTML += "<td class=\"dataCell\">"+a+".0.0.0</td>";
docHTML += "<td class=\"dataCell\">"+(a+1)+".255.255.255</td>";
docHTML += "<td class=\"dataCell\" id=\""+a+"_Updated\">Updating...</td>";
docHTML += "<td class=\"dataCell\"><iframe id=\""+a+"\" name=\""+a+"\" onload=\"alertFrameLoaded(this.id);\" src=\"/05G/e?retURL=%2F05G&IpStartAddress="+a+".0.0.0&IpEndAddress="+(a+1)+".255.255.255&save=1\" width=\"0\" height=\"0\" scrolling=\"No\" frameborder=\"0\"></iframe></td>";
docHTML += "</tr>";
a = a+2;
}
docHTML += "</table>";
docHTML += "<div class=\"pShowMore\">Click here validate the Org network access: <a href=\"/05G\">View Network Access</a></div>";
document.getElementById("output").innerHTML = docHTML;
}
function alertFrameLoaded(id) {
document.getElementById(id+"_Updated").innerHTML = "Success!";
}
//-->
</script>
</head>
<body class="homeTab homepage" onload="initiatePage();">
<div class="bPageTitle"><div class="ptBody secondaryPalette"><div class="content"><img src="/s.gif" alt="Home" class="pageTitleIcon"><h1 class="pageType">IP Ranges<span class="titleSeparatingColon">:</span></h1><h2 class="pageDescription"> Open Up Security</h2><div class="blank"> </div></div></div></div>
<div class="filterOverview">This page uses a series of IFRAME tags to update the IP Range settings for the org. It may take a few minutes for all of the IP ranges to update correctly and you will know that the loading is complete when each row in the table below has a status set to "Success". At the bottom of the screen there is a link to the network settings page. Click this link to validate that the updates from this sControl actually finished successfully.</div>
<div class="bRelatedList">
<div class="bPageBlock secondaryPalette"><div class="pbHeader"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="pbTitle"><img src="/s.gif" alt="" title="" width="1" height="1" class="minWidth"><img src="/s.gif" alt="" class="relatedListIcon"><h3 class="bodyBold">Results Area</h3></td><td class="pbButton"> </td></tr></table></div>
<div class="pbBody" id="output"></div>
<div class="listElementBottomNav"></div>
</div>
</body>
</html>
This code takes a minute or so to run completely but this is a short time period when compared to entry after entry that would need to be made in the trusted IP ranges table manually. Since the code only needs to be run once you can simply delete it after running the first time.
As always, you are welcome to send any questions directly to me using the email address listed at the bottom of this post or you can always contact my whole team by using the contact us page on this website. -greg
 Greg Hacic
|