Monday, July 18, 2011

AirPrint in corporate networks

AirPrint is a component of Apple since iOS version 4.2 for printing via WiFi, whose main advantage is that AirPrint does not require printer-specific drivers.

The adoption of tablets is a fact nowadays, so the system administrators must provide some mechanism in order to allow tablet users to print. If we focus on iPad type of tablets, these are able to print via AirPrint, but just using a small set of selected printers.

Any already established company has an infrastructure of computers and printers. Adding a new kind of printers does mean buying new hardware and this is not an option in many sites. On the other side, in large corporate sites (so, do not think on a small office with just a few computers) the network is organized and divided, and wireless users do use different network ranges or VLANs than wired users. AirPrint does not work across subnets.

So, the challenge involves two main tasks:
1.- Allow existing printers to be compatible with the AirPrint mechanism.
2.- Allow the usage of wired printers from wireless devices even if they are in different networks, so traveling across different subnets.

Both topics have been already covered in other blogs, but so far, I haven't found a tutorial indicating all the necessary tasks.

Our scenary:
A middle size network with a few hundreds of wired computers. These computers are organized into several subnets.
Several APs giving wireless access to users. Printers are all on some of the network ranges dedicated to wired devices. The IP range for wireless devices form another different subnet with no printers at all.

The proposal is to configure a server to act as a gateway to allow AirPrint devices (those running iOS 4.2 or above) to use any previously existing printer from the corporate network. In order to give this service, we are going to install all the necessary components on a Linux box running CentOS 5.x (5.6 at the time of writing).

These steps are taken from an article of Ryan Finnie.

First step is to install all the printers to be "exported" in this server. This task is optional, the gateway could export any available printer (either network printers or those served by other computers). The goal of this first step is to centralize the administration of the printers, and to be able to differentiate the AirPrint related stuff from the rest of the system, in order to allocate the cause of possible problems. This step is also very recommendable in order to automatically generate in a further step some necessary configuration files.

So, we enable CUPS in the server (if not already done), then we setup the remote printers and finally we make some changes to allow print sharing. Additionally we allow the CUPS server listening on its public interface instead of just listening on localhost.

# Modifications to the file /etc/cups/cupsd.conf
ServerAlias *
Browsing On

As stated above, AirPrint does not require printer-specific drivers or setup tasks. AirPrint achieves this goal by means of bonjour, the Apple implementation of the zeroconf mechanism.
According to wikipedia, Zero configuration networking (zeroconf), is a set of techniques that automatically creates a usable Internet Protocol (IP) network without manual operator intervention or special configuration servers.

On the other side, Avahi is a free Zeroconf implementation available for Linux and BSDs. The solution is to use avahi to announce the desired printers.

Creation of the avahi configuration files for the printers is not an easy task. Luckily, Timothy J. Fontaine wrote a script to automatically generate the avahi configuration file from the CUPS printer definitions existing on the system. So, the next step is to download or copy that script in our system to create our own avahi configuration files with no effort.

In order to run this script, we need to install the package providing the bindings between CUPS and python.
In many systems this package is named "pycups", but in CentOS this is provided by "system-config-printer-libs". We proceed to install it.

# yum install system-config-printer-libs

The script requires python >=2.5, but since we are using CentOS 5.x, our system has just python 2.4.3 installed. If we try to execute the script, we will obtain the following error:

# python 
Traceback (most recent call last):
File "", line 46, in ?
raise 'Failed to find python libxml or elementtree, please install one of those or use python >= 2.5'
Failed to find python libxml or elementtree, please install one of those or use python >= 2.5

In this case, it becomes necessary to make some modifications to the script. This can be done applying this patch, or just editing the file and changing line #43

# vi airprint-generate.patch 
< from elementtree import Element, ElementTree, tostring
> from cElementTree import Element, ElementTree, tostring

Once created the patch file, we apply it to the script:

# patch airprint-generate.patch
# python

Once patched, we can run the script and we will obtain the files to configure avahi. Just copy these files to the avahi directory and reload (or restart) the service.

# cp AirPrint-*.service /etc/avahi/services/
# service avahi-daemon reload

In this step, you should be able to print via AirPrint if your CentOS has an IP on the same subnet of your iPxx devices. This may happen in small ofices or domestic networks, if the CentOS box uses a wireless connection, but it is not the usual scenario in medium or large size corporate networks. This second scenario will be covered in the next blog entry.

