Stop Talking About Backups

So your desktop is backed up? Did you backup that server? Your backups are even on a different machine?

Not bad.

You even know to store a copy of your data in a geographically different location (“offsite backup”).

Excellent… Excellent start, but far from sufficient.

All the above are best practises – it’s a low bar, you need to do this, no questions asked. A failure to do so would be incredibly negligent and set yourself up for desaster. But it’s only half the story – if that: Lets not even talk about potential privacy issues or protection of your important data in case the unencrypted backup media are stolen, etc.

The real problem with backups appear when you have to restore them!

And that’s when you discover that:

  • The backed-up files were encrypted with a cryptographically-secure key, the only copy of which was on the machine that was lost
  • The Windows server had enormous amounts of configuration information stored in the IIS metabase which wasn’t backed up
  • Your accounting software wrote important data files in areas that weren’t coverred by the backup
  • Your Linux setup had vast amounts of organically grown SELinux configurations that were neither documented nor captured by your backup
  • The backup files were being copied to a FAT partition and were silently being truncated to 2GB
  • Your backups were on an LTO drive which was lost with the data center, and you can’t get another LTO drive for three days
  • And a million other things that can go wrong even when you “have backups.”

The minimum bar for a reliable service is not that you have done a backup, but that you have done a restore. On a new machine from ground up. If you’re running a web service, you need to be able to demonstrate that you can build a reasonably recent copy of the entire site, in a reasonable amount of time, on a new server or servers without ever accessing anything that was in the original data center. The bar is that you’ve done a restore.

We never ask our clients if they’re doing backups, we ask if they’re doing restores.

Simply Efficient powered products featured during the olympics

Simply Efficient is proud to support our clients during the current Olympic Winter Games. Several of them are featuring exciting new products powered by custom server software designed and implemented by us.

For example, go check out Empower Software demo of their nifty power consumption monitoring product Smart Home. Not just does Smart Home feature a very cool, touchscreen based interface and supports various mobile devices, it also helps you save your hard earned dollars while at the same helping the environment. Very cool…

You can see Smart Home in action at BC Hydro’s Olympic Pavilion.

Staying On Top Of The Game – Podcasts for Developers

As a professional software developer, or for anyone working in IT for that matter,  it’s hard to stay on top of the game: Staying competitive includes following up on the latest industry trends and knowing about the latest technologies. But you better still be productive in your job and all the while maintain a certain social life – chances are you won’t get a lot of sleep.

Reading books, blogs, etc is of course a great way of going about it, but then again: Who really has time to read nowadays. I am trying to get through “The Art of Unit Testing” for almost a month now. It’s by no means a big book (approx 250 pages of content) – I just don’t find the opportunity to read more than 5 pages in one sitting.

For me, podcasts present a great alternative. There are a number of very high quality, development and technology related podcasts out there with an incredible information density. I listen to the following on my IPod whenever I am “in between” things (on the way to work, while running, shopping, etc) or while performing more or less mindless tasks (cleaning, cooking, …):

Cranky Geeks: In a very cut and dry style that is right up along my alley, John C. Dvorak and guests discusses latest events in the industry. Every podcast packed with information and gives you a good idea of “what’s happening”: Industry rumors, new technologies, new devices, you name it. John is not talking about software development specifically, so it’s a great complement to the podcasts mentioned below. The cast is very easy and entertaining  also to listen to and with a length of half an hour ideal for the daily commute.

Java Posse:  You can tell that Tor Norbye (Sun Microsystems), Carl Quinn (Netflix), Dick Wall (Navigenics) and Joe Nuxoll (independent) are having fun producing this podcast. If you want to know what’s going on in the Java community, there is no better place to go than “Java Posse”. It’s an hour long, but well structured and the chemistry between the hosts makes it easy and entertaining to listen to.

Hanselminutes: Focussing mainly on the .Net and Windows world, Scott Hanselman discusses utilities, tools and gives practical how-to advice. The podcasts are a nice mix of .Net/Windows specific subjects and more generic topics such as agile development and project management. The guests are high profile and Scott is a great host who manages to distill and compress valuable in-depth information within a 30min time box.

