Languages
Social Media
Feeds
Social

Friday
Jan272012

Building Amazon EC2 Machine Images (AMIs)

Amazon's EC2 provides a great platform for your applications, it can allow you to scale your application seemingly infinitely. This is great, however there are people like myself who like to have more control over the servers we run. Amazon provides a decent set of prebuilt systems, mostly ready to use, there are also a vast selection of community images, however I don't much like these, call me paranoid but one just doesn't know whats installed. I feel that the best option is to build your own image, the process, although not for a novice, is fairly straight forward. I'm going to attempt to detail what I feel is the best process, this will be based on Debian, and the process will require an existing Debian system.

What you'll need:

 

  • Working Debian System - You could use any other distro, but you'll have to do some research to replace some of these commands
  • Amazon AWS Account (Create one free @ http://aws.amazon.com/
  • Amazon Account Number (#1)
  • Access Key ID and Secret Access Key (#2 and 3)
  • x.509 Cert, you'll need both files pk-xxxx and cert-xxxx (one the tab labeled #4)
  • About 2-3 hours depending on your internet connection.

First thing is to install some required packages.

apt-get install debootstrap ruby sun-java6-bin libopenssl-ruby curl zip
Now lets download and setup some packages that are necessary to bundle and upload the AMI.
mkdir /opt/ami_tools
mkdir /opt/api_tools
mkdir ~/ami_tools
cd ~/ami_tools
wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.zip
unzip -d ./ ec2-ami-tools.zip
cp -R ./ec2-ami-tools-1.4.0.5/* /opt/ami_tools/
#note that your version number may be different than this.
mkdir ~/api_tools
cd ~/api_tools
wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
unzip -d ./ ec2-api-tools.zip
cp -R ./ec2-api-tools-1.5.2.4/* /opt/api_tools/
#note that your version number may be different than this.

#add the ami-tools and api-tools to the $PATH var
PATH=$PATH";/opt/ami_tools/bin;/opt/api_tools/bin"

#this bit here is not necessary but I like to clean up
cd ~
rm -Rf ami_tools/
rm -Rf api_tools/

Next we need to create a disk image for our AMI, you can use most any size you want from ~350MB (roughly the smallest Debian/Apache server I've been able to build) to sever hundreds of GB (I don't know where the roof is).  I'm using a VM to build the AMI it has a second disk attached to it which is where I store the images it is mounted at /ami we'll assign this to variable so that you can copy and past most of my commands. First lets assign the name of our image to a variable so you can copy and past, this also helps reduce typos.

export AMI_Name=debian_lamp
export AMI_Path=/ami/$AMI_Name
#change this to fit your environment.
Now lets create what will become our virtual disk.
dd if=/dev/zero of=$AMI_Path count=10240 bs=1M 
The output should be something like
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 36.9953 s, 290 MB/s
This will create a file of all zeros whose size which 10240 blocks of 1 MB (~10GB), you can adjust this to be however large you'd like. This will take a few minutes, when it's done let create a file system on the new file.
mkfs.ext3 -F $AMI_Path
the output should be something like
mke2fs 1.41.3 (12-Oct-2008)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
655360 inodes, 2621440 blocks
131072 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2684354560
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:

        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 31 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
If you don't want to use ext3 you can choose most any other option. Now that we've got a filesystem its time to mount this disk and get the operating system setup.
mkdir /chroot
mount -o loop $AMI_Path /chroot
Verify that it is mounted and that everything looks good:
mount
/ami/debian_lamp on /chroot type ext3 (rw,loop=/dev/loop1)

df -H
/ami/debian_lamp        11G   158M   9.9G   2% /chroot
Now we can bootstrap Debian unto this disk
debootstrap --arch i386 lenny /chroot/ http://ftp.debian.org 
This one is also going to take a while, it will download and install all of the packages needed for a base system to run, except for the kernel. Once that is finished we'll enter the disk with a `chroot /chroot`. Now everything we do here effects only the virtual disk, which will become our AMI, not our host system. Now that we've created an environment, we can start preparing that environment for Amazon and we can install some of our software now.
chroot /chroot
Now, until we leave the chroot everything we do only affects only that environment. Lets first setup some of the 'devices' that are both required, and nice to have.
mount /proc
cd /dev
MAKEDEV console
MAKEDEV std
#You'll need these to mount Amazon EBS Volumes.
mknod /dev/sdf b 8 80
mknod /dev/sdg b 8 80
mknod /dev/sdh b 8 80
mknod /dev/sdi b 8 80
mknod /dev/sdj b 8 80
mknod /dev/sdk b 8 80
mknod /dev/sdl b 8 80
mknod /dev/sdm b 8 80
mknod /dev/sdn b 8 80
mknod /dev/sdo b 8 80
mknod /dev/sdp b 8 80
Now lets set a root password
passwd
Setup both networking, and fstab
echo -e 'auto lo\niface lo inet loopback\nauto eth0\niface eth0 inet dhcp' >> /etc/network/interfaces
echo -e '/dev/sda1 / ext3 defaults 0 1\n/dev/sda2 swap swap defaults 0 0' > /etc/fstab
There are a few packages which will make things easier and at least one which is required (ssh).
apt-get install ssh locales
#locales & tzconfig make it easier to install other packages
dpkg-reconfigure locales
dpkg-reconfigure tzconfig
At this point you can install any packages you need, if this is going to be a LAMP system:
apt-get install apache2 php5 php5-mysql libapache2-mod-php5 mysql-common mysql-server
You may also choose to add any code that you would like to have. If you are running a website you can upload it. When you've installed all of the packages that you want, leave the chroot, and unmount it.
exit
umount -l /chroot
You'll need to upload both the certificate files that you downloaded from Amazon (pk-xxx & cert-xxx) and we'll assign some variables to them (I keep mine in ~/.ec2)
export EC2_PRIVATE_KEY=~/.ec2/pk-xxxx.pem
export EC2_CERT=~/.ec2/cert-xxxx.pem 
Set the Java environment variables.
export JAVA_HOME=/usr/
If your not sure where java is run
whereis java

Were almost done, I promise ;).

So now were going to bundle the image into an AMI and upload it to Amazon. To do this we'll set a few variables to make things a bit easier.
#These are fake I promise, although if you really want to try feel free.
export EC2_ACCOUNT_NUM=12345678901
export EC2_ACCESS_KEY=qwerty123
export EC2_SECRET_KEY=321ytrewq
export EC2_HOME=/opt/ami_tools
Lets create a variable to store the name of the S3 bucket were going to upload to.
export S3_BUCKET=ami_bucket
Now lets create the bundle, this is done by the Amazon AMI tools package we downloaded earlier. This process is going to take a while and is going to consume some disk space in /tmp/.
/opt/ami_tools/bin/ec2-bundle-image -i $AMI_Name --cert $EC2_CERT --privatekey $EC2_PRIVATE_KEY -u $EC2_ACCOUNT_NUM
Now we'll begin the upload process, this is also done by the Amazon AMI tools package we downloaded. This is also going to take a while depending on the size of your Image and the speed of your internet.
/opt/ami_tools/bin/ec2-upload-bundle -b $S3_BUCKET-m /tmp/$AMI_Name.manifest.xml -a $EC2_ACCESS_KEY -s $EC2_SECRET_KEY
Now we can use the EC2 API to start an instance of our new image so that we can test it.
export EC2_HOME=/opt/api_tools
We can register the AMI which will allow us to create an instance of it.
/opt/api_tools/bin/ec2-register $S3_BUCKET/$AMI_Name.manifest.xml
The result from that command will include the AMI Id of the new AMI, it will look like 'ami-s35123'. Now lets run an instance of this image.
#Be sure to use the AMI ID you got from the ec2-register command
/opt/api_tools/bin/ec2-run-instances ami-s35123
This command will also output some important information, including the instance id in the format 'i-chd3382'. We can use this id to check the status of the instance.
#Again use the id from above.
/opt/api_tools/bin/ec2-describe-instances i-chd3382
If this isn't your first AMI your going to need to open port 22 so that you can connect to ssh on the new server.
/opt/api_tools/bin/ec2-authorize default -p 22
You should now be able to connect to the server, you can get the ip from the 'ec2-describe-instances' command and with the same command you'll see when it's online and ready to use (it's status will be 'running').
Tuesday
Jan242012

Searching recursively through the contents of an entire directory.

A bash script to search recursivly through the entire current directory looking for the specified text. I'm just posting this because it's something I use fairly regularly.
#!/bin/bash
lookingFor='_CHANGE_ME_TO_WHAT_YOUR_LOOKING_FOR_'
MINLEN=${#lookingFor}
i=0
for f in `find . ! -type d`;
do
if [ $f == $0 ];then
j=12
else
line=`grep -i "$lookingFor" $f | sed 's/^[ \t]*//'`
#echo $line
len=${#line}
if [ "$MINLEN" -lt "$len" ]
then
echo "$f:`grep -n "$lookingFor" $f | cut -f1 -d:`"
echo "$line"
echo ""
i=$(($i+1))
fi
fi
done
echo $i" files found with: "$lookingFor
Sunday
Jan152012

SOPA/PIPA The end of the internet as we know it.

Ok, so the title may have been marginaly overdone, but I honestly believe that if SOPA or PIPA were to be passed it would mean massive changes to the ineternet and most (if not all) of them will be bad.
Instead of telling you how SOPA and PIPA are bad, I'm going to give you a tour through what my day might be like if SOPA or PIPA were to pass.
I like to start off my day (like many people) by checking my email, so I open my browser and tap the bookmark for my gmail account.  I read through my email and decide to check on twitter.  When I navigate to http://twitter.com I see something like this
Well damn, I guess I'll just head over to facebook.
Well, thats unfortunate but no worries I liked Google+ better.
What in the world is going on, I think I need to search for some news, better go to google.com
Yahoo?
Bing?
Hmm, maybe this is a temperary problem I guess I could just buy some of the stuff I need, amazon.com
Well... thats interesting...  I guess I'll just go watch TV or something.
While it may be that I'm slightly exagerating the situation, this is what will happen.  Any website that provides or even links to illegal copywritten materials will be shutdown, this could include Google and Facebook.  To further add insult to injury there is no defined procedure for who gets to decide what is offending and what isn't.  It is likely that private companies will be able to submit a trivial request to a new government agency which will blindly comply with the request and terminate the website.  For those of you who are outside of the country and don't think this matters to you, guess what it does.  The bill allows for the termination of websites through modifacation of the root DNS servers, which means that for any .com/org/net website can be shutdown by the US Government could at the request of a US company.
WHAT THE HELL HAPPENED TO THE FIRST AMENDMENT!?!?!?!
Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the Government for a redress of grievances.
Uh, violation much.  Oh and don't forget about the Fifth Amendment.
No person shall be held to answer for a capital, or otherwise infamous crime, unless on a presentment or indictment of a Grand Jury, except in cases arising in the land or naval forces, or in the Militia, when in actual service in time of War or public danger; nor shall any person be subject for the same offense to be twice put in jeopardy of life or limb; nor shall be compelled in any criminal case to be a witness against himself, nor be deprived of life, liberty, or property, without due process of law; nor shall private property be taken for public use, without just compensation.
Is it just me or does SOPA seem to deprive companies of their private property?  And maybe the 6th Amendment?
In all criminal prosecutions, the accused shall enjoy the right to a speedy and public trial, by an impartial jury of the State and district wherein the crime shall have been committed, which district shall have been previously ascertained by law, and to be informed of the nature and cause of the accusation; to be confronted with the witnesses against him; to have compulsory process for obtaining witnesses in his favor, and to have the Assistance of Counsel for his defence.
Nope, sorry if you anger the RIAA or MPAA you dont get the right to a trial, just the right to have your website shut down.

Ok, I'm going to stop ranting now, but I refuse to get off of my soap box.  SOPA and PIPA are the end of the internet as we know it, and a further distruction of our civil liberties.
If you use Facebook, Twitter, Google, Bing, Yahoo, Amazon, Youtube or any part of the internet I implore you to understand what SOPA really is and tell your congressmen that it is unacceptable to vote for.
I also beg you to go to the EFF's page, enter your zip code.  They will tell you who your representatives are and give you the information so that you can contact them and voice your concern.
References:
Wednesday
Nov092011

Netduino Powered True Random Number Generator (TRNG)

In software development, most often when we want to generate a random number we have to generate a Pseudorandom Number.  However there are times when you need a true random number, weather for cryptographic purposes or for lotteries.  To generate true random numbers you need a True Random Number Generator (TRNG), which must be a piece of hardware.  There are several on the market which use a variety of methods to generate their randomness.  I used the circuit developed by Rob Seward, which uses avalanche noise between the two transistors... I'll let Rob Seward explain it in his own words.

The two transistors with their bases touching create "avalanche noise in a reverse-biased PN junction." This noise is amplified by the third transistor, and sent across a voltage divider to Arduino. On the oscilloscope, the signal looks very fuzzy. In software, that randomness is converted into a stream of 1s and 0s.

Since I love my Netduino, and I love building cool stuff, I decided to build one of these for my Netduino.

The code for it is fairly straight forward

 

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace TRNG
{
    public class Program
    {
        #region configuration
        //Configuration
        //8 Bits gives you an int output of 0-255
        //16 bits gives you an int output of 0-65535
        //32 bit gives you a stackoverflow. :)
        private static int bits = 8;
        //End Configuration
        #endregion

        #region ports
        private static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
        private static AnalogInput in_port = new AnalogInput(Pins.GPIO_PIN_A0);
        private static OutputPort _0led = new OutputPort(Pins.GPIO_PIN_D0, false);
        private static OutputPort _1led = new OutputPort(Pins.GPIO_PIN_D1, false);
        #endregion

        #region bias removal stuff
        private static int previous;
        private static int flip_flop = 0;
        #endregion

        private static int calibration_value = 0;
        private static string byt = "";

        private static void Loop()
        {
            int d = in_port.Read();

            if (d > calibration_value)
            {
                ExclusiveOr(1);
                //byt = byt + "1";
                _0led.Write(true);
                Thread.Sleep(30);
                _0led.Write(false);
            }
            else
            {
                ExclusiveOr(0);
                //byt = byt + "0";
                _1led.Write(true);
                Thread.Sleep(30);
                _1led.Write(false);
            }

            if (byt.Length == bits)
            {
                Output();
            }
    }
        private static void Calibrate()
        {
            DateTime start = DateTime.Now;
            TimeSpan ts = DateTime.Now - start;
            int count = 0;
            int total = 0;
            //Making this a bit lager may, or may not, provide better results.
            while (count < 10000)
            {
                total += in_port.Read();
                count++;
                //ts = DateTime.Now - start;
            }
            calibration_value = total / count;
            BlinkLed();
            return;
        }
        private static void vonNeumann(int input)
        {
            if (input != previous)
            {
                byt = byt + input.ToString();
                previous = (in_port.Read() > calibration_value) ? 0 : 1;
            }
        }
        private static void ExclusiveOr(int input)
        {
            flip_flop = (flip_flop == 1) ? 0 : 1;
            byt = byt + (flip_flop ^ input).ToString();
        }
        private static void BlinkLed()
        {
            led.Write(true);
            Thread.Sleep(30);
            led.Write(false);
        }

        public static void Main()
        {
            Calibrate();
            //setup Von Neumann
            previous = (in_port.Read() > calibration_value) ? 1 : 0;
            Debug.Print("Loop");
            while(true)
                Loop();
        }
        private static void Output()
        {
            //Dont have an LCD to output to yet...
            Debug.Print(byt + " = " + ParseBinary(byt).ToString());
            byt = "";
        }
        public static long ParseBinary(string input)
        {
            //Thanks to Jon Skeet for this one http://stackoverflow.com/questions/4281649/convert-binary-to-int-without-convert-toint32/4282972#4282972

            // Count up instead of down - it doesn't matter which way you do it
            long output = 0;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i] == '1')
                {
                    output |= 1 << (input.Length - i - 1);
                }
            }
            return output;
        }
    }
}

 

The first thing we do is to calibrate the device, because as the device ages the output can drift a bit.  We read the values from the ADC 10,000 times and average the readings, which gives us our middle point, anytime we read a value higher than this, we will make it a 1, and when we read lower it is a 0.  We can use this to create either numbers or letters, since its simply a binary stream.  It is a good idea to have some filtering of the output and I have implimented 2 methods to do that vonNeumann and ExclusiveOr.  The vonNeumann provides the best results, however I find that in most cases I don't need to use it.  Your results will vary based on how noisy your enviornment is, I find that when I head out on the lake the numbers are far more stable then when I'm at home or even just in town.  I could imagine that around large motors (such as those in factories) you will find more noise in your output.

I should have a PCB for this circuit available for purchase on BatchPCB shortly, and I may make up a quick kit and make that available.

Wednesday
Oct052011

Steve Jobs - Will be missed.

Today we have lost one of the greatest visionaries the computing world has ever known, it was announced that Steve Jobs, co-founder of Apple, has died.  Trying to summarize just how Steve helped to shape the technological world we live in today is a task that in the coming days many will attempt, it is no easy feat.

"Steve, thank you for being a mentor and a friend. Thanks for showing that what you build can change the world. I will miss you." - Mark Zuckerberg

After dropping out of college Steve Jobs and his partner, Steve Wozniak, founded “Apple Computer” which is now the second largest company in the world.  Whether you like Apple and its products or not is irrelevant, Steve Jobs help to build the personal computer industry into the goliath it is today.  While Steve had a reputation as a bit eccentric he was well respected, this is most clearly evidenced in my mind, by the words that his long time business rival Bill Gates had to say as the news broke.

“I'm truly saddened to learn of Steve Jobs' death. Melinda and I extend our sincere condolences to his family and friends, and to everyone Steve has touched through his work. Steve and I first met nearly 30 years ago, and have been colleagues, competitors and friends over the course of more than half our lives. The world rarely sees someone who has had the profound impact Steve has had, the effects of which will be felt for many generations to come. For those of us lucky enough to get to work with him, it's been an insanely great honor. I will miss Steve immensely.”  - Bill Gates

Steve’s influence stretched so far that today companies, who currently compete with Apple from Microsoft to Google, paid their respects, Google went so far as to post on their homepage.  The Wired (wired.com) homepage closely resembled Apple’s, with a picture of Steve, and quotes from some of the biggest names in tech.


I have often aspired to be half as successful as Steve Jobs, and while I have never had the pleasure of meeting him, I cannot help but to share the sentiment that so many have expressed today, Steve will be missed.

"I am very, very sad to hear the news about Steve. He was a great man with incredible achievements and amazing brilliance. He always seemed to be able to say in very few words what you actually should have been thinking before you thought it. His focus on the user experience above all else has always been an inspiration to me. He was very kind to reach out to me as I became CEO of Google and spend time offering his advice and knowledge even though he was not at all well. My thoughts are with his family and the whole Apple family." — Larry Page (Co-Founder of Google)