Руководство по установке Hylafax

Trend, 23.05.2003, Linux.ru

Автор не претендует на полное описание возможностей системы hylafax (http://www.hylafax.org), как не претендует и на первенство такого описания. Я пользовался многими материалами в процессе установки и настройки этой системы, в частности это русскоязычные материалы (http://ldp.linux.by/linuxfocus/Russian/March2001/article196.shtml) и (http://linux.ru/docs/russian/hylafax/) за что большое спасибо тем кто потрудился и написал (или перевел) эти руководства, и англоязычными, это man и материалы с http://www.hylafax.org, но считает, что как человек, убивший много времени на настройку и подстройку системы к своим, достаточно плохим (в отличие от других авторов писавших по этому вопросу), условиям, имеет право, рассказать кое-что из своего опыта (надеясь что его не забросают помидорами и яйцами ;) ).

Итак, моя серверная операционная система - Red Hat 7.2.

Установка самого по себе hylafax, ничего сложного не представляет, обратить внимание надо лишь на то чтобы его версия была самой последней (поскольку в недавней была обнаружена возможность DoS атаки).

Вкратце:

Для самого hylafax необходимы следующие вещи, которые надо поставить перед этим либо просто убедиться в их наличии в системе:

Конфигурирование hylafax.

Модем уже должен быть корректно проинсталлирован в системе. Корректность его работы можно проверить с помощью wvdial или minicom.

Итак, к этому моменту, faxq (основной сервер) и hfaxd (управляет сетевыми соединениями), должны висеть в системе и отображаться по ps -e. Если это не так, то выполните /etc/rc.d/init.d/hylafax start (кстати, если вы потом посмотрите его состав, уясните несколько команд, которые могут потом помочь в дальнейшей работе).

Переходим к собственно настройке модема и сервера.

Выполним faxsetup. На этом этапе, думаю, ни у кого не возникнет вопросов. Далее faxaddmodem, нашел и оттестировал мой модем.

Теперь стандартно предлагается добавить в /etc/inittab строчку вида mo:2345:respawn:/usr/sbin/faxgetty tty*, для того чтобы faxgetty слушал указанный порт.

Разработчики hylafax заявляют, <что, мол, хорошо бы, чтобы этот сервис висел все время, в независимости от того, хотите ли вы принимать входящие факсы. Они говорят, что достаточно просто поставить RingsBeforeAnswer: 0, чтобы faxgetty не отвечал на входящие звонки. А этот сервис, мол, очень хорошая вещь, тестирует модем все время, проверяет, не появилось ли новых модемов, и говорит обо всем этом основному модулю программы>. Поскольку я и не хотел использовать модем на прием факсов, так как он находится на линии от офисной АТС, и нет возможности предоставить ему отдельный канал, да и есть уже в офисе факс с прямым каналом, то я так и сделал в файле config.tty* (RingsBeforeAnswer: 0).

Если у вас при работающим faxgetty появится ошибка вида <id "mo" respawning too fast: disabled for 5 minutes> (обычно нагло ;) выскакивает прямо на текущую консоль), значит модем вы настроили некорректно, или ошиблись в строке inittab, где прописывали faxgetty.

К этому моменту у нас уже должен был появиться файл вида /var/spool/hylafax/config.tty* (например, config.ttyS1, если модем привязан к COM2).

В нем могут потребоваться некоторые изменения. Например, я для своего модема (USR Sportster 33.6 INT), к стандартной конфигурации добавил:

Последняя строчка иногда необходима, когда после какой-либо комбинации цифр, нужно дождаться гудка, и только потом набирать остальной номер, а без паузы соединение сразу же обрывается.

Что касается ModemWaitTimeCmd, то это опять же специфика моего офиса, внутренний набор идет тоном, а АТС передает его на внешнюю линию уже пульсом, таким образом, модем уже ждет ответа, а номер все еще набирается. Там же можно поковыряться например с LocalIdentifier, это строка которая (в зависимости от настройки TagLineFormat) будет появляться в заголовке каждого отправленного факса (по умолчанию как раз появляется, так что не стоит там оставлять что-то типа ;) ).

Так же я перенастроил под себя файл, на который указывает параметр DialStringRules.

Оформил я его следующим образом:
WS="    ()"                                     ! our notion of white space
CanonicalNumber := [
#.*                     =                       ! strip calling card stuff
[^+0-9]+                =                       ! strip white space etc.
[-+]+                   = ,                     ! change on pause simbol
]
!
DialString := [
[${WS}]+                =                       ! strip syntactic sugar
[-+]+                   = ,                     ! change -,+ on pause simbol
]
Как можно видеть (по сравнению с etc/dialrules.europe), я убрал всяческие замены с подстановкой кодов, мне это просто не нужно, каждый в офисе пусть набирает то, что ему нужно, с кодом межгорода или без и т.д. Вставил только обрезание скобок (в переменной WS), и замену +/- на символ паузы. То есть, к примеру, введенный номер 8-095-1231231, будет передан модему как 8,095,1231231 (то есть набираться будет с паузами), что, в принципе, и требуется на некоторых линиях.

Итак, будем считать, что модем настроен, правила дозвона настроены.

В файл /var/spool/fax/etc/hosts.hfaxd надо добавить строки вида:
localhost
127.0.0.1
192.168.1
Думаю понятно, что такими действиями мы разрешили использование модема компьютерам с IP адресом 192.168.1.*. Надо проверить, чтобы этим файлом владел пользователь fax, и его permissions были 600.

Мне так же еще потребовались следующие настройки:

В директории /etc/hylafax находятся файлы hyla.conf и hfaxd.conf. Файл hyla.conf я не менял, хотя может кому-нибудь, понадобиться там что-нибудь изменить (в частности там есть параметр KillTime). А вот hfaxd.conf я поменял.

В частности раскомментарил параметры PriorityMap, RetryTimeMap и KillTimeMap, потому что в офисе телефонные линии довольно перегружены, и стандартный алгоритм посылки факсов встроенный в hylafax не подходит. Он так и может все 12 (по умолчанию) попыток прозвониться по занятой линии, и потом удалить задачу. Я просто увеличил время между повторами, и изменил список приоритетов.

Далее, опять же из-за не очень высокого качества, маленького количества и постоянной занятости исходящих офисных линий, мне пришлось еще немного поработать напильником ;)

Покопавшись по манам, я сделал в директории /etc/hylafax файл с названием sendfax.conf, в котором прописал следующие строки:
AutoCoverPage:  No
MaxDials:       50
MaxTries:       15
Первый параметр запрещает титульную страницу (критично к регистру, так что именно No, а не no). Второй параметр относится как раз к плохим линиям связи, то есть за дефолтовые 12 раз, можно просто не попасть на свободную линию ;) Ну и последний параметр, как описывается в man sendfax, это количество попыток успешного, но оборванного соединения, в то время как MaxDials это вообще максимальное количество звонков, в независимости от того было соединение или нет.

Кстати, с параметром MaxDials, надо быть поосторожнее, и четко понимать к чему это может привести. Представим себе на секунду, что мы ошиблись номером при отсылке факса. И наша ошибка такова, что такой номер есть, и он, к примеру, домашний ;) и более того, там берут трубку, но не факс, не модем, а человек ;) Так вот выполнение этих предположений приведет к тому, что бедному держателю этого номера, ваша программа позвонит 15 раз пока не успокоится ;), при этом каждый раз что-то пищща ему в ухо ;) Приятного мало ;) (именно поэтому по дефолту этот параметр равен 3).

Почесав в голове, и посмотрев на результаты тестирования, я понял, что при обработке напильником я малость схалявил ;).

Покопался еще в манах, и нашел еще один нужный мне и важный параметр. Называется он NoCarrierRetrys. Отвечает он за количество попыток перезвонить на тот же номер после получения NO CARRIER сообщения. У них в штатах ;), как пишется в мане, это означает, что с другой стороны факс отвергает прием, или просто не поднимает трубку, а у меня это означало лишь то, что модем не поймал обрыв связи или сигнал занятости (это не значит, что у меня не настроен модем, чтобы ловить BUSY -- это значит, что на наш BUSY, в нашей стране, а особенно с учетом настроек, как городских АТС, так и сторонних офисных -- не совсем прямыми руками, иной раз этот BUSY не поймаешь при всем желании ;) ).

Так вот я этот параметр прописал в config.tty* (только туда он и может быть прописан, как говорится only in per-device configuration files):
NoCarrierRetrys:        15
Во время всего тяжкого труда по настройке ;), а ведь многое что я написал я не нашел в русскоязычном виде, а только лишь перекопав около 100 страниц мануалов (целую папку распечаток собрал ;) ), я пользовался следующими командами:
sendfax -n -d    ..
просто посылаем факс(ы). -n -- это флаг означающий что передача должна идти без coverpage. Это на тот случай если вы еще не успели прописать AutoCoverPage: No ;)