Software Engineering Radio: This one is a slightly different beast. While all the previously mentioned postcasts focus on being right on top of what’s happening, the SE Radio hosts and their thick accents go back to basics: Their guests talk about SQL and release management, the books they have written and “old news” such as MDA, etc.
The episodes are long (1h) and the hosts are by no means skillful interviewers: You can easily zone in and out of the podcast and answer a phone call without having to rewind. The artificial laugh’s at not-funny jokes get annoying pretty quick and sometimes there is just no clear direction in the interview.
However, I am a firm believer in knowing the roots and basics of what we do in our industry, and for that reason alone I follow this podcast. I would classify it as “interesting background noise” and I do take home little bits and pieces from every episode.

StackOverflow: Joel Spolsky, a software developer in New York City who is probably best known in the community for his blog Joel on Software, and his collegue Jeff produce this podcast which talks about…well… mostly themselves. The podcast doesn’t necessarily convey a lot of new new information and I treat this podcast as a replacement for mp3s or radio. I personally like to to listen to others talk about their pet project and the associated worries, problems and victories.

Cutting Corners Doesn’t Buy You Anything

There has been a lot of talk of identity theft, security threats and securing private data lately. You’ve all seen reports of a buggy company websites which exposes private data to the public, phishing scams or an employee using private data for personal use. It makes you think about all of the personal data that you make available each day, whether that be to social media sites, for online purchases or even your phone and utiliy provider. How secure is it?

From a service provider perspective, the minute we store a user’s private data, for example their username and password, we’ve taken on the responsibility of securing that data too. Let’s say a hacker somehow obtains a list of all our usernames and passwords. Either it was an inside job by someone who had access to the database, or the database was accidentally exposed to the public web. It doesn’t matter how. It just happened.

Now as a customer I wouldn’t be happy about my prvate data becoming available. However, I would expect the owner of the application in question to have taken sufficient measures to render it useless to third parties. At the very least, the password is going to be encrypted, right?

RIGHT?????

The answer – from experience – is way too often “unfortunately not”!

Don’t get me wrong, most system designers, developers and project managers are smart people. They think long and hard and often times come up with a reason to avoid taking the standard security measures which everyone sort of knows about.

They are wrong!

How can I be so sure? Because, when it comes to web-app security, cutting corners doesn’t buy you anything. It doesn’t save you coding time (in the long run). It doesn’t give your users a better experience. All it does is weaken the security of your web site, needlessly putting your users, your employer, and yourself at risk.

As the developer, you might think that it’s relatively unimportant if your user’s application password is exposed as plain text. After all, what’s an attacker going to do with, for example, forum credentials? Post angry messages on the user’s behalf? And what about the small business that requires private data from their customers to sign up for a company newsletter? Same thing here. The consequences of exposed data seem small.

But most users tend to re-use the same passwords, probably because they can’t remember the two dozen unique usernames and passwords they’re forced to have. So if you obtain their forum password, it’s likely you also have the password to something a lot more dangerous: online banking, PayPal, etc

So please allow me to state the obvious:

If you are storing plaintext passwords in a database, you are making a mistake!!!

A lot of developers – often times too late – move to hashed passwords. Even this is not enough to thwart a determined attacker. Hashes alone are better than plain text, but barely. Hashing the passwords prevents plaintext exposure, but it also means you’ll be vulnerable to astonishingly effective rainbow table attacks.

The solution here is salted hashes based on computationally expensive(!) hash functions which were designed for password applications. If you do not know what a “salted hash” is or why you should waste precious compute cycles for password storage – you need some help. Hire someone that knows. Otherwise, it’s only a matter of time before you pay for this…

So please let me take this opportunity to ask if you know of (or perhaps work on) any software systems that store passwords plain text in a database. If so, fix your software now:

  • Salt and hash each and every password (use a computationally expensive hashing function such as bcrypt that was designed for password applications)
  • Store the salt and hash – not the password – in your database.
  • Throw the password itself away.
  • Educate your fellow developers! This might feel like “development 101″,but not everyone knows what you know. Really!

You will be glad you did…

Time Management Tip #1 – Get to Know the Enemy

