Friday, March 25, 2011

Making your locally hosted Web Application Look Live

INTRODUCTION
------------------
I didn't really know  what to call this article, but the title notwithstanding,
this article takes you through how to get rid -not exactly, of that damned
http://localhost, thingie when you are running your webapp locally -using a local
httpd like apache, or the more complete package, lampp, wampp or xampp.
This article only discusses apache, but I bet there is some smartie out there who
will make it work for IIS or something.

Please note that I used xampp for this example, because I was trying to stop myself
from, como se dice, swala-ing. So no GNU/Linux (lampp).

The above issue having been brought to the reader's attention, I must add that for
people who have been working with apache, lampp and GNU/Linux will find a way around this
article to make it work for them. However if the gentlemen -ladies too, refered to in
this paragraph just can't make it work, please let me know so I extend this issue to
cover lampp.

PRE-REQUISITES
--------------------
A knowledge of how http daemons, web servers work is assumed in this article
Also a knowledge of name resolution, be it DNS -if you don't know what this means,
this article is not for you, is assumed.
For those lacking the above pre-requisites, I am not in the mood to provide links,
so you just might as well google it.
>:) Happy Hunting!!! (:<


DISCUSSION
---------------
Okay, again a recap of the top story...

The article is targeted at final year students who are working on web applications
for their projects. During development the project is hosted locally using a httpd
like -most commonly apache.

The project is then accessed in the browser via http://localhost/theproject, for
viewing and whatever one does during web development.

The problem is that during the presentation, after the development of the project,
using the http://localhost/theproject address to access the webapp is not really
'ish'.

We would want to use an address like www.theproject.org, -please note I am making an
assumption here that the reader is fairly, como se dice, knows whats up!

So how do we achieve this.

This process is two-fold,
    1. We need a way to resolve the address www.theproject.org to our ip address.
    2. We need a way to make our httpd know what page to serve depending on what
       site name we request.
      
WARNING: All changes made in this article are made as root, so please make backup
copies of the configuration files before you edit them, just in case.
   
1. RESOLVING www.theproject.org TO IP ADDRESS USING /etc/hosts
------------------------------------------------------------------------------------
Whenever you type an address, like www.facebook.com in the browser, the browser does
name resolution to map the human-rememberable form www.facebook.com to the form the browser can work with, ip adress. This is called Name resolution -approximately.

Name resolution on personal computers is done in two steps, first the TCP/IP stack,
tries to resolve a domain name|host by refering to a file in /etc/hosts.

If a match is found in this file, the TCP/IP stack replaces the domain name|host with
the ip adress blah blah blah.

If the attempt at using /etc/hosts does not turn up a match, the TCP/IP stack then uses
DNS to do the name resolution, and if everything works out fine, DNS returns the ip
address for the domain name|host. DNS is not something I will talk about here.

In our situation, our site www.theproject.org is not a registered domain, it is just a
name we want to use, so we will like to avoid the DNS part, by making an entry for our
site in the /etc/host file.

The /etc/hosts path is for those using GNU/Linux, for those using Windows, the host
file is in c:\windows\system32\drivers\etc\hosts.

Open a new line, and type the following, please use tabs, not spaces;

127.0.0.1        www.theproject.org
    ::1            www.theproject.org


The above lines causes any name resolution attempt for www.theproject.org to return
the address 127.0.0.1, you can replace the loopback address with another address if
you are going to access the project over a local network.

Usefulness: If you want to, you can actually eliminate the time the browser uses to do
DNS name resolution, by creating entries for all the sites you frequent, hypothetically
this should improve your browsing speed, -initially, please note, I haven't actually
done the study, hence the word hypothetical you see.

2. MAKING APACHE SERVE THE RIGHT PAGE(S) FOR www.theproject.com
----------------------------------------------------------------------------------------
The Apache httpd, has a functionality known as virtual hosts http://httpd.apache.org/docs/2.2/vhosts/.
According to the apache docs:
     The term Virtual Host refers to the practice of running more
     than one web site(such as www.company1.com and
     www.company2.com) on a single machine.
     Virtual hosts can be "IP-based", meaning that you have a 
     different IP address for every web site, or "name-based",
     meaning that you have multiple names running
     on each IP address. The fact that they are running on the  
     same physical server is not apparent to the end user.
   
Interesting huh? We are interested in name-based virtual host. Why?
Because, we don't want to mess with the httpd serving correctly via http://localhost,
we just want it to add www.theproject.org to the mix, hence our choice.

To do that the NameVirtualHost directive must be added to the httpd.conf file, with path
c:/xampp/apache/conf/httpd.conf for Windows and for GNU/Linux i have no idea, but if you
need it that bad you could run a find for it, with;
 find / -name httpd.conf    -exec gedit {}\;

We need to add the following under the 'Main Server configuration' section, right below
the DocumentRoot settings;
    NameVirtualHost    *:80

    <VirtualHost *:80>
        ServerName    localhost
        DocumentRoot    "C:/xampp/htdocs"
    </VirtualHost>

    <VirtualHost *:80>
        ServerName    www.theproject.org
        DocumentRoot    "C:/xampp/htdocs/theProject"
    </VirtualHost>



The above assumes you are using xampp.
   
The NameVirtualHost *:80 directive says that we want to declare a virtual host for all
ip addresses on the server. A corresponding VirtualHost container must also be declared
for every NameVirtualHost.

The first VirtualHost block handles request for the server localhost, and serves up pages
from the c:/xampp/htdocs directory, DocumentRoot.This block is important because
when you start using virtual hosts, the default configuration will not work, so you must
explicitly specify how request for the default configuration, localhost in this case is to 
handled.

The second VirtualHost block, the one we are interested in, says 
that for every request sent to all ip addresses, where the
server name requested is 'www.theproject.org', serve pages from the DocumentRoot
"C:/xampp/htdocs/theProject", this DocumentRoot will be replaced by
/opt/lampp/htdocs/theProject assuming you installed lampp to /opt in GNU/Linux, or again,
/www/theProject if you installed apache directly.
For more explanation on how virtual host works please refer to the apache docs, at
http://httpd.apache.org/docs/2.2/vhosts/.

After you have done all this, restart apache, and now go ahead and access your project
via www.theproject.org.

After doing all the above, congratulations, you may not be able to  access you webapp. Why?
Because your browser may be configured to use a proxy, so it will try to resolve
www.theproject.org anyways.

The solution to this is simple;
    1. disable proxy, set to no proxy
    2. add the site www.theproject.org to the proxy exception list in your browser.
    3. or both.
Now try again and voila, we are in business. If you did not do voila at the point, please
go over again, and if failing persists, consult me, I might be able to help :)

