Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> программы —> Scan+Print server FreeBSD 9

Scan+Print server FreeBSD 9 для Canon PIXMA MP540

Автор: zentarim.


Несколько лет назад я писал статью про создание роутера с функционалом аналогичным обычному домашнему роутеру:
http://www.lissyara.su/articles/freebsd/tuning/wifi_router/
Прошло время, сдохла старая материнка, да и Wi-fi мне перестал быть нужным. На земену ей была куплена подходящая мне по всем параметрам материнка:Intel 2500CC
На ней также был поднят роутер. Но одна недоработка все это время меня немного напрягала. Эта недоработка заключалась в том, что моя МФУшка Canon PIXMA MP540 была подключена к моей машине. Соответственно все, кому нужно было что-нибудь отсканировать, прибегали ко мне...
К тому же моя машина работает под linux, а второй домашний компьютер работает под Windows 7. Поэтому принтер был расшарен через Samba и периодически отваливался (Да, у меня кривые руки и я не могу настроить Самбу нормально :) ) В любом случае сложившаяся ситуация меня не устраивала и наконец-то у меня дошли руки ее исправить. В процессе установки открылись некоторые особенности настройки, которые я решил для себя задокументировать. Заодно и решил статью набросать.
Что было решено сделать:
1) Подключить МФУ к FreeBSD роутеру через USB
2) Расшарить принтер при помощи CUPS и печатать при помощи кроссплатформенного протокола IPP (Краткое описание протокола в Википедии)
3) Дать доступ к сканеру через браузер (сначала была идея расшарить сканер при помощи встроенных сетевых средств sane, но потом я решил, что через веб-морду будет удобнее).

Приступаем. Предполагаем, что внутренняя подсеть 192.168.0.0/24, а шлюз с фряхой - 192.168.0.1
По устройствам в ядре точно сказать не могу, но думаю, что понадобятся такие:
   device      usb       # USB Bus (required)
   device      ulpt      # Printer

   # Эти устройства вам нужны, если вы собираетесь пользоваться встроенным 
   # в МФУ кардридером
   device      scbus      # SCSI bus (required for ATA/SCSI)
   device      da         # Direct Access (disks)
   device      umass      # Disks/Mass storage - Requires scbus and da

Подключаем принтер по USB и смотрим как определился:
   # dmesg | grep -i canon
    # Как выяснилось позднее - это устройство сканера
   ugen4.5: <Canon> at usbus4
    # Это устройство принтера
   ulpt0: <Canon MP540 series, class 0/0, rev 2.00/1.02, addr 5> on usbus4   
    # Устройство встроенного в MP540 кардидера
   umass3: <Canon MP540 series, class 0/0, rev 2.00/1.02, addr 5> on usbus4   
    # Этот диск монтируется при подключении карты к кардридеру
   da3: <Canon MP540 series 0102> Removable Direct Access SCSI-2 device 

Все определилось корректно. Для подключения принтера ставим следующие пакеты:
1) CUPS (Common Unix Printing System) - Сам сервер печати
   # cd /usr/ports/print/cups-base/ && make install clean

2) Gutenrint-base (High quality drivers for Canon, Epson, Lexmark, and PCL printers for use with Ghostscript, CUPS, Foomatic, and the Gimp). Драйвера для MP540 я нашел в этом пакете.
Предупреждение: сборка этого порта тянет за собой чертову кучу графбиблиотек, поэтому будьте готовы к долгому процессу сборки. Также при сборке этого пакета будут подтянуты библиотеки pango и cairo (Внимание: ОБЯЗАТЕЛЬНО соберите их с поддержкой X11, иначе устанавливаемые в дальнейшем пакеты будут ругаться на ее отсутствие у этих библиотек)
   # cd /usr/ports/print/gutenprint-base/ && make install clean