On frequent request from both participants and people interested in our Time Management courses (http://www.simplyefficient.ca/training.php) , we will publish handy Time Management tips and tricks.

In the first installment of this miniseries, we will start at the basics. There are some fact we cannot change, like: There are always only 24 hours in a day. That’s a constant, no matter how organized we are, all we can actually manage is ourselves and what we do with the time that we have.

In order to do so, the very first thing we have to do is find out where and how we are spending our time. It’s like driving a car: If you want to find the best route to a better place, knowing where you are now is just as important than knowing where you want to end up! One additional result the following exercise is to give us a benchmark we can measure our progress against.

So how do we actually spend our time? We all wear many hats during the day (and sometimes at night, too). But what does this mean? What tasks are we actually performing and how much time do we spend on each activity?

For the following week, I invite you to find out by tracking your daily activities lets you see where your valuable time is being spent, and gives you the data you need to set goals and make the changes to your work habits that will make you more successful.

Our goal is to get a 24h coverage – without any gaps – of a “normal” week of your life. Don’t distinguish between business and personal activities at this point. You need to have a complete picture of your schedule so you can more easily see where to make the changes that will make you more successful.


Daily Activity Tracking Tips

Use a device to record your daily activities that is constantly accessible to you, so you can record exactly what you do when you do it. Memory is fallible – and kind.

A Day-Timer or calendar, a PDA, an organizer software program, a digital recorder, or an ordinary notebook will all work to record your daily activities; choose whichever method you are already comfortable with and find the easiest to use.

Don’t record unnecessary information; it’s the activity and the time you spent on it that’s important for our purposes. For example, in the morning, we only need to record “get ready for work” followed by the start and end time.

The Power of Facelets (Part 1 – Motivation)

Ever since Java Server Faces (JSF) were released, we utilized them successfully for many web application projects. While being conceptually really nice and well thought through, one problem with JSF has always been the mismatch with JSP (Java Server Pages).

The issue is how to integrate JSP’s dynamic content into JSF’s component-based model. JSPs are singularly focused on generating dynamic output, whereas JSF requires JSP to coordinate building a component model. The disjunct occurs because that task is beyond the original intention of JSP.

Even though most JSF developers simply learn to navigate such problems, it made the usage of JSF in large projects a huge pain and always resulted in ugly code that was difficult to read and maintain. Far from what you want to achieve with a new technology.

The Problem with JSPs

…Well – maybe not JSP per se. JSPs are great for their intended use: Mixing both static and dynamic content made available by other parts of the application – servlets, plain java code, databases, etc.

But keep in mind that – historically – JSPs are nothing more than “fancy servlets” with some added semantic sugar. Their sole purpose of existence is to generate a response to a request; a JSP page is processed in one pass from top to bottom, with JSP action elements processed – here it comes – in the order in which they appear in the page.

JSF are component based and have a much more complex life cycle. They are created, asked to process their input (if any), and then asked to render themselves (I am simplifying here). For JSF to work well, these three things must happen separately in a well-defined order, but when JSF is used with JSP, they don’t. Instead, the component creation and rendering happens in parallel, causing all kinds of problems.

The fact that both JSP and JSF components add content to the response is another cause for a lot hard to track down issues. Unless you understand the difference between how these two technologies write to the response, you’re in for a lot of surprises – such as content appearing out of order or not at all.

There are severe limitations on how JSF and non-JSF tag libraries can be mixed in a JSP page. On top of that, developing a JSF application requires understanding the event-driven component model.

When learning JSF, a JSP developer now has to not only understand those (likely unfamiliar) concepts, but also learn the pitfalls of how to use the two technologies together and – more importantly – how not to. It’s a lot to learn and often unintuitive.

Lets have a look at a very simple example that illustrates the issue with parallel component creation and rendering. Say you want to create a label for a checkbox – bread and butter which we developers don’t even want to think about, right? Intuitively you would write something like this:

There is no intuitive reason this shouldn’t work, but if run this example, you’ll notice that no <label> element is rendered the first time you request the page, but if you request the page a second time, a <label> element is rendered.

This strange behavior has to do with the combination of JSF and JSP. When JSF receives the first request for the page, the component tree for the view represented by the page doesn’t yet exist. JSF creates a tree with just a UIViewRoot at the top and forwards the request to the JSP page to add the real components.

The JSP container now processes the page and invokes the JSF action tag handlers (here it comes again:) in the order they are encountered. A JSF tag handler looks for the JSF component it represents in the component tree. If it can’t find the component, it creates it and adds it to the component tree. It then asks the component to render itself. This means that on the first request, the components are created and rendered in parallel. On subsequent requests, the component tree exists, so no new components are created; the tag handlers just ask the existing components to render themselves.

On the first request, the >h:outputLabel< action creates its component and asks it to render itself. To do so, it needs to find the component identified by the for attribute, but this component doesn’t exist because the action element that creates it appears after the <h:outputLabel> element and hasn’t been invoked yet. Hence, the component created by <h:outputLabel> action can’t render its <label> element. On the second request, all components exist, so the component represented by the <h:outputLabel> finds the component the label belongs to and happily renders the label element.

Of course in this case there are easy workarounds, but hey: Why should I “work around’ something as simple as adding a label to a checkbox? Furthermore – as you start going beyond “Hello World” pages, you encounter more and more examples like the one above, and many of them aren’t as easy to understand. Matters get worse once you start using AJAX, A4JSF and similar technologies.

In a recent project, the code for the view pages were – out of necessity – plastered with <f:verbatim>pages – creating pages with unbalanced tags (hey – we had no choice) and making it almost impossible to work with.

The solution was – of course – to dump JSP altogether and move to Facelets – more about this in the next article.

Negotiation – Lessons Learned

There were four key lessons that I learned from several interest based negotiations that I have undertaken in the last year. The following will either improve the outcomes for you or lessened the risk of not achieving a win-win:

1) An often overlooked aspect is that of timing. You should allow ample time to complete the negotiations. A relationship must be established in most cases before any long term negotiations can take place. Your negotiating partner must understand what to expect of you. Not doing this could be very detrimental to the exact long-term relationship that you are trying to protect and nurture. Pushing for an outcome with short notice, can also negatively effect on your reputation.

