XO yum cache on the local XS

With the release of the new 860 XO build, you might have a few XOs to update.  Of course, flashing an XO with a USB drive is the fastest way to get a clean install, but then you might want to yum update or install other stuff.  In low bandwidth situations or where USB drives are small and scarce, it’s really easy to keep the yum cache on the XS.
You’ll need a user account on the XS and ssh access (keys or passwords).  In the user account on the XS, create a directory to keep the XO yum cache.  I’ve got an XS user named olpc and I created xo1/yum in /home/olpc.

Get a fuse-sshfs rpm into an Apache accessible directory on the XS.  Mine is in /var/www/html/olpc/updates.

On the freshly flashed XO, connect to the XS’s wifi.  Become root and install the rpm.  You can do this in Gnome or Sugar.

sudo su –
rpm -ivh

If you want to enable the RPM Fusion repos go ahead and do that now.

Set it up so you can connect to the XS’s wifi AP in single user mode.  Put this in /etc/sysconfig/network-scripts/ifcfg-eth0 where OLPCOFW is the ssid of the AP.


Change /etc/yum.conf so it keeps the cache.


Get into single user mode.

init 1

Bring up the wifi connection.  Note – this will not work if your AP is B only.

ifup eth0

Mount the remote cache.  If you run ssh on a non-standard port, put the port number in.  Otherwise omit -p port.

sshfs -p port olpc@ /var/cache/yum

Now when you yum update or yum install stuff, it’ll download it to the XS and install over the network.  When you move to the next XO and mount the cache from the XS on the XO, it doesn’t have to download all that stuff again, making updates and installations a lot faster.  If you’re like me and have a scandalous number of USB drives in your lab, this way you don’t have to remember which one you were keeping the yum cache on.

When yum stuff is finished, go ahead and reboot and you’ll be back in Sugar or Gnome (whichever you were using last).

Fedora 11 RPM Fusion Repository

Since the regular way of setting up RPM Fusion for Fedora 11 doesn’t work any more, and most XOs are still using F11, download and install these rpms instead.  Just rpm -ivh <name of rpm>



Automatically SCP Screenshots from the XO up to the XS

After fooling around with sshfs and incron and whatnot with the Journal in an attempt to get screenshots on my XS (not to mention dealing with the peanut gallery on my chat server), I was at the end of my patience.  If you’ve ever delved into the Journal file structure, you know it’s tricky business.  So I started XChat, logged into the olpc-devel IRC channel, and asked if there was an update to the Quick Screenshot Hack.  Lo and behold, one of the devs, Quozl, got me all fixed up.
Here’s how I got this to work…

First, on the target XO, create your screenshot directory:
mkdir /home/olpc/screenshots
For scp to work, you’ll need passwordless ssh access.  Here are some easy instructions for the server and the client.
Make sure to successfully ssh into the XS.  Seriously, ssh in from the XO and make sure you can get to the XS without a password.  The first ssh session lets you accept the XS so the script below will work.

[Note – having an olpc user on the XS can sometimes keep stuff sorted out rather than dumping this into some else’s dir]
I made a script on the XO called /home/olpc/cpscrn (copy screen) with these little arguments.  Oh, I have an XS with an Apache server, which is handy.  The first command scp’s up the screenshot.  The second command copies the screenshot file on the XS with a timestamp for archive purposes.  You’ll see later why I’m doing this.
scp -P port $1 olpc@schoolserver:/var/www/html/olpc/screenshot.png
ssh -p port olpc@schoolserver ‘cp var/www/html/olpc/screenshot.png /var/www/html/olpc/$(date +%Y-%m-%d_%H%M%S)-screenshot.png’
Of course chmod +x /home/olpc/cpscrn
Here’s where Quozl got me fixed up.  I didn’t know where the path to this darn file was, despite grepping all the live long day.  That should probably be a country song.  “Grepping all the live long day.”  Anyway…
Simply edit this file (now that you know where it is):
Look for handle_key_press and add the second line as you see here.  If you don’t want to keep your screenshots in /home/olpc/screenshots, modify that accordingly.

    def handle_key_press(self):
        file_path = os.path.join(“/home/olpc/screenshots”, ‘%i.png’ % time.time())
        window = gtk.gdk.get_default_root_window()
