Linux: Mehrbenutzer-Scan2Fax-Gateway mit einem Multifunktionsdrucker und Postfix

Wie man einen Multifunktionsdrucker mit Hilfe von Postfix dazu bewegt, zu einem passablen Netzwerkscanner zu mutieren, habe ich bereits in einem Artikel beschrieben. Der Hauptgrund für die Anschaffung des Druckers war jedoch ein anderer: Der bereits auf meinem Server laufenden Faxserver Hylafax sollte um die Möglichkeit erweitert werden, Faxe zu versenden.

Wieder eine Ausgangssituation

Hinweis: Dieser Artikel baut auf einem vorhergehenden Artikel auf und soll zeigen, wie einfach man mit Bash-Skripten und etwas Phantasie (fast) beliebige Funktionen nachrüsten kann. Auf wesentliche Grundlagen, die bereits erläutert wurden, wird an dieser Stelle nicht noch einmal eingegangen.
Auch die Einrichtung von Hylafax wird in diesem Artikel nicht beschrieben. Informationen hierzu finden sich jedoch zu Hauf im Netz. Ein guter Startpunkt ist in jedem Fall die Webseite des Projektes.

Der von mir verwendete Multifunktionsdrucker Oki C5550 MFP ist bereits mit einer analogen Faxfunktion ausgerüstet. Dieses möchte ich jedoch aus den folgenden Gründen nicht verwenden:

  • das Senden soll mehrbenutzerfähg für unterschiedliche Sender und Empfänger mit unterschiedlichen Rufnummern funktionieren
  • ISDN-Anschluss: der Weg über A/D-Wandler ist umständlich, außerdem ist sowieso keine Telefonsteckdose in der Nähe und der Drucker ist bereits per Ethernet angebunden

Der Faxempfang läuft seit längerem problemlos über das auf meinem Server installierte Hylafax in Verbindung mit einer ISDN-Karte im Server. Ankommende Faxe werden anhand der empfangenden MSN auf E-Mailpostfächer verteilt.

Hylafax bietet von Haus aus die Möglichkeit, das Programm faxmail als Postfix-Filter zu verwenden, um einen Mail2Fax-Gateway zu betreiben. Eine Anleitung zur Inbetriebnahme findet sich unter anderem hier. Dies hat jedoch einen für mich entscheidenden Nachteil: Faxmail verarbeitet lediglich den Klartextteil einer übergebenen E-Mail. Bei der bei mir installierten Hylafaxversion werden Dateianhänge sogar komplett ignoriert. Ich möchte aber genau das Gegenteil erreichen: Der Klartextteil soll ignoriert werden, nur Dateianhänge im PS- oder PDF-Format sollen bei Hylafax landen.
Daher wird, angelehnt an den vorhergehenden Artikel, ein Bash-Skript als Filter zum Einsatz kommen, welches den Faxversand nach meinen Vorgaben steuert.

Hier der leicht abgeänderte Ablauf:


Drucker/Scanner

Auch diesmal muss der Drucker/Scanner wissen, wohin er die gescannten Dokumente schicken soll.

Postfix

Das Konzept der Postfix-Transports wurde bereits beschrieben. Diesmal wird ein Transport mailfax eingerichtet.
In diesem Beispiel gehe ich davon aus, dass eine MSN für geschäftliche und eine MSN für private Faxe eingerichtet ist. Für jeden Fax-Absender wird eine Subdomain eingerichtet. Für dieses Beispiel wähle ich 71 für private und 81 für geschäftliche Faxe.

Die Datei /etc/postfix/master.cf muss um die Zeilen

#Richte den Transport mailfax ein, der alle Mails per Pipe an das
#Skript /usr/local/bin/scanmail2fax weiter leitet
mailfax       unix  -       n       n       -       1       pipe
  flags=    user=fax argv=/usr/local/bin/scanmail2fax ${recipient}

erweitert werden. In die Datei /etc/postfix/transport ergänzt man die folgenden Zeilen:

# <meinserver> muss durch den Hostnamen des Servers ersetzt werden
# 71 und 81 sind die im Beispiel verwendeten Subdomains für den Faxversand
71.<meinserver>  fax:localhost
81.<meinserver>  fax:localhost

Mit dem Befehl

postmap /etc/postfix/transport

wird /etc/postfix/transport in ein für Postfix lesbares Format umgewandelt und mit dem Befehl

postfix reload

wird die geänderte Konfiguration eingelesen und aktiviert.

Skript

Das als Filter eingesetzte Bash-Skript kann (wieder zusammen mit der Konfigurationsdatei) als Archiv (scanfax.tar.gz) heruntergeladen werden. Es sollte als /usr/local/bin/scanmail2fax abgelegt werden und sieht folgendermaßen aus:

#!/bin/sh
##################################################################### 
# scanmail2fax                                                      # 
# Simple shell-based filter. It is meant to be used as postfix mail # 
# transport and is invoked as follows:                              # 
#                                                                   # 
# /path/to/script -f <recipient>...                                 # 
#                                                                   # 
# Author: yeat (y[]yeat.net)                                        # 
#                                                                   # 
# It takes a message from stdin, extracts all MIME-parts            # 
# (i. e. binary attachments) and hands PS and PDF attachments to    # 
# hylafax for processing.                                           # 
# Recipient must be an e-mail address in format                     # 
#                                                                   # 
# <destination number>@<sender-id>.<yourdomain>                     # 
# where                                                             # 
#                                                                   # 
# <destination number> is the receivers fax number                  # 
#                                                                   # 
# <sender-id>          specifies the sending hylafax modem using    # 
#                      $INIFILE (see below) to map between          # 
#                      sender-ids and hylafax modems                # 
##################################################################### 


##################################################################### 
# Configuration                                                     # 
# adjust variables to your system environment                       # 
##################################################################### 
#Location of fax map 
INIFILE=/etc/scanmail/scanmail2fax

#Location of logfile 
LOGFILE=/var/log/scanmail2fax

#Location for temporary files 
FAXTMP_DIR=/var/spool/fax/tmp

##################################################################### 
# No user-servicable parts beyond this point...                     # 
##################################################################### 

RECEIVER=$1
DEST_NO=$(echo $RECEIVER | sed 's/@.*$//')
SENDER_NO=$(echo $RECEIVER | sed 's/^.*@\([0-9]*\)\..*$/\1/') 
EX_TEMPFAIL=75 


# Clean up when done or when aborting. 
trap "cd ..; rm -rf mailfax.$$" 0 1 2 3 15 

# Check for fax map 
[ -f $INIFILE ] || { 
    echo $INIFILE does not exist; exit $EX_TEMPFAIL; } 

# Start processing. 
cd $FAXTMP_DIR || { 
    echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; } 


mkdir mailfax.$$ 
cd mailfax.$$ 


cat >in.$$ || { 
   echo Cannot save mail to file; exit $EX_TEMPFAIL; } 

grep -m 1 $SENDER_NO $INIFILE | while read PREF MODEM NOTIFY; do 

  #Is there an e-mail address for notification? 
  if [ -n "$NOTIFY" ]; then OPT_NOTIFY=" -f $NOTIFY"; fi 
  
  #write all attachments to temporary files 
  cat in.$$ | METAMAIL_TMPDIR=. metamail -d -w -q 
  
  #fax all PDF and PS files to destination 
  for fn in $(ls -tr *.pdf *.ps); do 

     #write status to logfile 
     echo $(date +%c)": mail to $RECEIVER -> fax to $DEST_NO with $SENDER_NO ($MODEM), notification to $NOTIFY" >> $LOGFILE 
     #commit file to hylafax 
     cat $fn | sendfax -v -n -D $OPT_NOTIFY -h $MODEM -d $DEST_NO 

  done 

done 

exit $?

Die eigentliche Konfiguration erfolgt in der Datei /etc/scanmail/scanmail2fax. Für dieses Beispiel sieht sie folgendermaßen aus:

######################################################################
#sender-id      hylafax modem                   e-mail notification
######################################################################
71              faxCAPI_privat@localhost        fax_privat@localhost
81              faxCAPI_gesch@localhost         fax_gesch@localhost

Wobei sender-id den in Postfix konfigurierten Subdomains entspricht, hylafax modem das in Hylafax eingerichtete (virtuelle CAPI-)Modem bezeichnet, über das gesendet werden soll und unter e-mail notification eine E-Mailadresse angegeben werden kann, an die der Faxserver Erfolgs- und Fehlerberichte senden soll.

Das Skript macht folgendes:

  • die Empfänger-Mailadresse wird nach dem Schema <Empfänger-Faxnummer>@<Sender> zerlegt
  • in /var/spool/fax/tmp ($TMP_DIR) wird ein temporäres Unterverzeichnis angelegt (mailfax.$$) und dort hin gewechselt
  • die E-Mail wird in die Datei in.$$ geschrieben
  • die Dateianhänge der E-Mail werden mittels metamail extrahiert und gespeichert
  • alle Dateien mit der Endung ps und pdf werden mittels sendfax an Hylafax übergeben und an den entsprechenden Empfänger gefaxt


Voila! Wenn ich nun ein Dokument am Multifunktionsdrucker scanne und als PDF an die Adresse 1020304050@71 senden lasse, so wird es von Hylafax kurze Zeit später über den privaten Fax-Anschluss faxCAPI_privat an die Nummer 1020304050 gefaxt und ich erhalte eine Bestätigung in das E-Mailpostfach fax_privat auf dem Server.

Anmerkungen

Das ganze ist in der besprochenen Konfiguration natürlich nicht auf E-Mails vom Multifunktionsdrucker beschränkt, da alle an die entsprechenden Fax-Adressen gesendeten E-Mails an den Fax-Transport übergeben werden. Möchte man dies verhindern, so muss man Postfix entsprechend einrichten (z.B. Filterregeln anhand der IP-Adresse des Senders oder SMTP-Authentifizierung).