2) Making your BATNA (best alternative to a negotiated agreement) stronger in advance, for example by confirming and bettering your options, will improve your confidence in the negotiations. If you do this, you will have the confidence and objective criteria to ask for more – within reason.

3) On a personal note, it is important to separate rational choice from your personal predisposition. You must not only be able to control the display of negative emotions to your negotiation partners but when matters are highly personal you must also try to minimize the role of your personality and predisposition. Increased separation of your emotions will make the whole experience far less stressful for you. This is not an easy task, but well worth the effort.

4) Above all else, the power of preparation in negotiation can not be overemphasized. The time and effort spent obtaining information on and analyzing the interests, style and BATNA of the other parties are always well spent. If you do not do this, you will go into the negotiations blind which may result in positional bargaining instead of interest based negotiation. A great book to read on the subject is “Getting to Yes”.

AJAXified Location Search Text Field in 15min Using MS Life Search, Java and EXTJS

A recent project involved a Microsoft Virtual Earth mashup. As it turns out, the initial component set shipped with the Virtual Earth (VE) SDK is rather limited and – quite frankly – very ugly.

One of the things needed was an input field the user can utilize to type in an address or location, which gets then of course shown in the map. Ideally this input field would provide a “suggestion drop down” containing places known to VE. As it turns out, this is accomplished using…

  • Java Servlets for the middle tier (project requirement)
  • EXTJS for the components and the AJAX communication
  • The MS Virtual Earth Life Search web service

The Servlet

Wrapping the call to the VE web service into a servlet has several advantages: We can perform caching of the requests, thus significantly lowering the response time of the service while being able to create nice statistics of what people are searching for. It also allows us to process both the search string and the results on the server to perform e.g. filtering, limiting searches to geographic areas, etc.

Calling the web service to perform the address lookup is very easy:

private static String URL_PARAMETER_PREFIX ;
private static String URL_PARAMETER_POSTFIX;

static{
try {
URL_PARAMETER_PREFIX =  URLEncoder.encode("a", "UTF-8") + "=" + "&" + URLEncoder.encode("b", "UTF-8") + "=";
URL_PARAMETER_POSTFIX = "&" + URLEncoder.encode("c", "UTF-8") + "=" + URLEncoder.encode("0.0", "UTF-8");
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("d", "UTF-8") + "=" + URLEncoder.encode("0.0", "UTF-8");
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("e", "UTF-8") + "=" + URLEncoder.encode("0.0", "UTF-8");
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("f", "UTF-8") + "=" + URLEncoder.encode("0.0", "UTF-8");
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("g", "UTF-8")  + "=" ;
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("i", "UTF-8")  + "=" ;
URL_PARAMETER_POSTFIX += "&" + URLEncoder.encode("r", "UTF-8") + "=" + URLEncoder.encode("0", "UTF-8");
} catch (UnsupportedEncodingException e) {
URL_PARAMETER_POSTFIX = null;
URL_PARAMETER_PREFIX = null;
e.printStackTrace();
}
}