Проверка статуса сервера осуществляется командами
faxstat -s (факсы ожидающие посылки)
faxstat -r (полученные факсы)
faxstat -d (факсы отправленные, а также не отправленные, из-за ошибок)
Удаление факса из очереди
faxrm job_number
Очистка спула (посланных факсов, и не посланных из-за ошибок)
faxqclean
Статистика
faxcron
По желанию, две последних команды, можно вставить в crontab. Точнее первая там точно нужна, важно лишь подобрать параметры запуска, чтобы когда к вам прибегут разъяренные пользователи и спросят почему факс не отправился, вы смогли посмотреть что же случилось, а не смотреть на любовно очищенную faxqclean директорию ;) Ну а вторую команду, разработчики советуют засунуть в крон таким образом, чтобы вся статистика отсылалась на FaxMaster email (пользователя FaxMaster, создает hylafax при инсталляции, впрочем, на самом деле там можно вставить что угодно, чтоб в лог писало, или на другой email отправляло, но я думаю это вы и сами сделаете). Так что сами решайте нужно это вам или нет.

Рабочие директории:
$FAX_DIR/docq/ -- сконвертированные в формат ps файлы
$FAX_DIR/doneq/ -- отработанные документы (посланные, и не посланные из-за ошибок)
$FAX_DIR/info/ -- информация о телефонах и параметры последнего сеанса связи
$FAX_DIR/log/ -- логи каждого их проведенных сеансрв связи с командами модему
$FAX_DIR/recvq/ -- получаемые факсы
$FAX_DIR/sendq/ -- факсы находящиеся в очереди
В этих директориях можно найти практически любую информацию, о том как факс отправлялся, сколько попыток было, из-за чего не проходили те или иные попытки, на какой скорости прошло соединение и т.д., и т.д. Их полезно чистить, и часто полезно вручную ;). Это довольно просто, надо просто стирать все файлы, кроме файла seqf, а его отредактировать и снова поставить цифру 1.

Все что написано ранее, по большому счету, это всего лишь предварительная настройка факс-сервера. При такой настройке, максимум, что возможно, это отослать факс командой sendfax.

Моя же задача была другой, дать возможность как минимум всем пользователям локальной сети отправлять факс через этот сервер с модемом, а как максимум, реализовать возможность отправки факса, откуда угодно, но естественно только <посвященным>.

Первая задача была решена довольно просто, как говорится не я первый, не я последний. Даже в русскоязычном Интернете ;) подробно расписано много возможностей, ну и чтобы не разрывать цельности статьи, я вкратце изложу одну из них (ту которую сам использовал) здесь, с копирайтом ;) и своими комментариями, полученными из опыта ;)

Так вот автором статьи является HackLinux, переводчиком на русский Кирилл Пухляков.

Вариант, который предлагает автор, состоит в следующем

Скачиваем архивы с программами respond (Win клиент), и printfax (это своеобразный сервер для *nix) с сайта http://www.boerde.de/~horstf

Оттуда надо скачать три файла:
    Respond.zip
    Printfax.pl
    Smb_conf.add
Скопируйте printfax.pl куда-нибудь (я, например, скопировал его в корень каталога hylafax, то есть в /var/spool/hylafax, чтобы у меня все лежало в одном месте), и слегка его отредактируйте для использования с hylafax (о том что perl не ниже версии 5.0 должен стоять и работать, я умалчиваю ;) ):
### Format of commandline
#    $cmdlinefmt='mgetty';
    $cmdlinefmt='hylafax';

### The faxspoolprogram
###   for mgetty+sendfax:
#    $faxspool = '/usr/bin/faxspool';
###   for hylafax:
    $faxspool = '/usr/bin/sendfax';

### Additional faxspool args (e.g. header, coverpage)
###   empty:
    @faxspool_args = qw(-n);
