GnomeContinuous using systemd-nspawn


One of interesting projects from Gnome Community which tries to define a new way of packaging. I really don’t know how exactly OSTree works, but it generates daily builds (qcow2 images) for Gnome. The OSTree repository which helps in building qcow2 images for Gnome is called “GnomeContinuous“. Similarly, there is another OSTree repository which builds qcow2 images for Fedora is called “rpm-ostree“(see ProjectAtomic)


Someone in the vast internet call this tool as “Poor Man’s Virtualization”. This is nothing but the good old chroot jail with modern walls (namespaces).

So, my experiment is to boot gnome-continus generated qcow2 image using systemd-nspawn to run a pure gnome OS parallelly. First thing is to download the gnome-continuous qcow2 image.

Note: all commands in this post executed under root

# wget
# gunzip gnome-continuous-x86_64-devel-debug-20140720.0.qcow2.gz
# ln -s gnome-continuous-x86_64-devel-debug-20140720.0.qcow2 gnome.qcow2

Network Block Device:

In order to open-up qcow2 images, qemu provides a tool called “qemu-nbd”. this tool requires ‘nbd’ kernel module to be loaded. So, load nbd driver as root,

# modprobe nbd
# qemu-nbd --connect /dev/nbd0 gnome.qcow2

Now, we have associated /dev/nbd0 with qcow2 image. This image contains three partitions(boot, swap and root), we have to seperate them into loop devices,

# parted /dev/nbd0 unit B print
Model: Unknown (unknown)
Disk /dev/nbd0: 8589934592B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start       End          Size         Type     File system     Flags
 1      32768B      209747967B   209715200B   primary  ext4            boot
 2      209747968B  276856831B   67108864B    primary  linux-swap(v1)
 3      276856832B  8589934591B  8313077760B  primary  ext4

# losetup -o 276856832 -f /dev/nbd0
# losetup -o 32768 -f /dev/nbd0
# losetup -j /dev/nbd0
/dev/loop0: [0005]:849 (/dev/nbd0), offset 276856832
/dev/loop1: [0005]:849 (/dev/nbd0), offset 32768

Now we have to get the “ostree” boot parameter from /dev/loop1 (which is the boot partition in qcow2 image)

#mkdir boot
#mount /dev/loop1 boot
#grep 'ostree=' boot/syslinux/syslinux.cfg
APPEND root=LABEL=gnostree-root quiet splash ostree=/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0
#umount /dev/loop1
#rm boot

“ostree” boot parameter is importent for ostree tools to operate properly, so we have to append this boot parameter into our host machine’s /boot/grub/grub.cfg so that this boot parameter will be reflected in /proc/cmdline. Open your host machine’s /boot/grub/grub.cfg and append “ostree” parameter like this,

        linux   /kernel-genkernel-x86_64-3.14.0-sabayon init=/sbin/init root=UUID=80b5a49b-4156-49b3-ab4d-71d1de2dca36 resume=UUID=7550843f-1e8a-4c8e-b9a3-3c9907164726 ro rd.vconsole.keymap=us quiet splash ostree=/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0
        initrd  /initramfs-dracut-x86_64-3.14.0-sabayon

Once done, reboot your host machine and re-setup /dev/loop0 and /dev/loop1 as we did in above steps.

We have to adjust root partition to stop plymouthd and modify default runlevel to “multi-user” instead of “graphical”,

# mkdir root
# mount /dev/loop1 root
# rm root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0/etc/systemd/system/
# ln -s root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0/usr/lib/systemd/system/ root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0/etc/systemd/system/
# mv root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0/usr/bin/{plymouthd,plymouthd.disabled}
# umount /dev/loop1
# rm root

Now, time to setup the filesystems,

# mkdir root
# mount /dev/loop0 root
# mount --bind root/ root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0/sysroot/
# mkdir /dev/exported
# ln /dev/loop1 /dev/exported/

Now we are ready to chroot,

# systemd-nspawn --bind /dev/exported -b -D root/ostree/boot.0/gnome-continuous/f5a97103e9911b5a19ec154ecccfc6bd77f43e90e27a64adabf054e4db06c38b/0

this will boot the qcow2 image which we downloaded and show a login prompt, get inside as root and mount the boot partition we exported from host machine which will be available inside /dev/exported/loop1,

GNOME-OSTree 0+snapshot-20140717 qemux86-64 console
qemux86-64 login: root
Last login: Sat Jul 19 22:38:48 SGT 2014 on console
root@qemux86-64:~# mount /dev/exported/loop1 /boot

