Emulating minix using bochs on linux

September 17, 2007

First of all, let me provide an explanation for what minix is and why it may be useful. I remember hearing about minix a long time ago when I was reading Just For Fun: The Story of an Accidental Revolution, where Linux Torvalds and Andrew Tanenbaum, creator of Minix, argued which OS would survive. Linux originated from minix, and even though they are both derived from unix, they differ greatly how they function on the inside, with the most notable feature being the kernel. Linux is monolithic, with all the drivers running in kernel-space, meaning a bug in some driver could crash your computer easily, whereas Minix uses a client-server model for its kernel, where drivers are run in user-space. This introduces some latency, but also introduces reliability, since a driver crash will be the equivalent of a user program crashing, which is harmless to the system. The easiest way to check it out is to put it on a virtual machine and let it run. I chose bochs because it was the easiest to install (qemu wanted me to have a different compiler), and it seems to be the most suitable for testing OS code. The biggest downside is that everything is emulated, which makes it rather slow to run. For regular file editing and browsing it’s fine, but when it has to write to a disk, it can take significantly longer than running it bare on the machine. The hardest part for me was getting minix to run, so I will explain it in detail. Once you install/compile bochs on your HDD, it will look for a .bochsrc file in your user directory (/home/username or ~). You can acquire minix through downloading from their website, or you may already have a CD-ROM with minix, as in my case. In our .bochsrc file, we will first need to specify a romimage and vgaromimage that bochs can load. Bochs comes with a default one, I used it and it was fine. They’re located usually under /usr/share/bochs, but may be different depending on your system. The names of the files are BIOS-bochs-latest and VGABIOS-lgpl-latest. The first two lines, if you plan to use the default images, should be:

romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest

Now is the time to emulate a CD-ROM from which to boot minix. The power of bochs lies it the fact that it can very easily emulate devices, and they can be pretty much any file that you specify. So, in the case that you are booting from a CD-ROM, and the name of the device is /dev/cdrom (you may have to adjust), your line to add would be

ata0-master: type=cdrom, path=/dev/cdrom, status=inserted

In the case that you have only the minix iso file, the line to add would be

ata0-master: type=cdrom, path=/path/to/iso/file, status=inserted

For whichever type you use, at the end you will need to specify to boot from cdrom:

boot: disk

Now you should try running minix by typing “bochs” at the prompt. You will see the Main Menu of Bochs. Specify [5] (the default) to get on with the simulation. It should present you with a nice bootup screen and after the OS loads, you should be able to login with “root”. This is a live CD so you can explore the structure and all from the CD image directly. Of course, you’d want to install it to disk to be able to change minix around and save its current state. In order to do that, you will need to save the OS to disk. In order to do that, you will need to make an image file on your HDD, which acts as a partition for your virtual machine. You can use dd for that, but in order to make it easier, bximage should be used, which comes with bochs. After starting it up, you should see

Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd]

Specify the default, [hd]. After that you would get

What kind of image should I create?
Please type flat, sparse or growing. [flat]

The default, [flat], should be specified again. You should now see

Enter the hard disk size in megabytes, between 1 and 129023

Minix does not need a lot of space to run, however I read somewhere that you should allocate 1 GB in order to install anything you want on there, so I specified I typed in 1024 MB, and if you have the space and plan to add packages, should too. The minix website specifies that for minimum you will need 50 MB, and if you want to have all the sources, you will need 600 MB. After you specify how much space you want to allocate, the program will give a diagnostic message of what it will do, and ask you to specify the name of the image

What should I name the image?

I chose the name “minix.img” but it’s up to you what you want to name it. After writing to the HDD, it will print out a line which you should add to your .bochsrc file

ata0-master: type=disk, path="minix.img", mode=flat, cylinders=cn, heads=hn, spt=sn

You can add that line, but you will need to change ata0-master to ata1-master, considering you still have the line where your ata0-master corresponds to your CD-ROM image, and change the boot: parameter to point to disk. This is what my final .bochsrc file looked like

romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
ata0-master: type=cdrom, path=/dev/cdrom, status=inserted
ata1-master: type=disk, path="minix.img", mode=flat, cylinders=2080, heads=16, spt=63
boot: cdrom

