Reviving the old blog

So a little over a year ago, around the original launch of this blog, I mused about my apprehension that I wouldn't ever update it. As I said it then:

I spend enough time sitting in front of a computer, and a blog just [is] yet another thing to keep me from ever seeing the sun. So why now? I'm not really sure, other than a recurring and nagging desire to share my thoughts and notes.

Well. I was right that I would never update the site; or at least I haven't substantially in 16 months or so. Though that nagging feeling is back. This post is mainly to make sure my workflow still functions, and get the juices flowing, so that I can write a slew of new posts following up on my previous post about privilege separation using xpra, this time using machine virtualization.

In the time that has passed since I stopped post here, lots has happened.

For starters, after ten plus years in Brooklyn, and more than eleven in NYC, I moved from New York back home to Baltimore. I did so for many reasons, including a new job as a Technologist at the the Open Technology Institute, which is part of the a think tank in Washington DC called New America. For the most part, I'm working on Commotion Wireless.

That change, plus the other joys and complications of life have changed the time I have to do things like write blog posts, but I think I've finally figured it out! So stay tuned, there hopefully will be more coming, at least if you're into obscure tech things. I would like to write about more fun things, like gardening, cycling, and politics. we'll see...

Checking OpenPGP Key and Signature Revocations

Today, I was responding to an issue on Mayfirst's issue tracker, involving the ssh key for a decommissioned server having never been revoked (and thus still active in the monkeysphere). Since the ticket had languished without followup for two years, I wanted to see if the work had been done, and just not commented on, so I went to check for revocations. There was only one problem — I rarely do that and realized that the process wasn't clear in my mind.

A little bit of searching on the Internet turned up descriptions and howtos about creating and publishing revocation certificates. Also, many layers of links back to some version of the GPG manual. Read up there for background on key and signature revocation.

To fill the lazy search void that I found, here is a quick and dirty guide to determining revoked keys and signatures.

Checking for key revocation

To get information about a key in your keyring, first make sure you have it your keyring with gpg --search or gpg --recv-key (eg: gpg --search "ssh://zimmermann.mayfirst.org"). You can follow along with my examples by pulling the User IDs I use in the examples into your local key ring.

If you already had the key in your keyring, now is a good time to refresh it. This will refresh it using the full key fingerprint.

0 nat@pigtown:~$ gpg --refresh-key  $(gpg --with-colons --fingerprint "ssh://zimmermann.mayfirst.org" |grep fpr |cut -f10 -d ":")
gpg: refreshing 1 key from hkps://keys.mayfirst.org
gpg: requesting key 860E8F9C from hkps server keys.mayfirst.org
gpg: key 860E8F9C: "ssh://zimmermann.mayfirst.org" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

0 nat@pigtown:~$

Now, to actually check the key, use gpg --list-key. This is what a non-revoked key will look like:

0 nat@pigtown:~$ gpg --list-key  $(gpg --with-colons --fingerprint "ssh://zimmermann.mayfirst.org" |grep fpr |cut -f10 -d ":")
pub   2048R/860E8F9C 2008-10-29 [expires: 2014-09-25]
uid                  ssh://zimmermann.mayfirst.org
uid                  ssh://zimmerman.mayfirst.org

0 nat@pigtown:~$

And this is what a revoked key will look like:

0 nat@pigtown:~$ gpg --list-key $(gpg --with-colons --fingerprint "ssh://sontag.mayfirst.org" |grep fpr |cut -f10 -d ":")
pub   2048R/AE2C8DE3 2010-09-10 [revoked: 2011-10-30]
uid                  ssh://sontag.mayfirst.org

0 nat@pigtown:~$

Observe the "revoked" in the pub line there, compared to the expiration date in the example above. You can probably guess what that changes to when a key expires.

Checking for signature revocation (and expiration)

To get information about published signatures on a key, use gpg --check-sigs. Here's what that looks like:

0 nat@pigtown:~$ gpg --check-sigs $(gpg --with-colons --fingerprint "ssh://ella.mayfirst.org" |grep fpr |cut -f10 -d ":")
pub   2048R/EF945F28 2010-08-27
uid                  ssh://ella.mayfirst.org
sig!3        EF945F28 2010-08-27  ssh://ella.mayfirst.org
sig!         E3D30824 2011-01-27  Greg Lyle <greg@stealthisemail.com>
sig!         5F2E4935 2010-08-27  Jamie McClelland <jamie@mayfirst.org>
sig!      X  D21739E9 2011-01-27  Daniel Kahn Gillmor <dkg@fifthhorseman.net>
sig!         D21739E9 2012-10-13  Daniel Kahn Gillmor <dkg@fifthhorseman.net>
rev!         5F2E4935 2012-11-17  Jamie McClelland <jamie@mayfirst.org>