Now, we can start the gnome session by running a X in host’s vt2 and point gnome-session inside chroot to connect to DISPLAY=:1

In Host Machine:

press ctrl-alt-f1 and login as root, then type this command
# X :1 vt2

Above step will start another X server in vt2 (you can switch between different X servers using ctrl-alt-f[1-9]).

Inside Systemd-Nspawn type,

root@qemux86-64:~# DISPLAY=:1 gnome-session

This will start gnome session in host machine’s vt2(ctrl-alt-f2) and show the latest gnome version built by OSTree which you downloaded as qcow2 image in the first step,

Screenshot from 2014-07-20 14:50:49

Also, you can verify which ostree version the current qcow2 image pointing to, open a gnome-terminal in the gnome-session started in vt2(ctrl-alt-f2) and type the below command,

root@qemux86-64:~# ostree admin status
* gnome-continuous 9b441d1f14c4caea17eb2b50a778da4a08e31cbbdf1104edf2cd2cb40a4e3374.0
    origin refspec: gnome-continuous:gnome-continuous/buildmaster/x86_64-devel-debug

you can also update to the latest version of gnome using following command,

root@qemux86-64:~# ostree admin upgrade

To stop the gnome-session, go to the terminal where you started it and press ctrl-c. It will stop the gnome-session on vt2(ctrl-alt-f2) and give root prompt, now type following command to shutdown the systemd-nspawn machine

root@qemux86-64:~# systemctl poweroff

You will be back to host machine. Now, type following commands to peacefully disconnect everything,

# umount /dev/loop0
# umount /dev/loop0
# rm root
# rm -fr /dev/exported
# losetup -D
# qemu-nbd --disconnect /dev/nbd0

Thats it, the qcow2 image will be properly closed.

Well, if you don’t understand the steps in this post, commant here, I’ll try to explain as much as possible.


Creating My Own Website with Zero Cost

First of all, I’m not at all a web developer and had very little interest to learn web technology. All started changing during my marrage time, I wanted to create a wedding invitation website just to invite my friends.

My invitation website got good response in office. my colleagues asked about how I managed to create it because I belongs to c/c++ croud and very few in my team have broad knowledge about web technologies to create a website.

I came to know about node.js when I was digging with spidermonkey and gjs. So, for me, node.js becomes obvious choice as I already know little bit about javascript through spidermonkey and gjs.

A little research about node.js exposed me to express.js(web application framework), jade.js(HTML Template engine), stylus.js(CSS Engine) and jeet.js(Grid system)

I then created my wedding invitation site. Initially, I thought I have to spend money to host my wedding invitation site, but I came to know more about Heroku from one of the talk in Ilugc. Soon, my research about PaaS environments introduced me to OpenShift from RedHat. Openshift provides free hosting and OpenShift itself is OpenSource.

So, All I have to do is, create free account in OpenShift, Install rhc gem in my laptop, push my website into openshift through git. Thats all. My wedding invitation site is accessable anywhere and I was able to impress my friends,colleagues and finally my wife.

My wedding invitation app gave me overview of how current web development works, so I decided to have my personal website which consists of blog posts and my photos gallery. Instead of using blog framework available for node.js, I decided to use my existing wordpress blog for blog posts and my existing google drive account for storing photos so that I don’t need to use any database for my personal website.

I wrote two node.js modules wordpressrest.js and googlerest.js to access contents in wordpress and google dynamically.

Finally, I was able to come up with somewhat viewable personal website

If you are viewing this Article through, checkout my personal website at and suggest me better ways to improve it.

SystemCtl Restart MyBlog

Its been 1yr 3months since I published my last post, lot of changes happened in my life. Just a quick look at my past


I got married on 06-Dec-2013 to Deepa (A facebook addict who always wants to be in touch with her friends). Atlast, there is someone who will scold me when I don’t eat/sleep/bath properly. I got a nice traveller now to travell with me rest of my life. My stomach is not burning when I go to multiplexes and malls after marrage :)

Moved to Pune

Moved to beautiful Pune on Oct-2013. Nice city. But, I’m missing ilugc meetings very much. I have to start going to lug meeting in pune.


Learnt GStreamer basics and wrote a module for dhvani-tts which can use gstreamer for playing sound.

Node.js & Web

First started learning during my wedding to create a simple website just to show my invitation, now developed a personal website using node.js (more about this in next post).

Well, nice to be back to blogging after a long gap.