From there, running minix and setting it up on your HDD should be a breeze. After logging in with “root”, run setup and accept all the defaults. There should be a partition that you can now install to. After a considerate amount of time of installing packages (considering you did a Full Install), you should get a screen telling you that everything succeeded. After that, exit bochs and just change the boot: parameter to point to disk and you are done. Next time you run the simulator, it should boot from the image file and you should be presented with you brand new minix installation.

firefox and dns security through ssh tunnel

September 6, 2007

Thanks to tor and a packet sniffer, I was able to conclude that firefox by default leaks its dns requests when using a SOCKS v5 proxy. Therefore, what happens is that even though the rest of the traffic is encrypted, the actual requests for the names are leaked through, and if some knowledgeable administrator looks at the logs, can conclude that we are encrypting our traffic. For instance, a request for facebook.com would look like this:

the content of this site should be blocked by the http proxy
DNS REQUEST: www.facebook.com


where this is usually blocked, this file should not have been able to be accessed
DNS REQUEST: www.facebook.com/profile.php

To get rid of this disparity, we need to change some settings in firefox. At the url bar type in about:config, after which look for network.proxy.socks_remote_dns and change it from default, which is set to false, to user set which is set to true. In such a way, your dns traffic will be routed through the socks proxy rather than leaked through.

switched over to git

August 19, 2007

I just switched over to git from cvs after a long period of putting it off. Git, so far, seems a lot easier and more intuitive to use rather than cvs. One thing I hated about cvs was that long CVS_IMPORT variable that you had to input. Git seems to be a lot more user-friendly and works well with ssh too.

my first ebuild

August 4, 2007

I have been using gentoo for quite a while and really love it, it gives you all the tools and more you would need. I especially love how easy it is to emerge stuff, all the dependencies are automatically installed without problems. I remember back in the days when I used Mandrake, I would have to search for hours trying to find which packages depended on which, and then manually install each one. It was really painful. Gentoo’s portage reminds me of FreeBSD’s ports that I used for half a year before switching. Gentoo, however has a much better package management system that FreeBSD, I think. Anyways, because I run a server at home, it is also behind a router, which assigns an ip address using dhcp everytime it boots up. The only way my computer can function as a server is if its DMZ ip address is set to the server. Therefore, I would have to manually update that ip address every time it is changed. Well, since computers are so good at automation, I decided to write a script in python that updates that the DMZ’s ip address every time it starts. Writing the script was relatively easy, because of python’s great urllib2 module, which can do almost anything involving http. The way Gentoo works is, it has a special folder inside /etc/init.d that have special scripts that are formatted just as if you are starting a service. For instance, to start apache, you would type:

$ /etc/init.d/apache2 start

This file also depends on a file in /etc/conf.d/ with the same name that supplies its global variables. Using ntp-client as an example, I was able to write up two files that call that script at start-up. Since this is a Gentoo-specific program, I also decided to write an ebuild, just for practice and to see what it looks like. Well, let me just say that my initial effort was fruitless. Thanks to the article on gentoo-wiki, I was able to with ease create an overlay in /usr/local/portage. When I looked at similar ebuilds, I realized that they have the syntax of a bash script, except they have custom names for installing and compiling packages. For instance, the make utility is called emake, and no use of tar is necessary, the key command is unpack. Well, initially I used dobin, which installs a file in /usr/bin, doconfd, installing in /etc/conf.d, and doinitd, installing in /etc/init.d. However, I realized soon that the files in conf.d and init.d actually have the same name, which they cannot have in the tar archive. I luckily found out they had newconfd and newinitd, which as a second argument specifies the destination file. Therefore, I could have two files with different names in the archive, but when they are installed, they will have the same name, just different paths. However, to my disappointment, when I tried to emerge the package, it said that they could not find the files in the current directory. Apparently, the current directory is known as $S (source) and the destination is $D. $S in turn translates into $WORKDIR/$P, whereas $WORKDIR is the the directory being worked on, and $P is just the name of the ebuild. In turn, through a regular cp command I realized that I needed $WORKDIR rather than $S as my current working directory. Changing into $WORKDIR worked quite well. Please check out my ebuild here.

