SANE network backend

SANE Network Daemon


saned is the SANE (Scanner Access Now Easy) daemon that allows remote clients to access image acquisition devices available on the local host. This has two advantages. First you can access one or even several scanners connected to your scanner server from different hosts. Second you can control access to the scanner by password based user authentication or grant access to parallel port scanners to non-root users.

Another thing you want saned for is to allow Windows boxes to access your scanner. See Links for some TWAIN data sources supporting SANE using the network daemon.


saned is part of the SANE distribution, you can download it from the official SANE homepage. Please follow the installation instructions included into the tarball.

However, you will still have to configure saned for your system. The exact setup depends on whether you are running inetd or xinetd. If you have neither, you first have to install either. (Hey, this rhymes!)

It's a good idea to get your scanner working without saned before installing saned, so you can make sure that if something doesn't work it's not related to your basic scanner setup.

You have to edit two files in order to install saned on your system:



Some distributions (like Gentoo) may put this block into a file called /etc/xinetd.d/sane-deamon or similar.

Sometimes this block contains a setting only_from = localhost. If you want to access saned from other hosts, you have to add the IPs of those other hosts seperated by spaces.

If your saned and/or tcpd binary are installed somewhere else you have to supply the correct paths. Furthermore, you have to make sure user and group saned exist and they have appropriate access rights to your SCSI, parallel port, and USB devices. If your scanner is attached to /dev/sga for example, you can set the access rights like this:

        # chown root:saned /dev/sga && chmod g+rw /dev/sga

Examples for USB devices would be /dev/usbscanner or /dev/usb/scanner0, /proc/bus/usb/001/005, or /dev/bus/usb/001/005, parallel port scanners are connected for example to /dev/parport0. Note that you don't may not have those devices for your USB scanner if you are using libusb instead of the kernel module (libusb is the recommended access method). If you are using libusb, you may want to setup hotplug to set the correct access rights. See the sane-usb man page for further details about USB device access rights or read README.linux.

If your Linux distribution uses hal (most do), you should create a file /etc/hal/fdi/policy/saned.fdi with the following contents:

      <?xml version="1.0" encoding="UTF-8"?>
      <deviceinfo version="0.2">
          <match key="info.capabilities" contains="access_control">
            <match key="access_control.type" contains="scanner">
              <append key="access_control.grant_user"

To test whether the access rights are set correctly, you should try whether user saned can access the scanner:

        # su -s /bin/sh - saned
        $ scanimage -L

However, if you want to use saned to access a parallel port scanner, and the respective backend doesn't support libieee1284 yet (you may want to file a bugreport against the backend), you have to replace saned.saned with root in your inetd.conf or user = saned, group = saned with user = root in your xinetd.conf and you do not need to change any device access rights.

Reload your inetd or xinetd server and check whether saned is started by telneting port 6566:

        $ telnet localhost 6566

If the connection is refused, something went wrong. Check your syslog for hints whether inetd or xinetd rejected your configuration or saned or tcpd refused to start. If you still can't connect, please see the section FAQ.

Basic Setup

Now that your saned server is running, you have to setup which hosts may access which scanners.

This is done in the file /etc/sane.d/saned.conf or /usr/local/etc/sane.d/saned.conf depending on your installation.

If you have both directories, your installation is broken. You have two versions of SANE installed, this is not going to work. Please remove both and do a clean installation.