Приводим конфиг CUPS (/usr/local/etc/cups/cupsd.conf) к такому виду:
# Важный момент: Без директивы ServerName вы, скорее всего, не сможете печатать
# с других компьютеров, а по умолчанию она не прописана.
# Она отвечает за то, с каким именем хоста принимать запросы от клиентов.
# Когда директива не прописана - в качестве имени хоста используется имя машины
# Сюда лучше вписать IP адрес, на котором будет слушать CUPS
# Симптомы: Работает печать с локальной машины, работает тестовая печать, 
# но не работает печать с других компов.
# Отдельные люди на форумах советуют при этом патчить файл hosts на клиенте.
# Не поддавайтесь на провокации, все можно сделать гораздо проще и правильнее
ServerName 192.168.0.1

# Группа, с правами которой запускается CUPS
SystemGroup wheel

# Определяет, на каком IP адресе и порту будет слушать CUPS
# По умолчанию стоит localhost:631, 
# т.е. доступ будет только с локальной машины.
Listen 192.168.0.1:631
Listen /var/run/cups.sock

# Уровень логирования.
# Мне так и не потребовалось включать более подробный уровень.
LogLevel error

# Обнаружение принтера мне нафиг не нужно, поэтому отключаю.
Browsing Off

# По умолчанию включаем авторизацию (используются системные пользователи UNIX)
DefaultAuthType Basic

# Включаем доступ к веб-морде как таковой
WebInterface Yes

<Location />
   # За доступ к печати и принтерам отвечает этот подраздел конфига.
   # Я разрешаю доступ к нему без аутентификации и только из локальной сети.
  AuthType None 
  Order allow,deny
  Allow 192.168.0.0/24 
</Location>

<Location /admin>
   # Доступ к администрированию принтеров.
   # Тут уже кому попало и что попало менять нельзя.
   # Поэтому тут уже аутентификация (определено директивой DefaultAuthType)
   # и доступ только из локальной сети.
  AuthType Default
  Order allow,deny
  Allow 192.168.0.0/24 
</Location>
<Location /admin/conf>
   # Непонятно, за что отвечает этот раздел. 
   # Сделал такой же доступ как к администрированию.
  AuthType Default
  Order allow,deny
Allow 192.168.0.0/24
</Location>
   # Далее идут всевозможные разграничения, кому и что можно делать. 
   # Меня вполне устраивают стандартные.
<Policy default>
  JobPrivateAccess default
  JobPrivateValues default
  SubscriptionPrivateAccess default
  SubscriptionPrivateValues default
  <Limit Create-Job Print-Job Print-URI Validate-Job>
    Order deny,allow
  </Limit>
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job
 Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription 
Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job 
Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job 
CUPS-Move-Job
 CUPS-Get-Document>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class
 CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer
 Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs 
Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer 
Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs 
CUPS-Accept-Jobs CUPS-Reject-Jobs>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Cancel-Job CUPS-Authenticate-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit All>
    Order deny,allow
  </Limit>
</Policy>
<Policy authenticated>
  JobPrivateAccess default
  JobPrivateValues default
  SubscriptionPrivateAccess default
  SubscriptionPrivateValues default
  <Limit Create-Job Print-Job Print-URI Validate-Job>
    AuthType Default
    Order deny,allow
  </Limit>
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs
 Set-Job-Attributes Create-Job-Subscription Renew-Subscription 
Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job
 Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job
 CUPS-Get-Document>
    AuthType Default
    Order deny,allow
  </Limit>
</Policy>
BrowseWebIF Yes

Во время работы CUPS мне приходилось наблюдать в логе ошибок cups /var/log/cups/error_log подобные сообщения:
E [10/Aug/2013:22:56:31 +0400] [CGI] Saw EOF, expected '}'!
E [10/Aug/2013:22:56:43 +0400] [CGI] Saw EOF, expected '}'!
E [10/Aug/2013:22:56:43 +0400] [CGI] Saw EOF, expected '}'!
E [10/Aug/2013:22:57:39 +0400] [CGI] Saw EOF, expected '}'!
E [15/Aug/2013:08:25:13 +0400] [CGI] Saw EOF, expected '}'!