Even if you’re not going to run a script when you take a screenshot, you still need to add the return line.  Otherwise your screenshots will disappear into the ether (I found that out the hard way).  The second line isn’t mandatory, it’s just what you want to run when alt+1 is pressed.  You could play a sound file for all I care.  Or just omit it.
    screenshot.save(file_path, “png”)
        os.system(“/home/olpc/cpscrn %s” % file_path)
Save and exit and restart Sugar.  Make sure the remote directories exist and have the proper permissions.  When Sugar comes back up, hit alt+1.  In about 10-15 seconds (or at least on my LAN) you’ll see screenshot.png come up on the remote server.
You’re probably wondering, “Why in the heck is she copying the screenshot.png file after it’s up?”  Well, lemme show you.
In /var/www/html/olpc I have this simple index.html
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<meta content=”text/html; charset=ISO-8859-1″ http-equiv=”content-type”>
<title>XO Screenshot</title>  
<img src=”screenshot.png” height=”700″ align=”center”>
<a href=”../index.html”>Home</a>
Guess what that does?  Oh, it displays the current screenshot when you go to http://schoolserver/olpc
I’ve also got a record of all the screenshots I took sitting right there in /var/www/html/olpc
-rw-rw-r– 1 olpc olpc 49K 2011-01-07 19:37 2011-01-07_193711-screenshot.png
-rw-rw-r– 1 olpc olpc 49K 2011-01-07 19:42 2011-01-07_194214-screenshot.png
-rw-rw-r– 1 olpc olpc 347 2011-01-07 03:06 index.html
-rw-rw-r– 1 olpc olpc 49K 2011-01-07 19:42 screenshot.png

See how screenshot.png and the latest dated .png have the same timestamps?  They’re the same file.  This way you can have only a few second delay for “live” presentations without a projector, as XOs can easily view these screenshots in the Browse Activity.  All you need is a LAN and all the users need to do is refresh their browser when there’s a new screenshot.  Of course screenshot.png is overwritten everytime you hit alt+1 on the XO, but that’s OK as there’s a “permanent record.”
Later you can go back into /var/www/html/olpc and get all the screenshots for any documentation you need to do up. 
Don’t forget to clean out /home/olpc/screenshots on the little XO when you’re satisfied you’ve gotten everything.

If you don’t have an XS and want to host a presentation with the XO you’re taking the screenshots from, all the extra hardware you’ll need is a USB ethernet dongle, an ethernet cable, and an AP.  Use dnsmasq for DHCP and boa for the webserver so the XO can make its own little “LAN.”  Both dnsmasq and boa are really light.  And there’s the added bonus of not having to scp anything, as you can simply use cpscrn to put the screenshots in a directory served by boa.

And many thanks to Quozl

Who’s Using My Proxy?

Now that I’ve figured out TinyHTTPProxy, have login notifications posting to Statusnet, and can use incron to monitor files, let’s pull that all together to let me (and my users) know when the TinyHTTPProxy is in use and who’s using it.  Remember only one user can use it at a time, so instead of trying to log in and wondering what the issue is, they can check Statusnet to see if it’s currently in use.

Since everything else is pretty much all set up, let me create a little script in ~/bin to take care of the Statusnet posting.  I’ll call it proxy-use.


curl -u security:pass http://myserver/statusnet/api/statuses/update.xml -d status=”TinyHTTPProxy.py has been accessed on `date`”

I created a statusnet user named security to handle this notice as well as the ssh login notices.  Remember that’s in /etc/bashrc:

curl -u security:pass http://myserver/statusnet/api/statuses/update.xml -d status=”`whoami` has logged into `hostname` on `date`”  >/dev/null 2>&1

So now all I need to do is add my incrontab entry.

/usr/local/bin/TinyHTTPProxy.py IN_ACCESS,IN_NO_LOOP proxy-use  >/dev/null 2>&1

