<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Daniel P. Berrangé</title>
	<atom:link href="http://berrange.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://berrange.com</link>
	<description>Writing about photography, open source software, virtualization &#38; more</description>
	<lastBuildDate>Wed, 01 Feb 2012 16:12:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>libvirt, libguestfs &amp; more at FOSDEM 2012</title>
		<link>http://berrange.com/posts/2012/01/31/libvirt-libguestfs-more-at-fosdem-2012/</link>
		<comments>http://berrange.com/posts/2012/01/31/libvirt-libguestfs-more-at-fosdem-2012/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 10:39:05 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[boxes]]></category>
		<category><![CDATA[fosdem]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[libguestfs]]></category>
		<category><![CDATA[povirt]]></category>
		<category><![CDATA[sandbox]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=598</guid>
		<description><![CDATA[As many readers are no doubt aware, the FOSDEM 2012 conference is taking place this weekend in Brussels. This year I was organized enough to submit a proposal for a talk and was very happy to be accepted. My talk is titled &#8220;Building app sandboxes on top of LXC and KVM with libvirt&#8221; and is [...]]]></description>
			<content:encoded><![CDATA[<p>As many readers are no doubt aware, the <a href="http://fosdem.org/2012/">FOSDEM 2012</a> conference is taking place this weekend in Brussels. This year I was organized enough to submit a proposal for a talk and was very happy to be accepted. <a href="http://fosdem.org/2012/schedule/event/libvirt_lxc_kvm_sandboxes">My talk</a> is titled &#8220;<em>Building app sandboxes on top of LXC and KVM with libvirt</em>&#8221; and is part of the <a href="http://fosdem.org/2012/schedule/track/virtualization_and_cloud_devroom">Virtualization &amp; Cloud Dev Room</a>. As you can guess from the title, I will be talking in some detail about the libvirt-sandbox <a href="http://berrange.com/posts/2012/01/17/building-application-sandboxes-with-libvirt-lxc-kvm/">project I recently announced</a>. Richard Jones is also attending to provide <a href="http://fosdem.org/2012/schedule/event/libguestfs">a talk on libguestfs</a> and how is is used in cloud projects like OpenStack. There will be three talks covering different aspects of the <a href="http://ovirt.org/">oVirt project</a>, a general project overview, technical look at the management engine and a technical look at the node agent VDSM. Finally the GNOME Boxes project I <a href="http://berrange.com/posts/2011/11/22/gnome-3-desktop-virtualization-support-from-gnome-boxes-and-the-future-for-virt-manager/">mentioned</a> a few weeks ago will also be <a href="http://fosdem.org/2012/schedule/event/gnomeboxes">represented</a> in the <a href="http://fosdem.org/2012/schedule/track/crossdesktop_devroom">CrossDesktop devroom.</a></p>
<p>Besides these virtualization related speakers, there are a great many other Red Hat people attending FOSDEM this year, so we put together a small flyer <a href="http://people.redhat.com/duffy/fosdem/redhat-fosdem_2012.pdf">highlighting all the</a><a href="http://people.redhat.com/duffy/fosdem/redhat-fosdem_2012.pdf">ir talks</a>. In keeping with the spirit of FOSDEM, these talks will of course be community / technically focused, not corporate marketing ware :-) I look forward to meeting many people at FOSDEM this year, and if all goes well, make it a regular conference to attend.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/01/31/libvirt-libguestfs-more-at-fosdem-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rambling about the pain of dealing with passwords for online services</title>
		<link>http://berrange.com/posts/2012/01/23/rambling-about-the-pain-of-dealing-with-passwords-for-online-services/</link>
		<comments>http://berrange.com/posts/2012/01/23/rambling-about-the-pain-of-dealing-with-passwords-for-online-services/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 21:25:43 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=592</guid>
		<description><![CDATA[Over the last 6 months or so, I&#8217;ve become increasingly paranoid about password usage for online web services. There have a been a number of high profile attacks against both the commercial world and open source project infrastructure, many of which have led to compromise of password databases. Indeed, it feels like my news feed [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last 6 months or so, I&#8217;ve become increasingly paranoid about password usage for online web services. There have a been a number of high profile attacks against both the commercial world and open source project infrastructure, many of which have led to compromise of password databases. Indeed, it feels like my news feed has at least 1 article a week covering an attack &amp; user account compromise against some online service or other. And this is only the attacks that are detected and/or reported. Plenty more places don&#8217;t even realized they have been attacked yet, and there are likely plenty of cover-ups too. This leads me inescapably to my first axiom of password management:</p>
<ul>
<li><strong>Axiom #1: Your password(s) will be compromised. There is no &#8220;if&#8221;, only &#8220;when&#8221;</strong></li>
</ul>
<p>It follows from this, that it is the epitome of foolishness to use the same password for more than one site. Even if you are diligent to watch for news reports of site compromises &amp; quickly change your passwords across all other sites, you are wasting hours of time, and still vulnerable for the period between the attack taking place &amp; being reported in the media (if at all). Out of curiosity, I made a list of every website I could remember where I had registered an account of some kind. I was worried when the list got to 50, I was shocked when it went over 100, and I stopped counting thereafter.</p>
<p>There is a barrage of often conflicting suggestions about how to create strong passwords for accounts. Most websites simply say things like &#8220;<em>you must use a mixture of at least 8 letters, numbers and special symbols</em>&#8220;. Google have been trying to educate people about how to make up more easily remembered passwords, but XKCD <a href="https://www.xkcd.com/936/">points out the flaws</a> in these commonly suggested approaches. Even if you do decide upon some nice scheme for creating your passwords, you quickly come across many websites which will reject your carefully thought up &amp; remembered password. Compound this with the fact that many websites (typically financial ones) also require you to enter &#8220;passwords hints&#8221; based on questions that are supposedly easy to remember, but in fact turn out to be anything but. Now multiply by the number of sites you need passwords for (x100). This leads me inescapably to my second axiom of password management:</p>
<ul>
<li><strong>Axiom #2: It is beyond the capabilities of the human brain to remember enough strong passwords</strong></li>
</ul>
<p>There have been a great many proposals for shared authentication services, whether owned &amp; managed centrally by a corporation like Microsoft Passport, or completely decentralized &amp; vendor independent like OpenID. Today out of all the 100+ sites I use, I can count the number that allow OpenID login on the fingers of one hand. More recently the big social networks have been having some success with positioning themselves as the managers of your identity &amp; providers of authentication to other sites. I am not happy with the idea of any social network being the controller of not only my online identity, but also controller of access to every single website I register with. I don&#8217;t trust them with all this data, and they are an extremely high value target for any would be attackers if they control all your website logins. Letting them control all my logins, feels akin to just re-using the same password across every website. I know they have marginally stronger login procedures than most sites, by allowing you to authenticate individual clients used to login, but this isn&#8217;t enough to balance the downside. In fact I&#8217;m not really convinced that I want any online service to be the manager or all my login details for websites. It is just too big a single point of trust/failure.</p>
<p>A minority of online banking websites now provide you some form of hardware key token generator, or pin entry device to authenticate with. This is clearly not going to work for most websites, due to the cost &amp; distribution problem. Even within the limited scope of financial websites the practicality is limited &#8211; if every financial institution I dealt with had key token generators, I&#8217;d have a huge pile of hardware devices to look after ! I do like hardware authentication devices and <a href="http://berrange.com/posts/2011/12/18/multi-factor-ssh-authentication-using-yubikey-and-ssh-public-keys-together/">now use them for login</a> to any personal SSH servers that I manage, but with a few exceptions like Fedora, they are not a solution for the online password problem today or the forseable future. I am depressingly lead to my third axiom of password management:</p>
<ul>
<li><strong>Axiom #3: Widespread password authentication is here to stay for many, many years to come</strong></li>
</ul>
<p>Hmm, perhaps the problem is better described by mapping to the <a href="https://en.wikipedia.org/wiki/K%C3%BCbler-Ross_model">5 stages of grief</a></p>
<ol>
<li><strong>Denial</strong> &#8211; only careless people have their details compromised, i&#8217;ll be fine using the same 4-5 passwords across all sites</li>
<li><strong>Anger</strong> &#8211; how could $WEBSITE have been so badly run / protected, to let themselves be compromised</li>
<li><strong>Bargaining</strong> &#8211; if I just let Facebook handle all my logins, they&#8217;ll solve all the hard problems for me</li>
<li><strong>Depression</strong> &#8211; the industry will never get its act together &amp; solve authentication</li>
<li><strong>Acceptance</strong> &#8211; passwords are here to stay, what can I do to minimize my risks</li>
</ol>
<p>Well I think I am at step 5 now. I have accepted that passwords are here to stay, that sooner or later one or more of the sites I am registered with will be compromised, and it is impossible for me to remember enough passwords. My goal is thus to minimise the pain and damage.</p>
<p>My conclusion is that the only viable way to manage passwords today is to do the one thing everyone tells you never to do</p>
<ul>
<li><strong>Write down all the passwords</strong></li>
</ul>
<p>Of course this shouldn&#8217;t be taken too literally. I am not suggesting to put a post-it on the monitor with the passwords on it, rather I mean store the passwords in some secure location, which is in turn protected a master password. ie use a password manager application.</p>
<h3>Using KeePassX for managing passwords</h3>
<p>After looking at a few options on Linux, I ended up choosing <a href="http://www.keepassx.org/">KeePassX</a> as my password manager because it had a quite advanced set of features that appealed to me. Before anyone comments, I had discounted any usage of a password manager built into the web browser before even starting. The browser is a directly network facing process of great complexity and frequent security flaws &#8211; they just aren&#8217;t the right place to be storing all your valuable secrets. The features in KeepPassX that I liked were:</p>
<ul>
<li>Passwords are stored encrypted in a structured database</li>
<li>It is possible to specify many different metadata attributes with each password, username, site URL, title, comment, and more.</li>
<li>It can copy the password to the clipboard, allowing paste into web browser forms, avoiding the need to manually type in long password sequences</li>
<li>It automatically purges passwords from the clipboard after 30 seconds to minimise the window when it is visible</li>
<li>The database can be set to automatically lock itself against after 30 seconds, requiring the master password to be entered again to access further password entries</li>
<li>The password database can be secured using a password, or a keyfile, or both. The keyfile is just a plain file with random bytes stored somewhere (like a USB key)</li>
<li>An advanced password generator with many tunable options</li>
</ul>
<p>I have several laptops and I want the password database to be usable from either machine. At the same time though, the password database should not become a single point of failure / data loss, so there needs to be multiple copies of it.  Using a password database does have the downside that it becomes a nice single point of attack for the bad guys. It would thus be desirable to have separate password databases for websites used on a general day-to-day business vs security critical seldom used sites ie bank accounts, and other financial institutions. With this in mind the way I decided to use KeepPassX is as follows</p>
<ul>
<li>I purchased 4x USB stick 4 GB capacity for &lt; 5 GBP each, two coloured black and two coloured white</li>
<li>All 4 USB sticks were split into 2 partitions, each of 2 GB size.</li>
<li>The primary partition is formatted with a Fedora 16 LiveCD. This is to facilitate easy access to the passwords, should I find myself without one of my own Linux laptops close by</li>
<li>The second partition is setup with LUKS full disk encryption and formatted with ext4.</li>
<li>The partition with the encrypted filesystem is used to store the KeePassX database files and any other important files (GPG keys, SSH keys, etc)</li>
<li>The black coloured USB sticks are used to store a database for financial account details</li>
<li>The white coloured USB sticks are used to store a database for any other website logins</li>
<li>One USB stick of each colour is the designated backup. The backup sticks are kept<span class="st"> in the bottom of a locked <em>filing cabinet</em> stuck in a disused lavatory with a sign on the door saying &#8216;Beware of the <em>Leopard</em>.&#8217;</span></li>
<li>A shell script which will synchronize files between sticks, to be run periodically to ensure recent-ish backups</li>
</ul>
<p>With that all decided there merely followed the tedious task of logging into over 100 websites and changing my password on each one. I decided that my default policy would be to let KeePassX generate a new random password for each site made up of letters, numbers and special characters, with a length of 20 characters. Surprisingly the vast majority of sites coped just fine with these passwords. BugZilla turns out to be limited to 16 characters and a handful of ecommerce sites had even shorter limits, or refused to allow use of special characters!</p>
<h3>Using E-Mail &#8220;<em>plus addressing</em>&#8221; for accounts</h3>
<p>It is often said that when bad guys have compromised a website&#8217;s account database they will try to reuse the same email and password on a number of other high value sites. Since many people reuse passwords &amp; many sites allow login based off an email address, the bad guys will trivially gain access to a significant number of accounts on other non-compromised sites. I am already generating unique passwords for each site, but to add just one more roadblock, I decided that while changing passwords, I would also set a unique email address for every single site.</p>
<p>My exim mail server supports what is known as &#8220;plus addressing&#8221;, whereby you can append an arbitrary tag to the local part of an email address. For example given an address &#8220;<strong>fred@example.com</strong>&#8221; you have an infinite number of unique email address &#8220;<strong>fred+TAG@example.com</strong>&#8221; where &#8220;<strong>TAG</strong>&#8221; is any reasonable string. Sadly when I tried using plus addressing, I immediately hit problems, because many (broken) form data validation checks think &#8220;+&#8221; is not a valid character to use in email addresses, or worse they would accept the address but all email they sent would end up in a black hole. Fortunately, it is a trivial matter to reconfigure Exim to allow use of &#8216;-&#8217; as the separator for plus addressing, ie to allow &#8220;<strong>fred-TAG@example.com</strong>&#8220;.</p>
<p>Out of &gt; 100 websites I updated my account details on, only 1 rejected the use of &#8216;-&#8217; in my email address. So now more or less every account I am registered to has both a unique password and unique email address.</p>
<p>In the end, the main thing I an unhappy about is that using a password manager presents a single point of attack for a local computer virus/trojan. Given the frequency with which websites are being compromised these days &amp; the number of sites I need to remember passwords for, I think overall this is clearly still a net win. I will remain on the lookout though for ways to improve the security of the password manager database itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/01/23/rambling-about-the-pain-of-dealing-with-passwords-for-online-services/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Building application sandboxes with libvirt, LXC &amp; KVM</title>
		<link>http://berrange.com/posts/2012/01/17/building-application-sandboxes-with-libvirt-lxc-kvm/</link>
		<comments>http://berrange.com/posts/2012/01/17/building-application-sandboxes-with-libvirt-lxc-kvm/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 23:30:26 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[containers]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[libvirt-sandbox]]></category>
		<category><![CDATA[lxc]]></category>
		<category><![CDATA[sandbox]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=584</guid>
		<description><![CDATA[I have mentioned in passing every now &#38; then over the past few months, that I have been working on a tool for creating application sandboxes using libvirt, LXC and KVM. Last Thursday, I finally got around to creating a first public release of a package that is now called libvirt-sandbox. Before continuing it is [...]]]></description>
			<content:encoded><![CDATA[<p>I have mentioned in passing every now &amp; then over the past few months, that I have been working on a tool for creating application sandboxes using libvirt, LXC and KVM. Last Thursday, I finally got around to creating a <a href="https://www.redhat.com/archives/libvir-list/2012-January/msg00516.html">first public release</a> of a package that is now called <em>libvirt-sandbox</em>. Before continuing it is probably worth defining what I consider the term &#8220;<em>application sandbox</em>&#8221; to mean. My working definition is that an &#8220;application sandbox&#8221; is simply a way to confine the execution environment of an application, limiting the access it has to OS resources. To me one notable point is that there is no need for a separate / special installation of the application to be confined. An application sandbox ought to be able to run any existing application installed in the OS.</p>
<h3>Background motivation &amp; prototype</h3>
<p>For a few Fedora releases, users have had the <a href="http://danwalsh.livejournal.com/28545.html">SELinux sandbox</a> command which will execute a command with a strictly confined SELinux context applied. It is also able to make limited use of the kernel filesystem namespace feature, to allow changes to the mount table inside the sandbox. For example, the common case is to put in place a different $HOME. The SELinux sandbox has been quite effective, but there is a limit to what can be done with SELinux policy alone, as evidenced by the need to create a setuid helper to enable use of the kernel namespace feature. Architecturally this gets even more problematic as new feature requests need to be dealt with.</p>
<p>As most readers are no doubt aware, libvirt provides a virtualization management API, with support for a wide variety of virtualization technologies. The KVM driver is easily the most advanced and actively developed driver for libvirt with a very wide array of features for machine based virtualization. In terms of container based virtualization, the LXC driver is the most advanced driver in libvirt, often getting new features &#8220;for free&#8221; since it shares alot of code with the KVM driver, in particular anything cgroup based. The LXC driver has always had the ability to pass arbitrary host filesystems through to the container, and the KVM driver gained similar capabilities last year with the inclusion of support for virtio 9p filesystems. One of the well known security features in libvirt is sVirt, which leverages MAC technology like SELinux to strictly confine the execution environment of QEMU. This has also now been adapted to work for the <a href="https://www.redhat.com/archives/libvir-list/2012-January/msg00418.html">LXC driver</a>.</p>
<p>Looking at the architecture of the SELinux sandbox command last year, it occurred to me that the core concepts mapped very well to the host filesystem passthrough &amp; sVirt features in libvirt&#8217;s KVM &amp; LXC drivers. In other words, it ought to be possible to create application sandboxes using the libvirt API and suitably advanced drivers like KVM or LXC. A few weeks hacking resulted in a proof of concept tool <a href="https://gitorious.org/virt-tools/virt-sandbox">virt-sandbox</a> which can run simple commands in sandboxes built on LXC or KVM.</p>
<h3>The libvirt-sandbox API</h3>
<p>A command line tool for running applications inside a sandbox is great, but even more useful would be an API for creating application sandboxes that programmers can use directly. While libvirt provides an API that is portable across different virtualization technologies, it cannot magically hide the differences in feature set or architecture between the technologies. Thus the decision was taken to create a new library called libvirt-sandbox that provides a higher level API for managing application sandboxes, built on top of libvirt. The virt-sandbox command from the proof of concept would then be re-implemented using this library API.</p>
<p>The libvirt-sandbox library is built using GObject to enable it to be accessible to any programming language via <a href="https://live.gnome.org/GObjectIntrospection">GObject Introspection</a>. The basic idea is that programmer simply defines the desired characteristics of the sandbox, such as the command to be executed, any arguments, filesystems to be exposed from host, any bind mounts, private networking configuration, etc. From this configuration description, libvirt-sandbox will decide upon &amp; construct a libvirt guest XML configuration that can actually provided the requested characteristics. In other words, the libvirt-sandbox API is providing a layer of policy avoid libvirt, to isolate the application developer from the implementation details of the underlying hypervisor.</p>
<p>Building sandboxes using LXC is quite straightforward, since application confinement is a core competency of LXC. Thus I will move straight to the KVM implementation, which is where the real fun is. Booting up an entire virtual machine probably sounds like quite a slow process, but it really need not be particularly if you have a well constrained hardware definition which avoids any need for probing. People also generally assume that running a KVM guest, means having a guest operating system install. This is absolutely something that is not acceptable for application sandboxing, and indeed not actually necessary. In a nutshell, libvirt-sandbox creates a new initrd image containing a custom init binary. This init binary simply loads the virtio-9p kernel module and then mounts the host OS&#8217; root filesystem as the guest&#8217;s root filesystem, readonly of course. It then hands off to a second boot strap process which runs the desired application binary and forwards I/O back to the host OS, until the sandboxed application exits. Finally the init process powers off the virtual machine. To get an idea of the overhead, the /bin/false binary can be executed inside a KVM sandbox with an overall execution time of 4 seconds. That is the total time for libvirt to start QEMU, QEMU to run its BIOS, the BIOS to load the kernel + initrd, the kenrel to boot up, /bin/false to run, and the kernel to shutdown &amp; QEMU to exit. I think 3 seconds is pretty impressive todo all that. This is a constant overhead, so for a long running command like an MP3 encoder, it disappears into the background noise. With sufficient optimization, I&#8217;m fairly sure we could get the overhead down to approx 2 seconds.</p>
<h3>Using the virt-sandbox command</h3>
<p>The Fedora review of the libvirt-sandbox package was nice &amp; straightforward, so the package is already available in rawhide for ready to test the <a href="https://fedoraproject.org/wiki/Features/VirtSandbox">VirtSandbox F17 feature</a>. The virt-sandbox command is provided by the libvirt-sandbox RPM package</p>
<p># yum install libvirt-sandbox</p>
<p>Assuming libvirt is already installed &amp; able to run either LXC or KVM guests, everything is ready to use immediately.</p>
<p>A first example is to run the &#8216;/bin/date&#8217; command inside a KVM sandbox:</p>
<pre>$ virt-sandbox -c qemu:///session  /bin/date
Thu Jan 12 22:30:03 GMT 2012</pre>
<p>You want proof that this really is running an entire KVM guest ? How about looking at the /proc/cpuinfo contents:</p>
<pre>$ virt-sandbox -c qemu:///session /bin/cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 2
model name	: QEMU Virtual CPU version 1.0
stepping	: 3
cpu MHz		: 2793.084
cache size	: 4096 KB
fpu		: yes
fpu_exception	: yes
cpuid level	: 4
wp		: yes
flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm up rep_good nopl pni cx16 hypervisor lahf_lm
bogomips	: 5586.16
clflush size	: 64
cache_alignment	: 64
address sizes	: 40 bits physical, 48 bits virtual
power management:</pre>
<p>How about using LXC instead of KVM, and providing an interactive console instead of just a one-shot command ? Yes, we can do that too:</p>
<pre>$ virt-sandbox -c lxc:/// /bin/sh
sh-4.2$ ps -axuwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 165436  3756 pts/0    Ss+  22:31   0:00 libvirt-sandbox-init-lxc
berrange    24  0.0  0.1 167680  4688 pts/0    S+   22:31   0:00 libvirt-sandbox-init-common
berrange    47  0.0  0.0  13852  1608 pts/1    Ss   22:31   0:00  \_ /bin/sh
berrange    48  0.0  0.0  13124   996 pts/1    R+   22:31   0:00      \_ ps -axuwf</pre>
<p>Notice how we only see the processes from our sandbox, none from the host OS. There are many more examples I&#8217;d like to illustrate, but this post is already far too long.</p>
<h3>Future development</h3>
<p>This blog post might give the impression that every is complete &amp; operational, but that is far from the truth. This is only the bare minimum functionality to enable some real world usage.  Things that are yet to be dealt with include</p>
<ul>
<li>Write suitable SELinux policy extensions to allow KVM to access host OS filesystems in readonly mode. Currently you need to run in permissive mode which is obviously something that needs solving before F17</li>
<li>Turn the virt-viewer command code for SPICE/VNC into a formal API and use that to provide a graphical sandbox running Xorg.</li>
<li>Integrate a tool that is able to automatically create sandbox instances for system services like apache to facilitate confined vhosting deployments</li>
<li>Correctly propagate exit status from the sandboxed command to the host OS</li>
<li>Unentangle stderr and stdout from the sandboxed command</li>
<li>Figure out how to make dhclient work nicely when / is readonly and resolv.conf must be updated in-place</li>
<li>Expose all the libvirt performance tuning controls to allow disk / net I/O controls, CPU scheduling, NUMA affinity, etc</li>
<li>Wire up libvirt&#8217;s firewall capability to allow detailed filtering of network traffic to/from sandboxes</li>
<li>Much more&#8230;</li>
</ul>
<p>For those attending FOSDEM this year, I will be giving a <a href="http://fosdem.org/2012/schedule/event/libvirt_lxc_kvm_sandboxes">presentation about libvirt-sandbox</a> in the virt/cloud track.</p>
<p>Oh and as well as the released tar.gz mentioned in the first paragraph, or the Fedora RPM, the  code is all <a href="http://libvirt.org/git/?p=libvirt-sandbox.git;a=summary">available in GIT</a></p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/01/17/building-application-sandboxes-with-libvirt-lxc-kvm/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The libvirt &amp; virtualization tools software development platform</title>
		<link>http://berrange.com/posts/2012/01/13/the-libvirt-virtualization-tools-software-development-platform/</link>
		<comments>http://berrange.com/posts/2012/01/13/the-libvirt-virtualization-tools-software-development-platform/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 14:40:12 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Gtk-Vnc]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[libguestfs]]></category>
		<category><![CDATA[libvirt-gconfig]]></category>
		<category><![CDATA[libvirt-sandbox]]></category>
		<category><![CDATA[virtualization tools]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=577</guid>
		<description><![CDATA[In the five years since the libvirt project started, alot has changed. The size of the libvirt API has increased dramatically; the number of languages you can access the API from has likewise grown to cover most important targets; libvirt has been translated to fit into several other object models; plugins have been developed to [...]]]></description>
			<content:encoded><![CDATA[<p>In the five years since the <a href="http://libvirt.org">libvirt</a> project started, alot has changed. The size of the libvirt API has increased dramatically; the number of languages you can access the API from has likewise grown to cover most important targets; libvirt has been translated to fit into several other object models; plugins have been developed to bind libvirt to other tools. At the same time many other libraries have grown up alongside libvirt, not least <a href="http://libguestfs.org">libguestfs</a>, gtk-vnc and more recently spice-gtk. Together all these pieces provide a rich software development platform for people building virtualization management applications. A picture is worth 1000 words, so to keep this blog post short, here is the way I visualize the pieces in the virtualization tools platform, and a selection of the applications built on it (click to enlarge the image)</p>
<p style="text-align: center;"><a href="http://berrange.com/wp-content/uploads/2012/01/virt-platform-2.png"><img class="aligncenter  wp-image-578" title="The libvirt &amp; virtualization tools software development platform" src="http://berrange.com/wp-content/uploads/2012/01/virt-platform-2.png" alt="The libvirt &amp; virtualization tools software development platform" width="643" height="368" /></a></p>
<h3 style="text-align: left;">The base layer</h3>
<ul>
<li><strong>libvirt</strong>: the core hypervisor agnostic management API, coring virtual machines, host devices, networking, storage, security and more</li>
<li><strong>libvirt-qemu</strong>: a small set of QEMU specific APIs, such as the ability to talk to the QEMU monitor, or attach to externally launched <a href="http://qemu.org">QEMU</a> guests. This library builds on top libvirt.</li>
<li><strong>libguestfs</strong>: the library for manipulating and accessing the contents of guest filesystem images. This uses libvirt for some actions internally. libguestfs has its own huge set of language bindings which are not shown in the diagram, for the sake of clarity. It will also soon be gaining a mapping into the GObject type system, which will help it play nicely with other GObject based APIs here.</li>
</ul>
<h3>Language bindings</h3>
<p>The language bindings for libvirt aim to be a 1-for-1 export of the libvirt C API into the corresponding language. They generally don&#8217;t attempt to change the way the libvirt API looks or is structured. There is generally completely interoperability between all language bindings, so you can trivially have part of your application written in Perl and another part written in Java and play nicely together.</p>
<ul>
<li><strong>libvirt-ocaml</strong>: a binding into the OCaml functional language</li>
<li><strong>libvirt-php</strong>: a binding into the PHP scripting language</li>
<li><strong>libvirt-perl</strong>: a binding into the Perl scripting language</li>
<li><strong>libvirt-python</strong>: a binding into the Python scripting language, which comes as a standard part of the libvirt package</li>
<li><strong>libvirt-java</strong>: a binding into the Java object language</li>
<li><strong>libvirt-ruby</strong>: a binding into the Ruby scripting language</li>
<li><strong>libvirt-csharp</strong>: a binding into the C# object language</li>
</ul>
<h3>Object mappings</h3>
<p>The object mappings are distinct from language bindings, because they will often significantly change the structure of the libvirt API to fit in the requirement of the object system being targeted. Depending on the object systems involved, this translation might be lossless, thus an application generally has to pick one object system &amp; stick with it. It is not a good idea to do a mixture of SNMP and QMF calls from the same application.</p>
<ul>
<li><strong>libvirt-snmp</strong>: an agent for SNMP that translates from an SNMP MIB to libvirt API calls.</li>
<li><strong>libvirt-cim</strong>: an agent for CIM the translates from the DMTF virtualization schema to the libvirt API</li>
<li><strong>libvirt-qmf</strong>: an agent for Matahari that translates from a QMF schema to the libvirt API</li>
</ul>
<h3>Infrastructure plugins</h3>
<p>Many common infrastructure applications can be extended by adding plugins for new functionality.  This particularly common with network monitoring or performance collection applications. libvirt can of course be used to create plugins for such applications</p>
<ul>
<li><strong>libvirt-collectd</strong>: a plugin for collectd that reports statistics on virtual machines</li>
<li><strong>libvirt-munin</strong>: a plugin for collectd that reports statistics on virtual machines</li>
<li><strong>libvirt-nagios</strong>: a plugin for nagious that reports where virtual machines are running</li>
<li><strong>fence-virt</strong>: a plugin for clustering software to allow virtual machines to be &#8220;fenced&#8221;</li>
</ul>
<h3>GObject layer</h3>
<p>The development of a set of GObject based libraries came about after noticing that many users of the basic libvirt API were having to solve similar problems over &amp; over. For example, every application wanted some programmatic way to extract info from XML documents. Many applications wanted libvirt translated into GObjects. Many applications needed a way to determine optimal hardware configuration for operating systems. The primary reasons for choosing to use GObject as the basis for these APIs was first to facilitate development of graphical desktop applications. With the advent of GObject Introspection, the even more compelling reason is that you get language bindings to all GObject libraries for free. Contrary to popular understanding, GObject is not solely for GTK based desktop applications. It is entirely independent of GTK and can be easily used from any conceivable application. If libvirt were to be started from scratch again today, it would probably go straight for GObject as  the basis for the primary C library. It is that compelling.</p>
<ul>
<li><strong>libosinfo</strong>: an API for managing metadata related to operating systems. It includes a database of operating systems with details such as common download URLs, magic byte sequences to identify ISO images, lists of supported hardware. In addition there is a database of hypervisors and their supported hardware. The API allows applications to determine the optimal virtual hardware configuration for deployment of an operating system on a particular hypervisor.</li>
<li><strong>gvnc</strong>: an API providing a client for the RFB protocol, used for VNC servers. The API facilitates the creation of new VNC client applications.</li>
<li><strong>spice</strong>-<strong>glib</strong>: an API providing a client for the SPICE protocol, used for SPICE servers. The API facilitates the creation of new SPICE client applications.</li>
<li><strong>libvirt-glib</strong>: an API binding the libvirt event loop into the GLib main loop, and translating libvirt errors into GLib errors.</li>
<li><strong>libvirt-gconfig</strong>: an API for generating and manipulating libvirt XML documents. It removes the need for application programmers to directly deal with raw XML themselves.</li>
<li><strong>libvirt-gobject</strong>: an API which translates the libvirt object model, also integrating them with the lbivirt-gconfig APIs.</li>
<li><strong>libvirt-sandbox</strong>: an API for building application sandboxes using virtualization technology.</li>
</ul>
<h3>GTK layer</h3>
<ul>
<li><strong>gtk-vnc</strong>: an API building on gvnc providing a GTK widget which acts as a VNC client. This is used in both virt-manager &amp; virt-viewer</li>
<li><strong>spice-gtk</strong>: an API building on spice-glib providing a GTK widget which acts as a SPICE client. This is used in both virt-manager &amp; virt-viewer</li>
</ul>
<h3>Applications</h3>
<ul>
<li><strong>python-virtinst</strong>: provides the original python virt-install command line tool, as well as a python API which is leveraged by virt-manager. The python-virtinst internal API was the motivation behind the libosinfo library and libvirt-gconfig library</li>
<li><a href="http://virt-manager.org"><strong>virt-manager</strong></a>: provides a general purpose desktop application for interacting with libvirt managed virtualization hosts. The virt-manager internal API was the motivation behind the libvirt-gobject library</li>
<li><a href="http://ovirt.org"><strong>oVirt</strong></a>: the umbrella project for building an open source virtualized data center management application. Its VDSM component uses the libvirt python language bindings for managing KVM hosts</li>
<li><a href="http://openstack.org"><strong>OpenStack</strong></a>: the umbrella project for building an open source cloud management application. Its Nova component uses the libvirt python language bindings for managing KVM, Xen and LXC hosts.</li>
<li><a href="https://live.gnome.org/Boxes"><strong>GNOME</strong> <strong>Boxes</strong></a>: the new GNOME desktop application for running virtual machines and accessing remote desktops. It uses libirt-gobject, libosinfo, gtk-vnc &amp; spice-gtk via automatically generated vala bindings.</li>
</ul>
<h3>The Future</h3>
<ul>
<li>Get oVirt, OpenStack, python-virtinst and virt-manager using the libosinfo library to centralize definitions of what hardware config to use for deploying operating systems</li>
<li>Get oVirt &amp; OpenStack using the libvirt-gconfig library to generate configuration, instead of building XML documents up through string concatenation</li>
<li>Convert python-virtinst &amp; virt-manager to use the libvirt-gconfig, libvirt-gobject libraries instead of their private internal equivalents</li>
<li>Create a remote-viewer library which pulls in both gtk-vnc and spice-gtk in a higher level framework. This is essentially pulling the commonality out of virt-viewer, virt-manager and GNOME boxes use of gtk-vnc and spice-gtk.</li>
<li>Create a libvirt-install library which provides APIs for provisioning operating systems. This would be pulling out commonality between the way python-virtinst, GNOME boxes and other applications deploy new operating systems. This would be a bridge layer between libosinfo and libvirt-gobject</li>
</ul>
<p>There is undoubtably plenty of stuff I left out of this diagram &amp; description. For example there are many other data center &amp; cloud management projects that are based on libvirt, which I left out for clarity.  There are plenty more libvirt plugins for other applications too, many I will never have heard about. No doubt our future plans will change too, as we adapt to new information.  This should have given a good overview of how broad the open source virtualization tools software development ecosystem has become.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/01/13/the-libvirt-virtualization-tools-software-development-platform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using command line arg &amp; monitor command passthrough with libvirt and KVM</title>
		<link>http://berrange.com/posts/2011/12/19/using-command-line-arg-monitor-command-passthrough-with-libvirt-and-kvm/</link>
		<comments>http://berrange.com/posts/2011/12/19/using-command-line-arg-monitor-command-passthrough-with-libvirt-and-kvm/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 14:42:45 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[hmp]]></category>
		<category><![CDATA[kvm]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[passthrough]]></category>
		<category><![CDATA[qmp]]></category>
		<category><![CDATA[tainting]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=572</guid>
		<description><![CDATA[The general goal of the libvirt project is to provide an API definition and XML schema that is independent of any one hypervisor technology. This means that for every feature in KVM, we have to take a little time to carefully design a suitable API or XML schema to expose in libvirt, if none already [...]]]></description>
			<content:encoded><![CDATA[<p>The general goal of the libvirt project is to provide an API definition and XML schema that is independent of any one hypervisor technology. This means that for every feature in KVM, we have to take a little time to carefully design a suitable API or XML schema to expose in libvirt, if none already exists. Sometimes we are lucky and features in KVM can be expressed in almost the same way in libvirt, but more often than not, this does not hold true &#8211; the design for libvirt may look somewhat different. For example, several KVM monitor commands at the KVM level may be exposed as a single API call in libvirt. Or conversely, several different libvirt APIs may all end up invoking the same underlying KVM monitor commands. The need to put careful thought into libvirt API &amp; XML design means that there may be a short delay between a feature appearing in KVM, and it appearing in libvirt, though it can also be the other way around, where libvirt has a feature but KVM doesn&#8217;t provide a way to support it yet!</p>
<p>For many applications / developers this delay is a non-issue, since they don&#8217;t need to be on the absolute bleeding edge of development of KVM or libvirt, but there are always exceptions to the rule. For a long time, we did not want to enable direct use of hypervisor specific features at all via libvirt, because of the support implications of doing so. A little over a year ago though, we decide to change our position on this matter. The key to this change in policy was deciding how to clearly demarcate functionality which is long term supportable, vs that which is not.</p>
<h2>KVM custom command line arguments</h2>
<p>To support custom command line argument passthrough for KVM, we decided to introduce a new set of XML elements in a different XML namespace. This namespace is defined:</p>
<pre>  xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'</pre>
<p>Our policy is that any guest configuration that uses this QEMU XML namespace <strong>is not guaranteed to continue working</strong> if either libvirt or KVM are upgraded. A change to the way libvirt generates command line arguments may break the arguments the app has passed through. Alternatively KVM itself may drop or change the semantics of an existing command line argument. In other words applications should not rely on this capability long term, rather they should raise an RFE against libvirt to support it via the primary XML namespace, and just use the QEMU namespace until the RFE is complete.</p>
<p>The QEMU namespace defines syntax for passing arbitrary command line arguments, along with arbitrary environment variables:</p>
<pre>&lt;domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'&gt;
  &lt;name&gt;QEMUGuest1&lt;/name&gt;
  &lt;uuid&gt;c7a5fdbd-edaf-9455-926a-d65c16db1809&lt;/uuid&gt;
  ...
  &lt;devices&gt;
    &lt;emulator&gt;/usr/bin/qemu&lt;/emulator&gt;
    &lt;disk type='block' device='disk'&gt;
      &lt;source dev='/dev/HostVG/QEMUGuest1'/&gt;
      &lt;target dev='hda' bus='ide'/&gt;
    &lt;/disk&gt;
    ...
  &lt;/devices&gt;
  &lt;qemu:commandline&gt;
    &lt;qemu:arg value='-unknown'/&gt;
    &lt;qemu:arg value='parameter'/&gt;
    &lt;qemu:env name='NS' value='ns'/&gt;
    &lt;qemu:env name='BAR'/&gt;
  &lt;/qemu:commandline&gt;
&lt;/domain&gt;</pre>
<p>Remember that when adding the &lt;qemu:commandline&gt; element, you need to always declare the XML namespace &#8216;xmlns:qemu&#8217; on the top level &lt;domain&gt; element.</p>
<h2>KVM monitor command passthrough</h2>
<p>To support custom monitor command passthrough for KVM, we decided to introduce a second ELF library, libvirt-qemu.so, and separate header file /usr/include/libvirt/libvirt-qemu.h.<br />
An application that uses APIs in libvirt-qemu.so <strong>is not guaranteed to continue working</strong> if either libvirt or KVM are upgraded. A change to the way libvirt<br />
manages guests may conflict with the monitor commands the app is trying to issue. Alternatively KVM itself may drop or change the semantics of an existing monitor<br />
commands. In other words applications should not rely on this capability long term, rather they should raise an RFE against libvirt to support it via the primary<br />
library API, and just use libvirt-qemu.so until the RFE is complete.</p>
<p>Currently the libvirt-qemu.h defines two custom APIs</p>
<pre>typedef enum {
  VIR_DOMAIN_QEMU_MONITOR_COMMAND_DEFAULT = 0,
  VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP     = (1 &lt;&lt; 0), /* cmd is in HMP */
} virDomainQemuMonitorCommandFlags;

int virDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
                                char **result, unsigned int flags);

virDomainPtr virDomainQemuAttach(virConnectPtr domain,
                                 unsigned int pid,
                                 unsigned int flags);</pre>
<p>The first allows passthrough of arbitrary monitor commands, while the latter allows attachment to an existing QEMU instance <a href="http://berrange.com/posts/2011/07/13/attaching-libvirt-to-an-externally-launched-kvm-instance/">as discussed previously</a>. The monitor command API is quite straighforward, it accepts a string command, and returns a string reply.  The data for the command/reply can be either in HMP or QMP syntax, depending on how QEMU was launched by libvirt. The VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP flag allows an application to force use of the HMP syntax at all times.</p>
<h2>Using monitor command passthrough from virsh</h2>
<p>Not all users will be writing directly to the libvirt API, so the monitor command passthrough is also wired up into virsh via the &#8220;qemu-monitor-command&#8221; API. First is an example using QMP (JSON syntax):</p>
<pre>$ virsh qemu-monitor-command vm-vnc '{ "execute": "query-block"}'
{"return":[{"device":"drive-virtio-disk0","locked":false,"removable":false,"inserted":{"ro":false,"drv":"qcow2","encrypted":false,"file":"/home/berrange/VirtualMachines/plain.qcow"},"type":"unknown"}],"id":"libvirt-9"}</pre>
<p>And second is an example demonstrating use of HMP with a guest that runs QMP (libvirt automagically redirects via the &#8216;human-monitor-command&#8217; command)</p>
<pre>$ virsh qemu-monitor-command --hmp vm-vnc  'info block'
drive-virtio-disk0: removable=0 file=/home/berrange/VirtualMachines/plain.qcow ro=0 drv=qcow2 encrypted=0</pre>
<h2>Tainting of guests</h2>
<p>Anyone familiar with the kernel will know that it marks itself as tainted whenever the user does something that is outside the boundaries of normal support. We have borrowed this idea from the kernel and apply it to guests run by libvirt too. Any attempt to use either the command line argument passthrough via XML, or QEMU monitor command passthrough via libvirt-qemu.so will result in the guest domain being marked as tainted. This shows up in the libvirt log files. For example after that last example,  $HOME/.libvirt/qemu/log/vm-vnc.log shows the following</p>
<pre>Domain id=2 is tainted: custom-monitor</pre>
<p>This allows OS distro support staff to determine if something unusal has been done to a guest when they see support tickets raised. Depending on the OS distro&#8217;s support policy they may decline to support problem arising from tainted guests. In RHEL for example, any usage of QEMU monitor command passthrough, or command line argument passthrough is outside the bounds of libvirt support, and users would normally be asked to try to reproduce any problem without a tainted guest.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/12/19/using-command-line-arg-monitor-command-passthrough-with-libvirt-and-kvm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Securing the WordPress admin interface using (Free!) SSL certificates</title>
		<link>http://berrange.com/posts/2011/12/19/securing-the-wordpress-admin-interface-using-free-ssl-certificates/</link>
		<comments>http://berrange.com/posts/2011/12/19/securing-the-wordpress-admin-interface-using-free-ssl-certificates/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 13:13:28 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[startssl]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=569</guid>
		<description><![CDATA[Last year I migrated my website off Blogger to a WordPress installation hosted on my Debian server. Historically my website has only been exposed over plain old HTTP, which was fine since the Blogger publishing UI was running HTTPS. With the migration to WordPress install though, the publishing UI is now running on my own [...]]]></description>
			<content:encoded><![CDATA[<p>Last year I <a href="http://berrange.com/posts/2010/02/14/adventures-in-migrating-from-static-website-blogger-sftp-to-wordpress/">migrated my website</a> off Blogger to a WordPress installation hosted on my Debian server. Historically my website has only been exposed over plain old HTTP, which was fine since the Blogger publishing UI was running HTTPS. With the migration to WordPress install though, the publishing UI is now running on my own webserver and thus the lack of HTTPS on my server becomes a reasonably serious problem. Most people&#8217;s first approach to fixing this would be to just generate a self-signed certificate and deploy that for their server, but I rather wanted to have a x509 certificate that would be immediately trusted by any visiting browser.</p>
<h2>Getting free x509 certificates from StartSSL</h2>
<p>The problem is that the x509 certificate authority system is a bit of a protection racket with recurring fees that just cannot justify the level of integrity they provide. There is one exception to the norm though, <a href="https://www.startssl.com/">StartSSL</a> offer some basic x509 certificates at zero cost. In particular you can get Class1 web server certificates and personal client identity certificates. The web server certificates are restricted in that you can only include 2 domain names in them, your basic domain name &amp; the same domain name with &#8216;www.&#8217; prefixed. If you want wildcard domains, or multiple different domain names in a single certificate you&#8217;ll have to go for their pay-for offerings. For many people, including myself, this limitation will not be a problem.</p>
<p>StartSSL have a nice self-service web UI for generating the various certificates. The first step is to generate a personal client identity certificate, which the rest of their administrative control panel relies on for authentication. After generation is complete, it automatically gets installed into firefox&#8217;s certificate database. You are wisely reminded to export the database to a pkcs12 file and back it up somewhere securely. If you loose this personal client certificate, you will be unable to access their control panel for managing your web server certificates. The validation they do prior to issuing the client certificate is pretty minimal, but fully automated, in so much as they send a message to the email address you provide with a secret URL you need to click on. This &#8220;proves&#8221; that the email address is yours, so you can&#8217;t request certificates for someone else&#8217;s email address, unless you can hack their email accounts&#8230;</p>
<p>Generating certificates for web servers is not all that much more complicated. There are two ways to go about it though, either you can fill in their interactive web form &amp; let their site generate the private key, or you can generate a private key offline and just provide them with a CSR (Certificate Signing Request). I tried todo the former first of all, but for some reason it didn&#8217;t work &#8211; it got stuck generating the private key, so I switched to generating a CSR instead. The validation they do prior to issuing a certificate for a web server is also automated. This time they do a whois lookup on the domain name you provide, and send a message with a secret URL to the admin, technical &amp; owner email addresses in the whois record. This &#8220;proves&#8221; that the domain is yours, so you can&#8217;t requests certificates for someone else&#8217;s domain name, unless you can hack their whois data or admin/tech/owner email accounts&#8230;</p>
<h2>Setting up Apache to enable SSL</h2>
<p>The next step is to configure apache to enable SSL for the website as a whole. There are four files that need to be installed to provide the certificates to mod_ssl</p>
<ul>
<li>ssl-cert-berrange.com.pem &#8211; this is the actual certificate StartSSL issued for my website, against StartSSL&#8217;s Class1 root certificate</li>
<li>ssl-cert-berrange.com.key &#8211; this is the private key I generated and used with my CSR</li>
<li>ssl-ca-start.com.pem &#8211; this is the master StartSSL CA certificate</li>
<li>ssl-ca-chain-start.com-class1-server.pem &#8211; this is the chain of trust between your website&#8217;s certificate and StartSSL&#8217;s master CA certificate, via their Class1 root certificate</li>
</ul>
<p>On my Debian Lenny host, they were installed to the following locations</p>
<ul>
<li>/etc/ssl/certs/ssl-cert-berrange.com.pem</li>
<li>/etc/ssl/private/ssl-cert-berrange.com.key</li>
<li>/etc/ssl/certs/ssl-ca-chain-start.com-class1-server.pem</li>
<li>/etc/ssl/certs/ssl-ca-start.com.pem</li>
</ul>
<p>The only other bit I needed todo was to setup a new virtual host in the apache config file, listening on port 443</p>
<pre>&lt;VirtualHost *:443&gt;
  ServerName www.berrange.com
  ServerAlias berrange.com

  DocumentRoot /var/www/berrange.com
  ErrorLog /var/log/apache2/berrange.com/error_log
  CustomLog /var/log/apache2/berrange.com/access_log combined

  SSLEngine on

  SSLCertificateFile    /etc/ssl/certs/ssl-cert-berrange.com.pem
  SSLCertificateKeyFile /etc/ssl/private/ssl-cert-berrange.com.key
  SSLCertificateChainFile /etc/ssl/certs/ssl-ca-chain-start.com-class1-server.pem
  SSLCACertificateFile /etc/ssl/certs/ssl-ca-start.com.pem
&lt;/VirtualHost&gt;</pre>
<p>After restarting Apache, I am now able to connect to <a href="https://berrange.com">https://berrange.com/</a> and that my browser trusts the site with no exceptions required.</p>
<h2>Setting up Apache to require SSL client cert for WordPress admin pages</h2>
<p>The next phase is to mandate use of a client certificate when accessing any of the WordPress administration pages. Should there be any future security flaws in the WordPress admin UI, this will block any would be attackers since they will not have the requisite client SSL certificate. Mnadating use of client certificates is done with the &#8220;SSLVerifyClient require&#8221; directive in Apache. This allows the client to present any client certificate that is signed by the CA configured earlier &#8211; that is potentially any user of StartSSL.  My intention is to restrict access exclusively to the certificate that I was issued. This requires specification of some match rules against various fields in the certificate. First lets see the Apache virtual host configuration additions:</p>
<pre>&lt;Location /wp-admin&gt;
  SSLVerifyClient require
  SSLVerifyDepth  3
  SSLRequire %{SSL_CLIENT_I_DN_C} eq "IL" and \
             %{SSL_CLIENT_I_DN_O} eq "StartCom Ltd." and \
             %{SSL_CLIENT_I_DN_OU} eq "Secure Digital Certificate Signing" and \
             %{SSL_CLIENT_I_DN_CN} eq "StartCom Class 1 Primary Intermediate Client CA" and \
             %{SSL_CLIENT_S_DN_CN} eq "dan@berrange.com" and \
             %{SSL_CLIENT_S_DN_Email} eq "dan@berrange.com"
&lt;/Location&gt;</pre>
<p>The first 4 match rules here are saying that the client certificate must have been issued by the StartSSL Class1 client CA, while the last 2 matches are saying that the client certificate must contain my email address. The security thus relies on StartSSL not issuing anyone else a certificate using my email address. The whole lot appears inside a location match against &#8216;/wp-admin&#8217; which is the URL prefix all the WordPress administration pages have. The entire block must also be duplicated using a location match against &#8216;/wp-login.php&#8217; to protect the user login page too.</p>
<pre>&lt;Location /wp-login.php&gt;
  SSLVerifyClient require
  SSLVerifyDepth  3
  SSLRequire %{SSL_CLIENT_I_DN_C} eq "IL" and \
             %{SSL_CLIENT_I_DN_O} eq "StartCom Ltd." and \
             %{SSL_CLIENT_I_DN_OU} eq "Secure Digital Certificate Signing" and \
             %{SSL_CLIENT_I_DN_CN} eq "StartCom Class 1 Primary Intermediate Client CA" and \
             %{SSL_CLIENT_S_DN_CN} eq "dan@berrange.com" and \
             %{SSL_CLIENT_S_DN_Email} eq "dan@berrange.com"
&lt;/Location&gt;</pre>
<h2>Preventing access to the WordPress admin pages via non-HTTPS connections.</h2>
<p>Finally, to ensure the login &amp; admin pages cannot be accessed over plain HTTP, it is necessary to alter the virtual host config for port 80, to include</p>
<pre>RewriteEngine On
RewriteRule ^(/wp-admin/.*) https://www.berrange.com$1 [L,R=permanent]
RewriteRule ^(/wp-login.php.*) https://www.berrange.com$1 [L,R=permanent]</pre>
<p>To be honest, I should just put a redirect on &#8216;/&#8217; to prevent <strong>any</strong> use of the plain HTTP site at all, but I want to test how well my tiny virtual server copes with the load before enabling HTTPs for everything.</p>
<p>Hopefully this blog post has demonstrated that setting up your personal webserver with certificates that any browser will trust, is both easy and cheap (free), so there is no reason to use self-signed certificates unless you need multiple domain names / wildcard addresses in your certificates and you&#8217;re unwilling to pay money for them.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/12/19/securing-the-wordpress-admin-interface-using-free-ssl-certificates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multi-factor SSH authentication using YubiKey and SSH public keys together</title>
		<link>http://berrange.com/posts/2011/12/18/multi-factor-ssh-authentication-using-yubikey-and-ssh-public-keys-together/</link>
		<comments>http://berrange.com/posts/2011/12/18/multi-factor-ssh-authentication-using-yubikey-and-ssh-public-keys-together/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 18:19:55 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[public key]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[two-factor]]></category>
		<category><![CDATA[yubikey]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=559</guid>
		<description><![CDATA[A month or two ago I purchased a couple of YubiKey USB tokens, one for authentication with Fedora infrastructure and the other for authentication of my personal servers. The reason I need two separate tokens is that Fedora uses its own YubiKey authentication server, thus requiring that you burn a new secret key into the [...]]]></description>
			<content:encoded><![CDATA[<p>A month or two ago I purchased a couple of <a href="https://www.yubico.com/yubikey">YubiKey</a> USB tokens, one for authentication with <a href="https://fedoraproject.org/wiki/Infrastructure/Yubikey">Fedora infrastructure</a> and the other for authentication of my personal servers. The reason I need two separate tokens is that Fedora uses its own YubiKey authentication server, thus requiring that you burn a new secret key into the token. For my personal servers I decided that I would simply authenticate against the central YubiKey authentication server hosted by <a href="https://www.yubico.com/">YubiCo</a> themselves. While some people might not be happy trusting a 3rd party service for authentication of their servers, I decided this was not a big problem since I intend to combine the YubiKey authentication with the existing strong SSH RSA public key authentication which is entirely under my control.</p>
<h2>YubiKey authentication via PAM</h2>
<p>To start off with I decided to follow a <a href="https://code.google.com/p/yubico-pam/wiki/YubikeyAndSSHViaPAM">well documented configuration</a> path, enabling YubiKey authentication for SSH via PAM. This was pretty straightforward and worked first time. The configuration steps were</p>
<ul>
<li>Build and install the <a href="https://code.google.com/p/yubico-pam/">yubico-pam</a> module. You might be lucky and find your distro already ships packages for this, but I was doing this on my Debian Lenny server which did not appear to have any pre-built PAM module.</li>
<li>Create a file /etc/yubikey_mappings which contains a list of usernames and their associated yubikey token IDs. The Token ID is the first 12 characters of a OTP generated from a keypress of the token. Multiple token IDs can be listed for each user.
<pre>$ cat &gt; /etc/yubikey_mappings &lt;&lt;EOF
fred:cccccatsdogs:ccccdogscats
EOF</pre>
</li>
<li>Get a unique API key and secret for personal use from <a href="https://upgrade.yubico.com/getapikey/">https://upgrade.yubico.com/getapikey/</a></li>
<li>Add the yubico-pam module to the SSHD PAM configuration module using the previously obtained API key ID in place of <code>XXXX</code>
<pre>$ cat /etc/pam.d/sshd
# PAM configuration for the Secure Shell service

# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
auth       required     pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
auth       required     pam_env.so envfile=/etc/default/locale

<strong>auth sufficient pam_yubico.so id=XXXX authfile=/etc/yubikey_mappings</strong>

# Standard Un*x authentication.
@include common-auth

<em>...snip...</em></pre>
</li>
</ul>
<p>This all worked fine, with one exception, if I had an authorized SSH public key then SSH would skip straight over the PAM &#8220;auth&#8221; phase. This is not what I wanted, since my intention was to use YubiKey <strong>and</strong> SSH public keys for login. The yubico-pam website has instructions for setting up <a href="https://code.google.com/p/yubico-pam/wiki/TwoFactorPAMConfiguration">two-factor authentication</a> but this only works if both your factors are configured via PAM. SSH public key authentication is completely outside the realm of PAM. AFAICT from a bit of googling, it is not possible to configure OpenSSH to require PAM and public key authentication together; it considers either one of them to be sufficient on their own.</p>
<p>After a little more googling though, I came across <a href="http://www.tuxz.net/blog/archives/2010/03/17/how_to_quickly_setup_two-factor_ssh_authentication/">an interesting hack</a> utilizing the <code>ForceCommand</code> configuration parameter of SSHD. The gist of the idea is that instead of configuring YubiKey authentication via PAM, you use the <code>ForceCommand</code> parameter to get SSHD to invoke a helper script which performs a YubiKey authentication check and only then executes the real command (ie login shell).</p>
<p>I made a few modifications to Alexandre&#8217;s script mentioned in the blog post just linked</p>
<ul>
<li>Use the same configuration file, /etc/yubimap_mappings, as used for centralized yubico-pam setup</li>
<li>Allow the verbose debugging information to be turned off</li>
<li>Load the API key ID from /etc/yubikey_shell instead of requiring editing of the helper script itself</li>
</ul>
<p>Usage of the script is quite simple</p>
<ul>
<li>Create /etc/yubikey_shell containing
<pre>$ cat /etc/yubikey_shell
# Configuration for /sbin/yubikey_shell

# Replace XXXX with your 4 digit API key ID as obtained
# from https://upgrade.yubico.com/getapikey/
YUBICO_API_ID="XXXX"

# Change to 1 to enable debug logs for troubleshooting login
#DEBUG=1

# To override stanard key mapping location. This file
# should contain 1 or more lines like
#
#    USERNAME:YUBI_KEY_ID:YUBI_KEY_ID:...
#
# This is the same syntax used for yubico-pam
#TRUSTED_KEYS_FILE=/etc/yubikey_mappings</pre>
</li>
<li>Create the /etc/yubikey_mappings file, if not already present from a previous yubico-pam setup
<pre>$ cat /etc/yubikey_mappings
fred:cccccatsdogs:ccccdogscats</pre>
</li>
<li>Append to the /etc/ssh/sshd_config file a directive to enable YubiKey auth for selected users
<pre>Match User fred
  ForceCommand /sbin/yubikey_shell</pre>
</li>
<li>Save the wrapper script itself to /sbin/yubikey_shell
<pre>x
DEBUG=0
TRUSTED_KEYS_FILE=/etc/yubikey_mappings
# This default works, but you really want to use your
# own ID for greater security
YUBICO_API_ID=16

test -f /etc/yubikey_shell &amp;&amp; source /etc/yubikey_shell

STD="\\033[0;39m"
OK="\\033[1;32m[i]$STD"
ERR="\\033[1;31m[e]$STD"

##################################################
## Disconnect clients trying to exit the script ##
##################################################
trap disconnect INT

disconnect() {
  sleep 1
  kill -9 $PPID
  exit 1
}

debug() {
  if test "$DEBUG" = 1 ; then
    echo -e "$@"
  fi
}

if test -z "$USER"
then
  debug "$ERR USER environment variable is not set" &gt; /dev/stderr
  disconnect
fi  
####################################
## Get user-trusted yubikeys list ##
####################################
if [ ! -f $TRUSTED_KEYS_FILE ]
then
  debug "$ERR Unable to find trusted keys list" &gt; /dev/stderr
  disconnect
fi

TRUSTED_KEYS=`grep "${USER}:" $TRUSTED_KEYS_FILE | sed -e "s/${USER}://" | sed -e 's/:/\n/g'`
for k in $TRUSTED_KEYS
do
  debug "$OK Possible key '$k'"
done

#######################################
## Get the actual OTP                ##
#######################################

echo -n "Please provide Yubi OTP: "
read -s OTP
echo
KEY_ID=${OTP:0:12}
#######################################
## Iterate through trusted keys list ##
#######################################
for trusted in ${TRUSTED_KEYS[@]}
do
  if test "$KEY_ID" = "$trusted"
  then
    debug "$OK Found key in $TRUSTED_KEYS_FILE - validating OTP now ..."
    if wget "https://api.yubico.com/wsapi/verify?id=$YUBICO_API_ID&amp;otp=$OTP" -O - 2&gt; /dev/null | grep "status=OK" &gt; /dev/null
    then
      debug "$OK OTP validated"
      if test -z "$SSH_ORIGINAL_COMMAND"
      then
        exec `grep "^$(whoami)" /etc/passwd | cut -d ":" -f 7`
      else
        exec "$SSH_ORIGINAL_COMMAND"
      fi
      debug "$ERR failed to execute shell / command" &gt; /dev/stderr
      disconnect
    else
      debug "$ERR Unable to validate generated OTP" &gt; /dev/stderr
      disconnect
    fi
  fi
done
debug "$ERR Key not trusted" &gt; /dev/stderr
disconnect</pre>
</li>
</ul>
<p>The avoid the need to cut+paste, here are links to the <a href="http://berrange.com/~dan/yubikey/yubikey_shell.sh">full script</a> and the <a href="http://berrange.com/~dan/yubikey/yubikey_shell.cfg">configuration file</a>.</p>
<p>After restarting the SSHD service, all was working nicely. Authentication now requires a combination of a valid SSH public key <strong>and</strong> a valid YubiKey token. Alternatively, if SSH public keys are not in use for a user, authentication will require the login password <strong>and</strong> a valid YubiKey token.</p>
<p>I still feel a little dirty about having to use the ForceCommand hack though, because it means yubikey auth failures don&#8217;t appear in your audit logs &#8211; as far as SSHD is concerned everything was successful. It would nice to be able to figure out how to make OpenSSH properly combine SSH public key <strong>and</strong> PAM for authentication&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/12/18/multi-factor-ssh-authentication-using-yubikey-and-ssh-public-keys-together/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Watching the libvirt RPC protocol using SystemTAP</title>
		<link>http://berrange.com/posts/2011/11/30/watching-the-libvirt-rpc-protocol-using-systemtap/</link>
		<comments>http://berrange.com/posts/2011/11/30/watching-the-libvirt-rpc-protocol-using-systemtap/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 11:36:41 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[dtrace]]></category>
		<category><![CDATA[markers]]></category>
		<category><![CDATA[probes]]></category>
		<category><![CDATA[rpc]]></category>
		<category><![CDATA[systemtap]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=554</guid>
		<description><![CDATA[A couple of releases back I completely re-structured all the RPC handling code inside libvirt to make sure it could be properly shared between the client and server, as well as decoupling the RPC handling code from the implementation of the RPC functions. As part of this work I introduced a fairly comprehensive set of [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of releases back I completely re-structured all the RPC handling code inside libvirt to make sure it could be properly shared between the client and server, as well as decoupling the RPC handling code from the implementation of the RPC functions. As part of this work I introduced a fairly comprehensive set of DTrace static probe points into the libvirt RPC code. While one could write a WireShark plugin that is able to decode the libvirt RPC protocol (oh look Michal <a href="https://www.redhat.com/archives/libvir-list/2011-October/msg00301.html">already has</a> written one), that would not be able to examine encrypted libvirt connections &#8211; which is pretty much all of them. By using static probes in the libvirt RPC code we can see the RPC messages being sent and received before/after encryption has been applied.</p>
<p>The observant will notice that I said I inserted DTrace static probes, while this blog subject line says SystemTAP. Well the SystemTAP developers had the good sense to make their userspace probing infrastructure support the DTrace static probe marker syntax. So inserting DTrace static probes into userspace code, trivially enables support for both DTrace and SystemTAP. I previously added DTrace probe support to QEMU/KVM and was very happy when Bryan Cantrill told me (at the recent KVM forum) that the DTrace probe support I added to KVM only needed minor build system tweaks to work on Solaris, despite my only ever having tested with Linux + SystemTAP.</p>
<p>Along with adding the DTrace markers to the libvirt RPC code, I also created two SystemTAP tapset files to make it simpler to use the probes from SystemTAP scripts. The first, <code>/usr/share/systemtap/tapset/libvirt_probe.stp</code>, contains the actual probe points, grouped by functional area, while the second, <code>/usr/share/systemtap/tapset/libvirt_functions.stp</code>, contains a bunch of helper functions for converting enum values into human friendly strings. The idea is that inserting of seeing &#8220;Procedure 53&#8243;, a sysadmin would much rather see &#8220;Procedure domain_dump_core&#8221;. I won&#8217;t go into detail about what is in those two files here, instead I&#8217;ll just illustrate their use</p>
<h2>Tracing the RPC client</h2>
<p>Lets says we first want to see what messages the client is sending and receiving. There are two interesting probes here, &#8220;<code>libvirt.rpc.server_client_msg_rx</code>&#8221; and &#8220;<code>libvirt.rpc.server_client_msg_tx_queue</code>&#8220;. The former is triggered when a complete RPC message has been read off the wire, while the latter is triggered when an RPC message is queued for transmission. Ideally we would also have another probe triggered when an RPC message has been completely transmitted &#8211; that&#8217;s a future todo item. Simple usage of these two probes would be</p>
<pre># cat &gt; demo.stp &lt;&lt;EOF
probe libvirt.rpc.client_msg_rx {
  printf("client=%p len=%d program=%d version=%d procedure=%d type=%d status=%d serial=%d\n",
         client, len, prog, vers, proc, type, status, serial);
}
probe libvirt.rpc.client_msg_tx_queue {
  printf("client=%p len=%d program=%s version=%d procedure=%s type=%s status=%d serial=%d\n",
         client, len, prog, vers, proc, type, status, serial);
}
EOF
# stap demo.stp
client=0x7f827c3b1010 len=28 program=536903814 version=1 procedure=66 type=0 status=0 serial=0
client=0x7f827c3b1010 len=36 program=536903814 version=1 procedure=66 type=1 status=0 serial=0
client=0x7f827c3b1010 len=40 program=536903814 version=1 procedure=1 type=0 status=0 serial=1
client=0x7f827c3b1010 len=28 program=536903814 version=1 procedure=1 type=1 status=0 serial=1
client=0x7f827c3b1010 len=28 program=536903814 version=1 procedure=110 type=0 status=0 serial=2
client=0x7f827c3b1010 len=48 program=536903814 version=1 procedure=110 type=1 status=0 serial=2
client=0x7f827c3b1010 len=28 program=536903814 version=1 procedure=2 type=0 status=0 serial=3
client=0x7f827c3b1010 len=28 program=536903814 version=1 procedure=2 type=1 status=0 serial=3</pre>
<p>The example shows the results of running &#8220;virsh domname vm1&#8243;. There are 4 RPC calls made here, 66 (authenticate), 1 (open), 110 (get uri), 2 (close).</p>
<h2>Tracing the client with friendly output</h2>
<p>Unless you have memorized libvirt RPC enums, this isn&#8217;t a very friendly way to trace the code. This is where the aforementioned <code>libvirt_functions.stp</code> tapset comes into play.</p>
<pre># cat &gt; demo.stp &lt;&lt;EOF
probe libvirt.rpc.client_msg_rx {
  printf("R client=%p len=%d program=%s version=%d procedure=%s type=%s status=%s serial=%d\n",
         client, len,
         libvirt_rpc_program_name(prog, 0),
         vers,
         libvirt_rpc_procedure_name(prog, vers, proc, 0),
         libvirt_rpc_type_name(type, 0),
         libvirt_rpc_status_name(status, 0),
         serial);
}
probe libvirt.rpc.client_msg_tx_queue {
  printf("T client=%p len=%d program=%s version=%d procedure=%s type=%s status=%s serial=%d\n",
         client, len,
         libvirt_rpc_program_name(prog, 0),
         vers,
         libvirt_rpc_procedure_name(prog, vers, proc, 0),
         libvirt_rpc_type_name(type, 0),
         libvirt_rpc_status_name(status, 0),
         serial);
}
EOF
# stap demo.stp
T client=0x7f3e3dec0010 len=28 program=remote version=1 procedure=auth_list type=call status=ok serial=0
R client=0x7f3e3dec0010 len=36 program=remote version=1 procedure=auth_list type=reply status=ok serial=0
T client=0x7f3e3dec0010 len=40 program=remote version=1 procedure=open type=call status=ok serial=1
R client=0x7f3e3dec0010 len=28 program=remote version=1 procedure=open type=reply status=ok serial=1
T client=0x7f3e3dec0010 len=28 program=remote version=1 procedure=get_uri type=call status=ok serial=2
R client=0x7f3e3dec0010 len=48 program=remote version=1 procedure=get_uri type=reply status=ok serial=2
T client=0x7f3e3dec0010 len=28 program=remote version=1 procedure=close type=call status=ok serial=3
R client=0x7f3e3dec0010 len=28 program=remote version=1 procedure=close type=reply status=ok serial=3</pre>
<p>Much more friendly !</p>
<h2>Tracing the server at the same time</h2>
<p>It might desirable to see when the server itself receives the message, independently of when the client transmitted it. There are an identical set of probes available in the server, just replace &#8216;client&#8217; with &#8216;server_client&#8217; in the above examples. Thus the demo script can trivially be extended to show server messages at the same time:</p>
<pre># cat &gt;&gt; demo.stp &lt;&lt; EOF
probe libvirt.rpc.server_client_msg_rx {
  printf("R server=%p len=%d program=%s version=%d procedure=%s type=%s status=%s serial=%d\n",
         client, len,
         libvirt_rpc_program_name(prog, 0),
         vers,
         libvirt_rpc_procedure_name(prog, vers, proc, 0),
         libvirt_rpc_type_name(type, 0),
         libvirt_rpc_status_name(status, 0),
         serial);
}
probe libvirt.rpc.server_client_msg_tx_queue {
  printf("T server=%p len=%d program=%s version=%d procedure=%s type=%s status=%s serial=%d\n",
         client, len,
         libvirt_rpc_program_name(prog, 0),
         vers,
         libvirt_rpc_procedure_name(prog, vers, proc, 0),
         libvirt_rpc_type_name(type, 0),
         libvirt_rpc_status_name(status, 0),
         serial);
}
# stap demo.stp
T client=0x7ff3c4855010 len=28 program=remote version=1 procedure=auth_list type=call status=ok serial=0
R server=0x17a2070 len=28 program=remote version=1 procedure=auth_list type=call status=ok serial=0
T server=0x17a2070 len=36 program=remote version=1 procedure=auth_list type=reply status=ok serial=0
R client=0x7ff3c4855010 len=36 program=remote version=1 procedure=auth_list type=reply status=ok serial=0
T client=0x7ff3c4855010 len=40 program=remote version=1 procedure=open type=call status=ok serial=1
R server=0x17a2070 len=40 program=remote version=1 procedure=open type=call status=ok serial=1
T server=0x17a2070 len=28 program=remote version=1 procedure=open type=reply status=ok serial=1
R client=0x7ff3c4855010 len=28 program=remote version=1 procedure=open type=reply status=ok serial=1
T client=0x7ff3c4855010 len=28 program=remote version=1 procedure=get_uri type=call status=ok serial=2
R server=0x17a2070 len=28 program=remote version=1 procedure=get_uri type=call status=ok serial=2
T server=0x17a2070 len=48 program=remote version=1 procedure=get_uri type=reply status=ok serial=2
R client=0x7ff3c4855010 len=48 program=remote version=1 procedure=get_uri type=reply status=ok serial=2
T client=0x7ff3c4855010 len=28 program=remote version=1 procedure=close type=call status=ok serial=3
R server=0x17a2070 len=28 program=remote version=1 procedure=close type=call status=ok serial=3
T server=0x17a2070 len=28 program=remote version=1 procedure=close type=reply status=ok serial=3
R client=0x7ff3c4855010 len=28 program=remote version=1 procedure=close type=reply status=ok serial=3</pre>
<p>If the server is running on a different host than the client, just copy the demo.stp script to the other host and run a second copy there.</p>
<h2>Further extensions</h2>
<p>There are many further improvements that can be made to this script</p>
<ul>
<li>Display a timestamp on each message</li>
<li>Associate each server side message with an individual socket</li>
<li>Display payload length</li>
<li>Display a message when the script is actually ready to run</li>
</ul>
<p>To simplify life, we are maintaining a nice feature demonstration of the RPC SystemTAP probes in the libvirt GIT repository in the<br />
<a href="http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/systemtap/rpc-monitor.stp;hb=HEAD">examples/systemtap/rpc-monitor.stp</a> file.</p>
<p>Here is what it can print out</p>
<pre>  0.000 begin
  2.632 C + 0x7f1ea57dc010   local=127.0.0.1;0 remote=127.0.0.1;0
  2.632 C &gt; 0x7f1ea57dc010   msg=remote.1.auth_list(call, ok, 0) len=28
  2.632 + S 0x1c1f710        local=127.0.0.1;0 remote=127.0.0.1;0
  2.632 &gt; S 0x1c1f710        msg=remote.1.auth_list(call, ok, 0) len=28
  2.633 &lt; S 0x1c1f710        msg=remote.1.auth_list(reply, ok, 0) len=36
  2.633 C &lt; 0x7f1ea57dc010   msg=remote.1.auth_list(reply, ok, 0) len=36   2.633 C &gt; 0x7f1ea57dc010   msg=remote.1.open(call, ok, 1) len=40
  2.633 &gt; S 0x1c1f710        msg=remote.1.open(call, ok, 1) len=40
  2.639 &lt; S 0x1c1f710        msg=remote.1.open(reply, ok, 1) len=28
  2.639 C &lt; 0x7f1ea57dc010   msg=remote.1.open(reply, ok, 1) len=28   2.639 C &gt; 0x7f1ea57dc010   msg=remote.1.get_uri(call, ok, 2) len=28
  2.639 &gt; S 0x1c1f710        msg=remote.1.get_uri(call, ok, 2) len=28
  2.639 &lt; S 0x1c1f710        msg=remote.1.get_uri(reply, ok, 2) len=48
  2.640 C &lt; 0x7f1ea57dc010   msg=remote.1.get_uri(reply, ok, 2) len=48   2.640 C &gt; 0x7f1ea57dc010   msg=remote.1.domain_lookup_by_id(call, ok, 3) len=32
  2.640 &gt; S 0x1c1f710        msg=remote.1.domain_lookup_by_id(call, ok, 3) len=32
  2.640 &lt; S 0x1c1f710        msg=remote.1.domain_lookup_by_id(reply, error, 3) len=180
  2.641 C &lt; 0x7f1ea57dc010   msg=remote.1.domain_lookup_by_id(reply, error, 3) len=180   2.641 C &gt; 0x7f1ea57dc010   msg=remote.1.close(call, ok, 4) len=28
  2.641 &gt; S 0x1c1f710        msg=remote.1.close(call, ok, 4) len=28
  2.641 &lt; S 0x1c1f710        msg=remote.1.close(reply, ok, 4) len=28
  2.641 C &lt; 0x7f1ea57dc010   msg=remote.1.close(reply, ok, 4) len=28
  2.641 C - 0x7f1ea57dc010   local= remote=
  2.641 - S 0x1c1f710        local=127.0.0.1;0 remote=127.0.0.1;0</pre>
<h2>Tracing other areas of libvirt code</h2>
<p>The RPC code is not the only place with SystemTAP/DTrace probe markers in libvirt. We have also instrumented our main event loop and provide an <a href="http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/systemtap/events.stp;hb=HEAD">examples/systemtap/events.stp</a> demo that prints out info like this</p>
<pre>  0.000 begin
  2.359 18185 + handle 1 4 1
  2.360 18185 + handle 2 6 1
  2.360 18185 * handle 2 0
  2.360 14370 &gt; handle 3 1
  2.360 14370 + handle 33 16 1
  2.361 14370 ~ 7 -1
  2.361 14370 &gt; handle 33 1
  2.361 14370 * handle 33 1
  2.361 14370 * handle 33 1
  2.361 14370 * handle 33 3
  2.361 14370 ~ 7 -1
  2.361 14370 &gt; handle 1 1
  2.361 14370 ~ 7 -1
  2.361 14370 &gt; handle 33 2
  2.361 14370 * handle 33 1
  2.361 14370 ~ 7 -1
  2.361 18185 * handle 2 1
  2.362 18185 * handle 2 0</pre>
<p>And finally we have instrumented our code which talks to the QEMU monitor, again providing a demo <a href="http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/systemtap/qemu-monitor.stp;hb=HEAD">examples/systemtap/qemu-monitor.stp</a> which prints out info like this</p>
<pre>  0.000 begin
  3.848 ! 0x7f2dc00017b0 {"timestamp": {"seconds": 1319466931, "microseconds": 187755}, "event": "SHUTDOWN"}
  5.773 &gt; 0x7f2dc0007960 {"execute":"qmp_capabilities","id":"libvirt-1"}
  5.774 &lt; 0x7f2dc0007960 {"return": {}, "id": "libvirt-1"}   5.774 &gt; 0x7f2dc0007960 {"execute":"query-commands","id":"libvirt-2"}
  5.777 &lt; 0x7f2dc0007960 {"return": [{"name": "quit"}, {"name": ....snip....   5.777 &gt; 0x7f2dc0007960 {"execute":"query-chardev","id":"libvirt-3"}
  5.778 &lt; 0x7f2dc0007960 {"return": [{"filename": ....snip....   5.779 &gt; 0x7f2dc0007960 {"execute":"query-cpus","id":"libvirt-4"}
  5.780 &lt; 0x7f2dc0007960 {"return": [{"current": true, "CPU": 0, "pc": 1048560, "halted": false, "thread_id": 13299}], "id": "libvirt-4"}   5.780 &gt; 0x7f2dc0007960 {"execute":"set_password","arguments":{"protocol":"vnc","password":"123456","connected":"keep"},"id":"libvirt-5"}
  5.782 &lt; 0x7f2dc0007960 {"return": {}, "id": "libvirt-5"}   5.782 &gt; 0x7f2dc0007960 {"execute":"expire_password","arguments":{"protocol":"vnc","time":"never"},"id":"libvirt-6"}
  5.783 &lt; 0x7f2dc0007960 {"return": {}, "id": "libvirt-6"}   5.783 &gt; 0x7f2dc0007960 {"execute":"balloon","arguments":{"value":224395264},"id":"libvirt-7"}
  5.785 &lt; 0x7f2dc0007960 {"return": {}, "id": "libvirt-7"}   5.785 &gt; 0x7f2dc0007960 {"execute":"cont","id":"libvirt-8"}
  5.789 ! 0x7f2dc0007960 {"timestamp": {"seconds": 1319466933, "microseconds": 129980}, "event": "RESUME"}
  5.789 &lt; 0x7f2dc0007960 {"return": {}, "id": "libvirt-8"}
  7.537 ! 0x7f2dc0007960 {"timestamp": {"seconds": 1319466934, "microseconds": 881214}, "event": "SHUTDOWN"}</pre>
<h2>Conclusion</h2>
<p>The introduction of static probes into the libvirt code has been enormously helpful in understanding the operation of libvirt. While we have comprehensive debug logging present in libvirt is it hard to tailor the output to show the precise data desired. Traditional debuggers like GDB are not very practical when trying to understand the live operation of a heavily multi-threaded system crossing multiple processes, and while strace is useful in some scenarios it is too low level to be useful in most scenarios. SystemTAP userspace probing provides the kind of debugging experience / tool that really suits understanding the complex interactions in a system like libvirt. It is no co-incidence that the first set of probes we have written have focused on the libvirt event loop, RPC code and QEMU monitor &#8211; three of the areas in libvirt which are both very critical operationally, and exceptionally hard to debug with traditional approaches. We will certainly be expanding our use of static probe markers in systemtap in the future. My real immediate wishlist is for systemtap to get better at providing userspace stack traces, since it fails to provide a useful trace far too often, as compared to GDB.</p>
<p><strong>Update:</strong> Mark Wielaard showed me what <a href="http://sourceware.org/ml/systemtap/2011-q4/msg00254.html">I had todo</a> to get nice stack traces from SystemTAP. Apparently it is not getting enough memory space to deal with stack traces with its default settings. Telling it to use a little more memory makes it work nicely:</p>
<pre># cat &gt; demo.stp &lt;&lt;EOF
probe libvirt.rpc.client_msg_rx {
  printf("client=%p len=%d program=%d version=%d procedure=%d type=%d status=%d serial=%d\n",
         client, len, prog, vers, proc, type, status, serial);
  print_ustack(ubacktrace())
}
# stap -DTASK_FINDER_VMA_ENTRY_ITEMS=7680 demo.stp
client=0x7f775cf62010 len=36 program=536903814 version=1 procedure=66 type=1 status=0 serial=0
 0x3c57f0b3dd : virNetClientIOHandleInput+0x87d/0x890 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0b9a0 : virNetClientIOEventLoop+0x5b0/0x630 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0cb23 : virNetClientSend+0x2b3/0x590 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0d47c : virNetClientProgramCall+0x26c/0x8a0 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ef091e : callWithFD+0xce/0x120 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ef099c : call+0x2c/0x40 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57efee80 : doRemoteOpen+0x890/0x20f0 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0341b : remoteOpen+0x9b/0x290 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ec2133 : do_open+0x1f3/0x1100 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ec4616 : virConnectOpenAuth+0x76/0xb0 [/usr/lib64/libvirt.so.0.9.7]
 0x40ceb1 [/usr/bin/virsh+0xceb1/0x40000]
client=0x7f775cf62010 len=28 program=536903814 version=1 procedure=1 type=1 status=0 serial=1
 0x3c57f0b3dd : virNetClientIOHandleInput+0x87d/0x890 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0b9a0 : virNetClientIOEventLoop+0x5b0/0x630 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0cb23 : virNetClientSend+0x2b3/0x590 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0d47c : virNetClientProgramCall+0x26c/0x8a0 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ef091e : callWithFD+0xce/0x120 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ef099c : call+0x2c/0x40 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57eff57a : doRemoteOpen+0xf8a/0x20f0 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57f0341b : remoteOpen+0x9b/0x290 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ec2133 : do_open+0x1f3/0x1100 [/usr/lib64/libvirt.so.0.9.7]
 0x3c57ec4616 : virConnectOpenAuth+0x76/0xb0 [/usr/lib64/libvirt.so.0.9.7]
 0x40ceb1 [/usr/bin/virsh+0xceb1/0x40000]
....</pre>
<p>This makes me very happy :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/11/30/watching-the-libvirt-rpc-protocol-using-systemtap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Announce: Release of Entangle v0.3.0 – An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 00:17:27 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Photography]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=552</guid>
		<description><![CDATA[Over a year has gone by since I released Entangle 0.2.0, so I am very pleased to be able to announce that I have now just released Entangle 0.3.0, available from the usual download place which also contains the concise list of changes. There have in fact been a great many changes in this release, [...]]]></description>
			<content:encoded><![CDATA[<p>Over a year has gone by since I released <a href="http://berrange.com/posts/2010/09/18/announce-release-of-entangle-v0-2-0-%e2%80%93-an-app-for-tethered-camera-control-capture/">Entangle 0.2.0</a>, so I am very pleased to be able to announce that I have now just released Entangle <a href="http://entangle-photo.org/download/sources/entangle-0.3.0.tar.gz">0.3.0</a>, available from the <a href="http://entangle-photo.org/download/">usual download place</a> which also contains the concise list of changes.</p>
<p>There have in fact been a great many changes in this release, but many of them will not be immediately obvious from looking at the updated <a href="http://entangle-photo.org/screenshots/">screenshots</a>.</p>
<p>First of all, has been a big effort to port to the latest best practice desktop application libraries</p>
<ul>
<li>Port Gtk2 to <strong>GTK3</strong>. To enable use of many of the new desktop features, in particular, libpeas, Entangle now targets Gtk3 instead of Gtk2</li>
<li>Port LibGlade to <strong>GtkBuilder</strong>. With the use of Gtk3 there is no longer any point in using the external Glade library for UI building. Instead Entangle now uses the GtkBuilder infrastructure that is part of regular Gtk</li>
<li>Port GConf to <strong>GSettings</strong>. With the use of Gtk3, a newer Glib2 is required, which in turn brings in the GSettings APis. With these present, there is no longer any point in using the external GConf library</li>
<li>Port Unique/StartupNotifications to <strong>GApplication</strong>. Again, since a newer Glib2 is required, it is possible to take advantage of the GApplication APIs, to avoid using the external Unique/StartupNotifcation libraries.</li>
</ul>
<p>Next up was a major internal rewrite of the way the UI handles camera operations. In previous releases, most operations were handed off to a camera scheduler thread. The design of this was overly complicated and not friendly to future extension. Having recently gained experience with the way asynchronous operations are done by the GIO library, I decided that this would be an effective approach for Entangle. So all the internal thread scheduling code was ripped out, and the GIO style asynchronous APIs were added in its place. Doing this work was a major blocking item in why it has taken so long to release 0.3.0.  Now it is all complete, I am very pleased with the way it has turned out. The code for dealing with the camera is so much simpler &amp; more flexible at the same time.</p>
<p>With that out of the way, there are the general user visible feature improvements</p>
<ul>
<li><strong>Config refresh</strong>. For Nikon cameras, Entangle automatically updates the UI whenever any camera configuration setting changes</li>
<li><strong>Continuous monitoring</strong>. Instead of having to explicitly start/stop monitoring, Entangle now monitors the camera for new images at all times, and auto-downloads them as they are captured</li>
<li><strong>Continuous preview mode</strong>. Previously preview would be stopped after an image was captured. Now it is possible to capture many images in sequence, while remaining in preview mode</li>
<li><strong>Folder preserved</strong>. Previously when connecting to a camera, the session folder would be reset to a default location based on camera model name. Now Entangle simply always remembers the user&#8217;s last folder</li>
<li><strong>Avoid delete after download</strong>. The default behaviour is to delete files from the camera after downloading. This can now be disabled, to allow images to remain on the memory card.</li>
<li><strong>Config UI improvements</strong>. The UI for displaying camera settings has been improved &amp; simplified. The &#8220;Other PTP properties&#8221; panel has been removed to improve UI performance. The &#8216;Camera Status&#8217; panel now just uses labels, instead of readonly text fields for a more compact display.</li>
<li><strong>Image metadata summary.</strong> When moving the mouse over the Entangle window, a summary of the image metadata (extracted with GExiv2) will be displayed, showing the aperture, focal length, shutter speed, ISO and resolution.</li>
</ul>
<p>With such large changes in the basic infrastructure, there are bound to be new wierd bugs introduced, but overall this release should be a good foundation for ongoing incremental development of Entangle.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GNOME-3 desktop virtualization support from GNOME Boxes (and the future for virt-manager)</title>
		<link>http://berrange.com/posts/2011/11/22/gnome-3-desktop-virtualization-support-from-gnome-boxes-and-the-future-for-virt-manager/</link>
		<comments>http://berrange.com/posts/2011/11/22/gnome-3-desktop-virtualization-support-from-gnome-boxes-and-the-future-for-virt-manager/#comments</comments>
		<pubDate>Tue, 22 Nov 2011 18:10:16 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[libvirt]]></category>
		<category><![CDATA[Virt Tools]]></category>
		<category><![CDATA[boxes]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[gnome boxes]]></category>
		<category><![CDATA[openstack]]></category>
		<category><![CDATA[ovirt]]></category>
		<category><![CDATA[virt-manager]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=548</guid>
		<description><![CDATA[For many years now, the virt-manager application has been the primary open source tool for managing virtual machines under libvirt for Fedora/Linux hosts, attempting to satisfy both server and desktop users alike, with the result that often neither userbase were really too happy. The decision to use libvirt as the foundation of OpenStack, OpenNebula and [...]]]></description>
			<content:encoded><![CDATA[<p>For many years now, the <a href="http://virt-manager.org/">virt-manager</a> application has been the primary open source tool for managing virtual machines under libvirt for Fedora/Linux hosts, attempting to satisfy both server and desktop users alike, with the result that often neither userbase were really too happy. The decision to use libvirt as the foundation of OpenStack, OpenNebula and various other cloud projects has been a great validation of libvirt&#8217;s capabilities. More recently, the open sourcing of the RHEV-M product to create the <a href="http://www.ovirt.org/">oVirt community</a> project, has seen another step forward for open source data center virtualization management based upon libvirt. Finally, with today&#8217;s very <a href="http://zee-nix.blogspot.com/2011/11/behold-boxes.html">first release</a> of <a href="http://blogs.gnome.org/mccann/2011/11/22/we-deliver/">GNOME Boxes</a>, the same step forward is also happening for Linux desktop virtualization. No longer will desktop virtualization (or remote desktop access) feel like an afterthought, but rather it will be <a href="https://live.gnome.org/Design/Apps/Boxes">a seamless part</a> of the GNOME-3 desktop experience. This is coming to a Fedora release near you soon&#8230;.the target is Fedora 17.</p>
<p>What does this mean for virt-manager you might wonder ? Well first of all let me reassure people that virt-manager isn&#8217;t going away anytime in the forseeable future. There will always be people who prefer straightforward, directly controllable applications which do not try to impose clever policies on their usage. virt-manager, virsh, virt-install, etc all fill this gap and we don&#8217;t want to take that control away from people. With the growth in usage of OpenStack for cloud, oVirt for data center management, and GNOME Boxes for desktop virtualization, I think it is clear though, that virt-manager will have a diminished role / userbase in the future. I don&#8217;t consider this to be bad thing, on the contrary, it shows just how strong &amp; diverse the open source virtualization community has become. Where once there was only virt-manager, today we have a wide choice of applications providing highly effective virtualization solutions targeted towards the needs of their respective userbases.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/11/22/gnome-3-desktop-virtualization-support-from-gnome-boxes-and-the-future-for-virt-manager/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