a script to write all code snippets to a database

July 10, 2007

Since I have started seeing nice little code snippets around the web that I would like to keep somewhere as a reference, but not have in a program that I would have to search through, I decided to write a little script to save all those snippets to a database that I could retrieve later. Please check it out. It uses the new module mod_python that I recently installed and with it I could do almost anything that php could do. If you try to click on the modify button, it will present itself with an authentication popup, which blocks anyone trying to put bullshit in there. In the future, I hope to explore mod_python more and become more powerful with it.

opening shell using subprocess

July 6, 2007

Opening a shell can be useful in some cases. For instance, imagine that you are on a different network and you would like to use sockets to control another computer. All you need to do is open up a pipe to a shell, with the input being read with socket.revc() and the the output going to socket.write(text). In such a way, it becomes like a telnet or ssh session, whereas it’s like you are sitting directly on the machine. I thought that using the module subprocess in python would be ideal for it. However, whenever I used Popen to open a shell, I couldn’t keep write on stdin and get stdout only once, and then I would get a ‘Broken Pipe Error’. After a long search on comp.lang.python, I finally discovered that I need to set up the file descriptors to be non-blocking in order for the connection not to close when there is no more data to be written to stdin. What happens is that once the pipe detects that there is no more data to be read from stdin, the pipe issues a EOF and the pipe closes. Here is a link to the discussion on a forum: click

mediawiki vs. moinmoin

June 29, 2007

I am currently trying to build a wiki project which deals with bboying. Anyways, my first and obvious choice was to go with mediawiki, because naturally that is what wikipedia and almost any other site that maintains a wiki currently uses. The installation of it was a real piece of cake, it presented me with menu options and I barely did not really have to touch anything underneath the hood. Since it was all php, I guess it was pretty easy to do. However, halfway through, I decided that it would be really neat to embed youTube and Google videos of some old-school movies that I could post up. I went over to mediawiki’s extensions section and downloaded one that embeds like five different formats, really cool stuff. Finally by putting it into the extensions sub-folder, I get it to work and for a hot minute see my newly embedded video. However, as soon as I try to edit to test some more and hit the “submit” button, I get the weirdest database error. I submitted it on their site and did not yet get a reasonable response. After a week of waiting on their support channel in IRC, I finally gave up and decided to search for a new wiki engine. I decided to go with MoinMoin, which is this time written in python. I have a lot more experience with python and I also just installed mod_python on my apache server so I was ready to give it a try. Another cool feature about MoinMoin is that it didn’t have to deal with any database so it was easier to debug. Now, this installation was definitely harder to get right than mediawiki. Actually it wasn’t hard but was rather confusing. The setup.py file set up two directories for me, which I wasn’t sure how exactly related and was not certain when following the official installation guide which folder referred to which online. Since you need to use either cgi or mod_python, the interpeter isn’t embedded in apache and is not as native as in php. Firstly, it worked through cgi but there was no graphics. I got it to work with mod_python, by adding a path in the default python path to the second place MoinMoin was installed, something the installation guide failed to mention. When I got it working so that it uses a default DNS name rather than a folder name though, it worked like butter and the graphics were even showing. After that in a short time I copied all the data from the old wiki to the new by copying and pasting. Herein lay the final test, whether I would be able to embed youTube or Google Video inside. I searched around and luckily found both an Macro (that’s what they call their extensions) for YouTube and Google Video. Now getting YouTube working wasn’t that bad, but I did struggle a little. I guess what it was doing is not realizing that what I’m typing is not text but an actual video. I added another Macro that I knew would work into the site and it picked up the YouTube Macro seamlessly. I guess it needs to compile the Macro first and would then have no trouble recognizing it, the only problem is getting it to compile it. That was the major challenge when trying to install the Google Video Macro. It was named “gvid.py” and provided no instructions at all on how to use it. Luckily I already got YouTube working and since this was so similar, I didn’t want to give up. Needless to say, I finally realized that for some reason MoinMoin doesn’t like its macros to have lowercase names, so by changing “gvid” to “GVideo” I managed to get it working. The cool part about these macros was that they were so simple and I could understand them by browsing their source code, something I didn’t want to get into with php. So, as of now, I think I’ll stick with MoinMoin since it seems easier to troubleshoot if something goes wrong. Now all I have to do is change the default look, something mediawiki definitely has over moinmoin.