0 nat@pigtown:~$

This output has a bunch in it. sig! means that --check-sigs thinks this signature is valid. More specifically, its the "!" that signifies that.

The line that starts with rev! for Jamie McClelland; that's a signature revocation made on on 2012-11-17. Because of the permanence of the OpenPGP keyserver data, the original signature that Jamie made remains on the key, however, you can see that the revocation happens two years after the signature, and with the same key (5F2E4935).

The other thing to observe here is that one of dkg's signatures has expired. That is signified by the "X" right before the key id. Notice that dkg later signed the service key again.

Of course your best bet for more and better info is man 1 gpg, but I hope this is enough to get you started.

Ikiwiki, In Squeeze Backports, and on MFPL

This fairly new and simple blog has actually been months in the making. Almost two months at this point. For many reasons, I've been falling down what seems like an unending rabbit hole with Ikiwiki. Somewhere towards the bottom I found that I had backported ikiwiki, and written an ikiwiki puppet module for Mayfirst servers, and was working on an auto.setup file specific to MFPL servers.

Launching this site was far harder than I had imagined when I first started setting up Ikiwiki. It turned into about four different projects.

The first month or so was all my fault. I've been a web developer for years, so I couldn't help myself and was tweaking the CSS endlessly. I also couldn't help myself from twisting a bunch of the knobs in Ikiwiki. I was trying plugins, and learning markdown syntax. Once all that was done, I was ready to launch the site.

Or so I thought.

The site is hosted on Mayfirst, which runs Debian stable (squeeze) for all of our main hosting servers. I had been building out my blog on my wheezy laptop, blissfully unaware of the incompatibilities between the version available for squeeze and the version available in wheezy.

There is one "killer feature" that newer versions of Ikiwiki offers that I make heavy use of, and that is nested preprocessor directives. I make heavy use of that, to implement the more plugin, which lets me wrap my posts in [!more text=<<MORE and MORE]], so that I can get the nice landing pages on my site. However, it breaks old versions badly.

Since I decided that I actually needed this feature to launch pleonasm.info for real, I decided to jump into the world of Debian backports, and offered a backport. I am now keeping an eye on Ikiwiki for the life of squeeze-backports.

While I have been waiting for all of the issues related to that to clear out, I've also started taking a good hard look at how we have the Ikiwiki set up on Mayfirst. Ikiwiki has long been available on all standard MFPL servers. However that was limited to the ikiwiki package in squeeze. As most plugins need more packages than that, I opened ticket #6313 to deal with unmet dependencies. Somewhere in that process, I puppetized ikwiki into its own module (I will share the code at some point, it is in the MFPL puppet repo). This makes it easier to track ikwiki specific dependencies, as well as switch to the squeeze backport, followed on ticket #6373.

While I was playing around with all of this, I also started looking into making auto-install of Ikiwiki sites and blogs easier for other Mayfirst members. To that end I'm working MFPL specific Ikiwiki auto-setup files, which has been stalled since I have been waiting for the ikiwiki package to hit squeeze backports. There will be movement on this really soon.

By the way, this hit squeeze-backports today!

Hope other folks enjoy it.

Ahead of the curve, I start a blog

I just heard a about this new thing, they call it a blog! Have you heard? As one who is always up on their latest tech, I welcome you to my blog.

So, yeah, I'm really late to the whole blogging thing. If it were 2004, I might be ahead of the curve, but like a true trend setter I've waited until no one cares anymore. These days, setting up a blog is about as exciting as setting up an email address. But, like email, blogs are now a part of the way information travels on the Internet.

I have contemplated starting a blog many times over the years, but ultimately have put it off. I spend enough time sitting in front of a computer, and a blog just seemed like yet another thing to keep me from ever seeing the sun. So why now? I'm not really sure, other than a recurring and nagging desire to share my thoughts and notes. I have derived a lot of benefit over the years from blog posts about random tech topics; its time that I paid the Internet back with some of my knowledge.

I'm not sure of the breadth of content that will end up getting posting here, but it will probably include stuff about free software, and how to do crazy things using it. There may also be personal thoughts, stuff about bicycles, stuff about my neighborhood, and maybe politics if the mood strikes me.

