SANE 1.2.1 配置参数详解

SANE 1.2.1 配置面全解析:/etc/sane.d 82 个配置文件族(dll.conf/test.conf/net.conf/saned.conf)、systemd 托管单元、udev 权限与 SANE_DEBUG 调试变量,含配置热生效实测与生产模板。

SANESANE2026/10/29

SANE 1.2.1 配置参数详解

目标:系统梳理 SANE(sane-backends 1.2.1)在 Ubuntu 24.04 LTS 上的全部配置面——/etc/sane.d 配置文件族、systemd 托管单元、udev 权限规则与调试环境变量,逐项给出实测回显与修改验证。已在 Ubuntu 24.04.5 LTS 裸机服务器实测通过。

一、环境信息

本文所有配置操作与回显均来自以下实验环境(与《Ubuntu 24.04 安装 SANE 1.2.1 指南》同一套两台服务器组成的最小扫描网络):

  • 操作系统:Ubuntu 24.04.5 LTS(PRETTY_NAME="Ubuntu 24.04.5 LTS"),内核 Linux 7.0.0-38-generic x86_64,systemd 255(255.4-1ubuntu8.18)
  • 实验拓扑:扫描服务端 scan-server(10.89.68.10),客户端 scan-client(10.89.68.20),同内网互通;服务端运行 saned(systemd socket 托管),客户端通过 net 后端访问

软件包版本(dpkg -l 实测):

libsane-common 1.2.1-7build4
libsane1:amd64 1.2.1-7build4
sane 1.0.14-18
sane-airscan 0.99.29-0ubuntu4
sane-utils 1.2.1-7build4

前端版本(scanimage -V 实测):

scanimage (sane-backends) 1.2.1-debian; backend version 1.2.1

实验形态说明:实验服务器未接入任何 USB/SCSI 物理扫描仪,全部扫描功能验证基于 SANE 官方自带的 test 虚拟后端(产生 test:0、test:1 两个虚拟设备)与 net 网络后端(跨服务器访问 saned 服务)。test 后端的行为与参数面和真实硬件后端同构(分辨率、色彩模式、ADF 等选项一致),但不含硬件专属参数(如灯管预热、双面器进纸器型号差异等)。文中涉及真实硬件差异处均已注明。

二、前置条件

  • 已按《Ubuntu 24.04 安装 SANE 1.2.1 指南》完成 sane-utils、libsane1、libsane-common 的安装;
  • 至少一台服务器启用了 test 后端(dll.conf 中取消 test 行注释)并可通过 scanimage -L 看到 test:0/test:1;
  • 涉及网络扫描的章节需要两台服务器:一台运行 saned(下称"服务端"),一台作为客户端(下称"客户端"),网络互通;
  • 建议以 root 或具备 sudo 权限的账号操作;/etc/sane.d/ 下文件的属主为 root,直接编辑需要写权限。

三、参数查看与修改方式

3.1 man 手册页体系

SANE 的配置参数文档分散在三类 man 手册中,按手册页分节归属两个软件包(dpkg -L 实测):

sane-utils 包提供(man1 / man8):

/usr/share/man/man1
/usr/share/man/man1/gamma4scanimage.1.gz
/usr/share/man/man1/sane-find-scanner.1.gz
/usr/share/man/man1/scanimage.1.gz
/usr/share/man/man8
/usr/share/man/man8/saned.8.gz

libsane-common 包提供(man5,每个后端一册,命名 sane-<后端名>.5),节选:

/usr/share/man/man5/sane-dll.5.gz
/usr/share/man/man5/sane-epson2.5.gz
/usr/share/man/man5/sane-escl.5.gz
/usr/share/man/man5/sane-fujitsu.5.gz
/usr/share/man/man5/sane-genesys.5.gz
/usr/share/man/man5/sane-gphoto2.5.gz
...

查询约定:后端自身的配置参数查 man 5 sane-<后端名>(如 man 5 sane-test、man 5 sane-net、man 5 sane-dll),守护进程查 man 8 saned,扫描命令查 man 1 scanimage。后端名与 /etc/sane.d/<后端名>.conf 一一对应。

3.2 配置目录与 SANE_CONFIG_DIR

SANE 默认从 /etc/sane.d/ 读取全部配置。该路径可用环境变量 SANE_CONFIG_DIR 覆盖(冒号分隔多目录,按序查找)。Ubuntu 打包的 saned@.service 中显式写死了该变量(systemctl cat saned@.service 实测,见 5.5 节):

Environment=SANE_CONFIG_DIR=/etc/sane.d

若需让某次扫描会话使用另一套配置(例如灰度发布新配置),可在命令行临时指定:

SANE_CONFIG_DIR=/root/sane-test scanimage -L

3.3 SANE_DEBUG_* 调试环境变量

每个后端都支持 SANE_DEBUG_<后端名大写> 调试变量,级别 1~128,越大越详细。最常用的是加载器 dll 的调试(SANE_DEBUG_DLL=5 scanimage -L 实测回显,节选):