Port Tunneling HOWTO Part 2

May 22, 2007

In my previous post I focused on how to use port tunneling for only one server. In the world of world wide web, however, you will most likely want to connect to different servers repeatedly, jumping between pages without having to reissue ssh commands over and over. Well, the power of ssh provides even that option. Using this configuration, you will essentially create a SOCKS service running from your computer to the server. The command is simple:

ssh -N -D portNum userName@serverName

On the screen, a prompt will ask you for your password. The N flag stands for no output, meaning it will only make the connection, without actually letting you type commands. The D flag is for the SOCKS connection that I mentioned earlier. Now, all you will need to do is tell you browser/IM client/whatever else program that can use SOCKS sockets, to use your local address, ie, with port number being the number that you entered following the D flag. In Firefox it is accomplished by going to Preferences, hitting the Advanced tab, navigating the Network tab underneath, and under connections hitting Settings. From there, you can hit Manual Proxy Configuration, and under SOCKS Host write the mentioned before. When everything is good, try going to different sites and see if it works.

Firewall for the Practical User

May 21, 2007

Firewalls are mostly used in enterprise companies to restrict access to certain ports and services. The difference between proxies and firewalls is that proxies can filter or modify content that passes through them. Firewalls work on a lower lever, filtering access to certain ports, certain services, or tcp or udp traffic. With that being said, why would an average computer user want a firewall? Of course, there is increased security, since only the ports that you need are open, meaning you can deny ping requests or telnet sessions ever being opened. Most average users don’t really care about security though, since malicious users usually will try to go after big-name servers. However, a practical use of setting up a firewall at home is to allow to computers or more to exist on the network at the same time. Most people nowadays buy home routers made by Linksys or D-Link, but those can be expensive. For a firewall, all you really need is a computer with two NIC cards. You can buy one really cheap either from ebay or from a local computer store. Make sure it is working when you start the computer, and assign it with a static ip address, usually Make sure you can ping that ip address. If you only have one more computer to connect, you can connect it straight to the firewall, but make sure that you use a crossover cable, because it is a peer-to-peer connection. If you have more than one computer to connect, would like to have the potential to link other computers, or simply don’t want to deal with crossover cables, you can get yourself a small hub or switch to put between your firewall and your internal network. There’s no point in putting a router there, since it creates unneeded redundancy. Assign the internal node a static ip address also, for example If the internal node can ping the firewall at the static ip address, then you are golden. Otherwise, there is something wrong with the cables or with the switch/hub. Since assigning static ips is a pain, we want DHCP to do the work for us. So, install and configure dnsmasq, in order to make sure it is running. If you configure your internal nodes to automatically assign themselves an IP address from a DHCP server at boot up and point them to the firewall, they should have an automatic IP address on startup. Test this setup thoroughly to make sure it is working. That is the easy part. The hard part is getting iptables to work, which you’ll have to install in order to have the firewall running. What we want to do is NAT (Network Address Translation), which takes all the packets originating at the internal nic, and modifies the origin to be the external nic, thereby abstracting the internal computers from the rest of the world. First of all, you need to make sure that your kernel supports iptables. Most distributions come with iptables configured, but you need to make sure. Since I use Gentoo, the kernel usually doesn’t have it. I therefore used genkernel after many frustrating recompiles, but ideally this configuration guide should let you know what to have enabled in your .config file. After you know your kernel is working and supports iptables (I suggest building everything as modules), make some basic rules to know that it’s working. Now, in order to get everything flowing nicely together, you can do two things. You can either install firestarter, a firewall GUI which will setup the rules for you, or you can do it by hand. Here is what you would need to type in order for iptables to work with NAT:

First we flush our current rules
# iptables -F
# iptables -t nat -F