The about page has a little more information about me.

The first few posts in the pipe are all tech. Getting to this point has been a chore in and of itself. I can't stop tweaking and customizing this IkiWiki site. The problem with having been a web developer for so long, is that I'm really picky about web sites, and Ikiwiki lets you change a lot.

Finally, I cannot let the opportunity of innaugurating the site pass without commenting that even eight years later, I still find it hilarious that the word "blog" slipped into the lexicon and stayed there. It will always be amusing that we take people who call themselves "bloggers" seriously.

Privilege Separation Using Xpra

This is the next in a series on changes I made when I upgraded from Debian squeeze to wheezy (see the first one). I decided to take to opportunity of the upgrade to do some better privilege separation on my system. The goal was to get the software that I don't think should have any access to the rest of my running X session, to run as its own user and be completely cut off from my X session. This had to happen in a way that doesn't change my work flow and browsing habits. I accomplished this using Xpra, and some handler scripts.

Why separate privileges?

This idea was described in a post on Jamie McClelland's blog conveniently titled Privilege Separation. He lays out the problem pretty well.

What are the biggest security threats to my laptop? Almost all the software I install is vetted and signed by a member of the Debian team. I run reliable virus software on our mail server. My disk is encrypted and xscreensaver locks my screen after a few minutes of inactivity. What else?

The two biggest threats I've recently considered are: web browsing and non-free software or software that doesn't come from Debian

Another threat is only introduced if you're not running a DM, but I've addressed how to handle that, so in general what I don't trust is web browsing and non-free software.

There are two pieces of non-free software that I run with any regularity; Flash plugin and Skype.

The Adobe Flash plugin is evil. Lots of people, famously including Apple, think Flash is a scourge on the Internet. I could write a whole post on why Flash needs to go away, but I'll leave it at three basic problems.

  1. Flash is essentially a trojan. That is, it allows web sites to run arbitrary code on your computer and access hardware devices, in certain circumstances, invisibly to you.
  2. Flash decodes video in software, rather than hardware. This is bad for any number of reasons. Apple complains that it runs the batteries out faster in their devices, in Linux you can watch it start hogging the CPU as soon as you load some video. It also tends to raise the temperature of my machine about 10°C. This is horribly inefficient, and I've heard amusing speculation about the aggregate wast of all that of the increased energy use.
  3. Flash isn't free. I don't know what's going on in there, and neither do you (unless you happen to work in the right part of Adobe). Enough said.

However, I enjoy being able to watch video and access other "enhanced content" from time to time. In Debian, there is the flashplugin-nonfree package, which downloads a copy of Flash from Adobe, and makes it available system wide to installed browsers. This is all you need to get flash working in Debian.

The second piece of non-free software I use is Skype. I use the binary package provided by Skype. Again, who knows what its doing? However, it has become an industry standard way to communicate in distributed work groups, and I gotta work — so i gotta use Skype.

Then there's the web. The browser presents all sorts of opportunities for mischief. The proliferation of JavaScript means that you are almost constantly leaking information about yourself to third parties. This is somewhat mitigated by using NoScript, but you lose out even more by blocking JavaScript than you do by blocking Flash. So if you run JavaScript, you don't want it anywhere near your other information.

Finally, there is Tor. I trust Tor, but I want my Tor Browser Bundle running in a different session, because that browser session will have no access to things in my X session that could leak my identity. It is another step towards better privacy.

Why I'm using Xpra

A comment at the end of Jamie's blog post suggested that his approach to privilege separation did not adequately protect one against an attacker injecting commands into the terminal, or listening for passwords in the X session (even though they would be doing so as a different user). The commenter suggested Xpra as a way to avoid access from the user running the untrusted software to the parent X session.

What does Xpra do? Its site has a reasonable description.

Xpra is 'screen for X': it allows you to run X programs, usually on a remote host, direct their display to your local machine, and then to disconnect from these programs and reconnect from the same or another machine, without losing any state. It gives you remote access to individual applications.

Xpra launches a separate X session, which in my setup is owned by a different user than my primary account. Xpra uses SSH for remote connections, but you can also connect locally if you launch the Xpra session properly.

In addition to the untrusted software not having access to my primary X session, an unexpected benefit of this setup is that I can restart my X session without having to restart Iceweasel, or other software running in other sessions. This has proven to be a bit of a time saver.

How I set it up

This setup is using Debian wheezy. I am going to skip the part where I install Iceweasel, Skype and Tor Browser Bundle.

Installing Xpra

