Posts Tagged 'Guide'

November 19, 2013

Protect Your Data: Configure EVault for Server Backups

In "The Tenth Anniversary" episode of "Everybody Loves Raymond," Raymond accidentally records the Super Bowl over his wedding video. He hilariously tries to compensate for his gaffe by renewing his wedding vows so he can make a new tape for his wife Debra. If life imitates art, it's worth considering what would happen if that tape held your business data. It would be disaster!

While it's unlikely that one of your sysadmins will accidentally record the Super Bowl over the data in your database server cluster, data loss can occur in a number of ways. If your business data is not protected and backed up, it's unlikely that you'll have a neat and tidy sitcom episode resolution. Luckily, SoftLayer provides simple, inexpensive backup capabilities with software such as EVault, so you shouldn't ever be worried about anyone pulling a Raymond on your data.

The following quick, four-step process walks you through how to protect and back up your data by subscribing to SoftLayer's EVault Backup client. This software enables you to design and set your backup schedule, protecting your business from unexpected costs because of accidental deletions, viruses, and other disasters. To follow along on your own servers, your computing instances or bare metal servers need to be provisioned, and you need to have root or administrator level access to those servers. For the sake of brevity, I'll be using a Linux operating system in this guide, but if you're running Windows, the process, in general, is no different.

Step 1 - Order EVault Backup for the server or computing instance

  1. Log into the SoftLayer Customer Portal and select the server(s) that needs storage services from the device list.
  2. Scroll down to the Storage section. Select the Add (or Modify) link located on the right hand corner of the EVault record to place an order for an EVault Backup client subscription.
  3. On the EVault ordering screen, select either Local or Remote Data Center and the desired amount of storage. Agree to the terms and conditions and click the Order EVault button to place your EVault storage order.
  4. The order is typically provisioned in 5 minutes or less and the system creates a user and password for the new instance of EVault.
  5. Click Services→Storage→EVault and expand the EVAULT link to make note of the user credentials, which will be used in Step 3.

Step 2 - Download the EVault agent on the server or computing instance

  1. SSH into the server or computing instance and run the following command:
    # wget –N

Step 3 - Register the server or computing instance with EVault in order to run back up and restore jobs

  1. From the command prompt on the server or compute instance run the following command to register it with EVault:
    ~]# sh ./
  2. In the ensuing prompts, enter the credentials that were noted Step 1.5 and use for the web-based agent console address.

    Note: In the event the agent fails to register with EVault, you can quickly register the agent manually by running ~]#<Installation directory>/register

Once you've made it to this point, you're ready to run backup and restore jobs.

Step 4 – Login into EVault console with WebCCLogin

  1. From the SoftLayer Customer Portal, click Services→Storage→EVault.
  2. Expand the server or compute instance to which EVault Backup is attached. In the right-hand corner of the server entry you will find a link to WebCCLogin.
  3. Click the WebCCLogin link for the EVault Web CentralControl screen. Type in the credentials from Step 1.5 and you’ll be taken to the EVault Backup and Restore interface.
  4. You are now ready to run your backup and restore jobs!

Check your backups often to confirm that they're being created when, where, and how you want them to be created. To prepare for any possible disaster recovery scenarios, schedule periodic tests of your backups: Restore the most recent backup of your production server to an internal server. That way, if someone pulls a Raymond on your server(s), you'll be able to get all of your data back online quickly. If you're interested in learning more, visit the Evault Backup page on KnowledgeLayer.

-Vinayak Harnoor

Vinayak Harnoor is a Technical Architect with the IBM Global Technology Services (GTS) Global Cloud Ecosystem team.

January 29, 2013

iptables Tips and Tricks: APF (Advanced Policy Firewall) Configuration

Let's talk about APF. APF — Advanced Policy Firewall — is a policy-based iptables firewall system that provides simple, powerful control over your day-to-day server security. It might seem intimidating to be faced with all of the features and configuration tools in APF, but this blog should put your fears to rest.

APF is an iptables wrapper that works alongside iptables and extends its functionality. I personally don't use iptables wrappers, but I have a lot of experience with them, and I've seen that they do offer some additional features that streamline policy management. For example, by employing APF, you'll get several simple on/off toggles (set via configuration files) that make some complex iptables configurations available without extensive coding requirements. The flip-side of a wrapper's simplicity is that you aren't directly in control of the iptables commands, so if something breaks it might take longer to diagnose and repair. Before you add a wrapper like APF, be sure that you know what you are getting into. Here are a few points to consider:

  • Make sure that what you're looking to use adds a feature you need but cannot easily incorporate with iptables on its own.
  • You need to know how to effectively enable and disable the iptables wrapper (the correct way ... read the manual!), and you should always have a trusted failsafe iptables ruleset handy in the unfortunate event that something goes horribly wrong and you need to disable the wrapper.
  • Learn about the basic configurations and rule changes you can apply via the command line. You'll need to understand the way your wrapper takes rules because it may differ from the way iptables handles rules.
  • You can't manually configure your iptables rules once you have your wrapper in place (or at least you shouldn't).
  • Be sure to know how to access your server via the IPMI management console so that if you completely lock yourself out beyond repair, you can get back in. You might even go so far as to have a script or set of instructions ready for tech support to run, in the event that you can't get in via the management console.

TL;DR: Have a Band-Aid ready!

APF Configuration

Now that you have been sufficiently advised about the potential challenges of using a wrapper (and you've got your Band-Aid ready), we can check out some of the useful APF rules that make iptables administration a lot easier. Most of the configuration for APF is in conf.apf. This file handles the default behavior, but not necessarily the specific blocking rules, and when we make any changes to the configuration, we'll need to restart the APF service for the changes to take effect.

Let's jump into conf.apf and break down what we see. The first code snippit is fairly self-explanatory. It's another way to make sure you don't lock yourself out of your server as you are making configuration changes and testing them:

# !!! Do not leave set to (1) !!!
# When set to enabled; 5 minute cronjob is set to stop the firewall. Set
# this off (0) when firewall is determined to be operating as desired.

The next configuration options we'll look at are where you can make quick high-level changes if you find that legitimate traffic is being blocked and you want to make APF a little more lenient:

# This controls the amount of violation hits an address must have before it
# is blocked. It is a good idea to keep this very low to prevent evasive
# measures. The default is 0 or 1, meaning instant block on first violation.
# This is the amount of time (in seconds) that an address gets blocked for if
# a violation is triggered, the default is 300s (5 minutes).
# This allows RAB to 'trip' the block timer back to 0 seconds if an address
# attempts ANY subsiquent communication while still on the inital block period.
# This controls if the firewall should log all violation hits from an address.
# The use of LOG_DROP variable set to 1 will override this to force logging.
# This controls if the firewall should log all subsiqent traffic from an address
# that is already blocked for a violation hit, this can generate allot of logs.
# The use of LOG_DROP variable set to 1 will override this to force logging.

Next, we have an option to adjust ICMP flood protection. This protection should be useful against some forms of DoS attacks, and the associated rules show up in your INPUT chain:

# Set a reasonable packet/time ratio for ICMP packets, exceeding this flow
# will result in dropped ICMP packets. Supported values are in the form of:
# pkt/s (packets/seconds), pkt/m (packets/minutes)
# Set value to 0 for unlimited, anything above is enabled.

If you wanted to add more ports to block for p2p traffic (which will show up in the P2P chain), you'll update this code:

# A common set of known Peer-To-Peer (p2p) protocol ports that are often
# considered undesirable traffic on public Internet servers. These ports
# are also often abused on web hosting servers where clients upload p2p
# client agents for the purpose of distributing or downloading pirated media.
# Format is comma separated for single ports and an underscore separator for
# ranges (4660_4678).

The next few lines let you designate the ports that you want to have closed at all times. They will be blocked for INPUT and OUTPUT chains:

# These are common Internet service ports that are understood in the wild
# services you would not want logged under normal circumstances. All ports
# that are defined here will be implicitly dropped with no logging for
# TCP/UDP traffic inbound or outbound. Format is comma separated for single
# ports and an underscore separator for ranges (135_139).

The next important section to look at deals with conntrack. If you get "conntrack full" errors, this is where you'd increase the allowed connections. It's not uncommon to need more connections than the default, so if you need to adjust that value, you'd do it here:

# This is the maximum number of "sessions" (connection tracking entries) that
# can be handled simultaneously by the firewall in kernel memory. Increasing
# this value too high will simply waste memory - setting it too low may result
# in some or all connections being refused, in particular during denial of
# service attacks.

We've talked about the ports we want closed at all times, so it only makes sense that we'd specify which ports we want open for all interfaces:

# Common inbound (ingress) TCP ports
# Common inbound (ingress) UDP ports
# Common outbound (egress) TCP ports
# Common outbound (egress) UDP ports

And when we want a special port allowance for specific users, we can declare it easily. For example, if we want port 22 open for user ID 0, we'd use this code:

# Allow outbound access to destination port 22 for uid 0

The next few sections on Remote Rule Imports and Global Trust are a little more specialized, and I encourage you to read a little more about them (since there's so much to them and not enough space to cover them here on the blog). An important feature of APF is that it imports block lists from outside sources to keep you safe from some attackers, so the Remote Rule Imports can prove to be very useful. The Global Trust section is incredibly useful for multi-server deployments of APF. Here, you can set up your global allow/block lists and have them all pull from a central location so that you can make a single update to the source and have the update propogated to all servers in your configuration. These changes are synced to the glob_allow/deny.rules files, and they will be downloaded (and overwritten) on a regular basis from your specified source, so don't make any manual edits in glob_allow/deny.rules.

As you can see, apf.conf is no joke. It has a lot of stuff going on, but it's very straightforward and documented well. Once we've set up apf.conf with the configurations we need, it's time to look at the more focused allow_hosts.rules and deny_hosts.rules files. These .rules files are where where you put your typical firewall rules in place. If there's one piece of advice I can give you about these configurations, it would be to check if your traffic is already allowed or blocked. Having multiple rules that do the same thing (possibly in different places) is confusing and potentially dangerous.

The deny_hosts.rules configuration will look just like allow_hosts.rules, but it's performing the opposite function. Let's check out an allow_hosts.rules configuration that will allow the Nimsoft service to function:


The format is somewhat simplistic, but the file gives a little more context in the comments:

# The trust rules can be made in advanced format with 4 options
# (proto:flow:port:ip);
# 1) protocol: [packet protocol tcp/udp]
# 2) flow in/out: [packet direction, inbound or outbound]
# 3) s/d=port: [packet source or destination port]
# 4) s/d=ip(/xx) [packet source or destination address, masking supported]
# Syntax:
# proto:flow:[s/d]=port:[s/d]=ip(/mask)

APF also uses ds_hosts.rules to load the blocklist, and I assume the ecnshame_hosts.rules does something similar (can't find much information about it), so you won't need to edit these files manually. Additionally, you probably don't need to make any changes to log.rules, unless you want to make changes to what exactly you log. As it stands, it logs certain dropped connections, which should be enough. Also, it might be worth noting that this file is a script, not a configuration file.

The last two configuration files are the preroute.rules and postroute.rules that (unsurprisingly) are used to make routing changes. If you have been following my articles, this corresponds to the iptables chains for PREROUTING and POSTROUTING where you would do things like port forwarding and other advanced configuration that you probably don't want to do in most cases.

APF Command Line Management

As I mentioned in the "points to consider" at the top of this post, it's important to learn the changes you can perform from the command line, and APF has some very useful command line tools:

[root@server]# apf --help
APF version 9.7 <>
Copyright (C) 2002-2011, R-fx Networks <>
Copyright (C) 2011, Ryan MacDonald <>
This program may be freely redistributed under the terms of the GNU GPL
usage /usr/local/sbin/apf [OPTION]
-s|--start ......................... load all firewall rules
-r|--restart ....................... stop (flush) &amp; reload firewall rules
-f|--stop........ .................. stop (flush) all firewall rules
-l|--list .......................... list all firewall rules
-t|--status ........................ output firewall status log
-e|--refresh ....................... refresh &amp; resolve dns names in trust rules
-a HOST CMT|--allow HOST COMMENT ... add host (IP/FQDN) to allow_hosts.rules and
                                     immediately load new rule into firewall
-d HOST CMT|--deny HOST COMMENT .... add host (IP/FQDN) to deny_hosts.rules and
                                     immediately load new rule into firewall
-u|--remove HOST ................... remove host from [glob]*_hosts.rules
                                     and immediately remove rule from firewall
-o|--ovars ......................... output all configuration options

You can use these command line tools to turn your firewall on and off, add allowed or blocked hosts and display troubleshooting information. These commands are very easy to use, but if you want more fine-tuned control, you'll need to edit the configuration files directly (as we looked at above).

I know it seems like a lot of information, but to a large extent, that's all you need to know to get started with APF. Take each section slowly and understand what each configuration file is doing, and you'll master APF in no time at all.


September 6, 2012

Tips and Tricks - jQuery equalHeights Plugin

Last month, I posted a blog about dynamically resizing divs with jQuery, and we received a lot of positive feedback about it. My quest to avoid iframes proved to be helpful, so I thought I'd share a few more esoteric jQuery tips and tricks that may be of use to the developers and designers in the audience. As I thought back about other challenges I've faced as a coder, a great example came to mind: Making divs equal height, regardless of the amount of content inside.

I haven't seen many elegant div-based solutions for that relatively simple (and common) task, so I've noticed that many people struggle with it. Often, developers will turn back to the "Dark Side" of using tables to format the content since all columns would have the same height as the tallest column by default:

JQuery Tutorial

It was easy theme table columns and to achieve the coveted 100% height that many designers seek, but emulating that functionality with divs proves to be much more difficult. A div is like the Superman of HTML elements (faster-loading, more flexible, more dynamic, etc.), and while it has super powers, it also has its own Kryptonite-like weaknesses ... The one relevant to this blog post being that floating three div elements next to each other isn't going to give you the look of a table:

JQuery Tutorial

Each of the three divs has its own height, so if you're doing something as simple as applying background colors, you're going to wind up with an aesthetically unpleasing result: It's going to look funky.

You could get into some nifty HTML/CSS workarounds, but many frustrated theme creators and designers will tell you that if your parent elements don't have a height of a 100%, you're just wasting coding lines. Some complex solutions create the illusion of all three divs being the same height (which is arguably better than setting fixed heights), but that complexity can be difficult to scale and repeat if you need to perform similar tasks throughout your site or your application. The easiest way to get the functionality you want and the simplicity you need: The jQuery equalHeights plugin!

With a few class declarations in your existing HTML, you get the results you want, and with equalHeights, you can also specify the minimum and maximum parameters so it will create scrollable divs if the tallest element happens to be higher than your specified maximum.

How to Use jQuery equalHeights

First and foremost, include your JQuery lirbraries in the <HEAD> of your document:

<script src="//"></script>
<script language="javascript" type="text/javascript" src="jquery.equalheights.js"></script>

The equalHeights plugin is not a hosted library, so you have to host the file on your server (here's the link again).

With the required libraries called in our document, it's time to make the magic happen in your HTML.

Create Your Divs

<div class="divHeight">This DIV is medium sized, not too big and not too small, but just right.</div>
<div class="divHeight">This DIV has a lot of useful content and media that the user can interact with, thus it's very tall.</div>
<div class="divHeight">This DIV is tiny. Period.</div>

To have them line up next to each other, you'd have them float:left; in your CSS, and now you need to apply the equalHeights function.

Call the equalHeights Plugin
In order for the script to recognize the height of the tallest element, you'd need to call $(document).ready just before the </body> tag on your page. This will ensure that the page loads before the function runs.

The call looks like this:

<script type="text/javascript">$(document).ready(function() {

If you want to specify a minimum and maximum (i.e. The div should be at least this tall and should be no taller than [adds scrollbar if the div size exceeds] the maximum), just add the parameters:

<script type="text/javascript">$(document).ready(function() {
$(".divHeight").equalHeights(300, 600);

The initial call does not change the appearance of the divs, but the time it takes to do the resizing is so miniscule that users will never notice. After that call is made and the height is returned, each div with the class of divHeight will inherit the the same height, and your divs will be nice and pretty:

JQuery Tutorial

This trick saved me a lot of headache and frustration, so hopefully it will do the same for you too!


August 8, 2012

No iFrames! Dynamically Resize Divs with jQuery.

It's no secret that iframes are one of the most hated methods of web page layouts in the web development world — they are horrible for SEO, user experience and (usually) design. I was recently charged with creating a page that needed functionality similar to what iframes would normally provide, and I thought I'd share the non-iframe way I went about completing that project.

Before I get into the nitty-gritty of the project, I should probably unpack a few of the reasons why iframes are shunned. When a search engine indexes a page with iframes, each iframe is accurately recorded as a separate page — iframes embed the content of one we page inside of another, so it makes sense. Because each of those "pages" is represented in a single layout, if a user wanted to bookmark your site, they'd probably have a frustrating experience when they try to return to your site, only to find that they are sent directly to the content in one of the frames instead of seeing the entire layout. Most often, I see when when someone has a navigation bar in one frame and the main content in the other ... The user will bookmark the content frame, and when they return to the site, they have no way to navigate the pages. So what's a developer to do?

The project I was tasked with required the ability to resize only certain sections of a page, while asynchronously shrinking another section so that the entire page would always stay the same size, with only the two sections inside changing size.

Let's look at an example with two divs, side by side on a web page:

iFrame Tutorial

One div will contain a navigation menu to jump to different pages of the website (#sidebar), and the second div will contain all the content for that page (#content). If some of the elements in #sidebar are too long to read with the default width of the div, we want to let the user freely resize the two divs without changing the width of the page.

Our task is straightforward: When #sidebar expands in width, also expand the navigation and shrink #content along with the main content inside #content. If #sidebar shrinks, the navigation, #content and main content would respond accordingly as well:

iFrame Tutorial

It's a relatively easy concept to do with iFrames ... But then you remember that iframes are no longer cool (yes, there was a time long ago when iframes were cool). I decided to turn to my favorite alternative — jQuery — and the fix was actually a lot easier than I expected, and it worked beautifully. Let's run through a step-by-step tutorial.


Lay out your two divs:

<div id="sidebar"> 
<div class="sidebar-menu">
<!-- all your sidebar/navigational items go here -->
<div id="content">
<!-- all your main content goes here -->

2. CSS

Style your divs:

#sidebar {
       width: 49%;
#content {
width: 49%;
        float: left;

3. jQuery

Now that we have our two divs side by side, let's apply some jQuery magic. To do that, Let's include our jQuery files in the <HEAD> of our document:

<link href="" rel="stylesheet" type="text/css"/>
<script src=""></script>
<script src=""></script>

Now that we have the necessary scripts, we can write our function:

<script type="text/javascript">
  $(document).ready(function() {
    $( "#sidebar" ).resizable({      
    $("#sidebar ").bind("resize", function (event, ui) {
            var setWidth = $("#sidebar").width();

I know that might seem like an intimidating amount of information, so let's break it down:

   $( "#sidebar" ).resizable({      

This portion simply makes the div with the ID of "sidebar" resizable (which accomplishes 33% of what we want it to do).

   $("#sidebar ").bind("resize", function (event, ui) {

By using the .bind, we are able to trigger other events when #sidebar is called.

            var setWidth = $("#sidebar").width();

This is where the magic happens. We're grabbing the current width of #sidebar and subtracting it from the width you want your site to be. This code is what keeps your page stays the same width with only the divs changing sizes.


This part of the code that expands the contents in the navigation along with #sidebar.

You can see a working example of iframe-like functionality with jQuery here:

The only part you won't find there is the trick to adjust a corresponding div's size to make it grow/shrink with the first ... I had a heck of a time searching that on the web, so hopefully this quick tutorial will help other developers who might be searching for this kind of functionality!

- Cassandra

May 23, 2012

Web Development - JavaScript - Creating a Sticky Menu

When designing websites, I like to focus on ease of use and accessibility for the end user. While creating your site to be friendly to screen readers and text-based browsers is a must, the accessibility I'm referring to is making it easy for your audience to navigate your site and perform certain common actions. By providing an easy interface for your users, you are immediately increasing your chances that they'll return for more of your site's goodness.

Thus far in our "Web Development" blog series, we've looked at JavaScript Optimization, HTML5 Custom Data Attributes, HTML5 Web Fonts and using CSS to style the Highlight Selection. In this post, we're going to create a "sticky" menu at the top of a page. As a user scrolls down, the menu will "stick" to the top and always be visible (think of Facebook's Timeline view), allowing the user quicker access to clicking common links. With some simple HTML, CSS and JavaScript, you can have a sticky menu in no time.

Let's start with our HTML. We're going to have a simple header, menu and content section that we'll throw in our <body> tag.

    <h1>My Header</h1>
<nav id="menu">
    <ul id="menu-list">
<div id="content">
    Some content

For brevity, I've shortened the content I show here, but the working example will have all the information. Now we can throw in some CSS to style our elements. The important part here is how the <nav> is styled.

nav#menu {
    background: #FFF;
    clear: both;
    margin: 40px 0 80px 0;
    width: 99.8%;
    z-index: 2;
ul#menu-list li {
    border: solid 1px blue;
    list-style-type: none;
    display: inline-block;
    margin: 0 -3px;
    padding: 4px 10px;
    width: auto;

We have set the menu's background to white (#FFF) and given it a z-index of 2 so that when the user scrolls, the menu will stay on top and not be see-through. We've also set the list items to be styled inline-block, but you can style your items however you desire.

Now we get to the fun part – the JavaScript. I've created a class using Mootools, but similar functionality could be achieved using your favorite JavaScript framework. Let's examine our initialize method (our constructor) in our Stickit class.

var Stickit = this.Stickit = new Class({
    initialize: function(item, options) {
        // 'item' is our nav#menu in this case
        this.item =;
        // The element we're scrolling will be the window
        this.scrollTarget = || document.window);
        // The 'anchor' is an empty element that will always keep the same location
        // when the user scrolls. This is needed because this.item will change and
        // we cannot rely on it for accurate calculations.
        this.anchor = new Element('div').inject(this.item, 'top');
        // The 'filler' is an empty element that we'll use as a space filler for when
        // the 'item' is being manipulated - this will prevent the content below from
        // jumping around when we scroll.
        this.filler = new Element('div').inject(this.item, 'after');
        // Set the styles of our 'filler' to match the styles of the 'item'
        // Initialize our scroll events – see the next code section for details

What we're doing here is grabbing our element to stick to the top – in this case, nav#menu – and initializing our other important elements. I'll review these in the next code section.

var Stickit = this.Stickit = new Class({
    initEvents: function() {
        var that = this,
            // Grab the position of the anchor to be used for comparison during vertical scroll
            anchorOffsetY = this.anchor.getPosition().y,
            // Grab our original styles of our 'item' so that we can reset them later
            originalStyles = this.item.getStyles('margin-top', 'position', 'top');
        // This is the function we'll provide as our scroll event handler
        var stickit = function(e) {
            // Determine if we have scrolled beyond our threshold - in this case, our
            // anchor which is located as the first element of our 'item'
            var targetScrollY = that.scrollTarget.getScroll().y,
                fixit = targetScrollY > anchorOffsetY;
            if (fixit &amp;&amp; that.cache != 'fixed') {
                // If we have scrolled beyond the threshold, fix the 'item' to the top
                // of the window with the following styles: margin-top, position and top
                    'margin-top': 0,
                    position: 'fixed',
                    top: 0
                // Show our (empty) filler so that the content below the 'item' does not
                // jump - this would otherwise be distracting to the user
                that.filler.setStyle('display', 'block');
                // Cache our value so that we only set the styles when we need to
                that.cache = 'fixed';
            else if (!fixit &amp;&amp; that.cache != 'default') {
                // We have not scrolled beyond the threshold.
                // Hide our filler
                that.filler.setStyle('display', 'none');
                // Reset the styles to our 'item'
                // Cache our values so we don't keep resetting the styles
                that.cache = 'default';
        // Add our scroll event to the target - the 'window' in this case
        this.scrollTarget.addEvent('scroll', stickit);
        // Fire our scroll event so that all the elements and styles are initialized

This method contains the meat of our functionality. The logic includes that we test how far the user has scrolled down on the page. If s/he scrolls past the threshold – in this case, the anchor which is located at the very top of the "stuck" item – then we set the menu to be fixed to the top of the page by setting the CSS values for margin-top, position and top. We also display a filler so that the content below the menu doesn't jump when we set the menu's position to fixed. When the user scrolls back to the top, the styles are reset to their original values and the filler is hidden.

To see a full working example, check out this fiddle. The Stickit class I created is flexible enough so that you can "stick" any element to the top of the page, and you can specify a different scrollTarget, which will allow you to scroll another element (besides the window) and allow the item to stick to the top of that element instead of the window. If you want to give that a try, you can specify different options in Stickit and modify your CSS as needed to get it working as you'd like.

Happy coding,


April 23, 2012

Choosing a Cloud: Which Cloud Chooses You?

It's not easy to choose a cloud hosting provider.

In the first post of this series, we talked about the three key deciding factors every cloud customer has to consider, and we set up a Venn diagram to distinguish the surprisingly broad range of unique priorities customers can have:

Cloud Customer Zones

Because every customer will prioritize a cloud's cost, technology and hosting provider a little differently (for completely valid reasons), we mapped out seven distinct "zones" to differentiate some of the basic market segments, or "personas," of cloud hosting buyers. That post was intended to set the stage for a larger discussion on how customers choose their cloud providers and how cloud providers choose their customers, and we're just scratching the surface. We're tackling a pretty big topic here, so as Bill Cosby famously says, "I told you that story to tell you this one."

As a hosting provider, SoftLayer can't expect to be all things for all people. It's impossible to offer a quad-core hex-proc dedicated server for a price that will appeal to a customer in the market for a $49/mo dedicated server.

To better illustrate SoftLayer's vision in the cloud market, we need to take that generic cost v. technology v. hosting provider diagram and give it the "Three Bars" treatment:

SoftLayer Venn Diagram

We're much more interested in living and breathing the Zone 5 "Technology" space rather than the traditional Zone 2 "Hosting Provider" space. That's why in the past two months, you've seen announcements about our launch of the latest Intel Processors, HPC computing with NVidia GPUs, searchable OpenStack Object Storage, and an innovative "Flex Image" approach to bluring the lines between physical and virtual servers. We choose to pursue the cloud customers who make their buying decisions in Zone 3.

That's a challenging pursuit ... It's expensive to push the envelope in technology, customers primarily interested in technology/performance have demanding needs and expectations, and it's easier to make mistakes when you're breaking new ground. The majority of the hosting industry seems to have an eye on the buyer in Zone 1 because they believe the average hosting customer is only interested in the bottom line ... That hosting is more or less a commodity, so the focus should be on some unverifiable qualitative measure of support or the next big special that'll bring in new orders.

As you may have seen recently, GigaOm posted a lovely article that references several high-profile companies in our 25,000+ customer family. We like to say that SoftLayer builds the platform on which our customers build the future, and that short post speaks volumes about the validity of that statement. Our goal is to provide the most powerful, scalable and seamlessly integrated IT infrastructure for the most innovative companies in the world. Innovate or Die isn't just our company motto ... It's our hope for our customers, as well.

We might miss out on your business if you want a $49/mo dedicated server, but if you're looking to change the world, we've got you covered. :-)


April 20, 2012

Choosing a Cloud: Cost v. Technology v. Hosting Provider

If you had to order a new cloud server right now, how would choose it?

I've worked in the hosting industry for the better part of a decade, and I can safely say that I've either observed or been a part of the buying decision for a few thousand hosting customers — from small business owners getting a website online for the first time to established platforms that are now getting tens of millions of visits every day. While each of those purchasers had different requirements and priorities, I've noticed a few key deciding factors that are consistent in a all of those decisions:

The Hosting Decision

How much will the dedicated server or cloud computing instance cost? What configuration/technology do I need (or want)? Which hosting provider should I trust with my business?

Every website administrator of every site on the Internet has had to answer those three questions, and while they seem pretty straightforward, they end up overlapping, and the buying decision starts to get a little more complicated:

The Hosting Decision

The natural assumption is that everyone will choose a dedicated server or cloud computing instance that falls in the "sweet spot" where the three circles overlap, right? While that makes sense on paper, hosting decisions are not made in a vacuum, so you'll actually see completely valid hosting decisions targeting every spot on that graph.

Why would anyone choose an option that wouldn't fit in the sweet spot?

That's a great question, and it's a tough one to answer in broad strokes. Let's break the chart down into a few distinct zones to look at why a user would choose a server in each area:

The Hosting Decision

Zone 1

Buyers choosing a server in Zone 1 are easiest to understand: Their budget takes priority over everything else. They might want to host with a specific provider or have a certain kind of hardware, but their budget doesn't allow for either. Maybe they don't need their site to use the latest and greatest hardware or have it hosted anywhere in particular. Either way, they choose a cloud solely based on whether it fits their budget. After the initial buying decision, if another server needs to be ordered, they might become a Zone 4 buyer.

Zone 2

Just like Zone 1 buyers, Zone 2 buyers are a pretty simple bunch as well. If you're an IT administrator at a huge enterprise that does all of your hosting in-house, your buying decision is more or less made for you. It doesn't matter how much the solution costs, you have to choose an option in your data center, and while you might like a certain technology, you're going to get what's available. Enterprise users aren't the only people deciding to order a server in Zone 2, though ... It's where you see a lot of loyal customers who have the ability to move to another provider but prefer not to — whether it's because they want their next server to be in the same place as their current servers, they value the capabilities of a specific hosting provider (or they just like the witty, interesting blogs that hosting provider writes).

Zone 3

As with Zone 1 and Zone 2, when a zone doesn't have any overlapping areas, the explanation is pretty easy. In Zone 3, the buying decision is being made with a priority on technology. Buyers in this area don't care what it costs or where it's hosted ... They need the fastest, most powerful, most scalable infrastructure on the market. Similar to Zone 1 buyers, once Zone 3 buyers make their initial buying decision, they might shift to Zone 5 for their next server or cloud instance, but we'll get to that in a minute.

Zone 4

Now we're starting to overlap. In Zone 4, a customer will be loyal to a hosting provider as long as that loyalty doesn't take them out of their budget. This is a relatively common customer ... They'll try to compare options apples-to-apples, and they'll make their decision based on which hosting provider they like/trust most. As we mentioned above, if a Zone 1 buyer is adding another server to their initial server order, they'll likely look to add to their environment in one place to make it easier to manage and to get the best performance between the two servers.

Zone 5

Just like the transitional Zone 1 buyers, when Zone 3 buyers look to build on their environment, they'll probably become Zone 5 buyers. When your initial buying decision is based entirely on technology, it's unusual to reinvent the wheel when it comes to your next buying decision. While there are customers that will reevaluate their environment and choose a Zone 3 option irrespective of where their current infrastructure is hosted, it's less common. Zone 5 users love having he latest and greatest technology, and they value being able to manage it through one provider.

Zone 6

A Zone 6 buyer is usually a Zone 1 buyer that has specific technology needs. With all the options on the table, a Zone 6 buyer will choose the cloud environment that provides the latest technology or best performance for their budget, regardless of the hosting provider. As with Zone 1 and Zone 3 buyers, a Zone 6 buyer will probably become a Zone 7 buyer if they need to order another server.

Zone 7

Zone 7 buyers are in the sweet spot. They know the technology they want, they know the price they want to pay, and they know the host they want to use. They're able to value all three of their priorities equally, and they can choose an environment that meets all of their needs. After Zone 6 buyers order their first server(s), they're going to probably become Zone 7 buyers when it comes time for them to place their next order.

As you probably noticed, a lot of transitioning happens between an initial buying decision and a follow-up buying decision, so let's look at that quickly:

The Hosting Decision

Regardless of how you make your initial buying decision, when it's time for your next server or cloud computing instance, you have a new factor to take into account: You already have a cloud infrastructure at a hosting provider, so when it comes time to grow, you'll probably want to grow in the same place. Why? Moving between providers can be a pain, managing environments between several providers is more difficult, and if your servers have to work together, they're generally doing so across the public Internet, so you're not getting the best performance.

Where does SoftLayer fit in all of this? Well beyond being a hosting provider that buyers are choosing, we have to understand buyers are making their buying decisions, and we have to position our business to appeal to the right people with the right priorities. It's impossible to be all things for all people, so we have to choose where to invest our attention ... I'll leave that post for another day, though.

If you had to choose a zone that best describes how you made (or are currently making) your buying decision, which one would it be?


April 3, 2012

Tips and Tricks - How to Use SFTP

Too often, new customers can get overwhelmed by a small administrative task on a Linux server. One of the more common questions I see in technical support is when a drive partition runs out of space. The website appears offline, and on of my coworkers advises you to just free-up some space. "Just?! Where can I find files that are deletable without affecting my website?"

Don't worry ... it's really quit simple. If you can use FTP (File Transfer Protocol), you can handle this bit of server management. Depending on the exact problem, we might instruct you to free up space by removing files in one of the following directories:

  • /var/log
  • /usr/local/cpanel
  • /usr/local/apache/logs
  • /usr/local/apache/domlogs

The reason these directories are usually overlooked is because they are not accessible by normal FTP users — users who only upload website content. When you upload website content to the server via FTP, the FTP user is limited to the directory structure for that website. Directories starting with "/var" and "/usr" cannot be accessed by these non-root users (The "root" user can access anything). And while root is a powerful user, for the sake of security, it is not normally allowed to log in over FTP because FTP is not secure ... That's where SFTP (Secure File Transfer Protocol) comes in.

Most FTP clients support SFTP, so you don't have to learn a new environment to securely access any file on the server. Every FTP client is different, but I'll illustrate with FileZilla because it's free and available on Mac, Windows and Linux. If you don't already have an FTP client, I highly recommend FileZilla. Because there are a few ways to use FileZilla to get an SFTP connection, I can share different options for you to try:

Quick Connect

The Quick Connect bar is the quickest way to connect to your server. Start FileZilla and look immediately under the toolbar for the Quick Connect bar:

SFTP Tutorial

Enter the hostname (IP address or domain name), “root” in the Username field, the root password in the Password field, and “22″ in the port field. Remember, port 22 is for SFTP, the same as SSH. Click the Quickconnect button to connect.

Using the Site Manager

The Site Manager lets you save your login details. Start FileZilla and you'll see the following:

SFTP Tutorial

To open the Site Manager, click the left-most icon in tool bar or go to File >> Site Manager in the menu.

SFTP Tutorial

Enter an IP address or domain name for your server in the Host field, and select "SFTP" as your protocol. You'll enter the root user's login information, and you're ready to connect by clicking the "Connect" button or you can click the "OK" button to save and close the dialog box.

If you just saved your settings and the Site Manager is not open, click the Site Manager icon again. From there, you can select the site under the "Select Entry" box, and you just have to click "Connect" to initiate the SFTP connection with your saved settings.

If you see a pop-up that warns of an "Unknown host key," clicking the "Always trust this host, add this key to the cache" option will prevent this interruption from showing in the future. Once you click "OK" to complete the connection, your FileZilla screen should look like this:

SFTP Tutorial

Notice the "Remote site" section on the middle right of the FileZilla screen:

SFTP Tutorial

This area in FileZilla is the directory and file listing of the server. Navigate the server's file structure here, and click "/" to access the top of the folder structure. You should see the "/usr" and "/var" directories, and you can explore the filesystem to delete the files technical support recommended to create space!

Message Log

If you have a problem connecting to your server by FTP or SFTP, the open area below the Quickconnect bar is the Message Log. If you can copy and paste this text into a ticket, you'll help technical support troubleshoot your connection problems. Below is an example log of a successful FTP session:

Status: Connecting to
Response:   fzSftp started
Command:    open "" 22
Command:    Trust new Hostkey: Once
Command:    Pass: **********
Status: Connected to
Status: Retrieving directory listing...
Command:    pwd
Response:   Current directory is: "/root"
Command:    ls
Status: Listing directory /root
Status: Calculating timezone offset of server...
Command:    mtime ".lesshst"
Response:   1326387703
Status: Timezone offsets: Server: -21600 seconds. Local: -21600 seconds. Difference: 0 seconds.
Status: Directory listing successful

And here's an example of a failed connection:

Status: Resolving address of
Status: Connecting to
Error:  Connection timed out
Error:  Could not connect to server
Status: Waiting to retry...
Status: Resolving address of
Status: Connecting to
Error:  Connection attempt interrupted by user

If you have any questions, leave them in a comment below. Enjoy your new-found SFTP powers!


March 26, 2012

Planning Your Server Infrastructure = Buying a House

With a little one on the way, I've been spending a good amount of my free time starting to search for a new home for my growing family. While the search continues, I've learned a thing or two about what to look for and what should be done before taking the plunge, and as I've gone through the process, I can't help but notice lot of parallels to what it's like to purchase a new server:

  • It's an Investment

    Just like purchasing a new home, deciding to purchase a server is a huge investment. As you start shopping around, the costs may seem staggering, and while most servers don't cost as much as a small home, your new server will be your business's new home online. When you consider the revenue your site will generate (and the potential cost of not being able to properly support demand), you won't want to skimp on the details. The truth is that like any investment, you can reap great rewards with proper planning and execution.

  • You Have to Know What You Need

    One of the best tips I've incorporated in my home-buying process is the need to differentiate what you want, what you need, and what you can live without. Unless you're royalty, you're likely living on a budget. As cool as it would be to live in a 10-bedroom mansion with an indoor Olympic size pool, there's a lot there that I don't need. That sort of home palace also falls way outside of my personal budget. The same could be said about a business.

    I've heard plenty of stories about companies who slash their IT budgets in order to cut costs, and even the greatest IT departments have to live within their budgets. As you're determining what your next server will be, you need to understand the purpose (and needs) of your workload: Will it be database server? An application server? Will it be an additional web head? Are you using it for mass storage? You need to plan accordingly. I'm sure you'd want a new Xeon E5-2600 server with all of the bells and whistles, but if you don't need that kind of performance, you're likely just going to burn through your budget quicker than you have to. Know your budget, know your needs and purchase your server accordingly.

  • You Should Get to Know the Neighborhood

    I don't intend on purchasing a home in a high-crime area, nor do I plan on moving into a neighborhood with exorbitant HOA dues for services I don't intend to use. Your new server is going to have a "neighborhood" as well when it comes to the network it's connected to, so if you plan on outsourcing your IT infrastructure, you should do the same research.

    You want your critical environments in a safe place, and the easiest way to get them in the right "neighborhood" is to work with a well-established host who's able to accommodate what you're doing. A $20/mo shared hosting account is great for a personal blog site, but it probably wouldn't be a good fit for a busy database server or front-end application servers for an application dependent on advertising for revenue. A mansion worth of furniture doesn't fit very well in a studio apartment.

  • You're Responsible for Maintenance

    Ask any homeowner: Continuous improvements — as well as routine maintenance &mdashl are a requirement. Failure to take care of your property can result in fines and much more costly repairs down the road. Likewise with any server, you have to do your maintenance. Keep your software up to date, practice good security protocols, and continue to monitor for problems. If you don't, you could find yourself at the mercy of malicious activity or worse — catastrophic failure. Which leads me to ...

  • You Need Insurance Against Disaster

    Homeowner's insurance protects you from disaster, and it provides indemnity in the event someone is hurt on your property. Sometimes additional insurance may be required. Many professionals recommend flood insurance to protect from flood damage not covered under a typical homeowner's insurance policy. Ask any systems administrator, and they'll tell you all about server insurance: BACKUPS. ALWAYS BACK UP YOUR DATA!!! The wrong time to figure out that your backups weren't properly maintained is when you need them, more specifically in the event of a hardware failure. It's a fact of life: Hardware can fail. Murphy's Law would suggest it will fail at the worst possible time. Maintain your backups!

I can't claim that this is the guide to buying a server, but seeing the parallels with buying a new home might be a catalyst for you to look at the server-buying process in a different light. You should consider your infrastructure an asset before you simply consider it a cost.


March 13, 2012

Web Development - CSS - Highlight Selection

I immediately fell in love with CSS when we were introduced in late 2000. The ability to style a whole site outside the HTML was a fantastic concept and probably my first true introduction to separation of style and content. Put your words over here, and put how you display those words over there. So simple! Since then I have always been an advocate of cascading style sheets. Today's tip will involve an effortless addition that will have your readers say, "Ooooh. That's a clever little change."

I find that when I read articles and blogs online, I not only read with my eyes, I scan the page with my mouse. Especially if it's a wordy article or not styled in smaller columns, I highlight the text by clicking and dragging to help me maintain my focus. Up until recently, whenever you selected text that way in your browser, your operating system would choose the color of the background highlight. For Windows, this is generally blue. For OS X, this is whatever you've set your preferences to (which is light blue by default).

For those of you that use a newer version of Webkit (Chrome or Safari) or Gecko (Firefox), the site designer can determine what color to highlight your selection of text, and CSS has made it easy.

/* Webkit */
::selection {
    background: #972F2C;
    color: #FFF;
/* Gecko/Mozilla */
::-moz-selection {
    background: #972F2C;
    color: #FFF;

As of today, Webkit browsers are the only ones that support ::selection without browser prefixing. Firefox requires the -moz- prefix. Here we have set the highlight background color to "SoftLayer Red" (#972F2C) and made the text color white (#FFF). It should be noted that earlier versions of Webkit and Gecko did not support anything but the background property. There is still limited support for which CSS properties are allowed during selection. You are unable to change font-style, font-size, text-decoration and many other properties, but we can hope support for most of the properties will be available in the future.

This is pretty cool so far, but we can take it one small step further. Just like other selectors, we can apply the ::selection selector to other elements and style each one differently.

h2::selection {
    background: #B72E33;
    color: #FFF;
p::selection {
    background: #ACEFB2;
div::selection {
    background: #E4DB80;
span::selection {
    background: #C780E4;
    color: #FFF;

This produces the following:

Highlighting Example

Surprise your readers and give them some highlight goodness.

Happy coding!


Subscribe to guide