As you already know from by previous postfix article, Any mail going through domain will have my gmail address as sender. Thats good. What about receiving mail from gmail?

In your mind, you are saying “Its damn easy right? configure your evolution/thunderbird to poing to gmail stupid?” right? yeah, thats right. I can configure any mail client to point to gmail and get mails. But, I want my postfix to play a roll.

Postfix is basically a smtp server, it can also act like smtp client. But, it cant work as a imap/pop3 client.

So, Here is the task, I need to get mails from gmail through pop3 and put it into my postfix so that all other clients connected with my postfix can get that mail. Here comes fetchmail.

Fetchmail is a beautiful program which will act like imap/pop3 client (just like evolution/thunderbird) and instead of saving it somewhere, fetchmail will put that mail into your local machine’s mail server. So, all the mail clients connected with your local mail server will get your email from gmail.

Thats enough of theory, lets get down and install fetchmail, first install the package

$ sudo equo install fetchmail

Now time to configure fetchmail, it uses /etc/fetchmailrc as its only configuration file. But, we need to be careful with it. Because, we are saving the username/password a plain-text, so the permission for /etc/fetchmail should be (0600) for root.

If you start configuring fetchmail by reading ‘man fetchmail’, you will switchoff easily. That man page is such a damn brief and will confuse you easily. But, fetchmail config is really a easy one. It will take just three lines to configure it. Here is those three lines,

set daemon 120
set syslog
poll proto pop3 user "foo" pass "bar" to "stupid" ssl sslproto "TLS1"

Here, ‘set daemon 120’ will make fetchmail to connect to gmail server every 2 minutes.

‘set syslog’ will make fetchmail to put logs into syslog.

‘poll’ instructs fetchmail to connect to server.

‘proto pop3’ instructs fetchmail to use pop3 protocol.

‘user “foo” pass “bar” to “stupid”‘ instructs fetchmail to use ‘foo’ as username and ‘bar’ as password to open gmail account in gmail server, fetch those mail from gmail server and put it into local machine’s postfix as a mail for ‘stupid’ user.

‘ssl’ instructs fetchmail to use secure connection. ‘sslproto “TLS1″‘ tells fetchmail to use STARTTLS for sercure connection.

Thats it for configuration stuff, now its time to restart fetchmail

$ sudo eselect rc restart fetchmail

Now, you can see your mails are fetched from gmail and available to you through ‘mailx’ command.

Dovecot (with mbox)

There are different ways to save a mail in *nix systems. The old baddy is mbox which saves all your email in one single file. The new one is Maildir.

Even though mbox have difficulties, traditional commandline mail clients like ‘mailx’ works with ‘mbox’ style mail files flawlessly. Also postfix which I setup previously by default creates single mbox mail file inside /var/spool/mail/ directory for each user. So, I need a imap+pop3 server which can operate with mbox like mail files. Dovecot is the choice.

First we need to install dovecot. I’m using sabayon, the instruction is specific to sabayon/gentoo,

$ sudo equo install net-mail/dovecot

Its time to setup dovecot. Before we do, we need to create self signed certificates to use it for imaps and pop3s. Lets first create those certificates.

$ cd /etc/ssl/dovecot
$ sudo mkdir oldcerts
$ sudo mv * oldcerts
$ sudo openssl genrsa -out server.key.password -des3 1024
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
Enter pass phrase for server.key.password:
Verifying - Enter pass phrase for server.key.password:

We have to give ‘pass phrase’ here, otherwise openssl command will not create key file. But, having pass phrase for key file is not good, because we need to provide this pass phrase everytime dovecot access this file. Here is the step to remove the pass phrase from rsa key file

$ sudo openssl rsa -in server.key.password -out server.key
Enter pass phrase for server.key.password:
writing RSA key

Now generate certificate request with the rsa key file

$ sudo openssl req -out server.csr -new -key server.key
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:TamilNadu
Locality Name (eg, city) []:Chennai
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DrunkenMonk Private Limited
Organizational Unit Name (eg, section) []:Pattasarayam Generating Unit
Common Name (e.g. server FQDN or YOUR name) []
Email Address []

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

We should not give password when creating certificate request. Ok, know time to create self signed certificate.

$ sudo openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 365
Signature ok
subject=/C=IN/ST=TamilNadu/L=Chennai/O=DrunkenMonk Private Limited/OU=Pattasarayam Generating Unit/
Getting Private key