You might have to put the full path of the proxy-use script.

Now when a user logs in and uses the proxy:

ssh -L localhost:8000:localhost:8000 -t user@myserver TinyHTTPProxy.py

That sources the .bashrc, firing off a login notice to Statusnet.  It also accesses the TinyHTTPProxy.py file, firing off another notice.  Make sure to use IN_NO_LOOP in the incrontab entry, otherwise it fires off like 4 notices in a row.

So now you can check Statusnet and see that a user logged in and another notice directly after that reporting TinyHTTPProxy.py has been accessed.  When the user is finished with the proxy and kills the ssh session, that sends a final notice that TinyHTTPProxy.py has been accessed.  So by looking at the username of the ssh notice and the timestamps of the first proxy notice and the second, you can see who used the proxy and for how long.  If you only see one proxy notice after the ssh login notification, then you’ll know who’s currently using it.

Again, something like this is really only appropriate for small servers with just a few users.

Posting to Statusnet when a file is modified

I’ve got a guestbook of sorts on my XS, but don’t really pay any attention to it. What if someone dropped me a note and I didn’t know about it? Or even worse, what if someone posted something obnoxious that needed to be deleted immediately?

Let me use incron to monitor the guestbook and then notify me via Statusnet when someone posts something. First I install a couple of things:

yum install incron inotify-tools

Now I set up a little notification script in my ~/bin called guestbook-notify and chmod +x it.

curl -u user:pass http://myserver/statusnet/api/statuses/update.xml -d status=”Someone signed the guestbook on `date`” >/dev/null 2>&1

(Where user:pass are my Statusnet username and password.)

Since nano is so easy to use, I’m going to use that to edit the incrontab. This is pretty much like editing the crontab except I’ve read that putting comments in there might cause problems.

export EDITOR=nano

Now I simply

incrontab -e

And put in the entry that’ll watch for the guestbook file to be modified.

/var/www/html/guestbook/guestbook.db IN_MODIFY guestbook-notify

When incron detects that guestbook.db (it’s not really a database, it’s a flat text file from a simple PHP based guestbook) has been modified, it runs guestbook-notify to post to Statusnet, alerting me to take a look.

Since I’ve got the Statusnet XMPP bot running, I also receive the notifications in my Jabber client.

I could make the guestbook-notify command a little more complicated; for example using awk to get the signer’s name out of guestbook.db for the Statusnet post, but this is good enough for now.


Login Notifications via Statusnet

This will work for the Twitter API as well, but I have a Statusnet installation, so I’m going to use that.  If you put this in the global /etc/bashrc you’ll get notifications when anyone logs in.  You could also just put it in a particular user’s ~.bashrc if you only want notifications for that user.

curl -u user:pass http://myserver/statusnet/api/statuses/update.xml -d status=”`whoami` has logged into `hostname` on `date`”  >/dev/null 2>&1

Where user:pass is a username and password for Statusnet.  Now you’ll see a post on statusnet whenever someone logs in (i.e. sources their .bashrc).  It’s invisible to the user as far as the terminal goes, and will let you know immediately if someone’s managed to crack your server.  Of course it posts for legitimate logins too, but that can be good information.

I’ve got the Statusnet XMPP bot running, so I also get an instant message via my Jabber client.  Kinda neato to receive almost instant notifications of logins with a “ding!”

How to use TinyHTTPProxy.py

Note:  I’m using this on XS 0.6, but this should work for any Linux server.

Why would you need to do this? Well, say you’re at a Starbucks or other open wifi and would like to securely browse the internet, particularly Facebook. If you’ve heard of Firesheep, that’s a Firefox plugin that sniffs your Facebook and Twitter sessions – a huge security issue. If you browse over an ssh connection, you’re as safe as if you were at home.

Also, some connections might block certain content. Get your mind out of the gutter, I’m talking about, for example, the connections at the elementary schools that go through the XS. Per the instructions I got, I set the OpenDNS settings to the highest filtering level. Unfortunately this blocks Gmail, so if I’m onsite and need to send an email, I have to jump through hoops in order to do so. TinyHTTPProxy.py makes this a lot easier.