The version of Xpra that is in Debian wheezy is already woefully out of date. There has been a ton of development on Xpra over the last couple of months. I have been using upstream binaries that are built for wheezy, and hosted on a repository maintained by the developers. The newer versions fix major bugs that were in the upstream issue tracker. I've been running them for a while now, and have found them to be good and getting better. Hopefully once wheezy goes stable, newer versions can be uploaded to backports. It looks like somone has already uploaded them to experimental.

The repository instructions specify apt-get install winswitch, but unless you actually want to run winswitch, you can just apt-get install xpra.

Users, groups and permissions

Remember that the goal here is to have a specific user run a specific piece of software with minimal hassle to me as I go about my day. So, I started by creating a few users, with home directories. I used the name of the software as the user name, so all of my scripts use those names.

If I were planning to use Xpra remotely, I would just give myself SSH access to that user and wouldn't need any special configuration. Since I am running this locally, lazy access takes a bit more work up front.

You can launch an Xpra session with the --mmap-group option, which allows users that are in the same group as the Xpra session's socket to attach to the Xpra session. I added myself to the iceweasel, skype, and torbrowser groups. I needed to restart my X session before the group change took effect at the level that Xpra needed.

The other changes are to /etc/sudoers, making two kinds of changes. One is which environment variables get passed from my session to that of the user I'm switching to via sudo. The other change lets my user run certain commands as another user without having to type in a password. The additions look like this for the environment variables:

Defaults env_keep += "MONKEYSPHERE_VALIDATION_AGENT_SOCKET"
Defaults env_keep += "GTK2_RC_FILES"

The GTK2_RC_FILES var is there mainly because I want the windows I use in Xpra to match the ones in my running session. I set that path in my scripts.

The MONKEYSPHERE_VALIDATION_AGENT_SOCKET is important because I actually want Monkeysphere's validation agent to use my primary user's gpg keyring when it goes to check my trust path to signed certificates.

The changes to /etc/sudoers look like:

nat  ALL=(iceweasel) NOPASSWD: /usr/bin/iceweasel
nat  ALL=(iceweasel) NOPASSWD: /usr/bin/xpra
nat  ALL=(skype) NOPASSWD: /usr/bin/skype
nat  ALL=(skype) NOPASSWD: /usr/bin/xpra
nat  ALL=(torbrowser) NOPASSWD: /usr/bin/xpra
nat  ALL=(torbrowser) NOPASSWD: /home/torbrowser/tbb/tor-browser_en-US/start-tor-browser

You can, of course, manually launch all of this without changing /etc/sudoers, but it makes it easier to use handler scripts and other tools of laziness if you do.

Getting started using Xpra

Using Xpra is pretty simple. First, I'll go through launching everything by hand; this makes the scripts easier to follow, and will give some idea as to how to extend this to other software you might use.

In a terminal, switch to another user.

0 nat@pigtown:~$ sudo su - iceweasel
[sudo] password for nat:
0 iceweasel@pigtown:~$

All of my scripts are using special socket directories for each Xpra session I attach to, so I start by creating that directory.

0 iceweasel@pigtown:~$ mkdir xpra-socket

Now launch an Xpra session.

0 iceweasel@pigtown:~$ xpra --mmap-group --socket-dir="/home/iceweasel/xpra-socket/" start :201

I've picked a high X session display number, just to avoid possible collisions with anything else that might start an X session. Also notice that I've used the --mmap-group and --socket-dir options, since I am not using the default Xpra socket, and allowing other users in the iceweasel group to attach to the session.

Next launch iceweasel.

0 iceweasel@pigtown:~$ MONKEYSPHERE_VALIDATION_AGENT_SOCKET=$MONKEYSPHERE_VALIDATION_AGENT_SOCKET DISPLAY=:201 iceweasel

If you don't use monkeysphere, you can remove those bits. Then as my primary user, I attach to the Xpra session with:

0 nat@pigtown:~$ xpra --socket-dir=/home/iceweasel/xpra-socket attach :201

That's basically it. At that point it is up and running.

Stopping the Xpra session is easy.

0 iceweasel@pigtown:~$ xpra --socket-dir="/home/iceweasel/xpra-socket/" stop :201

or, if you've modified /etc/sudoers.

0 nat@pigtown:~$ sudo -u iceweasel xpra --socket-dir=/home/iceweasel/xpra-socket stop :201

Handler scripts and configuration