private String performMSLiveSearch(String address){

if (liveSearchURL == null
|| URL_PARAMETER_PREFIX == null || URL_PARAMETER_POSTFIX == null  ){
// log error here
return "";
}

StringBuilder requestResult = new StringBuilder();

try {
String paramteterString = URL_PARAMETER_PREFIX
+ URLEncoder.encode(address, "UTF-8")
+ URL_PARAMETER_POSTFIX;

// Send request
URLConnection conn = liveSearchURL.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(paramteterString);
wr.flush();

// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null)
requestResult.append(line);
wr.close();
rd.close();
} catch (Exception e) {
// log exception here
e.printStackTrace();
}

System.out.println(requestResult.toString());

return requestResult.toString();
}

Instead using heavyweight XML parsers, we can extract the needed information fast and simple using regular expressions:

private Pattern ambiguityListPattern = Pattern.compile(".*?new Array\\('(.*?)',.*?\\)");
private Pattern geoLocationPattern = Pattern.compile(".*?AddGeoLocation\\('(.*?)',.*?\\)");

private String[] analyzeSearchResults(String searchResultString){

if (searchResultString == null)
throw new IllegalArgumentException("Parameter must not be null!");

// unfortunately we are stuck with 1.4, so no generics
ArrayList results = new ArrayList();

// extract the "ambiguity list"
Matcher m = ambiguityListPattern.matcher(searchResultString);

while (m.find())
results.add(m.group(1));

//	 extract the "geolocation list"
m = geoLocationPattern.matcher(searchResultString);

while (m.find())
results.add(m.group(1));

return (String[])results.toArray(new String[results.size()]);
}

To finalize the servlet, we implement the doPOST method as follows:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String searchAddress = req.getParameter("address");
PrintWriter out = resp.getWriter();

// chaching and search string processing goes here
String[] results = analyzeSearchResults(performMSLiveSearch(searchAddress));
LocationSearchCache.getInstance().addSearchResults(searchAddress, results);

// format output for EXTJS array reader
out.print("[");
for (int i=0; i< results.length; i++){
if (i>0)
out.print(",");
out.print("['");
out.print(results[i]);
out.print("']");
}
out.println("]");
out.close();
}

This leaves us with the HTML and Javascript, which – thanks to the great EXTJS library, is a breeze:

 
 

Ajax Virtual Earth Search Test

That’s it! All the magic is done in…

Ext.onReady(function() {

var store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url:SERVLET_ADDRESS, method: 'POST'}),
reader: new Ext.data.ArrayReader({}, [{name: 'address'}])
});

var combo = new Ext.form.ComboBox({
store: store,
queryParam:'address',
displayField:'address',
hideTrigger:true,
typeAhead: false,
triggerAction: 'all',
emptyText:'City, Address or Postal Code',
selectOnFocus:true
});

combo.applyTo('addressCombo');

});

That’s it! We end up with a very flexible component that can be easily plugged into any page, or even modularized into a JSF component.

We used the doGet method of the servlet to spit out statistics about the current state of the query cache, which also only takes a few lines of code.

Know Your Enemy: Malicious Web Servers