Usefulness: I used this procedure to setup a bulletin board system on my department's local network, and made it possible for
members to access that local BBS with a name like www.css.org.

Wednesday, March 9, 2011

HOW GRUBSTERS TAME THE GRUB MMOTIA -An adventure in the Live disk world

BLURB:
Assumption: You have a faulty grub bootloader and you have in your hand a live disk.
The power is YOURS!!

1. sudo mount /dev/sda1 /mnt
2. sudo mount --bind /dev /mnt/dev
3. sudo mount --bind /proc /mnt/proc
4. sudo chroot /mnt
5. sudo grub-install /dev/sda
6. sudo update-grub
6. sudo reboot

After Reboot:
7. sudo update-grub

PROLOGUE:
The procedure for (re)installing the GRUB2 is not very different from
(re)installing GRUB Legacy (GRUB1). They are essentially the same, i.e;
    - install the primary bootloader into the Master Boot Record [MBR],
    - copy the image files for grub into /boot/grub,
    - update the grub configuration file.
The word grub will sometimes be used in in this text to refer to grub2, they are
are used interchangeably.

CHAPTER ALL-IN-1:
Being aware of the simple concept of grub (re)installation, the heros of this story,
us, Grubsters, champions and savior of the world of 'Linux installation', will procede to
tame the grub mmotia -mmotia: a SCARY apparition in Ghanaian[Akan] folklore, what the
english refer to as a dwarf, scary huh!