As easy as that is, it is still a bit of a hassle, and how do you do things like pass URLs from the terminal to the browser if its in another X session? I ended up writing a few handler scripts that make the whole thing a lot easier to use day to day.

The first configuration steps are covered in the changes to /etc/sudoers above.

All of the scripts that I've written are kept in ~/bin/, though I suppose there are better places to keep this stuff. These scripts are very much a functional first pass, so there are likely better ways to do some of this stuff.

I decided to create a configuration file, so that it would be easier to tweak settings in the future.

# Settings for various xpra launchers.

##
# Shared settings
##

# set the GTK theme to use.
GTKRC="/usr/share/themes/Shiki-Dust/gtk-2.0/gtkrc"
# set the default encoding
# the default is jpg, but rgb24 works best for local use
ENCODING="rgb24"

XPRA=$(which xpra)
SUDO=$(which sudo)
HOSTNAME=$(cat /etc/hostname)


##
# Iceweasel settings
##

# Iceweasel user/group
#  -- the intendended end user must be in this group
#  -- the /etc/sudoers file needs a line like:
#     nat  ALL=(iceweasel) NOPASSWD: /usr/bin/iceweasel
ICE_USER="iceweasel"
ICE_GROUP="iceweasel"

# set the dir where the xpra socket will live for iceweasel
ICE_SOCKET_DIR="/home/iceweasel/xpra-socket"

# Set a default display number for the Iceweasel display;
# I set it high to avoid collisions with any other tools that
# might create X displays
ICE_DISPLAY_NUM=201
# set a custom icon for the systray. this will be used  of the default Xpra
# icon. This helps to differentiate which sessions is which when running
# multiple.
ICE_TRAY_ICON="/usr/local/share/icons/Smokikon_v09/scalable/categories/applications-internet.svg"
# path to iceweasel binary.
ICEWEASEL=$(which iceweasel)


##
# Skype settings
##

SKYPE_USER="skype"
SKYPE_GROUP="skype"
SKYPE_SOCKET_DIR="/home/skype/xpra-socket"

SKYPE_DISPLAY_NUM=202
SKYPE_TRAY_ICON="/usr/share/icons/skype.png"
SKYPE=$(which skype)

##
# Tor browser bundle
##

TBB_USER="torbrowser"
TBB_GROUP="torbrowser"
TBB_SOCKET_DIR="/home/torbrowser/xpra-socket"

TBB_DISPLAY_NUM=203
TBB_TRAY_ICON="/home/nat/graphics/icons/tor/tor.png"
TBB="/home/torbrowser/tbb/tor-browser_en-US/start-tor-browser"

There are two other general helper scripts. One that I use to attach to the various Xpra sessions, and the other to stop them.

the attach script

#!/bin/bash

# load in a bunch of variables used across the xpra scripts.
. /home/nat/bin/xpra-launchers.conf

# check which expected session we're connecting to.
if [ $1 == 'skype' ] || [ $1 == '-s' ] || [ $1 == '--skype' ]; then
  if [ -z $SKYPE_TRAY_ICON ]; then
    $XPRA --socket-dir=$SKYPE_SOCKET_DIR --encoding="$ENCODING" attach :$SKYPE_DISPLAY_NUM
  else
    $XPRA --socket-dir=$SKYPE_SOCKET_DIR --tray-icon="$SKYPE_TRAY_ICON" --encoding="$ENCODING" attach :$SKYPE_DISPLAY_NUM
  fi
  exit 0
elif [ $1 == 'iceweasel' ] || [ $1 == '-i'  ] || [ $1 == '--iceweasel' ]; then
  if [ -z $ICE_TRAY_ICON ]; then
    $XPRA --socket-dir=$ICE_SOCKET_DIR --encoding="$ENCODING" attach :$ICE_DISPLAY_NUM
  else
    $XPRA --socket-dir=$ICE_SOCKET_DIR --tray-icon="$ICE_TRAY_ICON" --encoding="$ENCODING" attach :$ICE_DISPLAY_NUM
  fi
  exit 0
elif [ $1 == 'tbb' ] || [ $1 == '-t'  ] || [ $1 == '--tbb' ] || [ $1 == '--torbrowser' ] || [ $1 == 'torbrowser' ]; then
  if [ -z $TBB_TRAY_ICON ]; then
    $XPRA --socket-dir=$TBB_SOCKET_DIR --encoding="$ENCODING" attach :$TBB_DISPLAY_NUM
  else
    $XPRA --socket-dir=$TBB_SOCKET_DIR --tray-icon="$TBB_TRAY_ICON" --encoding="$ENCODING" attach :$TBB_DISPLAY_NUM
  fi
  exit 0