Even seemingly safe web addresses can be full of attack code aiming at vulnerable clients, according to a new study from the The Honeynet Project & Research Alliance(http://www.honeynet.org/). The findings also include that finds that methods such as blacklists can be surprisingly successful in stopping client-side attacks.

“The ‘black hats’ are turning to easier, unprotected attack paths to place their malware onto the end-user’s machine,” they said in the study, called “Know Your Enemy: Malicious Web Servers.”

Users can be led to malicious sites via links, typing in an address manually, mistyping an address or following search-engine results.

Using a “high-interaction” client honeypot called Capture-HPC developed by the Victoria University of Wellington, the researchers analyzed more than 300,000 addresses from around 150,000 hosts.

Analyzed were various site categories, including adult, music, news, “warez,” defaced, spam and addresses designed to grab traffic from users who mistype common web addresses. While some categories were more likely to contain malicious addresses than others, they could be found everywhere:

“As in real life, some ‘neighborhoods’ are more risky than others, but even users that stay clear of these areas can be victimized,” the report said. “Any user accessing the web is at risk.”

While the findings are not really surprising – the existence of this kind of attack is long known – the study also analyzed the effectiveness of safeguards against such infections in some detail, showing that blacklists, if regularly updated, can be a surprisingly effective way of blocking malicious addresses.

While the study also recommends regular patching, but this may not always be straightforward, since the a prevalence of attacks against plug-ins and non-browser applications becomes obvious: “Attacks also target applications that one might have not think about patching, such as Winzip”.

Another technique that can block attacks would be to use a less popular browser, such as Opera: “Despite the existence of vulnerabilities, this browser didn’t seem to be a target”.

The data used for the study as well as the paper can be found here: http://www.honeynet.org/papers/mws/

Common Sense and Network Security

Within the past few of months, two of our clients were encountering severe security breaches. In other words: They “got hacked”. Were they big multi-million dollar enterprises? No – they both were Vancouver based SMB’s with less than 100 employees. It is always amazing how little importance small and medium size ventures pay to network security. The most often heard question is…

Why Would Someone Want to Hack Into a Small Business Like Ours

For many reasons! First of all: It’s nothing personal! If you still think of “hackers” as guys in trench coats sitting dark rooms littered with pizza boxes, only lit by the glow of monitors: Think again. People are always amazed by the following demo: Take a freshly installed Windows machine with disabled firewall. Connect it to the internet and leave it alone for 30min. Now run a virus scan – whoa! That’s just 30 min. This is what your company network is facing every single day. So let’s face the fact:

Your Network is Under Attack

I am not trying to create panic. It’s a simple fact every sysadmin doing her job knows. Accept it! It’s real, and it’s probably happening right now. Go check!
Almost all attacks you are facing are widespread, automated attacks against large portions of the network. To use a common analogy, you are not dealing with a criminal mastermind spending all night trying to break into your house, but rather with a small time crook using a whole bunch of generic keys bought on ebay, trying to get into each house on the street by trying each key in every lock.
Aside from viruses spread via email, password guessing attacks as well as the automatic exploit of security holes in the software installed on both server and clients accessible from the outside world are the most common forms of attacks. The good news is: Since the attacks are generic, they can be easily prevented, using common sense and widely available, mostly free tools.

What Are They After?

The question is still out there: Why would someone try to infiltrate your network in the first place? Spammers will try and get their hands on your address books – already verified (by you!) email addresses are worth real money! Also, they often times will install software on your machines which helps distribute SPAM emails. If you notice emails being sent from your network get frequently stuck in other spam filters, it’s probably because you got blacklisted as a source of spam. This is very difficult to reverse and can mean a severe hit to your company’s credibility. Not to mention a waste of your computing and network resources as well as person hours to clean the system.
Often times the successful attacker will also routinely scan your system for credit card numbers and passwords stored on your hard drive.
Another common usage of infiltrated systems are targeted attacks against other networks – so called distributed denial of service (DDOS) attacks. The intruder will install software on your (and thousands of other) machines that “sleep” until they receive a start signal, at which point they bring the target network to its knees by flooding it with too many requests. This so happened to amazon, ebay and many other of the big players.
Thing get embarrassing when client related information get exposed and the source tracked back to your company. Remember that you are responsible for taking “appropriate measures” to protect your client’s information. While you might be able to demonstrate this in front of the court of law, it will be much harder to regain your client’s trust.

Apply Common Sense

Use secure passwords! Amazing how often the “number one rule” gets violated! The most basic form of attack applies a dictionary and name lists to guess username and passwords. Networks allowing remote access – via web forms, shell or VPN – and username/password combinations like “paul/paul” are easy targets.

Maintain a firewall for your network and configure it conservatively – only allow access to really essential ports. Ideally, only allow access from trusted IP addresses. If the person responsible for your network can’t explain to you in easy words what a “port” is, you are in big trouble! Ask her – now!!!

Utilize Intrusion Detection Systems (IDS) such as OSSEC or SNORT. If this for some reason proves unfeasible, at least use easy to install tools the like of denyhosts.

Scan emails BEFORE they reach the client machine. For some reasons it seems almost impossible to prevent employees from opening unknown attachments (“Oh look – someone I don’t know sent me a postcard! Lets open it…”) – curiosity kills the cat. Virus scanning emails before they get delivered to the client is a vital element in combating SPAM and preventing virus infestations.

Educate your employees! Knowledge is the best defense. Trust me: The time and money it takes to raise awareness amongst your workforce is nothing compared to spendings on system recovery, damage analysis and control. Some of our clients hold their employees personally responsible for carelessly imposing security risks on their network.

Update all your machines on a regular basis – especially the operating system. Apply the latest security patches for every software installed on your machines.
Regularly virus scan all machines in your network, use up-to-date virus libraries.

Check your server logfiles regularly for suspicious activities.

Encrypt your data using strong encryption! Thus, even if your network gets breached, the intruder wont be able to access any vital data.