Debian 7: Setting up production Exim MTA as an e-mail service provider

Note: This post is 9 years old. Some information may no longer be correct or even relevant. Please, keep this in mind while reading.

With a mis-configured email server, it is very easy to get your IP address blacklisted!

Recently, my Exim mail server was hopelessly spammed to such an extent that I wasn’t even able to clear the mail queue using rm ./*, nor even list the files, nor even count the files with ls.  How still I managed to delete probably millions of mail files in one folder is documented in my post “Removing a million files in a directory“.

After this shock, I decided to integrate anti-spam and anti-malware systems into my Exim MTA, and within a few hours my server was back up and running, and this time, bouncing spam emails back to where they belong. This blog post documents my steps in Debian 7 “Wheezy”.

My own knowledge about Exim comes from the excellent Official Guide to Exim by Exim’s author, Philip Hazel. Email servers are very complex. You won’t be able to go very far with ‘duct tape’ administration, nor come up with a good fix in a case of emergency.

If you are serious about the topic, I would suggest you grab your own copy of the Official Guide to Exim from Amazon.

How to install Exim

You can install Exim by running

apt-get install exim4

but by default, this installs the package exim4-daemon-light, which does not have advanced capabilities compiled in. Since we want to do spam filtering, we need to install exim4-daemon-heavy:

apt-get install exim4-daemon-heavy

This will remove exim4-daemon-light automatically.

We have to enable Exim for internet communications, since the default is only localhost communications. In /etc/exim4/update-exim4.conf.conf  change the line dc_eximconfig_configtype='local'  to


Enter the domains you want to receive emails for:


Make Exim listen on all interfaces by emptying the following config line:


Enable TLS for Exim by running the script …


… and add the following line somewhere at the top of Exim’s configuration template file /etc/exim4/exim4.conf.template .


Every time you modify /etc/exim4/exim4.conf.template , you have to run update-exim4.conf  and do service exim4 restart .

Next, we will install and configure Spamassassin for Exim. Luckily, it is a Debian package.

Spam Assassin


You can find instructions in this Debian Wiki, but you will find all commands here for convenience.

apt-get install spamassassin

This starts a daemon called spamd  automatically. However, it is disabled by default. Enable it by changing the following line in /etc/default/spamassassin :


Debian-specific modification: In the same file, change this line

OPTIONS="--create-prefs --max-children 5 --helper-home-dir"

to this:

OPTIONS="--create-prefs --max-children 5 --helper-home-dir -u debian-spamd"

This instructs the spamd daemon to run as the user debian-spamd  which is created when you install spamassassin. Its home directory is /var/lib/spamassassin . I had to do this because the following error messages was regularly logged into /var/log/syslog :

config: cannot create user preferences file /nonexistent/.spamassassin/user_prefs: No such file or directory
spamd: failed to create readable default_prefs: /nonexistent/.spamassassin/user_prefs
spamd: failed to create readable default_prefs: /var/spool/exim4/.spamassassin/user_prefs

Also, enable the cronjob to automatically update spamassassin’s rules:


The conjob file in question is /etc/cron.daily/spamassassin , which in turn calls sa-update .

Next, you can configure the behavior of spamassassin in the config file /etc/spamassassin/ . Especially the entries “rewrite_header” and “required_score” are interesting, but later we will configure Exim to do these jobs for us directly.

Restart the daemon to make the changes effective:

service spamassassin restart

Integration into Exim

All of following modifications have to take place in /etc/exim4/exim4.conf.template.

Now we have to enable spamd in Exim’s configuration file. Search for the line containing spamd_address and uncomment it like this:

spamd_address = 783

It is a good idea to add special headers to each processed email which specify the spam score. The configuration is already there, we just have to uncomment it (see also official documentation of this here):

    spam = debian-spamd:true
    add_header = X-Spam_score: $spam_score\n\
              X-Spam_score_int: $spam_score_int\n\
              X-Spam_bar: $spam_bar\n\
              X-Spam_report: $spam_report

Note that I have replaced spam = Debian-exim:true  with spam = debian-spamd:true to match the user of the spamd daemon. If you want to know what the :true  part means, study this section of the official Exim documentation.

At this point, emails which are definitely spam will still be delivered. This is not good, since when a mail client of one of your customers should be compromised, it could send thousands of spam emails per day, which still would cause your server and IP to be blacklisted. If you want to bounce emails that are over a certain spam point threshold, add the following lines directly below. In this case, the threshold is 12.0 (but you have to enter it without the comma):

    message = This message scored $spam_score spam points.
    spam = debian-spamd
    condition = ${if >{$spam_score_int}{120}{1}{0}}

Generate the real Exim4 configuration from /etc/exim4/exim4.conf.template  that we’ve just edited by running

service exim4 restart


Now, let’s test if our spamassassin setup was successful. Send an email to your Exim server that contains the following line. This code is taken from Spamassassin’s GTUBE (the Generic Test for Unsolicited Bulk Email):


The email should bounce back immediately and contain the message that we’ve entered above:

SMTP error from remote server after transfer of mail text:
This message scored 1000.0 spam points.

Now, send yourself a normal email. After you have received it, in your mail client (I’m using Icedove) inspect the mail source by pressing Ctrl + U. It should contain the following special header lines:

X-Spam_score: 2.7
X-Spam_score_int: 27
X-Spam_bar: ++
X-Spam_report: snip

So far, so good.


Next, let’s set up Greylisting, another spam defense measure. The tool of my choice was greylistd because Debian has its own package greylistd.


apt-get install greylistd

You will be shown a configuration notice, instructing you how to enable greylistd in the Exim configuration. The following will show you what to do.

Integration into Exim

greylistd-setup-exim4 add

As far as I could determine, this automatically adds some lines in the already existing Exim configuration templates exim4.conf.template and inside of the directory /etc/exim4/conf.d. It adds it right after acl_check_rcpt:.

At this point, greylistd is already running. In case you want to restart the service, run

service greylist restart

Of course, we have to restart Exim again so that our new configuration becomes active:

service exim4 restart


Observe the contents of the Exim log file

tail -f /var/log/exim4/mainlog

and send yourself a regular email. You will see a line in the logfile similar to this:

F=<> temporarily rejected RCPT <>: greylisted.

When it says “temporarily rejected RCPT” and “greylisted” it means that greylistd is working.

Anti-Malware and Anti-Virus

As an email provider you certainly want to have some anti-malware and anti-virus measures in place. My choice was ClamAV, since it’s part of Debian and rather easy to integrate with Exim. The following instructions are loosely based on the Ubuntu Wiki EximClamAV, but it contains one step too much which seems to be no longer necessary (the part about creating a new file). In any case, here are my working steps.


First, install the daemon:

apt-get install clamav-daemon

It will output the following failures, but don’t worry, they are harmless:

[FAIL] Clamav signatures not found in /var/lib/clamav ... failed!
[FAIL] Please retrieve them using freshclam ... failed!
[FAIL] Then run '/etc/init.d/clamav-daemon start' ... failed!

To get rid of the messages, you have to run


This command updates your virus databases from the internet. You should create a cron job to run it regularly. Now you are able to restart the daemon without failure messages:

service clamav-daemon restart

Next, add the clamav daemon user to the Debian-exim group, so that it can access the spool files:

usermod -a -G Debian-exim clamav

Integration into Exim

Locate the line in /etc/exim4/exim4.conf.template which contains av_scanner, un-comment it, and change it to the following (as the Ubuntu Wiki correctly says, the default value does not work):

av_scanner = clamd:/var/run/clamav/clamd.ctl

Next, un-comment the following lines in /etc/exim4/exim4.conf.template (this is where the Ubuntu Wiki says that you should create a new file, but it’s already there):

    malware = *
    message = This message was detected as possible malware ($malware_name).

As we have done before, we have to restart Exim so that our new configuration becomes active:

service exim4 restart


There is a special string that you can use to test Anti-Malware programs. It is taken from the eicar website.  At the bottom of the linked page you will find it:


Send an email to Exim which contains this string in a separate line. It should bounce immediately. The bounced message will contain:

SMTP error from remote server after transfer of mail text:
This message was detected as possible malware (Eicar-Test-Signature).

When you get this, ClamAV is working correctly.

Setting up Exim with DKIM (DomainKeys Identified Mail)

Google Mail suggests using DKIM for ISP providers. When you are signing outgoing messages with DKIM, you are reducing the chance that Google thinks you are a spammer. See also Google’s Bulk Senders Guidline as to how Google judges the Anti-Spam qualities of your mails. DKIM is not a strong Anti-Spam indicator, it only ensures (due to private/public key encryption) that an email was actually sent from the server it claims it was sent. Anyhow, here is how to do it (based on the articles here and here):

Generate a private key with openssl:

cd /etc/exim4
openssl genrsa -out dkim.private.key 1024

Extract the public key:

openssl rsa -in dkim.private.key -out dkim.public.key -pubout -outform PEM

Change permissions and ownership to make it readable for Exim and for security reasons:

chmod 640 dkim.p*
chown root:Debian-exim dkim.p*

Next add the following to exim4.conf.template  (or to your split-configuration files if you use that method), right before the line remote_smtp: 

DKIM_PRIVATE_KEY = CONFDIR/dkim.private.key
DKIM_CANON = relaxed

More information about these parameters see this section of the official Exim documentation.

Update the configuration and restart Exim:

service exim4 restart

Now send a test email to some address (e.g. free mail provider) which is not handled by your email server and inspect the sources of the received email. It should contain a line DKIM-Signature . To avoid confusion: If you are sending an email to yourself, which is received by the same server which you are configuring, no DKIM Signature is added (since not necessary).

Next, you have to add the DKIM public key as a TXT “selector record” to the DNS zone of For DKIM_DOMAIN  and DKIM_SELECTOR  you have specified above, you have to add the following entry:

TXT  |  exim._domainkey  |  v=DKIM1; k=rsa; p=MIGfMA...;

where p=  gives the public key from /etc/exim4/dkim.public.key  without headers and without line breaks.

You also should add a “DKIM policy record” for the subdomain _domainkey to state that all emails must be signed with DKIM. Otherwise, DKIM could simply be omitted by a spoofer without consequences. Again, this is a simple TXT entry in the DNS:

TXT  |  _domainkey  |  o=~;

You can use this tester to check the policy record:

However, this “o” policy record does not seem to be documented in any RFC (I found it on various blog posts), and it is superseded by RFC5617 (DKIM ADSP Author Domain Signing Practices). For ADSP you would have to add:

TXT  |  _adsp._domainkey  |  dkim=all

Similar in function to ADSP seems to be DMARC. I’ll write about this in a future blog post.

For details on DKIM see: RFC specification


Now check if your zone records have been saved and are effective:

dig TXT

It should output the contents of the TXT zone entry which you’ve made above. If you can see them, send an email to the excellent SMTP tester email

If it responds with

DKIM check:         pass

Then the DKIM set-up was successful.

Additional Anti-Spam measures

A characteristic behavior of malicious Spam senders is that they send a Spam Flood (as many messages as possible in the least time possible).  If possible, they will send many messages in just one SMTP connection (i.e. several MAIL commands in one session). If that happens, you will be blacklisted very soon, and with tens of thousands of sent spam emails, it will be very difficult to re-gain a good reputation in the eyes of email providers like Google or Yahoo. Legitimate human senders however will only send a few single messages, one message per SMTP connection, and it will take them at least 10 seconds to write a short email. So, we can rate-limit the submission of messages, having a big impact on spammers, but little impact on legitimate human senders. Exim has a rate-limiting feature, but I decided for an easier, more robust, low-level approach using the iptables firewall.

First, we will configure Exim to just allow one MAIL command per SMTP session. From the Exim Main Configuration Documentation, we can write somewhere in /etc/exim4/exim4.conf.template

smtp_accept_max_per_connection = 1

Next, we are going to limit the number of parallel SMTP connections per sending host to 1:

smtp_accept_max_per_host = 1

And we will limit the maximum SMTP connections which Exim will allow. You can set this to the approximate number of clients you have, plus a margin:

smtp_accept_max = 100

Now that we know that there only can be 1 message per SMTP connection, we limit the SMTP connection frequency in our firewall:

iptables -A INPUT -p tcp --dport 25 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 25 -m state --state NEW -m recent --update --seconds 60 --hitcount 6 -j DROP

This will limit incoming SMTP connections to 6 in 1 minute, which is one connection per 10 seconds in average – enough for private or business emails, not enough for spammers.

SMTP banner delay

(inspiration from here and here) Exim drops the connection if a SMTP client attempts to send something before the SMTP banner is displayed. This is a spam protection built directly into Exim:

SMTP protocol synchronization error (input sent without waiting for greeting): rejected connection

To further slow down spam, we simply delay this banner. Somewhere at the beginning of the Exim config file, write:

acl_smtp_connect = acl_check_connect

In layman’s terms, this tells Exim which ACL to execute when a connection is initiated. Then, after begin acl  add this:

    delay = 10s

You can test this by telneting to your server. The banner should appear only after 10 seconds.

More Anti Spam measures (not tested)


If you have succeeded so far, test your new Exim installation with the great tool at:

Exim is a very complex program (the most complex one I’ve encountered so far) and you can go very, very deep studying it. The complexity seems to stem from the complexity of the email delivery process itself. Despite that fact, this tutorial enables you to set up Exim with Anti-Malware and Anti-Spam measures in less than 1 hour. It is by no means exhaustive, but it at least bounces Spam emails above a certain threshold which is the most important thing when you don’t want your server and IP address to be blacklisted all over the internet. It also adds value to your customers when you are operating Exim as a business.

But: Anyone who would like to operate Exim for customers – would like to be a professional email hosting company – should think twice if it’s really worth it. Things do go wrong all the time, and if you don’t have a deep knowledge about what exactly to do in case of an technical or security-relevant incident – immediately, right there and then – you could upset all your customers pretty quickly. So, my advice would be: “hands-off” unless you know what you are doing. As I like to say: “You pays your money and you takes your chances!”

Follow up:

Exim and Spamassassin: Rewriting Subject lines, adding SPAM and Score

Home Entertainment goes GNU/Linux!

Note: This post is 9 years old. Some information may no longer be correct or even relevant. Please, keep this in mind while reading.

Since our old TV died, today our family bought a new flat-screen for the living room from Amazon: LG Electronics 55LN5700 55-Inch 1080p 120Hz LED-LCD HDTV with Smart TV (2013 Model)

I’m an Open Source advocate, so I was happy to learn that LG uses Open Source software for this particular TV family, since the User Manual contained a legal hint about Open Source Software.

This TV is pretty good, the installation is very easy. It comes with a quite advanced and progressive onscreen menu. This menu actually was the decisive factor for buying it. The best part is that it has a built-in browser (it seems to be webkit-based) and supports regular keyboard and mouse via a bluetooth dongle connected to one of the 3 available USB ports (I’m using a combined keyboard and mouse dongle from Logitech). The mouse cursor is attractive. The browser works fine for YouTube too. This is our Logitech wireless set from Amazon: Logitech Wireless Combo Mk520 With Keyboard and Mouse

There also is an LG App-Store for Games and other funny stuff, but since it requires a registered account, I haven’t tried that yet.

This TV also supports Media sharing from various PCs in the intranet via the DLNA system. Initially afraid that this would be all proprietary Windows stuff, it turned out that there are at least two good Open Source DLNA servers are part of the Debian distribution.

The first one I tried is rygel, but had medium successes with it. It worked when I ran it as root, but failed for some reason when I wanted to run it as an unprivileged user. Also, it didn’t come with an init.d script. Since I’m generally very busy, I immediately looked for an alternative.

The second server is minidlna, and I had immediate success with it. It is very thin and does an excellent job at serving media, all that is needed, and et even comes with an init.d script. Just do:

apt–get install minidlna

and the server is up and running. Then I tweaked /etc/minidlna.conf in the following way:

  • point media_dir to the folder where your media (pictures, videos, music) lives on your hard drive. In my case, this is also a folder shared by Samba, so that everyone in the house can copy media there and immediately watch it on the TV.
  • Uncommented log_dir and db_dir, but left the default values
  • As root_container I selected B, so that you can browse the acutal directory structure
  • set inotify=yes
  • set notify_interval=60

Then restart the minidlna service. Browse to port 8200 of your server to see a short HTML status message about the number of indexed files.

Then I ran into a problem: Moving a new media file into the folder wasn’t recognized by minidlna. It is supposed to be informed by new media by inotify, but it wasn’t. I found the fix here. Stop the service, delete /var/lib/minidlna/files.db, then start the service again. Now minidlna is immediately informed about new media files.

Considering that most of the entertainment technologies out there are proprietary and closed, the chance of success was extremely slim, but here it is anyway: GNU/Linux media server on a mainstream TV!

Dual Monitor (Multi seat) setup with Displaylink USB Montors

Note: This post is 10 years old. Some information may no longer be correct or even relevant. Please, keep this in mind while reading.

Note: I wrote this tutorial in 2012. It is terribly out of date and meanwhile probably partly or entirely wrong. Nevertheless I decided to re-publish it in case it is useful for others. I will likely not be able to answer any questions about the subject.

This tutorial shows you a working setup for operating 2 monitors (one conventional one connected to the normal VGA output of your graphics card and one USB monitor with a Displaylink chip), demonstrated on Ubuntu 12.10 and Debian GNU/Linux 7 (Wheezy).


First, I should mention that there is a lot of movement in working with Displaylink based USB monitors in GNU/Linux. Almost all documentation in the internet is either outdated or does not work, despite great interest in running many seats with just one computer.

Earlier tutorials in the internet concentrate on the xserver-xorg-video-displaylink package for the X Window System. To my great surprise, it as been removed from Ubuntu in August 2012 because the “displaylink KMS driver in the quantal kernel and x-x-v-modesetting replaces -displaylink”. After pulling some threads for an hour or so, it turned out that there is work going on to add displaylink support directly into the Kernel — this new support seems to be different from the already existing capability of the kernel to create a framebuffer device node like /dev/fb1. This DRM kernel module is called udl(announcement here and here), but the version at the point of this writing is 0.0.1 and, for now, it seems to do nothing more than to register and deregister Displaylink chips when plugged in and out.

If you research further, you will see that a new service manager called systemd is being developed as better replacement for existing startup/service managers, and that the udl Kernel module is supposted to work with systemd. Apparently it should be possible to have a single X11 server also ‘serve’ USB displays, so that you can share your desktop across several screens in true hotplug fashion.

This sounds very cool, but since all of that is in an extremely early stage, we can assume that a working plug and play for USB monitors will happen only a few years in the future, so going this route is a dead end, at least for now, and when you’re not a hardcore Kernel Module / X Windows developer that has a lot of experience in driving microchips.

In researching the alternatives, I found a working solution in running a separate X instance for the USB monitor. This second instance (apart from the first one that is ‘there’ by default) can either be started from a script — or from a Display Manager that supports Multi Seat setups.

In trying various configurations for X, it turned out that it is possible to make X use the framebuffer device node (like /dev/fb1) directly, even without the now obsolete xserver-xorg-video-displaylink package, by using the driver “fbdev” instead of the obsolete driver “displaylink”. How exactly this is set up, see the instructions below. In any case, you need to run 2 separate instances of X in parallel.

Once I knew that X worked with the USB monitor, the next step was to research Display Managers to find out methods how to start this second X instance. I have looked into LightDM and the Gnome Display Manager gdm3.

To my dismay, I found out that LightDM, while advertised as very small and lean, almost has no useful documentation, and I spent several hours restarting lightdm to find out working settings in trial-and-error. Even though I found working settings for LightDM, those still seem to be extremely brittle and subject to bugs over bugs in LightDM. The advantage of lightdm over gdm is that it supports a Multi Seat setup, whereas newer versions (!) of gdm outright do not support multi seats any more. The subjectively perceived ‘brittleness’ of LightDM is such, that it will start only Unity whenever the slightest thing goes wrong in its configuration. Once Unity is started (by mistake), LightDM will remember Unity in a handful of configuration files and it becomes very hard again to get rid of Unity.

So, below we’ll present 2 solutions:

  1. LightDM multi-seat setup in Ubuntu 12.10, where two X servers are spawned from LightDM, running 2 instaces of the X Window System, with two different system users.
  2. Manual start of a second X server in Debian Wheezy, because gdm3 does not allow for Multi Seat configuration

Ubuntu 12.10 with LightDM and Window Managers “Unity” and “Fvwm”

Ubuntu 12.10 already prefers the new udl Kernel module over the udlfbframebuffer module, which means that you won’t get the “green screen of success” on Displaylink based USB monitors during system boot. Instead, you get the repeating test patterns, but we need the green screen for this method to work. So, we have to blacklist udl and un-blacklist udlfb:

  1. add blacklist udl to /etc/modprobe.d/blacklist-custom.conf
  2. comment out blacklist udlfb from /etc/modprobe.d/blacklist-framebuffer.conf

When you reboot, the USB monitor should be green.

In the course of my experimentation, I found that running “Unity” on the USB Displaylink monitor had severe distortions of color and window geometry, which rendered “Unity” useless for my purpose. So I chose a simpler and faster Window Manager as a workaround. I decided for “Fvwm”, which you can install with

apt-get install fvwm

Next, we need to create the X configuration for the second X instance. We will call the second X instance with the explicit path to the configuration file, so this does not need to go into /etc/X11/xorg.conf.d, and you also don’t need to generate a working xorg.conf first. Modern distributions come without this file anyway, and X autodetects everything. Simply create the file /root/displaylink.conf with the following contents:

Section "ServerLayout"
Identifier "displaylink"
Screen "DisplayLinkScreen"
InputDevice "Mouse0"

Section "Screen"
Identifier "DisplayLinkScreen"
Device "DisplayLinkDevice"
Monitor "DisplayLinkMonitor"
SubSection "Display"
Depth 24
Modes "800x480"

Section "Monitor"
Identifier "DisplayLinkMonitor"

Section "Device"
Identifier "DisplayLinkDevice"
driver "fbdev"
Option "fbdev" "/dev/fb1"

Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"

Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7"

Change /dev/fb1 to the device node that is created for you automatically by the Kernel when you plug in the USB monitor. Also, change the resulution “800×480” to the actual resolution you monitor has.

Now, in order to run two different Window Managers, we need to create 2 system users (the main user will have set “Unity” for the main monitor, and the second user will use “Fvwm” on the USB monitor). You cannot have both with just 1 user, we tried it and it does not work. Below, the main user is called “my_user1”, the second user “my_user2”. Create the user “my_user2” in the Settings dialog in Unity and set up a password. Of course, “my_user1” and “my_user2” are just examples, so make sure you use the real names in the configuration file below.

Next, change /etc/lightdm/lightdm.conf to enable Multi Seats:


xserver-command=/usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -sharevts

xserver-command=/usr/bin/X :1 -auth /var/run/lightdm/root/:1 -nolisten tcp vt8 -novtswitch -sharevts

The keys autologin-session and user-session should, in theory (but only in theory) determine which Window Manager to start. The values “Fvwm” and “ubuntu” correspond to the .desktop files in the directory /usr/share/xsessions. Now, here is an explanation of why LightDM is so brittle. Thanks to long and painful reverse-engineering, I found out that the keys user-session and autologin-session are outright ignored when there are other ‘magic’ files present in the file system, which ‘cache’ these settings. The files in question are /var/cache/lightdm/dmrc/my_user1.dmrc and /home/my_user1/.dmrc where the contents are:


AND the file /var/lib/AccountsService/users/my_user1 which has the content


Changing the values of user-session and autologin-session in lightdm.conf will be useless, since it seems that the values of ALL 3 files must match so that lightdm does not default to “Unity”. Once it defaults to “Unity”, it will add “ubuntu” into all of these 3 files. Since we want “my_user2” to use “Fvwm”, we have to add the string “Fvwm” to all of those 3 files AND lightdm.conf. If you now reboot, in theory, you should be auto-logged in in both X sessions, and you should have “Unity” on one screen and “Fvwm” on the USB monitor.

If you want to ‘autostart’ a few programs together with “Fvwm”, create a file /home/my_user2/.xsessionrc and make it chmod u+x. Add a few test programs:

xterm &
xeyes &
chromium-browser &

Here is the proof that it worked for me:

Window Managers Unity and Fvwm running on two separate Xorg servers, spawned by LightDM Multi Seat configuration, with 7 inch Displaylink USB screen

If you need to configure screen blanking and keyboard/mouse, see sections below.

Debian GNU/Linux 7 (Wheezy) with gdm display manager

Since the Gnome Display Manager gdm does not support Multi Seat configuration in its newer versions, we have to start the second X server manually. Also, the new udl kernel driver is not yet active (as opposed to Ubuntu 12.10), so we don’t have to do the blacklisting as described in the previous section of this tutorial.

First, create /root/displaylink.conf with the exact same contents as posted in the previous section of this tutorial.

You can call X directly only as superuser, since it needs raw access to hardware. So, execute the following command as superuser to test:

startx -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

This should start Gnome on the USB screen. Press Ctrl + C to quit X, since it does not detach to the background. To choose “Fvwm” as a faster and smaller Window Manager alternative, install Fvwm …

apt-get install fvwm

then add “fvwm” to the above command:

startx fvwm -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

It is not very flexible or elegant to add the command “fvwm” directly into the X startup line. We will copy it to a file called /root/startupprograms.shinstead, so that we can add other startup programs later. Create this file and make it chmod u+x. I am going to use my USB screen as a fullscreen web terminal, so I also start Chromium in kiosk mode. My /root/ looks like this:

fvwm &
chromium-browser --user-data-dir=~/.chromium --window-size=800,480 --window-position=0,0 --kiosk --incognito

Of course, the X startup command now becomes

startx /root/ -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts

Now we need to add this command as a startup script called displaylink (or any other name) in /etc/init.d, so that we don’t have to run it manually, and that it will start during boot time:

cd /etc/init.d

Add the following to a file called displaylink:

#! /bin/sh

case "$1" in
echo "Starting X server"
startx /root/ -- :1 -layout displaylink -config /root/displaylink.conf -nolisten tcp vt8 -novtswitch -sharevts &
echo "Cannot stop X server because I don't know the PID"
echo "Usage: /etc/init.d/displaylink {start|stop}"
exit 1

exit 0

This script must be executable:

chmod u+x displaylink

It must be symlinked to the Debian runlevel 2:

update-rc.d displaylink defaults

This creates a symlink in /etc/rc2.d/Sxxdisplaylink, where xx is a number automatically determined by update-rc.d.

Now if you reboot, you will get 2 working terminals: Gnome on the main monitor, and the fullscreen Chromium running on Fvwm on the USB monitor. Here is the proof:

Window Managers Gnome3 and Fvwm running on two separate Xorg servers

Disabling mouse and keyboard for the USB Monitor

Your mouse and keyboard will be enabled for both screens, which is undesirable. Disable keyboard and mouse in the X configuration file we’ve created above, /root/displaylink.conf, by adding the following into the Section "ServerLayout":

Option "AutoEnableDevices" "false"
Option "AutoAddDevices" "false"
Option "AllowEmptyInput" "true"

To move the mouse cursor to the bottom right corner (so that it is barely visible), add to /root/ after installing apt-get install xdotool:

xdotool mousemove 10000 10000

Before you start a browser that accesses a web application on localhost, you have to add a delay with sleep 10, otherwise Apache won’t be running yet at this point of time.

If you run into problems, please contact Red (E) Tools Ltd. personally in our Support Forum.

Prevent screen blanks

In a Point of Sale setting, blanking or turning off the screen is not welcome. To keep displays on, you can either use the Energy settings in your display manager, but on our test system, in Gnome3, the maximum on-period of the monitor is 1 hour, and it would blank the screen anyway. You may need to override this manually, for both monitors. To keep your USB monitor turned on always, add the following commands to our startup file /root/

xset s off
xset -dpms
setterm -blank 0 -powersave off -powerdown 0

To keep your main monitor turned on with Gnome, create a file in the home directory of your normal system user:

xset s off
xset -dpms
setterm -blank 0 -powersave off -powerdown 0

Make this file executable with chmod a+x Then, add it as a Gnome startup program: In the Gnome Activities menu, enter “startup” as search term and start up this helper utility.

After you have rebooted, check in a terminal if the settings have been taken. Run xset q and check that DPMS is disabled.