###   for mgetty+sendfax with a special header:
#   @faxspool_args = qw( -h /usr/local/etc/mgetty+sendfax/faxheader.smb);
###   for hylafax with send email when job is done or requeued and use
###   a4 sized paper:
#    @faxspool_args = qw(-D -R -s a4);
В самой программе комментариев достаточно чтобы самому понять, что где оставить, что где убрать. Мое добавление, как ярого противника ;) cover pages найти в программе (это практически в самом конце) вот такой участок кода (или похожий), либо редактировать задание массива @faxspool_args.
# Build faxspool arguments from above arguments, number and file
# --- Change this for other fax programs
if( $cmdlinefmt eq 'hylafax' ) {
  if ( $faxreceiver ) {
    # Add receivers name to faxspool arguments
    @faxargs = (@fixargs,"-d",$faxreceiver . '@'. $fnum,$faxfile);
  } else {
    @faxargs = (@fixargs,"-d",$fnum,$faxfile);
  }
и добавить -n перед -d ;) У меня это сделано даже несмотря на то что AutoCoverPage: No. И еще, в программе существует возможность оповещения пользователей через Службу сообщений. Понятно что для этого у пользователей которые будут использовать факс-сервер, она должна быть включена (для W2k и XP), и вы не должны менять в самом начале скрипта, где идут все настройки строку:
$smbclient = '/usr/bin/smbclient -U FAX';
Так вот текст присылаемых сообщений не совсем корректен, и я подправил код программы практически в самом конце:
&smbmessage("Fax $faxfname $msg_to $faxdest " );
заменил на:
&smbmessage("Fax $msg_to $faxdest ");
Таким образом осуществляется настройка скрипта. Теперь надо настроить самбу (кстати, никто еще не забыл ее обновить до 2.2.8a? ;) ).

В /etc/smb.conf (или где он у вас лежит) вставляем модуль smb_conf.add. А именно:
[fax]
    comment = Fax Printer
    public = yes
    printable = yes
    postscript = yes
    writeable = no
    print command = ( /var/spool/hylafax/printfax.pl %I %s %U %m; rm %s ) &
    path = /tmp
Все зависит от настроек самбы, если ей пользуются. У меня например там же еще стоят строчки:
    user = guest
    guest ok = true
Плюс, security = share, но прописаны hosts allow, и висит она только на одном из 4х интерфейсов. Т.о. я не имею геморроя, с самба паролями, прописываниями всех пользователей на серверной машине, но и с секъюрностью вроде все в порядке. Если я не прав, готов выслушать замечания по существу.

После изменения samba.conf перезапускаем самбу (/etc/init.d/smb restart), если кто не пользовался ею до этого времени -- прописывает ее в автостарт, и все, на этом настройка самбы закончена. Теперь с любого компьютера, прописанного в hosts allow в самбе, зайдя по нетбиос на сервер, мы должны видеть сетевой принтер с именем fax. Если это не так <читай Устав> (тобишь, для нас man).

Далее идет настройка этого <виртуального> принтера, на машинах, которым нужно использовать этот факс-сервер. Настройка осуществляется просто:

Файл respond.zip (который мы скачали чуть ранее), распаковывается в какой-нибудь каталог (например я делал стандартом c:Program FilesRespond). Далее делается ссылка на файл respond.exe в автостарт (естественно что для W2k, XP лучше это делать в All users, а для тех кто может понять ваши объяснения ;), кто будет нечасто пользоваться возможностью отсылки факсов, и кого будет раздражать постоянно висящая иконка в системтрее, просто ярлык на рабочий стол или куда захочет (с обязательным упоминанием что эта программа должна быть обязательно запущена ранее, чем попытка отправить факс таким образом)). Запустим программу. Проверим корректность ее установки запустив 'telnet localhost 5555', если окошко программы выскочило, с предложением набрать номер, то все хорошо, если нет - где-то скосячили. С помощью config.exe можно настроить параметры программы respond, какие поля отображать (правда все это имеет смысл только при включенном cover pages), например у меня в этом окошке показывается только поле для ввода номера факса.

Программу настроили.

Теперь необходимо настроить сетевой принтер:

Итак на локальной машине надо зайти в настройку принтеров и факсов. Далее установить новый принтер. Выбрать что это сетевой принтер, подключиться к сетевому принтеру \server-samba-ip(name)fax.

Замечу, что самба в этот момент должна быть включена и настроена ;). Должно выскочить окошко мастера установки драйвера для принтера. Выбираем HP LaserJet 4/4M PS (PostScript), и только его, это важно, не используем этот принтер по умолчанию. Тестовую страницу не печатаем. Теперь посмотрим в список принтеров, там уже должен появиться настроенный нами. Надо зайти в его свойства и указать, что печать начинается только после помещения в очередь всего задания. Для XP надо зайти Свойства -> Дополнительно и там выбрать <Начать печать после помещения в очередь всего задания>. Для Win98 Свойства -> Сведения -> Очередь, и тоже выбрать <Начать печать после помещения в очередь всего задания>.

Настройка завершена. Теперь в любом редакторе (Word & etc, на самом деле везде где можно печатать), можно послать документ по факсу. Для этого просто нужно <распечатать> его на принтере (\server-samba-ip(name)fax) который мы установили. Как только мы пошлем документ на печать, у нас выскочит окошко программы Respond с приглашением о вводе номера (если оно не появилось то надо поискать на таскбаре, может оно просто закрыто другими окнами). Вводим номер, нажимаем OK.

Все, документ ушел на факс (в случае если настроена служба сообщений, как на сервере, так и на клиенте, то еще и выскочит подтверждающее окошко).

Можно считать, что в случае использования факс-сервера только в локальной сети, на этом все можно завершить.

Жаль, что для меня на этом все не кончилось, а только началось ;)

Следующим требованием руководства было предоставление возможности отправления письма в определенном формате, на определенный email адрес, с аттачментом в виде документа Word, из любой точки земного шара ;) имея уверенность, что этот самый документ будет отправлен факсом по номеру указанному в письме ;).

Немного порывшись по Интернету (может слишком уж немного, но не судите меня строго), я понял, что всю эту функциональность придется писать самому. В результате был написан Perl скрипт, который проверяет определенный ящик (скрипт запускается по cron), вытаскивает из него все письма, проверяет их на соответствие настраиваемым параметрам, и, если все корректно, конвертирует документы *.doc программой antiword, и затем отправляет их с помощью sendfax.

Параметры находятся в начале скрипта. Про пути к директориям и программам я говорить не буду, это и так понятно. А так там только два параметра $MIN_TEL и $DEBUG. Первый это минимальный размер телефонного номера. Второй, если его установить в 1, не будет удалять временные директории и письма с ящика (на самом деле я его особо не тестил, так мне понадобилось один раз, вот я его и воткнул).

И в самом начале программы есть настройка почтового ящика, собственно с которого и собираются письма. Думаю там все понятно, IP-адрес, пользователь, пароль. В @FAX_MAIL перечислены все адреса которые соответствуют почтовому ящику факса (у меня их несколько), если у вас один просто оставьте одну строчку в скобках.

Итак, скрипт не только проверяет почту, отправляет на факс документы, он еще при каждом запуске, проверяет все документы которые он отправил, на предмет того ушли они, и если не ушли то почему, соответственно опять же отправляются письма вида: было столько-то звонков, а последнее состояние Busy signal detected, например, ну либо говорит что мол все благополучно ушло. Естественно подтверждается получение письма, конечно если оно составлено по правилам. А правила такие: в поле Subject письма пишем номер, безо всяких скобочек и буковок, и приаттачиваем к нему документы (можно несколько, но уйдут они все на один номер). Существует еще такая папочка strange (ее расположение задается в скрипте в начале). Ее цель собирать слегка некорректные письма:
    1. поле subject соответствует понятиям программы о правильном телефонном номере, но .doc файлов программа не нашла.
    2. .doc файлы есть, но телефонный номер неправильный
Все свои действия скрипт пишет в кучу логов, на всякий пожарный ;) Расположение логов задается.

Когда пользователь получает письмо о получении документов для факса, напротив названия каждого документа, пишется Unical ID, 11 символьная рандомная строка.

Если вдруг пользователь решит что какой-то факс отправлять не надо, или ошибся в чем-то, то послав на почтовый адрес закрепленный за факсом письмо вида:
    1. В поле Subject слово "delete".
    2. В теле письма соответствующий документу Unical ID
Он сможет удалить этот документ из очереди факсмодема (если конечно успеет до его отсылки).

Скрипт можно скачать здесь

Над ним ведутся работы, как тестирующие, так и для увеличения его функциональности (хочется еще добавить отсылку pdf документов, xls и txt и еще чего-нить придумать ;) ).

Вообщем пока, как я думаю о скрипте как о сложившемся, с хорошей функциональностью, решении, говорить немного рано, но основные задачи он выполняет и пока (тьфу-тьфу ;) ) неплохо.

Буду рад услышать предложения по скрипту, замеченные багги и тд. Если кто-то сам чего нить в скрипте добавит, то хотелось бы чтобы мне сообщили (исключительно в целях того что может я и себе то же самое добавлю ;) ).

Да и еще. Скрипт проверен на совместимость с почтой от клиентов The Bat!, Eudora, Outlook ;)


По всем вопросам, связанным со статьей и скриптом, писать автору на [email protected]. Автор не гарантирует немедленного ответа, но постарается в меру своих сил ответить на все что сможет.

С уважением,
Trend.