Setup default policies to handle unmatched traffic
# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD DROP

Copy and paste these examples ...
# export LAN=eth0
# export WAN=eth1

Then we lock our services so they only work from the LAN
# iptables -I INPUT 1 -i ${LAN} -j ACCEPT
# iptables -I INPUT 1 -i lo -j ACCEPT
# iptables -A INPUT -p UDP --dport bootps -i ! ${LAN} -j REJECT
# iptables -A INPUT -p UDP --dport domain -i ! ${LAN} -j REJECT

(Optional) Allow access to our ssh server from the WAN
# iptables -A INPUT -p TCP --dport ssh -i ${WAN} -j ACCEPT

Drop TCP / UDP packets to privileged ports
# iptables -A INPUT -p TCP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP
# iptables -A INPUT -p UDP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP

Finally we add the rules for NAT
# iptables -I FORWARD -i ${LAN} -d -j DROP
# iptables -A FORWARD -i ${LAN} -s -j ACCEPT
# iptables -A FORWARD -i ${WAN} -d -j ACCEPT
# iptables -t nat -A POSTROUTING -o ${WAN} -j MASQUERADE

Tell the kernel that ip forwarding is OK
# echo 1 > /proc/sys/net/ipv4/ip_forward
# for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 1 > $f ; done

This is so when we boot we don't have to run the rules by hand
# /etc/init.d/iptables save
# rc-update add iptables default
# nano /etc/sysctl.conf

Add/Uncomment the following lines:
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1

If you have a dynamic internet address you probably want to enable this:
net.ipv4.ip_dynaddr = 1

Courtesy of a gentoo linux howto.

From there on, try to access google from one your internal computers. If everything is done correctly it should work. Granted, some ports will be blocked by your firewall, so you will need to open them on a need-per-port basis.

Port Tunneling HOWTO

May 19, 2007

As almost everyone knows by now, the internet is not anonymous at all. There are numerous ways for someone, whether it be your Internet Service Provider, some curious onlooker, or a potential vandal, to see what you what articles and information you process when you are online. Whether that is right or not I don’t really care about, but what is annoying is someone restricting access to what you can use. Fortunately, there is OpenSSH, a free telnet-like service, which lets you remotely control a machine, but also encrypts everything on the way. The cool thing about it, though, is that we can use it as a secure channel to remotely send information, which no one in the middle can understand, since it is encrypted. Basically, what happens is that the client encrypts the information that it is about to send, and when the server receives the information, it decrypts it back into a normal packet and sends it to its appropriate destination. The opposite thing happens when the server sends information to a client. Therefore, it is possible to connect to a port which is restricted on the network you are on, as well as send and receive totally secure information between yourself and the ssh server. In order for this to work, you will need to have access to some remote ssh server that is outside of the network you feel uncomfortable with. A nice solution is to set up a ssh server at home, and then connect to it from work or school, where you are on the restricted network. If you’re using a Unix-like OS, just follow your distribution’s guides. If you’re using Windows, you can install cygwin or alternative try to get sshwindows working. Once you have it setup and running (you actually verified this), you should be able to connect to your server from the unsecure network. Although it is possible to use port tunneling for any port whatsoever, I will focus on port 80, known as http, which is restricted most of the time. If there is no ssh client on your client, and you are on Windows, you can always use plink, an ssh replacement, and replace all commands that start with “ssh” to start with “plink”. The syntax is such:

# ssh -l userName -v -L sourcePort:externalServer:DestPort sshServer

For instance, we will make a tunnel to ecks.homeunix.net (this site is always blocked). For the sourcePort, we will use 9999, although you can use any non-active port you choose.Thus, the command becomes such:

# ssh -l userName -v -L  9999:ecks.homeunix.net:80 mysshserver

After you login with your password, it should give you some diagnostic output as to what is going on. Next fire up your favorite web browser and type into the url field “”. If everything is done right, this site should be staring you in the face. You can now browse through it securely, without worrying about someone knowing what you are looking at. I hope you enjoyed this informative article. In the meantime, here is an article that explains tunneling in more detail:

securityfocus link