Sunday, July 10, 2011

Multiseat is coming back with ubuntu 11.10

Just a few days ago, the version alfa 2 of Ubuntu 11.10 was released. This version comes with some interesting changes, may be the most significant of them are the use of the branch 3 of the Linux kernel, as well as the use of Gnome 3.

As you probably already know, multiseat is closely related to display manager, since it is a key component which allows the starting of multiple simultaneous graphical sessions. You probably will know, too, that this feature was removed in gdm (the Gnome Display Manager) in version 2.22. This is the reason why since Ubuntu 9.10 there is no an easy setup to configure a multiseat computer.

In Ubuntu 11.10 LightDM has replaced GDM as the default display manager. This is a rather new display manager, so the first question was whether this new display manager would support a multiseat configuration. The question seems to have been answered and, accordingly to the comments, multiseat configurations will be possible.

We are currently preparing a computer with the alfa 2 of Ubuntu 11.10 just to test the multiseat setup. We will keep you informed about the results on the blog.

Meanwhile, you can have a look to the new features of Ubuntu 11.10

Thursday, March 31, 2011

Setup your own DLNA server

DLNA is a standards-based technology whose main goal is to ease the sharing of multimedia contents. DLNA is an open protocol based on UPnP.

This article describes how to install and configure a DLNA server. This software is going to be installed on a home server. Just as a comment, this home server is a very low power consumption machine (Atom N550 board) running a very powerful OS: 64 bit CentOS 5.5.

We started with a brief comparison and testing of some of the most popular DLNA servers for Linux uShare, MediaTomb and MiniDLNA). That was not an exhaustive comparison, but just a few quick tests. After that quick preview, we finally decided to use MiniDLNA.

The authors of the MiniDLNA project offer a statically compiled version, which makes very easy to install the software. Download it, and optionally, you can make some changes to file permissions in order to keep them consistent with the rest of your system.

Let's assume that you downloaded the installation package on /tmp

Previously to the installation, we set root as the owner of the files (optional) just to avoid having an unreferenced owner, then, we unpack the software.

# mkdir /tmp/mini
# tar -xzf /tmp/minidlna_1.0.19_static.tar.gz -C /tmp/mini
# chown -R root:root /tmp/mini
# cp -r /tmp/mini/* /

The configuration is really simple. You have a self-explaining configuration file (/etc/minidlna.conf) with a few options. Just indicate which interface are you running the service on, and the directory containing the media to share. In my case, these were the only changes I made, keeping the rest of the options with the default values.


The most difficult task is to configure the firewall (iptables, since it is a CentOS based server) properly. This home server offers public services to the outside. External services are separated from internal ones, being offered through a different interface. Even so, disabling the firewall is not an option.

First of all, we launch the service just to examine the ports that must be kept open:

# /usr/sbin/minidlna
# lsof -i4 -n | grep minidlna
minidlna 12964 root 8u IPv4 1155301 UDP *:ssdp
minidlna 12964 root 9u IPv4 1155302 TCP *:trivnet1 (LISTEN)
minidlna 12964 root 10u IPv4 1155303 UDP
minidlna 12965 root 8u IPv4 1155301 UDP *:ssdp
minidlna 12965 root 9u IPv4 1155302 TCP *:trivnet1 (LISTEN)
minidlna 12965 root 10u IPv4 1155303 UDP
minidlna 12968 root 8u IPv4 1155301 UDP *:ssdp
minidlna 12968 root 9u IPv4 1155302 TCP *:trivnet1 (LISTEN)
minidlna 12968 root 10u IPv4 1155303 UDP

Ports ssdp (1900/udp) and trivnet1 (8200/tcp) are proper of this service. The other port (37167/udp) varies in every execution.

I recognize not being an expert setting firewall rules, but firewall configuration in CentOS in this case resulted to be a very frustrating task.

After almost two whole days spent reading threads, tutorials and comments about UPnP, SSDP, DLNA, multicast, routing and filtering, I finally obtained a firewall configuration that, so far, seems to work properly. Neither more permissive than necessary nor too much complicated.

