Archive for April, 2005

Boot Debian from a USB Hard-Drive - Part 1

Note that I first performed these instructions back in September 2004 and there may be minor differences in the actual implementation.

Boot Debian by USBEver wanted to install Debian Linux on your laptop but haven’t got the space available to handle a dual boot configuration and don’t want to give away Windows? If you’ve got a spare hard-drive lying around, the solution might just be to purchase a USB2 HDD enclosure from EBay for as little as $15 and boot Linux by USB! Unfortunately this can be quite a challenging problem, but the following tutorial outlines how I solved it and is inspired by the article Boot Linux from a Firewire device over at IBM by Martyn Honeyford.

A few issues to note that make this problem tricky. Firstly, on BIOS’s that don’t support booting from a USB device directly, by default the USB drivers are loaded too late in the boot-chain to make it possible to boot to a USB device. Secondly, I’m using a Dell Latitude C640 which only has USB1, so I’m using a PCMCIA card with USB2 support when connecting to my removable HDD. Finally, I haven’t seen any one who’s done this for Debian, I was able to find a tutorial for Gentoo (the IBM link), and Redhat, but not for Debian. The solution is fairly similar but a few nity gritty details particularly around cramfs had me tearing my hair out at one stage.

Getting this setup working took me far longer than it probably should have, and the slightest differences in your configuration might make the situation more or less difficult. Persistance should eventually lead you to a working solution

To get started, remove your Windows HDD and install the soon to be Linux HDD into your laptop. Install Debian as you would normally, I chose unstable, but it really shouldn’t matter which build you choose. Complete your installation, boot into your fresh version of Debian and su as root. The first thing we want to is confirm that your mkinitrd.conf file is ready for the creation of our image. The following is how my one looks.

aflinux:~/usb-init# cat /etc/mkinitrd/mkinitrd.conf
MODULES=most
DELAY=5
ROOT=probe
UMASK=666
MKIMAGE=’mkcramfs %s %s > /dev/null’
BUSYBOX=yes
PKGSCRIPTS=yes
INITRD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH

The first things we want to do is create the default initrd image. Whilst a cramfs image is created by default, we want to create a directory version that we’ll edit ourselves before over-writing the automatically created cramfs version.

The following snippet prepares the directory we’re going to use.

aflinux:~# mkdir usb-init
aflinux:~# cd usb-init/
aflinux:~/usb-init# mkinitrd -k -o usb.img
/usr/sbin/mkinitrd: The working directory /tmp/mkinitrd.4432
  will be kept.
aflinux:~/usb-init# mv /tmp/mkinitrd.4432/initrd initrd

We now need to copy all the requried modules from our kernel folder into the relevant places. Make sure you’re copying all the relevant files for your kernel, when I first did this 2.6.7 was the latest kernel; the same instructions should apply for the latest version.

aflinux:~/usb-init/#
  cd ~/usb-init/initrd/lib/modules/2.6.7-1-386/
aflinux:~/usb-init/initrd/lib/modules/2.6.7-1-386#
  mkdir kernel/drivers/usb/host