Эта ошибка давно описана на дебиановском багтрекере. Ее причина - отсутствие закрывающих фигурных скобок в русских CGI файлах. Ну что же, раз не исправили разработчики, то придется нам:
Добавляем закрывающую фигурную скобку перед закрывающим тегом </P> в файле /usr/local/share/cups/templates/ru/classes-header.tmpl:
строку
<P ALIGN="CENTER">{total=0?Нет групп:Группа {#printer_name} из {total}.</P>

меняем на
<P ALIGN="CENTER">{total=0?Нет групп:Группа {#printer_name} из {total}.}</P>

Добавляем закрывающую фигурную скобку перед закрывающим тегом </P> в файле /usr/local/share/cups/templates/ru/jobs-header.tmpl:
строку
<P ALIGN="CENTER">{total=0?Нет заданий:Задание {#job_id} из {total}
{?which_jobs=?активных:{which_jobs=all?:завершенных}}.</P>

меняем на
<P ALIGN="CENTER">{total=0?Нет заданий:Задание {#job_id} из {total}
{?which_jobs=?активных:{which_jobs=all?:завершенных}}.}</P>

Добавляем закрывающую фигурную скобку перед закрывающим тегом </P> в файле /usr/local/share/cups/templates/ru/printers-header.tmpl:
строку
<P ALIGN="CENTER">{total=0?Нет принтеров:Принтер {#printer_name} из
 {total}.</P>

меняем на
<P ALIGN="CENTER">{total=0?Нет принтеров:Принтер {#printer_name} из
 {total}.}</P>

Все, эта назойливая ошибка теперь не будет мозолить глаза
Включаем CUPSD в /etc/rc.conf:
   # echo 'cupsd_enable="YES"' >> /etc/rc.conf

Стартуем CUPSD:
   # /usr/local/etc/rc.d/cupsd restart

Проверяем, запустился ли CUPS:
   # sockstat -l | grep cups
   root     cupsd      3047  7  tcp4   192.168.0.1:631      *:*
   root     cupsd      3047  8  stream /var/run/cups.sock

Все запустилось, теперь надо настроить принтер. Идем на веб-интерфейс:
https://192.168.0.1:631/admin
Тут вас спросят пароль от root. Внимание: после ручной правки конфига cups большинство "галочек" в веб-морде показывают хрен пойми чего. Поэтому не очень-то им доверяйте
Нажимаем кнопку "Добавить принтер":


Ага, принтер определился, но почему-то в двух ипостасях. Выбираем первую:


Даем принтеру имя. Внимание: это имя будет использоваться при обращении к принтеру из клиента печати!
Поэтому для удобства даем ему достаточно короткое и простое имя в латинской раскладке. Обращаем внимание на строку "Подключение" и ее значение "usb:/dev/ulpt0"
/dev/ulpt0 - это и есть устройство принтера. Разумеется, включаем общий доступ к принтеру.


В этом окне выбираем драйвер принтера (Производитель Canon, модель MP540). так как я без понятия - какой из драйверов мне надо, то выбираем тот, где есть подпись "ru":



Здесь оставляем все как есть, кроме пункта "Источник носителя". Его принудительно выставляем в значение "Cassette", так как по умолчанию принтер пытается найти бумагу в заднем лотке.


Все, принтер настроен:


Конфигурации всех принтеров будут храниться в /usr/local/etc/cups/printers.conf. После добавления принтера он будет выглядить подобным образом:
# Printer configuration file for CUPS v1.5.4
# Written by cupsd on
# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING
<Printer Canon>
UUID urn:uuid:127948e7-0ba2-311b-6e44-1b2c87d04d7a
Info Canon MP540 series
Location GATE
MakeModel Canon PIXMA MP540 - CUPS+Gutenprint v5.2.8
DeviceURI usb:/dev/ulpt0
State Idle
StateTime 1376160812
Type 36876
Accepting Yes
Shared Yes
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy stop-printer
</Printer>

Хоть CUPS хоть и запускается с правами root, но печатать будет только на устройства, принадлежащие системной группе "cups". Почему так происходит - я, к сожалению, не знаю.
Нам надо "инструктировать" devfs, чтобы она назначала определенные права устройству "/dev/ulpt0". Есть два способа это сделать:
1) При помощи файла /etc/devfs.rules и /etc/rc.conf . Приводим /etc/devfs.rules к такому виду:
   [operator=5]
   add path ulpt0 mode 0660 group cups

В /etc/rc.conf добавляем строку:
   devfs_system_ruleset="operator"

Перезапускаем devfs:
   # /etc/rc.d/devfs restart

Проверяем, подхватились ли правила:
   # devfs rule show
   100 path ulpt0 group cups mode 660

2) При помощи записей в /etc/devfs.conf. За этот способ отдельное спасибо пользователю USSR.
Дописываем в файл строки:
   # printer
   own     ulpt0   root:cups
   perm    ulpt0   0660

В любом случае теперь при перезагрузке системы или включении/отключении принтера у него сразу будут правильные права.Однако сейчас они не применятся, поэтому выдаем права принтеру вручную:
   # chown root:cups /dev/ulpt0

Проверяем, есть ли права на запись в устройство у группы "cups":
   # ls -la /dev/ulpt0 
   crw-rw----  1 root  cups    0, 137 10 авг 23:02 /dev/ulpt0

Все нормально, можно печатать. Пускаем на принтер пробную страницу из веб-интерфейса и, если все в порядке, идем настраивать клиенты печати.
Ниже привожу примеры настройки и скриншоты клиентов печати Windows 7 и Ubuntu (KDE):
1) Ubuntu (KDE)


2) Windows 7
Выбираем сетевой тип принтера:


Не дожидаясь окончания поиска тыкаем в "Нужный принтер отсутствует в списке":


Вручную вбиваем адрес принтера:


Выбираем драйвер принтера (ВНИМАНИЕ: У меня драйвер уже был установлен! Вам, вероятнее всего, придется выбрать расположение драйвера руками. Как это сделать я расписывать не буду.


С принтером все. Пускаем на него тестовые страницы и радуемся, если все работает. Если нет - то обращаемся к error_log cups.


Предположим, что принтер настроен и печать работает. Теперь настраиваем сканер и веб-интерфейс к нему.
Устанавливаем пакеты:
1) sane-backends (Собственно сам пакет sane и утилиты для работы со сканером из командой строки)
# cd /usr/ports/graphics/sane-backends && make install clean

2) sane-frontends (Еще какое-то барахло для работы со сканером. Было указано в инструкции к веб-морде)
# cd /usr/ports/graphics/sane-frontends && make install clean

3) ImageMagick-nox11 (различные утилиты для конвертаций графических форматов, в том числе и утилита convert который непосредственно используется в веб-морде. nox11 для того - чтобы не притащило за собой иксы)
# cd /usr/ports/graphics/ImageMagick-nox11 && make install clean

Вот далее я точно не помню, но что-то требовалось еще доустанавливать... В общем если по каким-то причинам не захочет сканировать - попробуйте проверить лог ошибок веб-сервера. Там будет ругань на то, чего не хватает.
Если наткнетесь - пожалуйста напишите в обсуждение и я добавлю информацию в статью.
В качестве веб-морды я использую phpsane, так как он достаточно прост в настройке и освоении. Однако для его работы необходим веб-сервер и установленный php. Лично я использую lighttpd+php53( сначала я пытался использовать yaws, однако там были косяки с скачиванием файлов, поэтому я вернулся к lighttpd). Поскольку настройка и установка php и lighttpd неоднократно рассматривалась и обсасывалась, я только распишу моменты, в которых могут возникнуть вопросы:
- создатель phpsane обозвал главную страницу "phpsane.php", а не index.php. Я хотел обращаться к веб-серверу без принудительного указания страницы,
поэтому в конфиг lighttpd я добавил такую строку:
index-file.names += ( "phpsane.php" )

Разумеется, можно переименовать сам phpsane.php в index.php, а также поменять все ссылки на него во всех остальных файлах... Но мне было просто лениво.
Я повесил веб-сервер на порт 8800 и запустил его:
Код:
# sockstat -l
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
www      lighttpd   10479 4  tcp4   192.168.0.1:8800     *:*

Веб-сервер работает. Теперь надо установить собственно веб-морду к сканеру. Скачиваем последнюю версию phpsane со странички
http://sourceforge.net/projects/phpsane/
Внутри архива находится папка, к которой надо предоставить доступ веб-серверу. Если вы все запустили правильно, то при заходе на веб-интерфейс у вас будет отображаться что-то вроде:


Однако это еще не все, ведь сервер работает с правами пользователя www, у которого нет прав на чтение со сканера! Для этого добавляем пользователя www во встроенную группу "operator":
   # pw groupmod operator -m www

Пробуем найти наш сканер:
   # sane-find-scanner -q
found USB scanner (vendor=0x04a9 [Canon], product=0x1730 [MP540 series]) at
 libusb:/dev/usb:/dev/ugen4.5

Сканер нашелся. Ключевое устройство - /dev/ugen4.5. Однако это устройство является ссылкой на "/dev/usb/4.5.0":
   # ls -la /dev/ugen4.5
   lrw-rw----  1 root  wheel  9  9 авг 23:20 /dev/ugen4.5 -> usb/4.5.0

Надо установить права для самого устройства. Я раньше считал, что также нужно установить права и для ссылки, но выяснилось, что это необязательно. Устанавливаем права устройству мы снова при помощи devfs одним из двух способов:
1) Добавляя строки в /etc/devfs.rules:

   # это добавлено для сканера
   add path usb/4.5.0 mode 0660 group operator 
   # это было ранее добавлено для принтера
   add path ulpt0 mode 0660 group cups

Как видно - мы в одном профиле устанавливаем права как для устройства принтера, так и для устройства сканера.

2) Добавляя строки в /etc/devfs.conf:
   # scanner это добавлено для сканера
   own     usb/4.5.0 root:operator
   perm    usb/4.5.0 0660
   # printer это было ранее добавлено для принтера
   own     ulpt0   root:cups
   perm    ulpt0   0660

Устанавливаем права для устройства сканера вручную (либо просто перезагружаемся):
   # chown root:operator /dev/usb/4.5.0
   # chmod 0660 /dev/usb/4.5.0

Проверяем, что получилось:
   # ls -la /dev/usb/4.5.0 
   crw-rw----  1 root  operator    0, 124 11 авг 00:10 /dev/usb/4.5.0

Теперь все в порядке, можно сканировать. Заходим на
http://192.168.0.1:8800
Выбираем нужные настройки, имя файла и т.д. и нажимаем кнопку "Сканировать". Если все сделано верно - под кнопками будут появляться ссылки на файлы сканов.
Если нет - ковыряем лог веб-сервера на предмет ошибок.[code]



размещено: 2013-08-20,
последнее обновление: 2013-11-22,
автор: zentarim


andryu, 2013-10-30 в 10:36:26

Первая статья на lissyara.su после почти двух лет затишья :)

USSR, 2013-11-06 в 18:19:33

Нашел еще один способ назначить права cups устройству /dev/ulpt0
место /etc/devfs.rules
ee /etc/devfs.conf
#Give cups printer access
own ulpt0 root:cups
perm ulpt0 0660

Zentarim, 2013-11-22 в 1:20:42

USSR, cпасибо вам. Указанный способ действительно работает. С вашего позволения добавляю в статью.

USSR, 2013-11-25 в 21:56:37

Конечно, я не против, но он стал у меня периодически не работать после перезагрузки, сильно долго не разбирался, вернулся к вашему способу, опять же это у меня тестовый сервак чего часто перегружаю, мало ли чего накрутил!

bammbr, 2014-12-22 в 8:21:18

> Разумеется, можно переименовать сам phpsane.php в index.php, а также поменять все ссылки на него во всех остальных файлах..

1) Можно было обойтись еще проще. Без правки конфигов.
ln -s phpsane.php index.php
2) В современных версиях phpSANE появился-таки index.html



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.1638 секунд
Из них PHP: 61%; SQL: 39%; Число SQL-запросов: 90 шт.
Исходный размер: 82394; Сжатая: 14769