Maybe due to my limited knowledge about iptables, I was not able to introduce these rules from the command line to behave as I expected, so, I had to edit, finally, the /etc/sysconfig/iptables file in order to introduce these rules. I added two rules in the RH-Firewall-1-INPUT section, just before the REJECT rule.

-A RH-Firewall-1-INPUT -s -d -p tcp -m tcp --dport 8200 -j ACCEPT
-A RH-Firewall-1-INPUT -s -d -p udp -m udp --dport 1900 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

The IP is where the machine offers services to other devices in the LAN (

First rule allow computers on the LAN to access the server on the port 8200/tcp
Second rule allow computers on the LAN (including the same server) to access the SSDP service (1900/udp) on a fixed multicast address (

Restart iptables after these changes, and you will have a working DLNA server without compromising the security of your server.

Saturday, March 26, 2011

Download Flash videos

Today there is a lot of websites with video contents. Most of them use flash as the platform to deliver the video contents to web browsers.

There can be many reasons to prefer to download the contents instead on watching them online, but unfortunately, many sites do only allow to watch the video contents while the user is connected to the corresponding website.

Older versions of flash player (previous to fall of 2010), just created a temporal file containing a cached copy of the video content. This way, getting a copy was an easy task: The user had just to locate the file containing the cached video to make a copy of such a file.

Current versions does not seem to create anywhere such a copy of the video.

In recent versions, such a file has been hidden trying to difficult to get a copy of the contents shown in the player. The trick is to use a deleted file as video cache. This way, the user is unable to find this file, at least in the usual way.

Here, we present a simple script whose goal is to get a copy of the deleted cache video file used by the flash player:

#! /bin/bash

PIDS=`ps aux | grep libflashplayer | grep -v npwrapper | grep -v grep | awk '{print $2}'`
for PID in $PIDS
FFILES=`ls -la /proc/$PID/fd/* | grep Flash | awk '{print $8}'`
FNAME=`tempfile -d $RECPATH -p vid_ -s .flv`
echo "Recovered file: "$FNAME


Using your favourite editor, create a script with the above commands.
Place it on any convenient location (for all users, like /usr/sbin, or just for your own ~/scripts ), and do not forget to give it execution permissions, i.e:

$ sudo vi /usr/sbin/capture_flash

Copy the above lines to this file. You can change the destination folder location (/tmp in the sample script) or modify the script to receive the destination as a parameter.

$ sudo chmod +x /usr/sbin/capture_flash

Open your browser, point to a site containing a flash player. Let the player buffer the full video contents and then execute the script.

$ capture_flash

Now you will have a copy of the video being played in the embedded viewer. You can rename it, and eventually move it to a more convenient location.


First of all, the script obtains the PID of all running instances of flash player. The npwrapper is excluded, considering that you can be running the 32 bit version on a 64 bit system

PIDS=`ps aux | grep libflashplayer | grep -v npwrapper | grep -v grep | awk '{print $2}'`

The script iterates through the identified PIDs examining the file descriptors associated with every process. Flash cache files can be identifies easily since they are the only ones containing the pattern 'Flash' on their names. Here we obtain references to the deleted cache files (unreachable and invisible otherwise).

FFILES=`ls -la /proc/$PID/fd/* | grep Flash | awk '{print $8}'`

For every flash file identified, the script generates a unique name on the destination directory, and finally copies the file descriptor of the deleted cache file to an ordinary file.

FNAME=`tempfile -d $RECPATH -p vid_ -s .flv`

You got it!

Note: The script has been successfully tested on Firefox 3.6.x and Chromium-browser 10.0.x with flash 10.2.x running on Ubuntu 10.04 x86_64. Comments and improvements are welcome.

Thursday, February 03, 2011

Android Market webstore: Change language

After the opening of the Android Market Webstore, there seems to be many complains about the fact that the webstore selects automatically the default language based on the country associated to your public IP.

Many people has been complaining about that, due to different facts: Countries with several official languages, people living or just staying not in their own country, companies accessing Internet through corporate gateways in another country, are among the most argued reasons.

So, If you want to choose another different language, just add a parameter with your language suffix (hl=xx).

Some samples:

That can be useful, too, if you want to read comments about any application in other language different than yours.

Wednesday, February 02, 2011

Android Market Webstore

Android Market Webstore has been just officially announced today.

Now, you can find the Tilt Meter Android Application on the webstore.