Hindsight's Twuni/20

Ramblings of a Seattle-dwelling software engineer with his head in the clouds.

Cloud Hosting Can Be Expensive. Should You Consolidate?

| Comments

I have a single server in the Rackspace Cloud that hosts all of my web infrastructure. On it I’m running multiple domains with Wordpress blogs, Java web applications, Ruby on Rails deployments, Jabber/XMPP instant messaging, source code management, MySQL databases, Maven repositories, Joomla installations, continuous builds, and whatever else I or my clients happen to need.

I know, I know. You’re asking yourself…

  • Why the hell would I want to host all of this stuff on one server?
  • Isn’t that just asking for trouble?
  • Isn’t it slow?
  • How can that possibly be a good idea?

If you’re in a situation where you need to deploy a lot of one-off applications, it can get expensive to spin up a new VM for each thing. This is especially true if you’re using managed virtualization like Rackspace Cloud or Amazon EC2, but also applies if you manage your own hardware and virtual machines. Each VM has a cost, whether it be monetary or computational overhead. Sometimes it just makes more sense to consolidate.

Thankfully, Unix was designed for multi-user systems, so installing and sandboxing multiple applications on a single system comes very naturally. By following a few simple principles, you can have your cake and eat it too with a single VM without sacrificing managability, scalability, or performance. Here’s how I do it.

Sandbox yourself.

Sudo sparingly, and avoid using system-level package managers like aptitude (apt-get) because they tend to affect all users. Also, over time you lose track of what libraries or dependencies you may have hurriedly installed. Learn to compile from source, and practice installing things without ever having to sudo.

I’ve adopted the habit of creating a new Unix user for each application or service I want to install. For example…

Adding a sandbox for nginx
1
2
adduser --system --home /srv/nginx --shell /bin/bash --disabled-password --disabled-login nginx
su - nginx

Git yourself together.

The next thing I do is to create a Git repository to keep track of all of the changes I make over time with the service I’m configuring.

Initializing a Git repository for nginx
1
2
mkdir -p /root/git
git init --bare /root/git/nginx

I add a post-receive hook to the service’s Git repository to update the configuration whenever I push changes to it.

/root/git/nginx/hooks/post-receive
1
2
3
4
#!/bin/sh

GIT_WORK_TREE=/srv/nginx git checkout -f
chown -fR nginx:nogroup /srv/nginx

Now I can locally clone the empty repository and get to work…

Cloning nginx from example.com
1
git clone root@example.com:git/nginx

Now I can test all I want locally, and when I’m ready to push the changes to the server, I just run git push.

Keep it up.

Once everything is working, the final step is to register the new service with the system’s startup and shutdown events. I keep a generic service template at /srv/service. When I’m configuring a new service, I do something akin to the following:

Registering the nginx service
1
2
3
4
5
cp /srv/service /srv/nginx/service
nano /srv/nginx/service
# ...configure the service script to taste...
ln -s /srv/nginx/service /etc/init.d/nginx
update-rc.d nginx defaults

Putting it all together.

addservice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/sh

if [ $# -lt 1 ]; then
  echo "Usage: $0 NAME [DESC [EXEC [ARGS]]]"
  exit 1
fi

SERVICE_NAME=$1
SERVICE_HOME=/srv/$SERVICE_NAME
SERVICE_REPO=$HOME/git/$SERVICE_NAME
SERVICE_DESC=$2
SERVICE_EXEC=$3
SERVICE_ARGS=$4

test -z "$SERVICE_DESC" && SERVICE_DESC="$SERVICE_NAME"
test -z "$SERVICE_EXEC" && SERVICE_EXEC=$SERVICE_HOME/sbin/$SERVICE_NAME

echo "+----- Adding service -----+"
echo "  Name:        $SERVICE_NAME"
echo "  Home:        $SERVICE_HOME"
echo "  Repository:  $SERVICE_REPO"
echo "  Description: $SERVICE_DESC"
echo "  Command:     $SERVICE_EXEC"
echo "  Arguments:   $SERVICE_ARGS"
echo "+--------------------------+"

adduser --system --home $SERVICE_HOME --shell /bin/bash --disabled-password --disabled-login $SERVICE_NAME || exit 1

mkdir -p $(dirname $SERVICE_REPO) && git init --bare $SERVICE_REPO || exit 1

cp post-receive.template $SERVICE_REPO/hooks/post-receive

sed -i '' "s|\$SERVICE_NAME|$SERVICE_NAME|" $SERVICE_REPO/hooks/post-receive
sed -i '' "s|\$SERVICE_HOME|$SERVICE_HOME|" $SERVICE_REPO/hooks/post-receive

cp service.template $SERVICE_HOME/service

sed -i '' "s|\$SERVICE_NAME|$SERVICE_NAME|" $SERVICE_HOME/service
sed -i '' "s|\$SERVICE_HOME|$SERVICE_HOME|" $SERVICE_HOME/service
sed -i '' "s|\$SERVICE_DESC|$SERVICE_DESC|" $SERVICE_HOME/service
sed -i '' "s|\$SERVICE_EXEC|$SERVICE_EXEC|" $SERVICE_HOME/service
sed -i '' "s|\$SERVICE_ARGS|$SERVICE_ARGS|" $SERVICE_HOME/service

ln -s $SERVICE_HOME/service /etc/init.d/$SERVICE_NAME
update-rc.d $SERVICE_NAME defaults
post-receive.template
1
2
3
4
5
6
#!/bin/sh

GIT_WORK_TREE=$SERVICE_HOME git checkout -f
chown -fR $SERVICE_NAME:nogroup $SERVICE_HOME

service $SERVICE_NAME restart
service.template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/bin/sh

### BEGIN INIT INFO
# Provides:          $SERVICE_NAME
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts $SERVICE_NAME.
# Description:       Starts $SERVICE_DESC.
### END INIT INFO

USER=$SERVICE_NAME
HOME=$SERVICE_HOME
PATH=$HOME/sbin:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

DAEMON=$SERVICE_EXEC
DAEMON_OPTS="$SERVICE_ARGS"
NAME=$SERVICE_NAME
DESC="$SERVICE_DESC"

test -x $DAEMON || exit 0

start() {
  stop
  sleep 1
  su -l $USER -c "$DAEMON $DAEMON_OPTS > /dev/null 2> /dev/null &"
}

stop() {
  for pid in `ps -U $USER -o pid --no-headers`; do kill $pid; done
}

reload() {
  for pid in `ps -U $USER -o pid --no-headers`; do kill -s HUP $pid; done
}

case "$1" in
  start)
    echo -n "Starting $DESC: "
    start
    echo "$NAME"
    ;;
  stop)
    echo -n "Stopping $DESC: "
    stop
    echo "$NAME"
    ;;
  restart|force-reload)
    echo -n "Restarting $DESC: "
    start
    echo "$NAME"
    ;;
  reload)
    echo -n "Reloading $DESC configuration: "
    reload
    echo "$NAME"
    ;;
  *)
    echo "Usage: service $NAME {start|stop|restart|force-reload|reload}" >&2
    exit 1
    ;;
esac

exit 0

Now, when I want to deploy a new service, I just do this…

1
2
3
4
5
ssh deploy@production addservice foo
git clone deploy@production:git/foo
cd foo
# ...commit some stuff...
git push

This boilerplate works well for most things, and all I usually have to do afterwards is tweak the /srv/foo/service file. This could be a good start toward a distributed configuration management system like Puppet. I haven’t actually automated as much of this process yet as it would seem from looking at the scripts here. In fact, I haven’t tested addservice at all, yet. The gist of what it’s doing, though, is this:

  1. Collect information about the service being added.
  2. Create a Unix user with minimal privileges, to own the new service.
  3. Create a bare Git repository to hold all configuration data for the new service.
  4. Configure this Git repository to deploy and restart the service whenever it receives a push.

My workflow is something akin to this:

  1. Develop this new service locally until I’m happy with it.
  2. Configure the service in production via the steps listed above.
  3. Add production as a remote, then push to it.

After the initial configuration, whenever I need to make changes, I do so on my local copy, then push whenever it’s ready. Some examples of services I operate this way include…

  • Nginx
  • Varnish
  • WordPress
  • Joomla
  • GitLab
  • Tomcat
  • Sinatra apps
  • Rails apps
  • Static websites
  • Archiva
  • Jenkins
  • Openfire

I’m paying for a single cloud server for all of these things, without compromising performance or introducing unnecessary complexity. If anything ever happens to this server, I can spin up another one just like it because I can account for every customization that has occurred with every application or service that has been installed.

In combination with a plan for synchronizing volatile data such as logs and databases, this has proven to be a pretty powerful way to manage my servers. Hopefully it will serve you well, too.

YMMV. This works well for me because I don’t get a significant amount of traffic, but I still need to host a wide variety of applications which, at any given moment, should perform optimally. I’ve tried to mitigate the risk of a sudden rush of heavy traffic causing the server to fall over, but that hasn’t yet been put to the test. Any suggestions of how to improve my configuration are welcome.

Password Policies

| Comments

Now I’m not fond of passwords or account creation in general, but since it is such a popular abomination to implement, I figured I should comment on how to make that process as painless as possible.

First of all, I can think of no reason to place any restrictions on a password input field. A password should be as short or as long as the user would like for it to be. Instead of restricting the user to do only what you want them to do, instead try and educate them on why a longer password is better than a short one, or why using a single dictionary word like “god” or “password” is probably a bad idea. A little education can go a long way. But if they still want to use their username as their password, let them do it. It’s their account, after all.

Here are some ideas of what to do when implementing an account creation form that contains a password field. In no particular order:

  • Allow all printable characters, including whitespace, symbols, numbers, letters, accented characters, and punctuation. If you are properly encoding/decoding the password and encrypting it for storage, then your application should be completely agnostic to whatever characters are actually contained in the password.
  • Allow any length of password, from zero-length to some reasonably high limit (e.g: 512 characters, allowing for the approximate size of a 4096-bit RSA public key).

More to come, with examples of ways folks are doin’ it right (or wrong)…

The Ideal Programming Language

| Comments

Just the other day I gave way to musing about how the ideal programming language might look. Some properties immediately came to mind:

  • Dependency inference, with support for explicit dependency declaration.
  • Each dependency is versioned and signed.
  • Concise, non-abbreviated, natural syntax.

The Hello World example for this language would be simple and elegant:

1
"Hello, world!"

I began putting together the semantics of such a program, and came up with the following:

  1. The entire script is global. Enclose it in the default, inferred container.
  2. The statement(s) contained within the script are not enclosed within a method. Use the default initializer method for its container.
  3. The statement is the last of its method, so its result will be the method’s return value.
  4. The statement is atomic, and its syntax determines that it is of type String.
  5. When any script in this language is initialized and the entry point is not specified, the default container will be initialized.
  6. The default container simply accepts input from stdin and prints the result to stdout.

Consider the following Java program:

HelloWorld.java
1
2
3
4
5
6
7
8
9
10
package com.example;

import java.lang.String;
import java.lang.System;

public class HelloWorld {
    public static void main( String [] args ) {
        System.out.println( "Hello, world!" );
    }
}

The language makes no assumptions about the programs that are built with it. Let’s consider what can be eliminated from this minimal example. In fact, though this example declares everything possible, it is functionally incomplete.

Dependency Declaration

The ideal programming language would have build tools that have cryptographic dependency management.

Consider the Apache Commons libraries. You might declare a dependency in a Maven project descriptor as follows:

1
2
3
4
5
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang</artifactId>
    <version>1.1</version>
</dependency>

This will tell Maven to search its known repositories for artifacts matching that descriptor and provide the dependency to your project at compile-time. While this works reasonably well, it is not fool-proof, and it contains some dependencies that are impossible to declare in a Maven project descriptor. Namely:

  • You are trusting that the Maven repository will actually contain the artifact you are describing.
  • You are trusting that the artifact provided to you by the Maven repository is actually the one you need, and not:
    • …a malicious artifact that happens to match the descriptor.
    • …a misnamed artifact uploaded by mistake.

A fool-proof dependency declaration would be as follows:

1
2
3
4
5
<dependency>
    <name>commons-lang</name>
    <author>98E7EDCB</author>
    <package>2b356ef829d10047842df10e508e7044a04177a0</package>
</dependency>

Where author is the PGP public key of the package author, and package is the SHA-1 checksum of the dependency package. If the repository contains the package, it will return an encrypted file which must then be decrypted using the author’s PGP public key. There is still no guarantee that the repository will contain the dependency package, but if it does, you can now verify that it is precisely the package you need.

Dependency Inference

The ideal programming language would not require explicit dependency declaration, but would encourage it. Some algorithm would determine how dependencies are located in the absence of explicit declarations.

Scope

The ideal programming language would allow scopes to be seamlessly declared.

The ideal programming language would be interface-driven, allowing nothing except entry points to exist in the global scope. There should be no method whatsoever to gain access to functionality or code that is not explicitly defined and exposed to the calling scope. All dependencies are guaranteed and mandated to be injected.

Sandbox

Every programming language exists within a sandbox defined by the libraries made available to it and the tools used to run programs built with them. The “Hello, world” Java example outlined above is only functional because the JRE provides java.lang.System and java.lang.String, and the java program executes the static main(String[]) method of the class identified by the name given to it at runtime. If these two things had not taken place, then the program would simply not be functional. There are many transitive dependencies that exist as well, such as the presence of System.out and its println method, which happens to be declared on the PrintStream class. Ultimately, this ends up as a set of machine instructions that places the bytes for “Hello, world!” into a buffer that is collected by the CLI and printed to the console.

Consider what Java would be like if you replaced its core libraries. How good is the Java language itself? Is it elegant? Is it concise? Is it complete?

CMAS Alert

| Comments

I just witnessed someone receive a CMAS Alert. I intend to comment on this further soon, but the concept of such a thing is so absolutely appalling that I had to share the fact of its existence immediately. CMAS describes itself as follows:

The CMAS system provides governments the ability to send location based targeted alerts to the general public, without requiring anything from their citizens.

This is the very definition of spam combined with outright government surveillance.

Reflections on Aboriginal Culture

| Comments

This morning, I gleamed the following observations from my reflections and research on Aboriginal Australian culture:

  1. Aboriginal peoples are nomadic, and have learned to tread lightly and treat their environment with respect. Before European settlers arrived, there were no permanent structures or dwellings and there was no concept of property ownership. Contrast this with the rest of the world’s desire for conquest, creation, and dominance. What effect, then, does this have on the phenomenon of war?
  2. If there are more than a few of something, then for many tribes, “many” is an adequate word to describe the quantity. What effect, then, does this have on the phenomenon of greed?

There are many nuances of Aboriginal life that I do not yet understand, but I believe we who hail elsewhere could learn much from this alone.

How Much of Your Identity Is Public Knowledge?

| Comments

I am compiling this list primarily to assist businesses and software companies in determining what information about a person is safe to collect and use for identification purposes. Because your customer has probably provided any or all of his global personally identifiable information (PII) to other companies as well, you should only allow a shared secret between you and the customer to serve your verification purposes. An easy way to do this is by allowing the customer to write their own security question and answer. You should encourage them to make the question and answer somewhat esoteric yet memorable.

For more information about protecting against identity theft, stopping spam, and retaining some privacy, read on. There is also good advice here.

Social Security

Chances are, your social security number has already been compromised due to a data breach or its inclusion on credit reports, background checks, or other records shared and sold by companies you have entrusted with your SSN. Even if it hasn’t, it can easily be guessed due to the number’s predictable pattern. Furthermore, if an attacker has access to the SSA’s Death Master File, he can guess an individual’s social security number in very few attempts by finding a deceased individual with a similar date of birth to the target and filtering out the SSNs of other deceased persons born around that time with the same area and group number. This Carnegie Mellon study explains the vulnerability in further detail.

Numbers assigned after June 25, 2011, are subject to randomization, which will improve the security of the number. Even with some randomization, however, SSN security is still the cryptographic equivalent of about a random 30-bit private key and is vulnerable to the aforementioned compromisation risks. The Social Security Administration needs to relax its policy of assigning new SSNs so that people born prior to June 2011 can take advantage of randomization in SSN assignments.

For more helpful information about your SSN, disclosure laws, privacy, and your rights, visit this SSN FAQ.

Voter Registration

If you registered to vote in your state, then the following information about you permanently becomes public knowledge:

  • Full legal name
  • Full physical address
  • Gender
  • Date of birth
  • Date of the last time you voted
  • Date you registered to vote

Trademark Application

If you filed a trademark application, then the following information about you permanently becomes public knowledge:

  • Full legal name of applicant
  • Full business name of registering entity
  • Full business address for registering entity
  • Cost of application
  • Email address of applicant

Business Registration

If you registered a business, then the following information about your business becomes public knowledge:

  • Tax Registration Number / UBI
  • Registration date
  • Full mailing address
  • Full physical address

Upgrading to Mac OS X 10.7 Lion

| Comments

I was perfectly happy with Snow Leopard. I upgraded to Lion because I needed to be able to build iOS applications that were written in Xcode 4. I didn’t really know anything about Lion other than that is a prerequisite for Xcode 4.

The upgrade was simple. I just loaded the App Store application, searched for “Lion”, paid the $30, and downloaded the Lion installer. The installer utility guided me through the install (which took all of 30 seconds before going on auto-pilot for 40 minutes). I opted out of iCloud, which seems to be just a repackaging of MobileMe and iDisk, neither of which I ever found the need to use.

Desktop Wallpaper in OS X Lion

After the upgrade, the first thing I noticed was that my desktop wallpaper had been replaced with a new galactic vista. Okay, fine. I never changed the Snow Leopard wallpaper from its default anyway.

Java in OS X Lion

Then I launched Eclipse. A dialog appeared telling me that I needed to download a new Java runtime. I need the full JDK, not just a JRE, but I clicked the Install now button anyway because I was surprised it even offered to download and install it for me. Turns out it was an empty promise, because the button was effectively a Dismiss button, and no task was triggered to download and/or install Java. Fortunately, a quick Google search turned up this Stack Overflow article and I had a JDK installed in short order.

UPDATE: This appears to have been remedied, as I was setting up a new MacBook Pro today, got the same prompt, and Java installed without a hitch. Good job, Apple.

Trackpad Gestures in OS X Lion

During my JDK search, I noticed that the trackpad gestures were not working properly. The gestures I had grown so familiar with and dependent upon had been completely changed in favor of the activation of two new applications (both of which I noticed had been added to my dock after upgrading): Mission Control and Launchpad. Mission Control is basically a mildly tweaked Expos’e. Launchpad is virtually identical to the Android Honeycomb app drawer. I took a trip to System Preferences -> Trackpad to acquaint myself with the new gestures. After using them for awhile, I realized that Expos’e is now completely broken and does not show all of the open windows like it should. I have no idea what the difference between Mission Control and Expos’e is supposed to be. Anyway, the newly added gestures can be summarized as follows:

  • Swipe between apps with four fingers. Cool!
  • Pinch with thumb and three fingers: Open Launchpad, which is basically an App Drawer. You would think that the inverse Spread gesture would make the Launchpad go away, but it only seems to respond to the Escape key. This is stupid.
  • Spread with thumb and three fingers: Show Desktop. This feels like saying “shoo!” to all of your windows, and when the gesture completes, the windows actually slide out of your way. It’s neat.
  • Slide up with four fingers: Show Mission Control, which is virtually identical to Expos’e.

UPDATE: After setting up a new MacBook Pro, I found something I had changed, but forgotten to mention here. The “natural” scroll direction in OS X Lion feels completely backwards to me. In Lion, a two-finger swipe downward will scroll the page upward (and vice-versa). It was simple enough to change, but the reason behind this configuration being called “natural” is beyond my comprehension.

Applications in OS X Lion

When you close an application, it retains its state the next time you open it. For example, if I open an image via the Preview application, then Command-Q to quit Preview, then later open another image via the Preview application, the image from earlier appears again. Keep this in mind. When you’re done with a file, close it with Command-W first. Then, if you want to close the application, go ahead and Command-Q it. I think Lion just assumes that most people will leave applications open anyway, and it probably takes lessons learned from building iOS to manage those idle resources fairly well.

There’s also this new notion of locking a file. Occasionally when I’m trying to edit something (a text document, perhaps), I get an alert box informing me that the file is locked and that I should click the Unlock button in order to start modifying it. So far, the algorithm for determining whether or not a file will be “locked” when I need to modify it seems arbitrary and random. I haven’t run into this very often, but it is reminiscent of Perforce and I don’t like it.

Wireless Networks in OS X Lion

After upgrading, I found that Lion started preferring to connect to open guest networks rather than the secured networks I had already configured and set to be preferred. I had to retrain it for my home network and for that of one of my clients. Just be aware of which network you’re connected to when you’re somewhere for the first time after upgrading to Lion.

Development in OS X Lion

Out of the box, Snow Leopard had a CLI for Ant, Maven, Subversion, and Git already installed. Lion has neglected including a Git CLI. This was an unpleasant surprise, but if I can’t install Git on my own, I probably shouldn’t be writing any code, either.

Finder in OS X Lion

When you launch the Finder now, the default view is All My Files instead of your Home directory. I’m sure this is great for most people, but I keep my files in a tight hierarchy. A quick trip to the Finder Preferences allowed me to change this default view back to my Home directory. Ahhh… sigh of relief

Shutting Down OS X Lion

The Shutdown dialog for Lion has a checkbox labeled, “Reopen windows when logging back in.” This is checked by default, and if it remains checked, Lion effectively goes into hibernation rather than shutting down. This causes the shutdown time to increase drastically (i.e: from 3-5 seconds to about 45-60 seconds in my case). There is no option in System Preferences for unchecking this by default, and this dialog does not remember whether I left it checked or unchecked last time. Fortunately, I’ve found this little script to help make sure that I don’t forget to uncheck that box ever again.

Other Thoughts on OS X Lion

Scrollbars work more like what I’ve gotten used to in mobile UI: they disappear when they’re not in use, when you scroll too far, you get the void space and the scroll acceleration decreases dramatically. The native OS buttons are also more crisp. I’ve noticed that Chrome now has a full-screen icon in the upper-right corner. I’m not sure if this is a Lion feature or a Chrome feature, but I’ve found it to be pretty useful except that full-screen mode also makes the Dock inaccessible. Aside from the initial Java hiccup, I haven’t found any incompatibility issues yet with Lion. Performance seems to be on par with Snow Leopard, and the amount of disk space used by the OS is comparable.

I still haven’t installed Xcode, yet. I’m hoping that it will install in the 7GB remaining on my puny but powerful 32GB Intel X25-E SSD hard drive formatted with the Mac OS X Extended Case-Sensitive Journaled filesystem, or at least onto my external Western Digital My Passport 1TB USB 3.0 hard drive formatted with ExFAT.

All in all, now that I’ve been using Lion for a couple of days, I’m happy with the upgrade. Sure, there are some growing pains, but if you’ve got the spare $30, go ahead and drop it.

Resources for Anti-Spam and Opt-Out

| Comments

Today, I researched and decided to take advantage of some resources for preventing spam and identity theft. Ironically, the “solution” to removing yourself from these lists is to add yourself to an “anti-list,” which of course is just another list. Still, I think that taking these steps is better than doing nothing.

For your benefit, here is the list of resources to help you to prevent spam and identity theft.

Stop Telemarketers

Prevent unsolicited telephone calls by registering with the National Do Not Call Registry at .

Stop Junk Postal Mail

Prevent unsolicited postal mail by registering with the Direct Marketing Association (DMA) at .

Stop Text Message (SMS) Spam

Check out this article at Internet Patrol (which, ironically, has popup advertisements, so watch out). I found that some of the information there is outdated, so if you are a Verizon Wireless customer and want to stop the vast majority of text message (SMS) spam, you’ll want to disable the “feature” that makes it easy to spam your phone: web/email SMS. Here’s how to do it.

  1. Login to your Verizon Wireless account.
  2. Visit the elusive Internet Spam Blocking page.
  3. Check the box for Block all text messages sent from the web..
  4. Check the box for Block all text messages sent from email..
  5. Click the Apply button.

This only blocks messages sent via Verizon’s website. There are plenty of other ways for spammers to abuse the SMS network, but this is a start.

Stop Email Spam

Use Spamgourmet and - once you have learned how to use it effectively - never give out your “real” email address again. It is by far the best spam prevention tool for email, and it’s free.

Protect Your Credit

Block access to your credit history by placing a security freeze at the three major credit bureaus (Equifax, Experian, and TransUnion). Amongst other things, this prevents anyone from taking out credit in your name, which can be a very important safeguard against identity theft. Whenever you need to provide an agency with access to your credit history (e.g: applying for an apartment, bank account, line of credit, or a loan), you can temporarily lift a freeze using a PIN that you create or receive when placing it.

  • Equifax: (fee: $10)
  • Experian: (fee: $10)
  • TransUnion: (fee: $10)

Reporting Spam

Finally, the spam you do receive even after following all of the above steps is probably a violation of FCC rules and you can file an official complaint. You can report telemarketing spam, SMS, and even email spam. The more information you provide in your complaint, the more likely the FCC will probably be to honor it.

Opinions on Convolution

| Comments

It’s easy to write about pet peeves. We’re quite familiar with our own, and because we are affected so much by them, we tend to go off on tangents and rants quite easily. Humans, generally speaking, are very good at whining. Sit me in the vicinity of some nuisance, give me a blog, and I’ll write for hours. This time, instead, I’ll try and keep it short and succinct.

One of my most prominent grievances is convolution. Most things are needlessly complex. Maybe this is because no one has taken the time to attempt to engineer a “perfect” solution for those things. Maybe this occurs when the initial development of that thing results in a tangled mess, but when faced with better solutions the affected parties have learned to deal with the mess well enough to resist changing to something arguably better long-term.

Sometimes interactions are overly complex due to a mutual lack of understanding of how to proceed most effectively with a resolution to the tasks in question. This happens most often with logistics among friends, such as splitting a dinner bill, determining car pools, or deciding on which X works best for everyone. Other times, they become tedious with procedural convolution wherein bureaucracy rules, such as printing and completing a 25-page questionnaire when the answer to every question is known beforehand to be “No.”

On a larger scale, it’s even easier to see the convolution. A large entity such as a government, a large corporation, or a global non-profit organization, is exceedingly vulnerable due to the number of people and rules involved in managing these entities. A system is difficult to understand at a level consistent with the number of rules governing that system. This is true of all systems, though I first learned of this during my Computer Science studies. This is an argument used in software to support modularity and object-oriented design, though I feel that the spirit is lost in the rigorous “agility” that embodies modern software development where the rush to market often trumps the importance of good engineering.

This observed convolution in today’s financial systems is one thing that initially drove me to developing Cash in Hand. The concept of exchanging goods and services is simple, so why should the systems that support it not be so? For special cases, let there be modules to support those and which integrate in reasonable ways.

Do you remember taking mathematics and having to simplify equations? Even in Logic courses, we had to simplify logic equations. This technique when applied to everyday situations is commonly referred to as “cutting the BS.” Let’s all work to hone that technique, and maybe we’ll live in a more simplified world.