Now we have two files /etc/ssl/dovecot/server.key and /etc/ssl/dovecot/server.crt to use it for SSL. Lets configure dovecot now, we need to modify /etc/dovecot/dovecot.conf like this,

protocols = imap pop3
listen = *, ::

Configuration not ends with /etc/dovecot/dovecot.conf, it has different conf files for different purpose inside /etc/dovecot/conf.d/, lets modify one by one, Here is /etc/dovecot/conf.d/10-auth.conf

auth_mechanisms = plain login
!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

If you want to permit only current machine’s users and don’t want to use ldap or other machinisms, then make sure you comment all includes except auth-system.conf.txt.

Here is modifications inside /etc/dovecot/conf.d/10-logging.conf

log_path = syslog
syslog_facility = mail

Here is modifications inside /etc/dovecot/conf.d/10-mail.conf

mail_location = mbox:~/.mail:INBOX=/var/mail/%u

Now /etc/dovecot/conf.d/10-ssl.conf

ssl = yes
ssl_cert = /etc/ssl/dovecot/server.crt
ssl_key = /etc/ssl/dovecot/server.key

Thats all from config stuff, lets restart dovecot.

$ sudo eselect rc restart dovecot

Now, we need to test if it is working, We need to connect with dovecot through imap port with TLS encryption

$ openssl s_client -connect localhost:143 -starttls imap

Above command will show lot of SSL stuffs, and then finally dovecot will say ‘. OK’, we need to start communication with dovecot from there,

. OK Pre-login capabilities listed, post-login capabilities have more.
a login mokka somepassword
a OK Logged in
b select inbox                   
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* OK [UIDVALIDITY 1343790396] UIDs valid
* OK [UIDNEXT 320] Predicted next UID
* OK [NOMODSEQ] No permanent modsequences
b OK [READ-WRITE] Select completed.
c list "" *
* LIST (\HasNoChildren) "/" "INBOX"
c OK List completed.

The above session with dovecot shows that things are ok. You can now configure your Thunderbird/Evolution to use your machine for local emails. Have a nice day!!

Postfix (with as relayhost)

Most of us forget that postfix not only acts like a mail-server, but it can act like a smtp-client (like thunderbird, evolution).

