How to design and implement unmaneagable and insecure systems
Author: | Jos Visser <josv@osp.nl> |
Version: | One dot zero |
Date: |
Wed Mar 24 11:08:53 CET 2004
|
Or: "Why make things simple and straightforward if we can make them
complex and wonderful?"
Notice: Try to find the real tense of a report you are reading: Was it done,
is it being done, or is something to be done? Reports are now written
in four tenses: past tense, present tense, future tense, and
pretense. Watch for novel uses of CONGRAM (CONtractor GRAMmer),
defined by the imperfect past, the insufficient present, and the
absolutely perfect future".
-- Amrom Katz
Introduction
As we all know, it is actually in nobody's interest that any system (be
it software, infrastructure or something else) we design and implement
is secure, simple and easy to maintain. For reasons of job security and
status elevation, insecure, complex and unmanageable systems deserve
our undivided loyalty. Because of this, we need to do anything within
our powers to build new systems with similar properties and to extend
and complicate existing systems even further.
It breaks my heart to see that, while the intention is surely there, so
many of the systems we create are far from the intricate interwoven
unfathomable mesh of components they could and should be. It requires
skill, perseverence and stamina to build a truly complex and (thereby)
unmanageable and insecure system. Without a dedicated effort, the
systems we create will be simple and straightforward, thus negating the
very purpose of our existence.
Some people think that sheer
incompetence is enough to make a system unmanageable. Nothing could be
further from the truth. Although it is certainly true that in every
simple and secure solution we build, there is a complicated and
insecure one trying to break free, it requires dedication to make that
happen.
This paper contains guidelines that we should adhere to when designing
and implementing systems. It is my hope that by following the
instructions laid down here we can realise the full potential of the
little gems of simplicity that we still got lying around.
Requirements
The most beautiful aspect of designing and implementing overly
complicated systems is in correct use of the requirements that we have
to build to. The quality of any system can be measured against how well
it implements the requirements and the better (more far fetched) the
requirements, the easier it is for us to let our imagination run wild
and to justify a more complex system.
Interpret requirements as set in stone
The core theorem of the art of designing and implementing unmanageable
and insecure systems is to take the original requirements (no matter
the process through which they came to us) as immutable and set in
stone. We all know that one fool can ask more questions than one
thousand wise men can possibly answer. By interpreting requirements as
axioms that can not be disputed we ensure that one of the other two
variables of every process (time or money) must be variable, leading to
job security for many (time is variable) or few (money is variable) of
us. Revering requirements as laws of nature is also the most precious
of your reasons for making any system as complex as you want it to be.
Invent new requirements
If in any situation the original requirements would not justify a
system on the scale of magnitude that we are striving for, liberally
invent new requirements that will complicate the system beyond anyone's
wildest dreams. In order not to draw too much attention to your actions,
there must be a sound reasoning behind your introduction of these new
requirements. The following list might help here:
- Cite auditing requirements
Requirements from the auditing department have the comforting side
effect that they are
indisputable (cast in stone), which gives weight to the new
requirement. Furthermore, nobody knows what the auditing
requirements actually are, so there is no one who will dispute your new
requirements.
- Mention future processing volumes or other changes
Predictions are difficult to make, especially when they concern the
future. A fool proof method of complicating your system is inventing
huge workloads that will be passed through the system in the near
future. Nobody will object, because huge workloads mean that the system
is important (which adds to everyone's status). And, as a bonus, nobody
will be able to prove you wrong in the here and now, which is a Good
Thing (tm). Another category of future events that you can use for
your purpose of creating the system as it Ought To Be is that of
changes in the environment in which the system lives. Think about
upcoming standards, a network redesign, a reorganisation or a new
baseline architecture (more on architecture later in this document).
- Mention corporate standards
A corporate standard is another great way to add requirements to a
system. As with auditing requirements, nobody knows what the
corporate standards actually are, and usually there are so many
conflicting ones to choose from that you have almost unlimited freedom
if you decide to take this route. More on this item in the section on
"standards" further down this paper.
- Align with other organisational units
Another great way to add requirements to a system is to strive for
alignment with other initiatives or organisational units. Again, there
are so many different avenues to choose from that the potential for
complicating the system are boundless. The best ones are where you can
align with an initiative which is not yet ready for productional use.
Not only does it
show that you are imaginative, willing to take risks and have a sharp
eye for future developments, but you are then also licensed to make
iterations in your design as you align with a moving target.
Technology
When striving to create the most complex (and thereby unmanageable and
insecure) system for a given set of requirements, technology is your
best friend. Most people's grasp of technology is so low that they won't
know whether your design will actually work or not, where its flaws are
and whether you're actually telling the truth or just plainly guessing.
Selecting complex technology is also your permit for extensive pilot
programs and proofs of concept (which take time, and are therefore
invaluable to your job security).
Using the age old adagium that every sufficiently advanced technology is
indistinguishable from magic, your selection of every advanced
technology that you can think off will complicate your system and thus
assist you in reaching your overal goal.
Justifying your technology selection can be done from any of the
following underlying reasons:
- Your advanced requirements require this advanced technoloy.
- This technology is a corporate standard.
- This technology is "best of breed".
- This technology conforms to the "best practices" in the field.
- Gartner says that this technology will be the winner in its field
(with a 80% probability or more), therefore we must "position" ourselves
for it right now.
- This is an out-of-the-box solution.
Technology solves all your problems!
Given people's meagre understanding of technology, you can safely
proclaim that a particular technology will solve any yet unsolved
problems in your design. Good statements to make here are:
- There is an API for this.
This statement is especially powerful if you are building a J2EE
application. J2EE is so huge that nobody actually knows what it
does or contains...
- This is solved by widget X.
Good examples of widget X are: layer four switch, proxy, firewall,
plugin, Websphere, SSL and HTTP protocol. Most people have no
understanding whatsoever about how these function or what they contain,
so they are not capable of contending your statements!
Product selection
An important aspect of every design and implementation process is the
selection of which tools and products will be used to build, monitor
and maintain the system. It is here that great progress can be made in
reaching our goal of complex, unmanageable and insecure systems.
It is clear that a prime method of creating the type of systems we aim
for is in selecting and using as much complex technology as possible.
This means amongst other things always using the highest releases and
employing as many advanced features as we can think of. Justifying this
is easy once you have done your homework in the requirements arena.
It is obvious that doing a technology push usually involves working as
much as possible with advanced proprietary technology from big vendors.
The beauty of proprietary solutions is that they usually contain the
features that the vendor can sell, as opposed to the features that you
actually need. Mostly these features are extremely complex, which plays
directly into our hand. Furthermore, maintaining vendor relations
enhances your status and insures you against wrong choices since a
scapegoat (in the form of the vendor) is readily available. This
strategy thus brings you three things at the same time: it enables you
to implement complex technology (thus supporting our main goal), but it
enhances your status and buys you insurance at the same time.
Disregard open source tools as much as possible
Open source software has the nasty habit of being simple,
straightforward and secure. I do not need to stress that this completely
opposes everything we stand for! Fortunately, open source software is
not difficult to block. Take the following list of arguments that have
proven their worth many times over:
- Support! Support! Support!
Since nothing motivates people more than fear, the "support" argument
is your best friend against easy to implement, secure and
functioning software. Since you are talking about future
problems (for which a support contract is an insurance policy) you can
safely disregard all evidence from the past which would point out that
most open source software usually runs flawlessly. Insisting on a
support contract makes you look responsible and proves that you want to
build a system that is surrounded by all the required safeguards (do you
also hear the word "requirement" here?). Furthermore, since most people
do not know that it is possible to take out support contracts on open
source software, you can simply ignore that very fact.
- Security by obscurity
Since most people do not understand security issues very well, the age
old argument that open source software is insecure because everybody can
inspect the code still works brilliantly.
- Fuel the GPL scare
A novel argument against open source (used amongst others by Microsoft and SCO)
is that it infects your intellectual property, forcing you to open
source your own proprietary application code. This is obviously
nonsense, but since most people have never read the GPL anyway you can get
away with saying this without any problems.
- Cite hobbyism
It has been shown to be difficult for people to differentiate between
PC shareware/public domain software and the open source software of the
GNU project and related movements. This fact can be abused by us quite
easily since it allows us to heap all open source software in the same
category as that shareware backgammon program everybody used in MSDOS
3.22.
Sow fear, uncertainty and doubt, and the unknowing will flock to you for
the solution to the problems that you have drawn their attention to!
Organisation
A big and complex organisation is the ideal cover for your complex and
insecure system. Since each department sees only a small part of your
entire system, nobody is capable of getting the helicopter view that
would show them the width and depth of what you have wrought. Your
job security depends largely on your ability to create the system
in such a way that everybody needs you in order to make the slightest
changes or solve problems. As always, there are time honoured methods of
achieving this that you should not ignore:
Ignore your syadmin scope of control
A key factor in creating our ideal unmanageable and insecure system is
to ignore your operations department's scope of control. Instead,
support the view that it is the sysadmin's job to administer whatever
we build. Then, to show them you are a caring and supportive person,
define a set of courses they have to go to in order to gather the
knowledge and acquire the skills necessary for administering our
system. There is never time or budget to attend the courses, so the
the sysadmins can not administer the hugely complex software
we have burdened them with. But that is not your fault, is it?
Use obfuscated naming standards
The power of a good naming standard should not be ignored lightly. There
is nothing that complicates a system as much as using names like
"sa01pt03" and "tavzh74". By stubbornly insisting on such naming
standards you will also show that you have a clear eye for how
structured names help you in categorising complex infrastructures. The
more information elements you can hide in a name, the better!
Ignore views and opinions from knowledgable people in the field
Every organisation has a bunch of people running around with an
unfortunate combination of talent, insight, experience and vision. It is
obvious that these should be marginalised and ignored as much as
possible since their goals are not ours. Working tactics here are:
- Publicly note that these persons' roles in the organisation do
not include responsibility for architectural issues. Even if this does
not diminish the validity of their views, it does legalise ignoring
them.
- Defuse their dangerous views by mentioning "organisational
realities" (such as corporate standards, auditing requirements,
political issues, budget requirements et cetera).
- If all else fails: Ascribe to their views, but do something else
altogether after "careful consideration".
Separation of functions
An important aspect of maintaining the foggy fuzziness
that is in fact in everyone's best interest is creating the correct
organisational structures. If done correctly you can achieve the
following:
- Involve as many people as possible in even the simplest issues.
This calls for long meetings, conference calls and many, many frequent
flyer miles.
- Encapsulate the techies (also see previous section).
Each project has a couple of people running around with the unfortunate
combination of understanding and hands-on experience that they could
singlehandedly destroy your good efforts to keep (literally) everyone
involved. A good organisational structure prevents this.
By referring to common practices as "separation of function" and "need
to know" you can ensure that:
- Those who understand, can't.
- Those who can, don't understand (nor care).
Doing this ensures that loads of people are required for even the
simplest of tasks. This invariably leads to overshooting deadlines and
budgets, which leads to new deadlines and bigger budgets. It is as
simple as this!
Architecture
(Architecture is the art of wasting space.)
There is no activity so brilliantly suited to supporting our goals of
complex and unmanageable systems as that of IT architecture. In real
life highly talented individuals go to university for many years to
study every possible aspects of designing and creating useful,
manageable and overall working buildings. Fortunately in our IT world
such outright job security damaging requirements do not exist. You
can be a total nitwit with no practical IT experience or understanding
whatsoever and still call yourself an architect.
This fact works greatly in our favour. Since nobody knows what IT
architecture actually is and how to assess an architecture's quality you
can bassically get away with anything as long as you call it "an
architecture". The best job of all is acutally being an
architect since it usually frees you from any and all responsibility.
And if "they" fail to build the system according to your architecture it
is blatantly obvious that they "did not get it" and in fact lacked
the necessary skills to begin with!
Bad software engineering
Do not underestimate the necessity of bad software engineering! All our
efforts to create an unmanageable and insecure system can easily be
twarthed by a few reckless individuals who manage to create a well
engineered and lucid piece of software that is easy to deploy,
configure, debug and administer. It is here that all your skills as a
project leader come into play to ensure that the "right" things are
prioritized and that you maintain the final say in which technological
(S/W engineering) decisions are made.
Whatever you do, PREVENT THE FOLLOWING FROM HAPPENING:
- All configurable settings in one easy to find location.
- All logging through a central mechanism.
- No manual intervention necessary after a crash.
- All error codes and exceptions logged with a stack trace and
legible error message.
- Automatic (non-manual) deployment.
- Automatic re-establishment of lost/dropped connections (to database,
network service, message queue).
This list could go on for quite a while, but you understand what I mean.
A good reference here is http://www.antipattern.com.
Conclusion
In this document I briefly delved into the art and science of creating
unmanageable and insecure systems. I believe there is much more to say
about this topic, but fortunately there are many examples around us.
Most of these examples however are not the product of a scientific
approach but more often than not the result of gifted amateurs. Or sheer
incompetence: You choose.