A Tangent… the Anarchy of Thought

| Comments

The overhead involved in getting a virtual currency wired into the existing financial system is proving to be nothing short of nightmarish. After weeks of battling legal and payment processing issues, I have decided to retire my personal efforts at creating an automated exchange for Digital Cash backed by $USD.

I created the Twuni, Inc. business entity as a means of abstracting my legal and commercial interactions and separating them from my personal legal identity. This is loosely based on the concept discussed in The Lifecycle of Software Objects (search for incorporation on the text to see what I’m referring to). It was relatively cheap and easy to create this entity (about $200 for the incorporation itself and $30 for a business license). I may document the process I followed to do this in another post, though I imagine it would be different for each state. Problem is… when you operate on behalf of a business entity, you still must present personal identification. In fact, there is not much difference between the interactions that take place when you are operating as an individual versus operating as a business entity. You can’t present identification that says, “I am Twuni, Inc.” Instead, you present your regular identification and say, “I am such-and-such, and I am authorized to act on behalf of Twuni, Inc.” This is not exactly the end I was going for.

After I realized this, I decided that I could still salvage the expense of forming the entity by creating an actual business. First, I intended to operate Twuni as a consulting agency, delegating my contracts to Twuni instead of signing them personally. I quickly discovered that unless I intend to hire additional employees, this arrangement is unnecessarily complex. My independent consulting would be much better off as a direct engagement. So scratch that idea.

Next, I decided that I would form a business of operating a Digital Cash exchange. Basically, I would provide an online gateway wherein one could exchange Digital Cash tokens for $USD and vice-versa. I’d charge a fee for each transfer to cover operating costs. After being rejected by three payment providers (PayPal, Authorize.net, and Cardservice International), I decided that this was simply not going to work. Even had I been approved for any of these, however, the fees involved would cause the transaction fee I charge to be at least 10%, which is ridiculous.

A rough overview of the credit card system should suffice to explain why it sucks to be a part of it and why some restaurants charge an additional fee when using credit cards.

To operate an online payment gateway, you have to register with a payment gateway and obtain a merchant account. The payment gateway interacts with the automated clearing house via your merchant account. This merchant account is held with a company that is a member of each of the credit card issuers (i.e: Visa, MasterCard, AmEx). These credit card issuers are each payment processors themselves, with accounts and contracts with different banks. Every one of these business interactions involve some sort of membership fees, transaction fees, or a combination of the two. To cover these, each business charges a fee to the next business upstream. So the bank charges Visa, Visa charges the merchant, the merchant charges me (the operator of the store), and then I charge you (the customer). Also, the payment gateway charges me for the convenience of interacting with the ACH. So basically, there are N businesses in the payment stream who each are each taking a cut. Contrast that with Digital Cash itself in which anyone could technically and directly operate an exchange.

So I have created a virtual currency called ECHO that is backed by text. This will be the reference implementation for Digital Cash. Digital Cash backed by $USD is a task that I will defer to banks and financial institutions. I’ll expend my efforts instead toward creating a good Developer’s Guide, offering assistance in setting up Digital Cash systems, and providing reference implementations for common use cases that Digital Cash would be perfect for.

On an unrelated note, I started to explicitly declare Twuni as the owner of my intellectual property. Not that this would make much of a difference from a legal standpoint, but I could remove my own name from such declarations and achieve my first goal. However, the more software I write and the more things I invent, the more I realize that I just want to volunteer it to the world.

This whole experience has taught me that I am not an entrepreneur. I am an inventor, an innovator, and an artist, but I have little interest in capitalism. I have a great passion for inventing useful software that I perceive as having significant social and practical benefits. I have a great passion for software engineering that extends beyond the scope of my independent projects, helping others realize their own innovations and dreams. I won’t make a living my giving software away for free, but I’m going to keep doing it. I’ll instead make my living by engineering software for others that are more entrepreneurial than myself.

That’s the plan.