This post is all about configuring postfix to work as mail-server for my local domain ( at the same time forward any outside domain mails to with my gmail account credentials. If you are curious about, read my previous articles about dnsmasq and virtual home network. These two articles will explain how I setup my home network.

First things first, lets install postfix (Well I’m using sabayon)

$ sudo equo install mail-mta/postfix


Postfix configuration is pretty simple and straight forward. You have to configure following parameters inside /etc/postfix/

mydomain =
myorigin = $mydomain
inet_interfaces = all
mydestination = localhost, localhost.$mydomain, $myhostname, $mydomain, mail.$mydomain
mynetworks_style = subnet

‘mydomain’ tells postfix that it should serve as mail server for ‘’ domain.

‘myorigin’ tells that postfix should append ‘’ to any incoming mail’s address if the address don’t have domain part. Which means, when you do ‘mail someuser’ from commandline, postfix will append ‘’ so that To address will become ‘’.

‘inet_interfaces’ tells postfix to listen on all network interfaces.

‘mydestination’ tells postfix that it should be the final destination for ‘localhost’, ‘’, ‘’, ‘’ and ‘’

‘mynetworks_style’ tells postfix that my local network is a ‘subnet’ type.

Thats all needed for postfix to get start. We can restart postfix with this configurations to send/receive mails between local users. However we want a little bit more from postfix. Lets configure it to use STARTTLS for its communication with its clients


If you wonder what is STARTTLS, its a simple method to establish communication in a secure way. Your server application (like Postfix listening on port 25) says “Hey client I have TLS support, If you want, we can communicate each other in TLS secure way within port 25 itself, If you don’t want, we can continue with plain-text, what you say?”, then your client (like Evolution or Thunderbird) will tell “OOh!! you offer TLS, then lets do TLS!!”. So the packets going between server and client will be encrypted using TLS.

Before STARTTLS, people used different port for secure smtp which is smtps(port 465). But nowadays it is changing, the regular smtp port itself been used for both plain-text and SSL/TLS communication.

We have to configure Postfix to talk in SSL/TLS way, for that we need Self Signed SSL certificate. Lets create one,

$ cd /etc/ssl/postfix
$ sudo mkdir oldcerts
$ sudo mv * oldcerts
$ sudo openssl genrsa -out server.key.password -des3 1024
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
Enter pass phrase for server.key.password:
Verifying - Enter pass phrase for server.key.password:

Here you have to give a ‘pass phrase’ to generate RSA private key, but having a key with ‘pass phrase’ is asking for trouble. You have to manually type this password everytime postfix access this key. The following command will remove ‘pass phrase’ from a RSA key

$ sudo openssl rsa -in server.key.password -out server.key
Enter pass phrase for server.key.password:
writing RSA key

Now you have a RSA private key file server.key without ‘pass phrase’. Its time to create certificate request,

$ sudo openssl req -out server.csr -new -key server.key
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:TamilNadu
Locality Name (eg, city) []:Chennai
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DrunkenMonk Pvt Ltd
Organizational Unit Name (eg, section) []: Pattasarayam Generating Unit
Common Name (e.g. server FQDN or YOUR name) []:MokkaPandi
Email Address []

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Don’t give any password when creating certificate request. Finally create a self signed ssl certificate using following command,

$ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=/C=IN/ST=TamilNadu/L=Chennai/O=DrunkenMonk Pvt Ltd/OU= Pattasarayam Generating Unit/CN=MokkaPandi/
Getting Private key

Ok, thats it. You will have two files, one is /etc/ssl/postfix/server.crt and another is /etc/ssl/postfix/server.key, Now configure postfix to use these two for SSL/TLS communication, Add the following lines at the end of /etc/postfix/

# TLS Support
smtpd_tls_cert_file = /etc/ssl/postfix/server.crt
smtpd_tls_key_file = /etc/ssl/postfix/server.key
smtpd_tls_security_level = may

Finally, start postfix

$ sudo eselect rc restart postfix

Check if postfix can operate with STARTTLS,

$ sudo openssl s_client -connect localhost:25 -starttls smtp

Above command will show the server certificate and all SSL stuffs. After this, whatever you send will be encrypted, now check if it can send mail,

250 DSN
250-SIZE 10240000
250 DSN
mail from:
250 2.1.0 Ok
rcpt to:
250 2.1.5 Ok
354 End data with .
Subject: test mail
test mail
250 2.0.0 Ok: queued as E0E352C0091
221 2.0.0 Bye

Now see if root got a test mail

$ sudo mail
>N  8 root@drunkenmonk  Tue Aug  7 16:50   14/533   test mail
From  Tue Aug  7 16:50:23 2012
Subject: test mail
Date: Tue,  7 Aug 2012 16:49:48 +0530 (IST)

test mail


We are not done yet. There is one more part. Lets make postfix to forward mails to gmail.


Till now, postfix can send/receive mails within domain. But if someone from your subnet want to send a mail to a person who have mail address outside domain (let say, then your current postfix will try to contact mail server of But, yahoo’s mail server will reject your mail because is not a vaild registered domain.

But, If you have a gmail account, you can forward the mail first to with your account credentials so that gmail will send your mail to with your gmail account credentials. The person who owns will receive a mail with from address as yours irrespective of whoever send within your local network.

To make postfix to know your credentials, we need to create a credential db with gmail account credentials, For that we need to add following line at the end of /etc/postfix/saslpass file

# run following command to generate hash password db
# that can be used inside postfix's
# command:
# postmap hash:saslpass
#file content format:
#remotehost username:password foouser:barpassword

Now run the following command to create saslpass.db

$ cd /etc/postfix
$ sudo postmap hash:saslpass

Now you can see saslpass.db created as a Berkeley DB file. We can now use this file inside to inform postfix about your gmail account credential. Before doing that, please remove /etc/postfix/saslpass file or change its access to 0600 for root. Because your credentials are in plaintext. We need to add following lines at the end of

# gmail
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/saslpass
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
smtp_tls_mandatory_ciphers = high
smtp_tls_verify_cert_match = hostname, nexthop, dot-nexthop
relayhost =

Here ‘hash:/etc/postfix/saslpass’ actually makes postfix to access /etc/postfix/saslpass.db file. You can remove /etc/postfix/saslpass which have your gmail password as plaintext. It will not affect postfix and postfix doesn’t need it.

Thats it, we are done. Once you restart postfix, It becomes capable of sending mail to outside world but with your gmail account’s credentials. Thanks for reading all the way down to this line. Have a nice day!!

Virtual Home Network (with Dnsmasq , Bridge, TUN/TAP, Qemu)

As I said in my previous article, this post will explain how we can use bridge interface to configure networks inside virtual hosts and much more about virtualization.

First we need to make sure our machine is capable of kvm virtualization, see if you get any output for below command

$ grep -E 'vmx|svm' /proc/cpuinfo

Most modern processers supports Hardware assisted Virtualization. If you don’t get any output for above command, It means you don’t have a processor capable of providing Hardware Assisted Virtualization. Qemu-kvm will not work, but you can use Qemu without kvm or some other virtualization applications like virtualbox etc. Also skip ‘LOADING KERNEL MODULES’ section of this article if you don’t have kvm support.


If your processor supports kvm, then we have to load following kernel modules and make sure they load automatically whenever we restart our system. In gentoo/sabayon, we need to modify ‘modules=’ line in /etc/conf.d/modules file as

modules="kvm-intel tun"

Here ‘kvm-intel’ is the kernel module for virtualization and ‘tun’ is the kernel module for ‘TUN/TAP’ devices. For, AMD machines, we need to load ‘kvm-amd’ instead of ‘kvm-intel’. Now we need to load these modules for the current run, Here is the commands which will load ‘kvm-intel’ and ‘tun’ drivers into kernel

$ sudo modprobe kvm-intel tun


Next is to install required packages, Here is sabayon command to install required packages

$ sudo equo install app-emulation/qemu-kvm net-misc/bridge-utilities net-dns/dnsmasq sys-apps/usermode-utilities

‘qemu-kvm’ is for virtualization, ‘bridge-utilities’ is to get ‘brctl’ command, ‘dnsmasq’ is to handle DNS and DHCP requests from guests, ‘usermode-utilities’ is to get ‘tunctl’ command.


Its time to create interfaces, first we need to create the bridge

$ sudo brctl addbr br0

Assign IP address to the bridge,

$ sudo ifconfig br0 netmask up

Next, create a tap0 interface, following command will create ‘tap0’ pseudo slave interface from /dev/net/tun master interface

$ sudo tunctl -t tap0

Now, we need to hook the tap0 interface with the bridge br0

$ sudo brctl addif br0 tap0

Bring up the tap0

$ sudo ifconfig tap0 up


If you read my previous article, I have dnsmasq configured to serve DHCP requests coming from br0. Hooking tap0 into br0 will make the guest send DHCP requests via tap0->br0 and my host machine’s dhsmasq process will serve ip address to the guest. We have to make sure iptables dont block BROADCAST packets as well as open the port 53 and 64 so that dnsmasq will get the DHCP and BOOTP packets. Make sure your iptables contains following lines,

$ sudo iptables -t filter -L | grep -E 'BROADCAST|domain|bootp'
ACCEPT     all  --  anywhere             anywhere             ADDRTYPE match src-type BROADCAST
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domainflags: FIN,SYN,RST,ACK/SYN
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootpsflags: FIN,SYN,RST,ACK/SYN

Now we need to make sure MASQUERADING is enabled and let your host system forward the packets. Also make these settings permanent so that reboot dont break the settings,

$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE
$ sudo sysctl net.ipv4.ip_forward=1
$ sudo /etc/init.d/iptables save
$ sudo /etc/init.d/iptables reload
$ sudo sed -i 's/^.*net.ipv4.ip_forward.*$/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf

Check these settings are ok,

$ sudo iptables -t nat -L
target     prot opt source               destination         
MASQUERADE  all  --  anywhere             anywhere
$ sudo sysctl -a | grep ipv4.ip_forward
net.ipv4.ip_forward = 1


Finally, its time to start virtual guest, first we need to create disk image, Here is the command to create a 5GB raw disk image for qemu-kvm

$ sudo qemu-img create -f raw Debian.img 5G

Now download debian netinstall image for amd64 architecture

$ sudo wget

Atlast, start the guest with with tap0 networking

$ qemu-kvm -cpu kvm64 -drive file=Debian.img,if=virtio -cdrom mini.iso -boot order=dc -m 512 -soundhw sb16 -name "Debian" -net nic,model=virtio -net tap,ifname="tap0",script=no,downscript=no

Thats it, your qemu guest will automatically get network settings from host machine. You can also verify that dnsmasq served a DHCP request via syslog

$ sudo grep 'dnsmasq-dhcp' /var/log/messages
dnsmasq-dhcp[9810]: DHCPDISCOVER(br0) 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPOFFER(br0) 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPREQUEST(br0) 52:54:00:12:34:56
dnsmasq-dhcp[9810]: DHCPACK(br0) 52:54:00:12:34:56 virt0

Well, if you still reading this article and not get bored, you must be a *nix admin. Have a great day!!