else
  exit 1
fi

the Xpra session stop script

#!/bin/bash

# since neither quitting an program, nor disconnecting from an xpra session
# actually stops the underlying xpra session. that's actually fine most of the
# time, since all the launch scripts check if the socket exists.
#
# however, sometimes they need to close, and its a pain the do it from the cli.

# load in a bunch of variables used across the xpra scripts.
. /home/nat/bin/xpra-launchers.conf

# check which expected session we're stopping
if [ $1 == 'skype' ] || [ $1 == '-s' ] || [ $1 == '--skype' ]; then
  if [ -S $SKYPE_SOCKET_DIR/$HOSTNAME-$SKYPE_DISPLAY_NUM ]; then
    $XPRA --socket-dir=$SKYPE_SOCKET_DIR stop :$SKYPE_DISPLAY_NUM
    exit 0
  fi
elif [ $1 == 'iceweasel' ] || [ $1 == '-i'  ] || [ $1 == '--iceweasel' ]; then
  if [ -S $ICE_SOCKET_DIR/$HOSTNAME-$ICE_DISPLAY_NUM ]; then
    $XPRA --socket-dir=$ICE_SOCKET_DIR stop :$ICE_DISPLAY_NUM
  fi
  exit 0
elif [ $1 == 'tbb' ] || [ $1 == '-t'  ] || [ $1 == '--tbb' ] || [ $1 == '--torbrowser' ] || [ $1 == 'torbrowser' ]; then
  if [ -S $TBB_SOCKET_DIR/$HOSTNAME-$TBB_DISPLAY_NUM ]; then
    $XPRA --socket-dir=$TBB_SOCKET_DIR stop :$TBB_DISPLAY_NUM
    exit 0
  fi
else
  exit 1
fi

Iceweasel

Iceweasel has the most complicated start up script. I regularly use Iceweasel with multiple profiles, and am likely to pass it a wider variety of options than with Skype or TorBB, so I need to actually handle those arguments. This isn't fool proof, I only wrote it to be used by one fool; me.

I'm passing the MONKEYSPHERE_VALIDATION_AGENT_SOCKET variable, which makes sure that the monkeysphere xul extension will use the instance of the monkeysphere validation agent that is running in my X session (and not Iceweasel's).

#!/bin/bash
# load in a bunch of variables used across the xpra scripts.
. /home/nat/bin/xpra-launchers.conf

# launch the iceweasel browser
function launch_iceweasel() {
  USE_PROFILE=0
  USE_NOREMOTE=
  REMOTE=
  URL=
  NEWTAB=
  # handle just the profile and set no-attach
  for ARG in "$@"; do
    if [ $ARG == '-P' ]; then
      USE_PROFILE=1
    elif [ $USE_PROFILE -eq 1 ]; then
      PROFILE_NAME=$ARG
      USE_PROFILE=0
    elif [ $ARG == '--no-remote' ]; then
      REMOTE=$ARG
    elif [ $ARG == '-new-tab' ]; then
      NEWTAB=$ARG
    # there's probably some room for mischief here, as a well crafted URL
    # could get passed, provided it starts with http.
    # a risk i will live with, since it requires apriori access to my account
    # though the right way to fix is probably with a proper regex.
    elif ?span> http<span class="hl opt">* ; then
      URL=$ARG
    fi
  done
  if [ $PROFILE_NAME ]; then
    PROFILE="-P $PROFILE_NAME"
  else
    PROFILE="-ProfileManager"
  fi

  # now actually launch iceweasel
  $SUDO -u $ICE_USER MONKEYSPHERE_VALIDATION_AGENT_SOCKET=$MONKEYSPHERE_VALIDATION_AGENT_SOCKET DISPLAY=:$ICE_DISPLAY_NUM GTK2_RC_FILES="$GTKRC" $ICEWEASEL $PROFILE $REMOTE $NEWTAB $URL
}

# create a new xpra socket for iceweasel
function create_xpra_socket() {
  $SUDO -u $ICE_USER $XPRA --mmap-group --socket-dir="$ICE_SOCKET_DIR" start :$ICE_DISPLAY_NUM
}

# Here's the actual flow of the script

# check if there's already an iceweasel xpra socket open
# if so, launch iceweasel, if not create a socket and then launch.
if [ -S $ICE_SOCKET_DIR/$HOSTNAME-$ICE_DISPLAY_NUM ]; then
  launch_iceweasel $@
else
  # Since there isn't already an xpra socket open, set it up
  create_xpra_socket
  sleep 5
  launch_iceweasel $@
fi

Skype

The skype script is pretty straightforward.

#!/bin/bash

# load in a bunch of variables used across the xpra scripts.
. /home/nat/bin/xpra-launchers.conf

# function to create a new xpra socket for when there isn't one
function create_xpra_socket() {
  $SUDO -u $SKYPE_USER $XPRA --mmap-group --socket-dir="$SKYPE_SOCKET_DIR" start :$SKYPE_DISPLAY_NUM
}

function launch_skype() {
  $SUDO -u $SKYPE_USER DISPLAY=:$SKYPE_DISPLAY_NUM GTK2_RC_FILES="$GTKRC" $SKYPE
}


if [ -S $SKYPE_SOCKET_DIR/$HOSTNAME-$SKYPE_DISPLAY_NUM ]; then
  launch_skype
else
  # Since there isn't already an xpra socket open, set it up
  create_xpra_socket
  sleep 5
  launch_skype
fi

Tor Browser Bundle

And here is my launcher for the Tor Browser Bundle.

#!/bin/bash

# load in a bunch of variables used across the xpra scripts.
. /home/nat/bin/xpra-launchers.conf

# function to create a new xpra socket for when there isn't one
function create_xpra_socket() {
  $SUDO -u $TBB_USER $XPRA --mmap-group --socket-dir="$TBB_SOCKET_DIR" start :$TBB_DISPLAY_NUM
}

function launch_tor_browser_bundle() {
  $SUDO -u $TBB_USER DISPLAY=:$TBB_DISPLAY_NUM GTK2_RC_FILES="$GTKRC" $TBB
}

if [ -S $TBB_SOCKET_DIR/$HOSTNAME-$TBB_DISPLAY_NUM ]; then
  launch_tor_browser_bundle
else
  # Since there isn't already an xpra socket open, set it up
  create_xpra_socket
  sleep 5
  launch_tor_browser_bundle
fi

How I use it, and integrate it with Xfce

The web browser is one of those things I end up using all the time. Its always kinda just sitting there with sixty or so tabs. I'm constantly clicking on links from emails and IRC. I usually want those to open in my default profile.

Xfce has a dialog for "Preferred Applications" (in the Settings menu). I changed Web Browser setting to my Xpra launcher script. This handles everything coming from the terminal, and a bunch of other things in Xfce. The actual setting looks like iceweasel-xpra -new-tab "%s", which opens the URL in a new tab.

I generally launch sessions, and attach by calling the scripts from the Run dialog.

Bugs and Issues

These are my settings, and they work for me. You may want to change any number of things if you're doing this yourself.

I originally attempted to attach to the Xpra session from the various launcher scripts. I'm not sure why, but this never worked. My guess is you have to wait long enough for there to be a drawn X window to attach to, and if there isn't it just fails. Adding a long sleep to the script might be a reasonable workaround, but I thought it was easier to just use the attach script, which I needed anyway for when I disconnect and want to reconnect.

If you're having trouble with the scripts, run them in the terminal, and see if there are any errors. You can always double check your settings by running everything by hand.

Next steps

I would like a better way of setting the display numbers, so that they don't have to be hard coded in the configuration file. Ideally I might actually want profile a, and profile b running in different X sessions (and possibly different users). Collapsing all the scripts into one command might also be helpful.

Though, to me, it seems like the most obvious next step in usage is to run these pieces of software on their own virtual machines and use Xpra's ssh connection to attach to the software that way. This would mean a complete separation of privileges, and would mean that my system wouldn't need to have Skype, or Flash installed. However, that will have to wait until I get a bigger hard drive, and possibly rebuild my machine; so not a task I'm going to take on any time soon.

Getting startx, Consolekit and Xfce 4.8 to play nicely in Debian wheezy

I recently upgraded from Debian squeeze to wheezy. As happens with these upgrades, I was awash in things that no longer worked quite the way I expected them to, and configuration changes to make.

This is the first of a couple pieces on what I did to get things working to my liking. As the title suggest, this is about the the interactions of startx, ConsoleKit, and Xfce 4.8. Or, more accurately, how the interactions between those things broke in my setup when I upgraded, and how I got it working again.

Setup

As noted, I run Debian wheezy. The machine is an aging Thinkpad x61 (amd64). It had been running squeeze for the last couple of years, at least since squeeze was testing, when I installed it through a clean reinstall.

I've been using Xfce for a long time. The move from squeeze to wheezy included a pretty major Xfce upgrade. The improvements between Xfce 4.6 and Xfce 4.8 are noticeably huge, it is faster, and handles some things better than the old version. Thankfully most of my tweaks to the look and feel didn't get too mangled on the upgrade. My profile settings were all in tact.

The only other bit of the setup that is relevant to this, is that I don't use a display manager. Instead I just run startx from the console — which has worked until now..

The Problems

PolicyKit bug

The first issue has to do with Xfce and ConsoleKit, something I've seen called called the the PolicyKit bug. Some time between Xfce versions 4.6 and 4.8, Xfce started referring to a console kit session to find out if it could let you do things like suspend or shut down. There are various other things that check the console kit session, and anything that does check it won't work if console kit isn't part of the session that you're running.

To see your running console kit sessions, run ck-list-sessions. With everything working, it looks something like this:


0 nat@pigtown:~$ ck-list-sessions
Session82:
unix-user = '1000'
realname = 'nat'
seat = 'Seat1'
session-type = ''
active = FALSE
x11-display = ''
x11-display-device = ''
display-device = '/dev/tty1'
remote-host-name = ''
is-local = TRUE
on-since = '2012-09-06T20:47:24.206129Z'
login-session-id = '57'
idle-since-hint = '2012-09-06T20:48:06.003241Z'
Session83:
unix-user = '1000'
realname = 'nat'
seat = 'Seat1'
session-type = ''
active = TRUE
x11-display = ':0'
x11-display-device = '/dev/tty7'
display-device = '/dev/tty1'
remote-host-name = ''
is-local = TRUE
on-since = '2012-09-06T20:47:35.435969Z'
login-session-id = '57'

Notice the "active = TRUE" for Sesson83 (on tty7) that is the active X session. When you have issues with your ConsoleKit, the same command will have "active = FALSE" set.

The problem I was hitting, in short, was that the scripts being run when I ran startx was failing to start Xfce with an active ConsoleKit session. So that was the first issue to solve.

startx & exit

Problem two also has to do with startx, but less what the script was running, than how it was being invoked.

In squeeze, I would launch Xfce (4.6), with a startx & exit. Without the & exit someone could not hit Ctrl-C in tty1 to close the X session and be dropped into a working shell. This would be very bad. Obviously I need to make sure that doesn't happen.

By the time I got the PolicyKit bug cleared up, and was using startx again, it turned out that console kit wouldn't remain active if I left the & exit on my startx command. X and Xfce would still start, just with no ConsoleKit privileges. However, if I remained logged in by leaving out the exit, everything worked as expected. But again, that is not acceptable, because it leaves access to shell.

The solutions

PolicyKit bug

So the first thing I needed to do, was figure out how to get Xfce to load a ck session properly. A little bit of searching revealed that I was not alone. It seems this was a problem for many people in Debian, and was report as a bug in both Debian and Ubuntu.

There were several suggestions on how to get it working, but the best help comes straight from /usr/share/doc/xfce4/README.Debian.

=== Console startup

Users that prefer to start X from the console can use startx or startxfce4.

The former is preferred in a Debian system as it will run all standard X session startup files (ConsoleKit, gpg-agent, ssh-agent etc.). You should not use any .xinitrc or pass any argument to startx (as it'll prevent running the Xsession scripts. Put:

exec startxfce4

in $HOME/.xsession to have startx run the complete Xfce desktop environment.

So I went ahead and tried putting this into my ~/.xsession:

#!/bin/sh
exec startxfce4

It launched, but ConsoleKit was in fact not active. After asking around and digging, I found that the right option to use is:

#!/bin/sh
exec startxfce4 --with-ck-launch

That's it. It works after that. On to problem two.

startx & exit

I liked my old setup of using startx & exit because it left nothing but a login prompt on the tty I used to launch my X session. However if I want the ConsoleKit session to remain active, I have to leave it open. So no matter what, someone can walk up to my machine, and if it is turned on, kill my X session by hitting Ctrl-C on the connected tty. That is annoying, but it is okay, so long as they are not able to get a functional shell — which they're not, i've tried.

Figuring that I'm not the only one who does this, I asked around, and with the help of vagrantc came up with:

exec startx

This will drop the person at a login prompt after killing the X session. Very simple fix.

I updated my bash aliases, so that I can still just run startx, and all is well. Hopefully this can help anyone with a similar problem.