aflinux:~/usb-init/initrd/lib/modules/2.6.7-1-386#
  cp /lib/modules/2.6.7-1-386/kernel/drivers/usb/host/*
    kernel/drivers/usb/host/
aflinux:~/usb-init/initrd/lib/modules/2.6.7-1-386#
  cp /lib/modules/2.6.7-1-386/kernel/drivers/pcmcia/yenta_socket.ko
    kernel/drivers/pcmcia/

Now we’ve got all the additional drivers we need on top of the ones included by the “most” directive in the mkinitrd.conf file. The following text should over-write the contents of the loadmodules file. It’s job is to load up the PCMCIA modules required to start my USB2/Firewire card, and enable USB storage support so that when the initrd ends we’re able to pivot to the new root stored on the USB Hard-drive.

aflinux:~/mkinitrd/initrd# cat loadmodules
echo “Loading up PCMCIA Support”
modprobe -k pcmcia_core
modprobe -k yenta_socket
modprobe -k ds

echo “Loading up USB Support”
modprobe -k  usbcore
modprobe -k  scsi_mod
modprobe -k  sd_mod
modprobe -k  usb-storage
modprobe -k  uhci-hcd
modprobe -k  ohci-hcd
modprobe -k  ehci-hcd

modprobe -k  ide-generic
modprobe -k  ide-disk

Finally the script file defines the root as /dev/sda1. In some cases this /dev point might not have been established, but this long hand format works for me.

aflinux:~/mkinitrd/initrd# cat script
ROOT=/dev/scsi/host0/bus0/target0/lun0/part1
unload_unused_ide ” generic

At this point we can bundle up our folder structure into a cramfs image that we can use as an initrd image!

aflinux:~/usb-init/initrd# cd ~/usb-init
aflinux:~/usb-init# mkcramfs initrd/ usb.img
Directory data: 8628 bytes
Everything: 4400 kilobytes
Super block: 76 bytes
CRC: 31c2161a

We’ve now bundled our image. If we step back a directory and look at the size of the image; mine happens to be a little over a 4MB. Due to the “most” directive we ended up including a number of modules that we really didn’t have to, once you get this image working as it stands, you might wish to go back and remove redundant modules to lower the image size!

At this point I recommend you copy the usb.img file to /boot as usb-26.img. This way if you’re ever using a computer that supports direct booting from usb, by editing your grub boot parameters you should be able to use this initrd as it stands to boot into your portable hard-drive. At this point you can shutdown Linux and if you’re lucky you can remove the Linux HDD from your laptop for the first and last time, put it into the USB enclosure and put your Windows HDD back in.

What’s a touch more complicated is where your laptop doesn’t support usb booting at all (such as the case with my Latitude C640). In order to get around this we need to setup a version of GRUB on our Windows partition. This will be discussed in Part2 of this post…

Update: I noticed an old link of mine mentions how to do this process for Fedora Core 3. Those mkinitrd preload statements might work on Debian too; but I haven’t tested. The article is available at: http://www.simonf.com/usb/

Metallic Shades 2.11 & Java Don’t Mix

Firstly I really need to thank Chris for solving this problem and the co-incidence that we happened to talk about it in a lecture was uncanny as I’ve never ever seen this issue reported anywhere on Google. If you haven’t heard of it, “Metallic Shades” is a custom Windows XP theme that is visually outstanding. A small screenshot of the typical UI elements within Metallic Shades is shown on the right.

Metallic Shades XP StyleMetallic Shades has been a feature of my desktop for at least 2 years, until recently when I found that it was the cause of a number of issues I was having with Java applications. I found that in a number of Java applications, most noticably the Java Installshield for Gallery Remote & NetBeans, WEKA, and a few others would fail on installation or first load, but during the installation buttons that should show would not have a button outline. I’ll take a screenshot of the problem sometime soon. When I ran the jar files manually I’d find an AWT exception would occur.

As soon as I switched to an alternate theme (I’m now using Reluna - Bluetify), all my Java applications ran perfectly and buttons had an outline once again! I’ve tried a number of different versions of Java 1.3-1.5 with Metallic Shades and all have had the same problem. Chris was able to seperately confirm the issue.

It’s a real pity Metallic Shades doesn’t work with Java correctly because it really is an excellent theme, hopefully in the next version these issues will be resolved.

Streaming Media with mod_mp3

iTunes playing a Stream

A month or so ago I decided I’d take a look into the various streaming audio options available on Linux. Whilst there are a number of different streaming server options available including IceCast, and ShoutCast. This is also combined with streamers like DarkIce, Ices, LiveStream and many others. With so many options it’s difficult to know where to start, and personally I had a suprising amount of difficulty combining many of the combinations of streaming servers with a streamer. That is until I stumbled across mod_mp3.

Mod_mp3 interfaces with your Apache server as a module, and instantly allows streaming. Whilst it’s supposed to work with Apache2, I noticed that mod_mp3 is actually in the Debian apt-get respository for use with Apache 1, so the following instructions relate to a simple install on Debian.

  1. To get started, lets get the package(s) we require:
    apt-get install libapache-mod-mp3
    
  2. In the /etc/apache/conf.d folder, a file called mp3.conf sets up our streaming settings. The following is how my config file looks.
    <location /audio>
      MP3Engine On
      MP3CastName "FUJI Tunes"
      MP3Genre "Streaming Media"
      MP3Playlist /var/hd2/media/playlist
      MP3DefaultOperation play
      MP3Encoder "/usr/bin/lame -q 2 -b 64 --silent % -"
    # MP3Random On
    </location>
    

    Something that is really important to note is that I’ve deliberately commented out the MP3Random tag. Leave it in and the module will crash, I know it should work, but it doesn’t and has been noted in a few forums. The other important thing to note is the MP3Encoder line, by default Debian doesn’t come with the Lame encoder, and I don’t think it’s in apt either. Whilst the MP3Encoder line isn’t necessary, resampling the tracks works well when I’m doing a long distance stream. I built it myself from source, and I’ll discuss that more in a second.

  3. Finally you’ll note that I’ve made a playlist file that’s stored in /var/hd2/media/playlist. I created this file with the command:
    find /var/hd2/media/mp3/*.mp3 > /var/hd2/media/playlist
    

    By using a Playlist file Apache will boot a tiny bit faster, especially if you have a large number of tracks.

  4. Restart Apache, then open up your favourite mp3 player and choose the Open Stream option. Enter the address http://<SERVER>/audio/?op=play and stream away! You might also want to go to http://<SERVER>/audio/?op=select and choose a song to play.

As a final aside you can get the Lame source from http://prdownloads.sourceforge.net/lame/lame-3.96.1.tar.gz?download. As long as the final executable ends up in /usr/bin then the MP3Encode tag line works great! I’ve set the ending bit-rate to 64. I found that small enough that buffering from anywhere was quick, and the quality is still ok. If your connection can handle it, try bigger numbers for better quality.

Christian Games Popup

Seems too slack to be true; but was reading The Daily WTF, specifically the latest post titled A Pop-Up Potpourri. One of the posts mentioned some Christian Games software that on exiting shows the following popup…

Christian Games Popup

Assuming this is true, I’m sure a lot of Christian kids have discovered the ‘Task Manager’ as a result :).

Convert Images to CSS

CSS Sample Image Screenshot

I’m still not quite sure how practical it is, but I came across a really interesting blog article titled Convert Image to CSS. The concept is pretty simple, use a combination of divs and span tags that are set at absolute dimensions with specificied background colours that end up rendering an image. Neat!

The script that Elliott Back (the author) has written up in PHP takes in a url to an image file and essentially converts single square pixel regions to an equivalent span tag with an appropriate background colour. The only problem with this implementation is that it can produce some fairly large files as it’s like using Bitmap encoding but each pixel is a one line span tag.

For the sake of procrastination I thought I might attempt to optimise the html output a bit by producing a Javascript 2D array of colours, and then have the browser do the marking up. The following link is the complete source with my ammendments integrated. Note that I’ve broken the mode feature, and whilst it’s pretty easy to fix, the focus of my changes was to see what impact using Javascript as a renderer would have and hence I haven’t pursued fixing the mode option. Note that some lines from the original might have got chopped as the PDF version of the code ran off the edge of the page in some areas so I had to guess in a few areas to complete the lines to get the original code to run.

Download the .phps Modified Script here

So how does it perform? As far as filesizes go, for a small sized image the final html file was generally 4 times smaller than that of Elliott’s version (pretty significant). With that being said, this version is pretty horrible as it practically locks up the browser for 10 seconds and you don’t get the neat “pixel by pixel” rendering that you get on the original.

As far as all the copyright and that sort of thing goes, please follow the conditions of use outlined by Elliott in his post. I don’t really care what you do with the little ammendments I’ve made, it’s ugly as all hell but made an interesting experiment.

XML HTTP

One of the major differences between conventional applications and web applications is the need to POST a form on a web application only to have the whole page reloaded. This is slow.

Gallery 2 XML HTTP ExampleI’m not sure how long this has been around, but a month or so ago I discovered some XML HTTP functions by looking at the source code for Gallery2 and wondering how they did the auto-completion on filling out usernames. I didn’t think they’d want to have a whole Javascript array of usernames if they could avoid it, and on looking at the code found that the auto-completion was being done manually by an xmlhttp.js file which was performing asynchronous background requests to a PHP script which would then populate the autocomplete field. For those of you who have done a fair bit of web programming you’d have to say this is really really neat.

I looked for the xmlhttp.js file on google and was directed to the Useful JS tools for Railers page where I found that not only is the script free to use for any purpose (as long as you keep the comments up the top); but that it’s really simple to use. Whilst the examples on the site don’t really show the true power of this script; I thought I’d give a simple auto-complete example below.

  1. Include the xmlhttp.js file in your html document.
    <script type="text/javascript" language="JavaScript"
      src="includes/xmlhttp.js">
    
  2. Add the following example function to your page.
    <script>
    function xmlupdate() {
      p = xmlHTTPRequest('services/autocomplete.php?text=' +
           document.getElementById("ac_field").value);
    
      cmb = document.getElementById('ac_combo');
      while (cmb.options.length > 0) cmb.options[0] = null;
    
      var lines = p.split(”\n”);
      for (var i=0; i < lines.length-1; i++) {
        var line = lines[i].split(",");
        cmb.options[cmb.options.length] =
          new Option(line[1],line[0]);
      }
    }
    </script>
    
  3. Add a text box and a combo box to your page, and make the text box call the Javascript method above on the keydown event.
    <input type="text" id="ac_field"
        onkeydown="javascript:xmlupdate();" />
    <select id="ac_combo" />
    
  4. Finally you need to make the script called autocomplete.php that resides in the services directory. Obviously this script could be written in any server side language, as long as it returns items in the form (id,text\n) and takes a GET parameter ‘text’. The following script is just a small example that uses a static array, in most applications you’ll be performing a database query.
    // We want at least one char before we output
    if (!isset($_GET['text']) or (strlen($_GET['text']) < 1)) {
      die;
    }
    
    $sample_array = ("apple", "application",
                     "applicable", "applicant");
    
    for ($i=0; $i < count($sample_array); $i++) {
      if (strpos($sample_array[$i],$_GET['text'])) {
        echo "$i,$sample_array[$i]\n";
      }
    }
    

I’m using a variation on this in a more complicated example and haven’t compiled the version above, but it should be close to working and provide the basis for a number of extensions. I can see many uses including:

  • Populating a database table with a text field when the entry isn’t already available in a combobox and then refreshing the combobox for those situations where you are setting up 1 to many relationships in web forms.
  • Progressive page loading so that you can pump out the layout and general features first so the user has something to see before rendering out the actual core data. I think GMail does this and it’s similar enough to the idea of interlaced gifs.
  • Many others! I think XML HTTP can solve a number of problems with regards to web applications

Have you used XML HTTP or have a good idea for a potential use that I haven’t mentioned? Please leave a comment.

How to Import BBlog Posts into WordPress

BBLog to WordPress Conversion

As part of my creation of this WordPress powered blog I imported my Thailand journal which used the BBlog software. I had a look over google and didn’t find a script to automatically do it, in fact I read in a couple of places that some people had done the conversion manually! I think by far the easiest way is to export your mysql tables from the bblog database into your Wordpress database so that you have 20 or so tables (the wordpress ones prefixed by wp_ and the bblog ones with bb_). A few SQL queries is all it takes to convert all your posts! Note that the following queries might have minor typos as I did this conversion the other day and are reproducing partly from memory.

My major focus was to import all the posts; and that’s all I did. I’ll provide some ideas here about how you might get things like comments and multiple categories, but that wasn’t a concern of mine. The following queries allowed me to extract the posts and create a Thailand category.

Note that I’m assuming the author has an author_id of 1, and that the GMT time is 10 hours behind (as I’m in Australia). I also had created a category called Thailand which I knew was category_id of 3.

INSERT INTO wp_posts (ID, post_author, post_date, post_date_gmt,
    post_content, post_title, post_category, post_modified,
    post_modified_gmt)
  SELECT postid, 1 as author, FROM_UNIXTIME(posttime),
    DATE_ADD(FROM_UNIXTIME(posttime), INTERVAL -10 HOUR), body,
    title, 3 as category, NOW(), DATE_ADD(NOW(), INTERVAL -10 HOUR)
    FROM bb_posts;

INSERT INTO wp_post2cat (post_id, category_id)
  SELECT ID, post_category from wp_posts where post_category = 3;

When you’re all done make sure you drop all the bb_ prefixed tables!

A full blown conversion for comments, users, and multiple categories would be just more of the same. If you’ve done any of the above conversions, and wish to share, please make a comment!

Blocking SSH Hack Attempts

As the University allows external access to port 22 (and only port 22) into the Honours labs I frequently use it to access my computer from home. I also login to my Debian Linux box from various locations, and have other user accounts that allow access to things like SVN for group projects. Since running logwatch I’ve noticed that it seems like I’ve got some script kiddie trying brute force attempts on my SSH daemon. Typically the resulting output looks something like the following:

localhost sshd[13512] Invalid user admin from ::ffff:210.86.143.194
localhost sshd[13514] Invalid user bruce from ::ffff:210.86.143.194
localhost sshd[13519] Invalid user chuck from ::ffff:210.86.143.194

It seems that I’m not the only person to have these attacks, in fact, the person at this link http://ubuntuforums.org/archive/index.php/t-26982.html seems to be getting attacked by the exact same IP! Although I’ve had attacks from a number of different IPs since this first one. I decided I’d make a simple ‘honey-pot’ solution to catch out these sort of attacks and then block them.

The idea is that from my looking on google, that these people seem to be using the same scripts (must be publically available somewhere) to try these random attacks as they tend to use the same usernames, and more often than not in the same order. Now I know that I don’t have an SSH user going by the name “anonymous”, on my computer, so I figured I’d make a catch out for anyone who tried to login to my computer with such a username, most likely due to the running of one of these scripts.

The following shell script looks to find an illegal user in the auth.log file going by the names “admin”, “anonymous” or “abc”, and if it’s found it will add the users IP to the /etc/hosts.deny file so they don’t get a second chance at logging in. The script runs regularly as a cron job and seems to have wiped out all these hack attempts.

for host in `grep -E "Illegal user (anonymous|admin|abc)"
    /var/log/auth.log | cut -d: -f 7 | sort -u`
do
        grep $host /etc/hosts.deny > /dev/null
        if [ $? -eq 1 ]
        then
                HOSTLINE=$(grep ALL: /etc/hosts.deny)
                echo “$HOSTLINE, $host” > /etc/hosts.deny
        fi
done

Note that I’ve reduced my hosts.deny file to a single line (removed all the comments at the top), to simplify the script a bit. I know a number of people have come up with different solutions to this problem, but this one seems to work great for me.

I’m sure there are better ways of solving this problem; or being as though SSH enforces a 5 second wait between tries; maybe it’s not even a big enough problem to warrant solving! That being said, if seeing a list of attacks starts to become a daily thing, then this solution provides some peace of mind.