The command to install the bootloader to MBR;
    ubuntu@ubuntu:~$ sudo grub-install /dev/sda1

However running this command in the live disk world, will not only OUCH!, burn our left
asses, but taunt us with the following error;
    /usr/sbin/grub-probe: error: cannot find a device for /boot/grub (is /dev mounted?).

DAMN, DAMN, DAMN!!!, no one told us that grub-install -the mmotia, uses another monster
program grub-probe.

grub-probe, 'probes' device info for the /boot/grub path. In this case /boot/grub maps to
the live disk world's /boot/grub not our Linux Installation, hence the error, grub-probe
cannot find the device.

Attempts to probe any other device, eg. /dev/sda1, will return useful information, try;
    sudo grub-probe /dev/sda1

So after applying salve to our burnt left asses, we come up with a clever way of fixing this
grub-probe monster, which is why grub-install will not work, ehm sorry, why we can't tame the
grub mmotia, we need to lure the two of them to our world, 'Linux installation', on the
hard disk plane.

Let us now welcome on stage the CHROOT fairy -neat right.

A hit-and-run-affair: root@ttousai:~# chroot DIR

The chroot command changes the root -duh- of a command. Commands
executed at the terminal have / as their root, so all commands are relative to /. However
chroot, changes the default / to the one specified by DIR, so now all commands will
be relative to DIR.

We are going to use chroot to make our Linux installation our root. This works because
our Linux installation also has the grub-install, and all relevant programs to install
grub on our hard disk. But first we have to mount our Linux partition;
    sudo mount /dev/sda1 /mnt

then chroot by;
    sudo chroot /mnt

Now we have access to all the commands and programs -weapons, if you like, we installed
on our Linux partition.

We can now go ahead and run grub-probe, expecting it to work since our /boot path
now is the /boot of our Linux installation. Wise guy! [sarcastic]. We get our right butts
burnt this time round.

    ubuntu@ubuntu:~$sudo grub-install /dev/sda
    /usr/sbin/grub-probe: error: cannot find a device for /boot/grub (is /dev mounted?).
    -- and some more trashy talk --

So we find ourselfs asking, WTF! After considerable background knowledge, thinking and
googling, we find out that, our chroot environment has no access to two important filesystems
 needed by grub, /dev and /proc. Talk about a hard-to-tame mmotia!

Now to make matters worse or better, which ever, these directories are generated automagically
by the operating system, oh yeah and our chroot environment is definitely not the OS.

But fear not, as we will realise during our brain and google storming period, we can
actually leverage the /dev and /proc filesystems generated in the world of live session, so
that grub-install will stop trash talking and just be tamed.

Question is, HOW?
    # NOTE: If you are following this explanation first exit the chroot environment by
    # typing exit.
    sudo mount --bind /dev /mnt/dev
    sudo mount --bind /proc /mnt/proc

The above commands just 'bind' -I don't know what else to say', our live session's /dev and
/proc to the /dev and /proc in our Linux installation, so any OS generated devices will be
mapped to our Linux installation.

Now we can chroot back to our Linux installation, and attempt to -not so confident huh,
Mr. Grubster?, defeat and silence the grub monster once and for all, >:)

So we once again engage in the battle, this time on our own world, Linux installation;
    ubuntu@ubuntu:~$ sudo chroot /mnt
    ubuntu@ubuntu:~$ grub-install /dev/sda

Finally, having tamed the grub mmotia, how do we know? Because it did not trash talk us to
death, or burn both our butts this time, thats how. We can now generate a file to make it
behave itself, and do some cool tricks, who says you can't teach an old dog new tricks?
Actually a list of all the available operating systems and other petty details;
    ubuntu@ubuntu:~$ update-grub   
    # to create the grub.cfg, a list of all the worlds
    # we have saved from the grub mmotia.

We can finally reboot and we will see a familiar grub boot menu. Tada!!!
And that is pretty much how you tame the grub mmotia. Cool huh!

EPILOGUE: Run update-grub again after booting to your Linux installation, to generate
and for a lack of a better word, more accurate grub.cfg.