[13:12:42.554173] [sanei_debug] Setting debug level of dll to 5.
[13:12:42.554211] [dll] sane_init: SANE dll backend version 1.0.13 from sane-backends 1.2.1-debian
[13:12:42.554217] [dll] sane_init/read_dlld: attempting to open directory `./dll.d'
[13:12:42.554221] [dll] sane_init/read_dlld: attempting to open directory `/etc/sane.d/dll.d'
[13:12:42.554230] [dll] sane_init/read_dlld: using config directory `/etc/sane.d/dll.d'
[13:12:42.554240] [dll] sane_init/read_dlld: considering /etc/sane.d/dll.d/airscan
[13:12:42.554257] [dll] sane_init/read_config: reading dll.d/airscan
[13:12:42.554278] [dll] add_backend: adding backend `airscan'
[13:12:42.554301] [dll] sane_init/read_config: reading dll.conf
[13:12:42.554311] [dll] add_backend: adding backend `net'
[13:12:42.554318] [dll] add_backend: adding backend `abaton'
[13:12:42.554325] [dll] add_backend: adding backend `agfafocus'
[13:12:42.554332] [dll] add_backend: adding backend `apple'
[13:12:42.554339] [dll] add_backend: adding backend `artec'
[13:12:42.554346] [dll] add_backend: adding backend `artec_eplus48u'
[13:12:42.554353] [dll] add_backend: adding backend `as6e'
[13:12:42.554360] [dll] add_backend: adding backend `avision'
[13:12:42.554367] [dll] add_backend: adding backend `bh'
[13:12:42.554392] [dll] add_backend: adding backend `canon'
...

(日志为节选;后续为按 dll.conf 顺序逐个 add_backend,直至列出全部启用的后端。)

这段日志可直接回答"我的 dll.conf 到底被读成了什么"——排查配置不生效时首选此法。

3.4 配置修改的生效时机

SANE 配置的生效模型由进程生命周期决定:

场景是否需要重启原因
scanimage 等命令行前端否每次执行都新起进程、重新读取全部配置
saned(systemd socket 模式,Accept=yes)否每个连接由 saned@.service 拉起新实例,读最新配置
saned(standalone 长驻进程)是配置仅在进程启动时读取一次
systemd 单元文件(socket/service)是需 systemctl daemon-reload 并重启对应单元

第 2 条在本实验中做了端到端验证:服务端把 /etc/sane.d/test.conf 中 number_of_devices 从 2 改为 3 后,客户端立即执行 scanimage -L,无需重启任何服务即看到三个网络设备:

device `net:10.89.68.10:test:0' is a Noname frontend-tester virtual device
device `net:10.89.68.10:test:1' is a Noname frontend-tester virtual device
device `net:10.89.68.10:test:2' is a Noname frontend-tester virtual device

服务端将配置恢复为 number_of_devices 2 后,客户端再次执行:

device `net:10.89.68.10:test:0' is a Noname frontend-tester virtual device
device `net:10.89.68.10:test:1' is a Noname frontend-tester virtual device

配置改动即时可见,双向闭环验证通过。

四、参数总览

SANE 1.2.1(Ubuntu 24.04 打包)安装后的 /etc/sane.d/ 共 82 个配置文件与 1 个子目录(ls -la /etc/sane.d/ 实测,文件按字母序):

-rw-r--r-- 1 root root   25 Mar 31  2024 abaton.conf
-rw-r--r-- 1 root root   13 Mar 31  2024 agfafocus.conf
-rw-r--r-- 1 root root 3328 Apr  8  2024 airscan.conf
-rw-r--r-- 1 root root   24 Mar 31  2024 apple.conf
-rw-r--r-- 1 root root   25 Mar 31  2024 artec.conf
-rw-r--r-- 1 root root 4157 Mar 31  2024 artec_eplus48u.conf
-rw-r--r-- 1 root root  547 Mar 31  2024 avision.conf
-rw-r--r-- 1 root root   29 Mar 31  2024 bh.conf
-rw-r--r-- 1 root root   26 Mar 31  2024 canon.conf
-rw-r--r-- 1 root root  193 Mar 31  2024 canon630u.conf
-rw-r--r-- 1 root root 4110 Mar 31  2024 canon_dr.conf
-rw-r--r-- 1 root root  258 Mar 31  2024 canon_lide70.conf
-rw-r--r-- 1 root root 1158 Mar 31  2024 canon_pp.conf
-rw-r--r-- 1 root root  552 Mar 31  2024 cardscan.conf
-rw-r--r-- 1 root root   34 Mar 31  2024 coolscan.conf
-rw-r--r-- 1 root root  753 Mar 31  2024 coolscan2.conf
-rw-r--r-- 1 root root  753 Mar 31  2024 coolscan3.conf
-rw-r--r-- 1 root root  983 Mar 31  2024 dc210.conf
-rw-r--r-- 1 root root  983 Mar 31  2024 dc240.conf
-rw-r--r-- 1 root root  703 Mar 31  2024 dc25.conf
-rw-r--r-- 1 root root  490 Mar 31  2024 dell1600n_net.conf
-rw-r--r-- 1 root root 1127 Oct 29 12:37 dll.conf
drwxr-xr-x 2 root root 4096 Oct 29 12:31 dll.d
-rw-r--r-- 1 root root   12 Mar 31  2024 dmc.conf
-rw-r--r-- 1 root root 2734 Mar 31  2024 epjitsu.conf
-rw-r--r-- 1 root root  792 Mar 31  2024 epson.conf
-rw-r--r-- 1 root root  374 Mar 31  2024 epson2.conf
-rw-r--r-- 1 root root  273 Mar 31  2024 epsonds.conf
-rw-r--r-- 1 root root 1447 Mar 31  2024 escl.conf
-rw-r--r-- 1 root root 3756 Mar 31  2024 fujitsu.conf
-rw-r--r-- 1 root root 2508 Mar 31  2024 genesys.conf
-rw-r--r-- 1 root root 1140 Mar 31  2024 gphoto2.conf
-rw-r--r-- 1 root root 7951 Mar 31  2024 gt68xx.conf
-rw-r--r-- 1 root root  497 Mar 31  2024 hp.conf
-rw-r--r-- 1 root root  395 Mar 31  2024 hp3900.conf
-rw-r--r-- 1 root root   76 Mar 31  2024 hp4200.conf
-rw-r--r-- 1 root root  238 Mar 31  2024 hp5400.conf
-rw-r--r-- 1 root root   23 Mar 31  2024 hpsj5s.conf
-rw-r--r-- 1 root root   24 Mar 31  2024 hs2p.conf
-rw-r--r-- 1 root root   38 Mar 31  2024 ibm.conf
-rw-r--r-- 1 root root  367 Mar 31  2024 kodak.conf
-rw-r--r-- 1 root root 2597 Mar 31  2024 kodakaio.conf
-rw-r--r-- 1 root root   39 Mar 31  2024 kvs1025.conf
-rw-r--r-- 1 root root  112 Mar 31  2024 leo.conf
-rw-r--r-- 1 root root  119 Mar 31  2024 lexmark.conf
-rw-r--r-- 1 root root  187 Mar 31  2024 ma1509.conf
-rw-r--r-- 1 root root 1253 Mar 31  2024 magicolor.conf
-rw-r--r-- 1 root root  665 Mar 31  2024 matsushita.conf
-rw-r--r-- 1 root root  268 Mar 31  2024 microtek.conf
-rw-r--r-- 1 root root  279 Mar 31  2024 microtek2.conf
-rw-r--r-- 1 root root 2118 Mar 31  2024 mustek.conf
-rw-r--r-- 1 root root 3801 Mar 31  2024 mustek_pp.conf
-rw-r--r-- 1 root root  808 Mar 31  2024 mustek_usb.conf
-rw-r--r-- 1 root root   13 Mar 31  2024 nec.conf
-rw-r--r-- 1 root root  573 Mar 31  2024 net.conf
-rw-r--r-- 1 root root  365 Mar 31  2024 p5.conf
-rw-r--r-- 1 root root   75 Mar 31  2024 pie.conf
-rw-r--r-- 1 root root  669 Mar 31  2024 pieusb.conf
-rw-r--r-- 1 root root 1246 Mar 31  2024 pixma.conf
-rw-r--r-- 1 root root 4140 Mar 31  2024 plustek.conf
-rw-r--r-- 1 root root  942 Mar 31  2024 plustek_pp.conf
-rw-r--r-- 1 root root  391 Mar 31  2024 qcam.conf
-rw-r--r-- 1 root root   29 Mar 31  2024 ricoh.conf
-rw-r--r-- 1 root root  183 Mar 31  2024 rts8891.conf
-rw-r--r-- 1 root root   13 Mar 31  2024 s9036.conf
-rw-r--r-- 1 root root 1093 Oct 29 12:42 saned.conf
-rw-r--r-- 1 root root   48 Mar 31  2024 sceptre.conf
-rw-r--r-- 1 root root 1458 Mar 31  2024 sharp.conf
-rw-r--r-- 1 root root  115 Mar 31  2024 sm3840.conf
-rw-r--r-- 1 root root 2239 Mar 31  2024 snapscan.conf
-rw-r--r-- 1 root root   10 Mar 31  2024 sp15c.conf
-rw-r--r-- 1 root root 2225 Mar 31  2024 st400.conf
-rw-r--r-- 1 root root  178 Mar 31  2024 stv680.conf
-rw-r--r-- 1 root root   27 Mar 31  2024 tamarack.conf
-rw-r--r-- 1 root root  355 Mar 31  2024 teco1.conf
-rw-r--r-- 1 root root  634 Mar 31  2024 teco2.conf
-rw-r--r-- 1 root root  217 Mar 31  2024 teco3.conf
-rw-r--r-- 1 root root 1807 Mar 31  2024 test.conf
-rw-r--r-- 1 root root 1494 Mar 31  2024 u12.conf
-rw-r--r-- 1 root root 3083 Mar 31  2024 umax.conf
-rw-r--r-- 1 root root  386 Mar 31  2024 umax1220u.conf
-rw-r--r-- 1 root root 1681 Mar 31  2024 umax_pp.conf
-rw-r--r-- 1 root root 4111 Mar 31  2024 xerox_mfp.conf

注:以上为 ls -la /etc/sane.d/ 实测清单的逐行誊录(略去表头 total 364 与 ./.. 两行)。其中 dll.conf 与 saned.conf 的修改时间为实验当日——这两处是本实验唯一改动过的文件;其余文件均为 2024 年 3 月/4 月打包时的原始状态。

按功能分组理解这 82 个文件:

分组成员作用
加载器dll.conf、dll.d/决定加载哪些后端(5.1、5.6 节)
网络访问net.conf(客户端)、saned.conf(服务端)跨主机扫描的两侧配置(5.3、5.4 节)
虚拟设备test.conftest 模拟扫描仪参数(5.2 节)
USB/SCSI/并口硬件后端epson2.conf、pixma.conf、fujitsu.conf、snapscan.conf 等 70+ 个对应各品牌硬件后端的设备寻址与型号微调
协议网关escl.conf、airscan.confeSCL/WSD 网络协议扫描(免驱动)
平台采集gphoto2.conf、qcam.conf、v4l(dll.conf 中启用)相机/并口摄像头/视频设备

规律:/etc/sane.d/<后端名>.conf 与 dll.conf 中的后端名一一对应;配置文件存在不代表后端被启用——是否启用只由 dll.conf(或 dll.d/)决定。

五、核心参数分类详解

5.1 dll.conf —— 后端动态加载配置

dll.conf 是 SANE 配置体系的总开关:dll 动态加载器(libsane 内置,版本 1.0.13)按此文件决定探测哪些后端。语法极简:每行一个后端名,# 开头为注释。全文实测(cat -n /etc/sane.d/dll.conf,101 行):

     1	# dll.conf - Configuration file for the SANE dynamic backend loader
     2	#
     3	# Backends can also be enabled by configuration snippets under the dll.d/
     4	# directory -- third party backends can drop their configuration file in
     5	# this in this directory, named after the backend.
     6	#
     7	# The next line enables the network backend; comment it out if you don't
     8	# need to use a remote SANE scanner over the network -- see sane-net(5)
     9	# and saned(8) for details.
    10	net
    11	abaton
    12	agfafocus
    13	apple
    14	artec
    15	artec_eplus48u
    16	as6e
    17	avision
    18	bh
    19	canon
    20	canon630u
    21	canon_dr
    22	canon_lide70
    23	#canon_pp
    24	cardscan
    25	coolscan
    26	#coolscan2
    27	coolscan3
    28	#dc210
    29	#dc240
    30	#dc25
    31	dell1600n_net
    32	dmc
    33	epjitsu
    34	#epson
    35	epson2
    36	epsonds
    37	escl
    38	fujitsu
    39	genesys
    40	#gphoto2
    41	gt68xx
    42	hp
    43	hp3500
    44	hp3900
    45	hp4200
    46	hp5400
    47	hp5590
    48	hpljm1005
    49	hpsj5s
    50	hs2p
    51	ibm
    52	kodak
    53	kodakaio
    54	kvs1025
    55	kvs20xx
    56	kvs40xx
    57	leo
    58	lexmark
    59	ma1509
    60	magicolor
    61	matsushita
    62	microtek
    63	microtek2
    64	mustek
    65	#mustek_pp
    66	mustek_usb
    67	mustek_usb2
    68	nec
    69	niash
    70	#p5
    71	pie
    72	pieusb
    73	pint
    74	pixma
    75	plustek
    76	#plustek_pp
    77	#pnm
    78	qcam
    79	ricoh
    80	ricoh2
    81	rts8891
    82	s9036
    83	sceptre
    84	sharp
    85	sm3600
    86	sm3840
    87	snapscan
    88	sp15c
    89	#st400
    90	#stv680
    91	tamarack
    92	teco1
    93	teco2
    94	teco3
    95	test
    96	u12
    97	umax
    98	umax1220u
    99	#umax_pp
   100	v4l
   101	xerox_mfp

要点解读:

  • 第 10 行 net:网络后端,做网络扫描客户端必须保持启用(Ubuntu 默认已启用)。
  • 第 95 行 test:当前实验环境已取消注释启用。Ubuntu 24.04 发行版默认此行为 #test(注释态),是本实验为完成模拟扫描所做的第一处改动。
  • 被注释的多为并口(canon_pp、mustek_pp、plustek_pp、umax_pp)、老旧相机(dc2x、gphoto2)与已废弃后端——按需启用。
  • 启用/停用后端后无需重启任何服务(生效模型见 3.4 节),直接重跑 scanimage -L 即可。

验证某个后端是否真的被加载,用 3.3 节的调试日志最直接:SANE_DEBUG_DLL=5 scanimage -L 2>&1 | grep add_backend。

5.2 test.conf —— test 虚拟后端参数

test 后端是 sane-backends 自带的"frontend-tester"虚拟扫描仪,用于无硬件环境的功能验证与前端调试。其参数面覆盖真实扫描仪的常见选项。全文实测(cat -n /etc/sane.d/test.conf,87 行):

     1	# test backend configuration file
     2	########################################
     3	
     4	# number of test devices
     5	number_of_devices 2
     6	
     7	# Initial option values and ranges
     8	########################################
     9	
    10	# Scan mode (Color, Gray)
    11	mode Gray
    12	
    13	# Bit depth (1, 8, 16)
    14	depth 8
    15	
    16	# Hand-scanner mode (true, false)
    17	hand-scanner false
    18	
    19	# Three-pass mode (true, false)
    20	three-pass false
    21	
    22	# Three-pass order (RGB, RBG, GBR, GRB, BGR, BRG)
    23	three-pass-order RGB
    24	
    25	# Resolution (dpi)
    26	resolution_min 1.0
    27	resolution_max 1200.0
    28	resolution_quant 1.0
    29	resolution 50.0
    30	
    31	# Draw test picture ("Solid black", "Solid white", "Color pattern", "Grid")
    32	test-picture "Solid black"
    33	
    34	# Invert upper and lower byte in 16 bit modes
    35	invert-endianess false
    36	
    37	# Read-limit (true, false)
    38	read-limit false
    39	
    40	# Read-limit size (1 - 65536 bytes)
    41	read-limit-size 1
    42	
    43	# Read-delay (true, false)
    44	read-delay false
    45	
    46	# Read-delay duration (1000 - 200,000 microseconds)
    47	read-delay-duration 1000
    48	
    49	# Status code (return-value) of sane_read() ("Default",
    50	#   "SANE_STATUS_UNSUPPORTED",
    51	#   "SANE_STATUS_CANCELLED", "SANE_STATUS_DEVICE_BUSY", "SANE_STATUS_INVAL",
    52	#   "SANE_STATUS_EOF", "SANE_STATUS_JAMMED", "SANE_STATUS_NO_DOCS",
    53	#   "SANE_STATUS_COVER_OPEN", "SANE_STATUS_IO_ERROR", "SANE_STATUS_NO_MEM",
    54	#   "SANE_STATUS_ACCESS_DENIED"
    55	read-status-code "Default"
    56	
    57	# Fuzzy parameters (true, false)
    58	fuzzy-parameters false
    59	
    60	# Loss of pixels per line (pixels)
    61	ppl-loss 0
    62	
    63	# Non-blocking io (true, false)
    64	non-blocking false
    65	
    66	# Support select fd (true, false)
    67	select-fd false
    68	
    69	# Enable test options (true, false)
    70	enable-test-options false
    71	
    72	# Geometry (mm)
    73	geometry_min 0.0
    74	geometry_max 200.0
    75	geometry_quant 1.0
    76	
    77	# Top-left x position (mm)
    78	tl_x 0.0
    79	
    80	# Top-left y position (mm)
    81	tl_y 0.0
    82	
    83	# Bottom-right x position (mm)
    84	br_x 80.0
    85	
    86	# Bottom-right y position (mm)
    87	br_y 100.0

核心参数速查:

参数默认值说明
number_of_devices2虚拟设备数量,产生 test:0 ~ test:N-1
modeGray初始扫描模式(Color / Gray)
depth8位深 1/8/16
resolution(含 min/max/quant)50.0(1~1200)分辨率范围与初始值,单位 dpi
test-pictureSolid black出图内容:Solid black / Solid white / Color pattern / Grid
read-status-codeDefault注入 sane_read() 返回值,模拟卡纸(JAMMED)、舱盖打开(COVER_OPEN)等错误
read-limit / read-limit-sizefalse / 1限制单次 read 返回字节数,模拟低速传输
read-delay / read-delay-durationfalse / 1000每次 read 延迟 N 微秒,模拟慢速设备
hand-scanner / three-passfalse手持扫描仪模式 / 三次扫描分色模式
geometry(min/max/quant)+ tl_x/tl_y/br_x/br_y0~200mm,幅面 80×100mm扫描幅面几何
enable-test-optionsfalse追加一组仅用于测试前端行为的合成选项
fuzzy-parameters / ppl-loss / non-blocking / select-fdfalse / 0 / false / false前端健壮性测试项

参数修改实测(完整链路,见 3.4 节):将第 5 行 number_of_devices 2 改为 3,客户端通过网络立即看到 test:0/1/2 三个设备;恢复为 2 后客户端重新只看到两个设备。注意 number_of_devices 只影响设备数量,不影响每个设备的功能选项。

与命令行参数的关系:scanimage 可用 --test-picture、--read-return-value 等运行时选项临时覆盖 test.conf 的初值(详见《SANE 1.2.1 常用 CLI 命令与工具详解》),test.conf 保存的是"每次打开设备时的初始值"。

5.3 net.conf —— net 网络后端(客户端)

net.conf 是客户端文件:列出要连接的 saned 服务器。全文实测(cat -n /etc/sane.d/net.conf,14 行,发行版原状):

     1	# This is the net backend config file.
     2	
     3	## net backend options
     4	# Timeout for the initial connection to saned. This will prevent the backend
     5	# from blocking for several minutes trying to connect to an unresponsive
     6	# saned host (network outage, host down, ...). Value in seconds.
     7	# connect_timeout = 60
     8	
     9	## saned hosts
    10	# Each line names a host to attach to.
    11	# If you list "localhost" then your backends can be accessed either
    12	# directly or through the net backend.  Going through the net backend
    13	# may be necessary to access devices that need special privileges.
    14	# localhost

参数说明:

参数默认说明
connect_timeout60(注释示例值;未设置时 net 后端使用内置超时)初次连接 saned 的超时秒数,防止对宕机主机长时间阻塞
服务器行无每行一个主机名或 IP;写 localhost 可把本机后端也经 net 通道暴露

实验环境实际配置(去掉注释后 grep -v "^#" 过滤实测):

connect_timeout = 60
10.89.68.10

两个实测结论:

① 不可达主机静默跳过。 向 net.conf 加入一个网内不存在的主机 10.89.68.99(并设 connect_timeout = 3 加速失败),scanimage -L 实测回显:

device `net:10.89.68.10:test:0' is a Noname frontend-tester virtual device
device `net:10.89.68.10:test:1' is a Noname frontend-tester virtual device

命令退出码为 0。不可达主机在设备发现阶段被静默跳过,不产生任何报错输出,也不影响其他主机的设备发现——排障时不能依赖 scanimage -L 的报错来发现"某台服务器配错了 IP",需要对照 net.conf 与实际可达主机列表。

② 配置语法失效无提示。 net.conf 对格式宽容,但没有配置校验工具;若怀疑配置未被读取,用 SANE_DEBUG_NET=13 scanimage -L 观察 net 后端日志(调试变量机制见 3.3 节)。

5.4 saned.conf —— saned 服务访问控制

saned.conf 是服务端文件:控制哪些客户端允许连接本机的 saned。全文实测(cat -n /etc/sane.d/saned.conf,前 31 行为发行版原状,第 33~34 行为本实验追加的白名单):

     1	# saned.conf
     2	# Configuration for the saned daemon
     3	
     4	## Daemon options
     5	# Port range for the data connection. Choose a range inside [1024 - 65535].
     6	# Avoid specifying too large a range, for performance reasons.
     7	#
     8	# ONLY use this if your saned server is sitting behind a firewall. If your
     9	# firewall is a Linux machine, we strongly recommend using the
    10	# Netfilter nf_conntrack_sane connection tracking module instead.
    11	#
    12	# data_portrange = 10000 - 10100
    13	
    14	
    15	## Access list
    16	# A list of host names, IP addresses or IP subnets (CIDR notation) that
    17	# are permitted to use local SANE devices. IPv6 addresses must be enclosed
    18	# in brackets, and should always be specified in their compressed form.
    19	#
    20	# The hostname matching is not case-sensitive.
    21	
    22	#scan-client.somedomain.firm
    23	#192.168.0.1
    24	#192.168.0.1/29
    25	#[2001:db8:185e::42:12]
    26	#[2001:db8:185e::42:12]/64
    27	
    28	# NOTE: /etc/inetd.conf (or /etc/xinetd.conf) and
    29	# /etc/services must also be properly configured to start
    30	# the saned daemon as documented in saned(8), services(4)
    31	# and inetd.conf(4) (or xinetd.conf(5)).
    32	
    33	## Lab: allow LAN clients
    34	10.89.68.0/24

参数说明:

参数默认说明
data_portrange未设置数据连接端口范围(1024~65535)。仅 saned 位于防火墙后需固定数据端口时设置;官方更推荐 Linux 网关用 nf_conntrack_sane 连接跟踪模块
访问列表(每行一条)空允许的主机名 / IP / CIDR 子网;IPv6 需方括号包裹并写成压缩形式;主机名匹配不区分大小写

访问列表的关键行为(本实验已完整验证,含正反用例):

  • 白名单命中(客户端 10.89.68.x 连接)→ 正常发现与扫描;
  • 白名单未命中的主机连接时,客户端侧报错、服务端 journalctl 记录拒绝日志(实测):
init: access by host 10.89.68.99 denied

(完整拒绝场景的客户端报错与服务端日志取证,见《Ubuntu 24.04 安装 SANE 1.2.1 指南》第十一章。)

修改即时生效:saned.socket 模式下每连接新起进程,编辑 saned.conf 后下一个连接即按新白名单判定,无需重启服务。

5.5 saned.socket 与 saned@.service —— systemd 托管参数

Ubuntu 24.04 的 sane-utils 包自带 systemd socket 激活模板。两份单元文件全文实测(systemctl cat):

/usr/lib/systemd/system/saned.socket:

[Unit]
Description=saned incoming socket

[Socket]
ListenStream=6566
Accept=yes
MaxConnections=64

[Install]
WantedBy=sockets.target

/usr/lib/systemd/system/saned@.service:

[Unit]
Description=Scanner Service
Requires=saned.socket

[Service]
ExecStart=/usr/sbin/saned
User=saned
Group=saned
StandardInput=null
StandardOutput=append:/var/log/saned.log
StandardError=append:/var/log/saned.log
Environment=SANE_CONFIG_DIR=/etc/sane.d
# Environment=SANE_CONFIG_DIR=/etc/sane.d SANE_DEBUG_DLL=255

[Install]
Also=saned.socket

逐项解读:

文件参数值说明
saned.socketListenStream6566监听端口,对应 /etc/services 第 336 行注册的 sane-port:336:sane-port 6566/tcp sane saned # SANE network scanner daemon
saned.socketAcceptyes每个连接派生一个 saned@<连接标识>.service 实例,天然隔离、配置即时生效
saned.socketMaxConnections64并发连接上限,超出的连接被内核拒绝(排队数由内核 backlog 决定)
saned@.serviceUser/Groupsaned服务以专用低权限用户运行(该账号由 sane-utils 预建,见 5.7 节)
saned@.serviceStandardOutput/Errorappend:/var/log/saned.log实例日志追加写该文件;正常运行时几乎无输出,文件为空不代表异常
saned@.serviceEnvironmentSANE_CONFIG_DIR=/etc/sane.d固定配置目录;注释行示例展示了叠加 SANE_DEBUG_DLL=255 打开全量调试

常用修改操作(改完单元必须重载):

systemctl daemon-reload
systemctl restart saned.socket
systemctl show saned.socket -p MaxConnections   # 核对生效值

端口与并发的生产建议见第六章模板。

5.6 dll.d/ 与 airscan.conf —— 第三方后端扩展

/etc/sane.d/dll.d/ 是发行版约定的第三方后端挂载目录(dll.conf 第 3~5 行注释说明了该机制):包管理器把"一行后端名"的片段放进这里,升级/卸载时自动增删,不污染用户手工维护的 dll.conf。实测内容:

$ ls /etc/sane.d/dll.d/
airscan
$ cat /etc/sane.d/dll.d/airscan
# sane-dll entry for sane-airscan
airscan

3.3 节的调试日志实证了加载顺序:dll 加载器先读 dll.d/ 下所有片段,再读 dll.conf(日志中 add_backend: adding backend 'airscan' 出现在读取 dll.conf 之前)。

sane-airscan(0.99.29)的主配置为 /etc/sane.d/airscan.conf(3328 字节),分三段(实测节选):

# sane-airscan example configuration file

# You can add scanners manually, using the following syntax:
# [devices]
#   name1 = url1           ; add eSCL device
#   name2 = url2, protocol ; protocol can be escl or wsd
#   name2 = disable        ; disable the device
...
[devices]
#"Kyocera MFP Scanner" = http://192.168.1.102:9095/eSCL
#"Some Unwanted Scanner" = disable

# Various options
#
# Automatic discovery may be enabled (the default) or disabled:
#   discovery = enable  ; Enable automatic device discovery
#   discovery = disable ; Disable both DNS-SD and WS-Discovery
#
# Protocol choice (eSCL vs WSD if both are available)
#   protocol = auto     ; Best protocol is chosen automatically, the default
#   protocol = manual   ; Manual choice is offered
...
[options]
#discovery = enable
#model = network
...
[blacklist]
#model = "Xerox*"       ; blacklist by model name
#name  = "HP*"          ; blacklist by network name
#ip    = 192.168.0.1    ; blacklist by address
#ip    = 192.168.0.0/24 ; blacklist the whole subnet

三段结构:[devices] 手工登记 eSCL/WSD 设备 URL(或 disable 屏蔽某台);[options] 控制自动发现(discovery)、协议择优(protocol)等;[blacklist] 按型号/网络名/IP 屏蔽自动发现的设备。实验环境无 eSCL 设备,airscan-discover 实测 [devices] 段为空,此处仅作参数面参考。

5.7 设备权限:udev 规则与用户组

Ubuntu 打包通过 udev 规则与预建账号解决扫描设备的访问权限,实测要素:

udev 规则文件(ls /lib/udev/rules.d/ | grep -i sane 实测):

60-libsane1.rules
99-libsane1.rules

60 号规则在设备插入时为扫描仪设备节点打标并授权特定组访问,99 号规则补充 ALSA/USB 权限场景;两份规则由 libsane1 包安装,包安装/升级后若设备节点权限未刷新,插拔 USB 线或重新触发 udev 即可。

预建账号与组(grep -E "saned|scanner" /etc/passwd /etc/group 实测):

/etc/passwd:saned:x:102:105::/var/lib/saned:/usr/sbin/nologin
/etc/group:scanner:x:104:saned
/etc/group:saned:x:105:

解读:

  • saned 系统用户:shell 为 /usr/sbin/nologin、家目录 /var/lib/saned,专供 saned@.service 降权运行;
  • scanner 组(gid 104)已包含 saned 用户:凡是需要被 saned 网络共享的本机设备,其设备节点必须允许 scanner 组读写——这正是 60-libsane1.rules 的授权目标组;
  • 若手工接入的扫描仪节点未自动授权,可将节点 chgrp scanner 并 chmod g+rw,或补一条自定义 udev 规则。

六、生产配置模板

以下模板给出三类典型场景的最小可用配置。模板中带 * 的行为本实验已实测验证;USB 硬件相关项在无硬件的实验环境中未逐项验证,依据对应 man 手册整理,落地时请以 man 5 sane-<后端名> 为准。

6.1 场景 A:局域网网络扫描服务器(已实测)

适用:1 台 Ubuntu 24.04 服务器(2GB 内存、20GB 磁盘起,无高性能要求——扫描 I/O 由客户端拉取),接 USB 扫描仪,向局域网提供共享扫描。

# 1. 白名单:只放行本网段(按实际网段修改)
cat >> /etc/sane.d/saned.conf <<'EOF'
10.89.68.0/24
EOF

# 2. 启用承载真实设备的后端(例:爱普生用 epson2,佳能用 pixma)
sed -i 's/^#test$/test/' /etc/sane.d/dll.conf   # 无硬件验证期可先用 test 后端

# 3. 启动 socket 托管(每连接一进程,配置热生效)
systemctl enable --now saned.socket
systemctl status saned.socket --no-pager

# 4. 验证监听
ss -ltn | grep 6566

要点:不要开放 0.0.0.0/0 白名单;跨网段/有防火墙的环境先评估 data_portrange 或在网关加载 nf_conntrack_sane。

6.2 场景 B:网络扫描客户端(已实测)

适用:任意 Ubuntu 24.04 主机,需要使用场景 A 服务器的扫描仪。

# 1. 确认 net 后端启用(Ubuntu 默认启用)
grep -n '^net$' /etc/sane.d/dll.conf

# 2. 登记服务器;多台每行一个;网络不稳可调小 connect_timeout
cat >> /etc/sane.d/net.conf <<'EOF'
connect_timeout = 5
10.89.68.10
EOF

# 3. 验证(设备名格式:net:<服务器>:<设备>)
scanimage -L

已实测的行为特性:列表中不可达的服务器会被静默跳过(见 5.3 节),多服务器环境下建议保留一台"探活基准"主机以确认 net 通道本身可用。

6.3 场景 C:单机 USB 扫描仪(未实测硬件,按 man 整理)

适用:单机直连 USB 扫描仪、不对外共享。核心是把当前用户加入 scanner 组并确认对应硬件后端启用:

usermod -aG scanner <你的用户名>          # 重新登录生效
scanimage -L                              # 确认设备出现
sane-find-scanner -q                      # USB 层确认枚举(不依赖后端)

若 scanimage -L 看不到而 sane-find-scanner 能看到,通常是后端未覆盖该型号或 dll.conf 未启用对应后端,对照 man -k sane- | grep <品牌> 查后端名。

七、常见问题

Q1:改了 dll.conf / test.conf / saned.conf 需要重启 saned 吗? 不需要。saned.socket(Accept=yes)为每个连接新起进程读取最新配置(3.4 节双向实测:改 number_of_devices 3→2,客户端两次发现即时跟随)。只有修改 systemd 单元文件本身才需要 daemon-reload 并 restart saned.socket。

Q2:客户端 scanimage -L 看不到网络设备? 按链路排查:① dll.conf 中 net 行被注释(Ubuntu 默认启用,确认未被改掉);② net.conf 没写服务器 IP 或写错(注意不可达主机静默跳过,见 5.3 节);③ 服务端 saned.conf 白名单未放行客户端 IP——服务端 journalctl 会出现 init: access by host <IP> denied;④ 服务端 saned.socket 未启用(systemctl status saned.socket)。

Q3:/var/log/saned.log 是空的,服务正常吗? 正常。saned@.service 把 stdout/stderr 追加到该文件,但连接级事件(谁连了、扫了什么)走 journald:用 journalctl -t saned 或 journalctl -u 'saned@*' 查看。实验中该文件确为 0 字节而服务完全可用。

Q4:想知道某个后端有哪些配置参数? 直接查手册:man 5 sane-<后端名>(如 man 5 sane-test、man 5 sane-net、man 5 sane-dll)。手册页由 libsane-common 提供,后端名与 /etc/sane.d/<后端名>.conf 一一对应(3.1 节实测清单)。

Q5:怀疑配置没被读取,如何取证? 用调试环境变量看加载过程:SANE_DEBUG_DLL=5 scanimage -L(可确认 dll.conf/dll.d 被逐行读取、后端逐一 add_backend,见 3.3 节实测回显);针对单个后端再叠加 SANE_DEBUG_<后端名>=13。日志时间戳与 add_backend/read_config 行可直接定位配置解析问题。

八、参考链接