Warning: Major Drawback
Only one ssh user can use this at a time. If you try to use it and get an error saying it’s in use, that means another user got to the server first.

Anyway, that warning aside, in order to use this, you will need ssh access to a remote server. The python script on this page needs to be in your path:


Simply copy and paste the code on that page into TinyHTTPProxy.py into somewhere in your path on the remote server. The server admin can put TinyHTTPProxy.py into /usr/local/bin, so it’ll work for everyone with an ssh account. Of course, given the warning I just mentioned, this is a good idea only for small servers with only a few users.

On your local machine, open a terminal and type this, all in one line:

ssh -p PORT -L localhost:8000:localhost:8000 -t user@example.com TinyHTTPProxy.py Where PORT is your ssh port (leave -p PORT out if you’re on 22) and user@example.com is your username and server. Open Firefox and set up the proxy configuration.

Go to Edit -> Preferences -> Advanced -> Network -> Settings

Click the Manual proxy configuration tick box and enter localhost for the HTTP Proxy and Port 8000. Click OK.

Now you can browse safely without fear of Firesheep. If the server you’re proxied into has Apache running, you can enter in localhost in the address bar to get to that content. Or go to http://localhost:631 to remotely configure CUPS or what have you. Or even an IP address on your home LAN, such as your DSL modem.

While you’re browsing, you can see the URLs scroll by in the terminal session and the idle time increment.

When you’re done, go back to the Connection Settings box and click the tick box for No Proxy. Close the ssh session. It might take a minute once you try to kill the session for it to finally close.

So you don’t have to remember that long ssh command, you can put it in your .bashrc (all in one line):

alias safebrowse=’ssh -p PORT -L localhost:8000:localhost:8000 -t user@example.com TinyHTTPProxy.py’ 
Now all you have to do is type safebrowse at the terminal and change your Firefox settings to use the proxy.

If a non-standard ssh port is blocked, as happens sometimes when you use non-standard ports, and nothing’s going on with your server as far as https, you can run ssh on port 443 in addition to your usual port. Simply enter in it your /etc/ssh/sshd_config alongside your “usual” ssh port.

Chatting when you’re not supposed to

Port 443 is for https traffic and thus you should be allowed to have traffic via that port, even if the sysadmin at the remote location is blocking everything else but http and https.

Say you’re at a location where ports 5222 and 5223 (Jabber ports) are blocked for some reason (probably because chatting is considered a waste of time) and your ssh port is blocked, you can do this to join the chat on your server, given you’ve configured ssh to listen on port 443 and also have ejabberd and MUCkl set up.

ssh -p 443 -L localhost:8000:localhost:8000 -t user@example.com TinyHTTPProxy.py

Set up the Firefox proxy settings, go to http://localhost in your browser and then browse to the MUCkl page to enter the chatroom. Of course, since MUCkl runs on port 80 as far as the end user can see anyway, this isn’t terribly vital, but the ssh proxy should keep your chat server off the radar as far as the remote sysadmin is concerned.

Jabber under MUCkl needs to say “Hi” every two minutes, so here’s something to change in /usr/local/bin/TinyHTTPProxy.py so it doesn’t reset the connection:

From this:

def _read_write(self, soc, max_idling=20):

To this:

def _read_write(self, soc, max_idling=99):

Increasing the max_idling time means that Jabber chat under MUCkl doesn’t time out after one minute, which can get annoying. Setting the proxy idle to slightly above two minutes keeps the MUCkl room connection alive indefinitely. Actually, 41 would do, but I set mine to 99 just in case. For every 20 of idle, that’s one minute, so 99 gives you just shy of five minutes.

Here’s what it looks like in Terminal when the Jabber on my XS says “Hi” while I’ve got MUCkl open under TinyHTTPProxy:

idle 38
idle 39
idle 40
connect to localhost:80
schoolserver.@@BASEDNSNAME@@ – – [02/Jan/2011 21:02:00] “POST http://localhost/http-bind/ HTTP/1.1” – –
idle 1
idle 2 
idle 3