Each line not starting with a hash-mark (#) is considered to be a valid hostname. Note that the hostname and IPv6 address matching was case-sensitive in older versions of saned but isn't anymore. A basic setup would be just one line "localhost" which allows users from localhost to connect to the saned server. If your system is using tcpd, you have to make sure that /etc/hosts.deny and /etc/hosts.allow allow access from these hosts to your saned server.

You can also specify complete networks, giving the bit-width of the netmask, or IPv6 addresses enclosed in square brackets:
        # this is a comment

The saned server provides access to all local scanners. If you have, for example, one Mustek SCSI scanner connected to /dev/sga, you now can access the scanner net:localhost:mustek:/dev/sga. If you want this scanner listed automatically, you also have to edit the file /etc/sane.d/net.conf (or /usr/local/etc/sane.d/net.conf) on the machine you want to scan from. If this is the same as the machine saned is running on, a line "localhost" should do the job.

Now your scanner should get listed by

        $ scanimage -L

If this isn't the case, please refer to section FAQ.

Advanced Setup

Since SANE 1.0.4 user authentication using some basic encryption is included into saned (details). This encryption is supported by scanimage and XSane.

The advantages of using user authentication is access control to your scanner and finer control who may access which scanner. However, this user authentication doesn't replace a firewall if your server is accessible from the internet. Actually, your saned server shouldn't be accessible from the internet or untrusted hosts at all.

The setup is done in the file /etc/sane.d/saned.users (or /usr/local/etc/sane.d/saned.users). Each line not starting with a hash-mask (#) is considered a valid entry of the form


Where user and password may be up to 127 letters long and consisting of any character besides \n \r : and \000. The last part identifies the backend this user is authorized to access.

If a user wants to access a specific scanner, the file saned.users is checked for a line mentioning that backend. If such a line exists, the user is queried for her username and password. If none or wrong information is supplied, the access is denied. However, if no line mentioning that backend exists, access is granted without password.

To automate the user authentication, each user can store her passwords in the file ~/.sane/pass. This files has to be be at least 0600 (chmod 0600 ~/.sane/pass) to prevent other people from reading it, since the passwords are stored in plaintext. Again, every line not beginning with a hash-mark (#) is considered a valid entry of the form


The format for the username and the password is the same as above, but here the ressource is not only the backends name but includes the host and the net backends name (like net:localhost:mustek). This file is read by XSane and scanimge.

With scanimage you should use the option --accept-md5-only to avoid server side attacks.


If saned doesn't work out of the box, this can have many reasons. So the most frequently asked question is "why?" or better "why not?". However, there are some few basic steps you can try to get a hint what could be wrong.

It turned out that helping people solving problems with saned always follows the same pattern:

  1. Is your installation broken?
    • If you are using Fedora Core 1, please remove the symbolic link /usr/lib/sane/
    • If you are using Gentoo, disable (by commenting out) the brother backend in your dll.conf
    • If you have a /etc/sane.d and a /usr/local/etc/sane.d directory, you have installed SANE twice. Please remove both installations and reinstall SANE.
  2. Are the device access rights correct?
    An error like "Device busy" is often caused by incorrect device access rights.
    • Log in as user saned and see whether scanimage -L finds your scanner.
    • If you're using a parallel port scanner, you need to run saned as user root. Please ensure you didn't configure inetd or xinetd to run saned as user saned in that case.
    • If you're using an USB scanner, depending on your distribution and kernel version, you need access rights to /dev/usbscanner* (old kernels), /proc/bus/usb/aaa/bbb (older hotplug based setup, aaa and bbb come from the devicename libusb:aaa:bbb), or /dev/bus/usb/aaa/bbb (current udev based systems). Please also read the file README.linux on how to set device permissions automatically.
  3. Is the server's setup correct?
    • Does your saned.conf contain all client IPs?
    • Can you connect from the server machine using telnet to saned (port 6566)? Make sure inetd or xinetd is up and running. You may have to restart them after changing their configuration. Please see your distributions manual on how to enabled inetd or xinetd, if they don't start up.
    • Can you connect from the client machine using telnet to the server? In case you are using tcpwrappers you may need to adopt your /etc/hosts.allow and /etc/hosts.deny files.
    • Does your servers hostname resolve correctly? The name returned by the hostname command has to be resolveable by the host or nslookup command. If not, add an entry to /etc/hosts consisting of the IP of your server and the hostname (or fix your DNS settings).
  4. Is the client's setup correct?
    • Does your dll.conf contain the net backend?
    • Does your net.conf contain the IP of the server?

Please check all above points. Do not assume something is setup correctly, check it. If you already checked it, check it again.

If you have checked all above and it still doesn't work, you may need to debug your setup a little:

You can start saned with debugging enabled. To do this, you to disable the saned in your inetd.conf or xinetd.conf - otherwise you will get an error message telling you that saned couldn't bind a port. Just comment it out with hash-marks (#) or stop the whole inetd or xinetd server. Then start saned from the command line like this

       # SANE_DEBUG_MUSTEK=128 saned -d128

(assuming you have a Mustek SCSI scanner, see the man page of your backend for the exact name of the debug variable). If you are using csh or tcsh, you need to use setenv to set the debug variable.

Maybe you can find the error from the output yourself, if not, you can include it into a mail to the sane-devel mailing list. There should also be some output in your syslog.

On the client side you should use something like

        $ SANE_DEBUG_NET=128 scanimage -L

Sometimes, saned starts only when debugging is enabled. To be able to use saned with debugging enabled from inetd or xinetd, you have to use a little wrapper. This is also handy, if you need debug output from the backend and you don't want to start saned by hand all the time... rename saned to something like saned.bin and create a shell script like this

        export SANE_DEBUG_MUSTEK
        cd /tmp
        exec $0.bin 2> saned.$$.stderr

This will make two files with stdout and stderr from the last session in /tmp. The debug information will be in saned.*.stderr.

Also make sure your script has appropriate ownership rights set and doesn't try to access root's startup files like /root/.bashrc, the warning about not being able to read this file would disturb the saned network traffic.

If you encounter further problems, feel free to get in contact with us using the sane-devel mailing list.

Another common topic is firewalling. saned listens normally on 6566/tcp. However, the actuall image data is transfered using an arbitrary port above 1024. We are aware of the fact that this is not easy to filter. On the other hand, a scanner daemon is nothing to run on a firewall.

A possible solution to this is to rewrite saned to use one specific port. This has the drawback that saned won't work if that port is already used by another program.

Another solution is using a packet filter that is able to match packets based on the process sending or receiving them. You could then enable the process saned to communicate on port 1024 and above while blocking other applications.

There are known problems with connections timing out and lockups in the net backend. This are open bugs and no good solution is known. Anyway, this does not happen often and if it was reproducable, it was fixed long ago :)



If you have questions, comments, bug reports, suggestions, or if you just wish to send me some nice greetings, feel free to contact me: