Asterisk empfängt Testfaxe und sendet sie automatisch zurück

7.9.2025 (zuletzt aktualisiert am 8.9.25)

Mit diesem kleinen Skript für Asterisk kannst du deine Faxgeräte – ob Hard- oder Software – schnell und zuverlässig testen: Du schickst ein Fax an eine interne Nummer und bekommst es nach einer Minute automatisch zurück.

Das hier gezeigte Skript für die extensions.conf von Asterisk ist ein kompletter Mini-Testserver für Faxe. Es nimmt Faxe auf einer internen Nummer (im Beispiel 1991) entgegen, speichert sie als TIFF-Datei und schickt sie nach exakt 60 Sekunden automatisch wieder zurück an den Absender. Alles läuft in einem einzigen Dialplan-Context, separate Rücksendungs-Contexts brauchst Du nicht.

Chatgpt image 7. sept. 2025, 17 47 02
Freude beim Testen: Unser Faxserver empfängt Testfaxe und sendet sie automatisch zurück.

Das Skript: Einfach in deine extensions.conf von Asterisk kopieren. Das Skript gehört in den Context deiner Telefon-Extensions. Das ist fast alles.

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; TESTFAX-SYSTEM 1991 - Empfang und automatischer Rückversand nach 1 Minute
; Alles in einem Context - ohne separaten [testfax-ruecksendung] Context
; Kopiere das hier in die extensions.conf von Asterisk
; Faxe die an die 1991 verschickt werden, kommen mit einer Minute
; Verzögerung wieder an den Versender zurück.
; https://claude.ai/share/f08f55bd-ae71-499b-b945-334b108df344
;
; Falls noch nicht vorhanden:
; sudo mkdir -p /var/spool/asterisk/fax/testfax
; sudo chown asterisk:asterisk /var/spool/asterisk/fax/testfax
; sudo chmod 755 /var/spool/asterisk/fax/testfax
;
; sudo chown asterisk:asterisk /var/spool/asterisk/outgoing
; sudo chmod 770 /var/spool/asterisk/outgoing
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

; Faxempfang Extension 1991
exten => 1991,1,Noop(Testfax-System: Faxempfang von "${CALLERID(name)}" <${CALLERID(num)}>)
  same => n,Set(SIP_CODEC=alaw)
  same => n,Answer()
  same => n,Wait(3)
  
  ; Konservative Fax-Einstellungen
  same => n,Set(FAXOPT(ecm)=no)
  same => n,Set(FAXOPT(modem)=v27,v29)
  same => n,Set(FAXOPT(minrate)=2400)
  same => n,Set(FAXOPT(maxrate)=9600)
  same => n,Set(FAXOPT(localstationid)=1991)
  same => n,Set(FAXOPT(headerinfo)=Testfax Server)
  same => n,Set(FAXOPT(debug)=yes)
  same => n,Set(FAXOPT(t38timeout)=5000)
  
  ; Variablen für Faxempfang
  same => n,Set(TRYCOUNT=0)
  same => n,Set(FAXDEST=/var/spool/asterisk/fax/testfax)
  same => n,Set(FAXFILE=${FAXDEST}/${UNIQUEID}.tif)
  same => n,Set(SENDER_NUMBER=${CALLERID(num)})
  
  ; Fax-Empfangsschleife
  same => n(faxloop),Set(TRYCOUNT=$[${TRYCOUNT} + 1])
  same => n,Noop(Fax-Empfangsversuch ${TRYCOUNT} von ${SENDER_NUMBER})
  same => n,Wait(2)
  same => n,ReceiveFax(${FAXFILE})
  
  same => n,NoOp(STATUS: ${FAXOPT(status)})
  same => n,NoOp(RESOLUTION: ${FAXOPT(resolution)})
  same => n,NoOp(RATE: ${FAXOPT(rate)})
  same => n,NoOp(PAGES: ${FAXOPT(pages)})
  same => n,NoOp(ERROR: ${FAXOPT(error)})
  
  ; Erfolg prüfen
  same => n,GotoIf($["${FAXOPT(status)}" = "SUCCESS"]?faxsuccess)
  
  ; Bei "Unexpected message" längere Pause
  same => n,GotoIf($["${FAXOPT(error)}" = "Unexpected message received"]?longwait)
  same => n,Wait(3)
  same => n,Goto(checkretry)
  
  same => n(longwait),Noop(Unexpected message - längere Wartezeit)
  same => n,Wait(8)
  
  same => n(checkretry),GotoIf($[${TRYCOUNT} < 5]?faxloop)
  same => n,Noop(Fax-Empfang nach ${TRYCOUNT} Versuchen fehlgeschlagen)
  same => n,Goto(faxfailed)
  
  ; Fax erfolgreich empfangen - Call-File für Rückversand erstellen
  same => n(faxsuccess),Noop(Fax erfolgreich empfangen: ${FAXOPT(pages)} Seiten von ${SENDER_NUMBER})
  same => n,Noop(Fax gespeichert als: ${FAXFILE})
  
  ; Call-File für automatischen Rückruf nach 60 Sekunden erstellen
  ; Verwendet den GLEICHEN Context und Extension 1991-send
  same => n,System(echo "Channel: SIP/${SENDER_NUMBER}" > /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "CallerID: \"Testfax Ruecksendung\" <1991>" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "Context: ${CONTEXT}" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "Extension: 1991-send" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "Priority: 1" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "SetVar: ORIGINAL_FAXFILE=${FAXFILE}" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "SetVar: ORIGINAL_SENDER=${SENDER_NUMBER}" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "MaxRetries: 3" >> /tmp/testfax_${UNIQUEID}.call)
  same => n,System(echo "RetryTime: 30" >> /tmp/testfax_${UNIQUEID}.call)
  
  ; Call-File mit 60 Sekunden Verzögerung aktivieren
  same => n,System(touch -t $(date -d '+60 seconds' +%Y%m%d%H%M.%S) /tmp/testfax_${UNIQUEID}.call)
  same => n,System(mv /tmp/testfax_${UNIQUEID}.call /var/spool/asterisk/outgoing/)
  
  same => n,Noop(Testfax-Rückversand geplant für ${SENDER_NUMBER} in 60 Sekunden)
  same => n,Goto(faxend)
  
  same => n(faxfailed),Noop(Fax-Empfang fehlgeschlagen von ${SENDER_NUMBER}: ${FAXOPT(error)})
  
  same => n(faxend),Hangup()

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; TESTFAX-RÜCKVERSAND (im gleichen Context)
; Extension 1991-send wird automatisch von der Call-File aufgerufen
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

exten => 1991-send,1,Noop(Testfax-Rückversand startet)
  same => n,Noop(Sende Fax ${ORIGINAL_FAXFILE} zurück an ${ORIGINAL_SENDER})
  same => n,Answer()
  same => n,Wait(3)
  
  ; Fax-Versandeinstellungen
  same => n,Set(FAXOPT(ecm)=yes)
  same => n,Set(FAXOPT(maxrate)=9600)
  same => n,Set(FAXOPT(minrate)=2400)
  same => n,Set(FAXOPT(headerinfo)=Testfax Ruecksendung)
  same => n,Set(FAXOPT(localstationid)=1991)
  same => n,Set(FAXOPT(debug)=yes)
  
  ; Prüfen ob Fax-Datei existiert
  same => n,GotoIf($[${STAT(e,${ORIGINAL_FAXFILE})}]?sendfax:nofile)
  
  same => n(sendfax),Noop(Sende Fax-Datei: ${ORIGINAL_FAXFILE})
  same => n,SendFax(${ORIGINAL_FAXFILE})
  
  ; Status-Informationen
  same => n,NoOp(SEND STATUS: ${FAXOPT(status)})
  same => n,NoOp(SEND RESOLUTION: ${FAXOPT(resolution)})
  same => n,NoOp(SEND RATE: ${FAXOPT(rate)})
  same => n,NoOp(SEND PAGES: ${FAXOPT(pages)})
  same => n,NoOp(SEND ERROR: ${FAXOPT(error)})
  
  same => n,GotoIf($["${FAXOPT(status)}" = "SUCCESS"]?sendsuccess:sendfailed)
  
  same => n(sendsuccess),Noop(Testfax erfolgreich zurückgesendet an ${ORIGINAL_SENDER})
  same => n,Goto(cleanup)
  
  same => n(sendfailed),Noop(Testfax-Rückversand fehlgeschlagen: ${FAXOPT(error)})
  same => n,Goto(cleanup)
  
  same => n(nofile),Noop(Fehler: Fax-Datei ${ORIGINAL_FAXFILE} nicht gefunden)
  
  same => n(cleanup),Noop(Testfax-Vorgang abgeschlossen)
  same => n,Hangup()

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Ende Testfax-System
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Du musst unter Linux noch einen neuen Ordner „testfax“ anlegen und Rechte vergeben: Der Ordner /var/spool/asterisk/outgoing ist meistens bereits schon vorhanden.

sudo mkdir -p /var/spool/asterisk/fax/testfax
sudo chown asterisk:asterisk /var/spool/asterisk/fax/testfax
sudo chmod 755 /var/spool/asterisk/fax/testfax

sudo chown asterisk:asterisk /var/spool/asterisk/outgoing
sudo chmod 770 /var/spool/asterisk/outgoing

Stelle sicher, das deine sip.conf folgende Einträge enthält:

; muss für Fax in der sip.conf unter [general] stehen
; FAX und T.38
faxdetect=yes
; t38pt_udptl=yes ; T.38 darf nicht aktiviert sein und ist deshalb auskommentiert
; directmedia=no

Die Faxempfangs-Extension ist so eingestellt, dass sie konservative Modemraten nutzt und mehrfach versucht, das Fax sauber zu empfangen. Sobald das klappt, wird im Hintergrund ein Call-File angelegt, das nach einer Minute einen Rückruf zum ursprünglichen Sender auslöst. Dabei ruft Asterisk dieselbe Nummer zurück und benutzt eine zweite Extension (1991-send), die das empfangene Fax wieder rausschickt.

Was passiert in der Asterisk-CLI? Da passiert eine ganze Menge, wenn das Fax mit der Nummer 1863 die 1991 anruft:

  
  == Using SIP RTP TOS bits 184
  == Using SIP RTP CoS mark 5
       > 0x73fc3300 -- Strict RTP learning after remote address set to: 5.150.201.25:7082
    -- Executing [1991@janson:1] NoOp("SIP/1863-00000245", "Testfax-System: Faxempfang von "Volker Lange-Janson" <1863>") in new stack
    -- Executing [1991@janson:2] Set("SIP/1863-00000245", "SIP_CODEC=alaw") in new stack
    -- Executing [1991@janson:3] Answer("SIP/1863-00000245", "") in new stack
       > Set codec to 'alaw' for this call because of ${SIP_CODEC*} variable
       > Set codec to 'alaw' for this call because of ${SIP_CODEC*} variable
       > 0x73fc3300 -- Strict RTP switching to RTP target address 5.150.201.25:7082 as source
    -- Executing [1991@janson:4] Wait("SIP/1863-00000245", "3") in new stack
[2025-09-07 20:12:11] NOTICE[13630][C-00002ce9]: chan_sip.c:8739 sip_read: FAX CNG detected but no fax extension
    -- Executing [1991@janson:5] Set("SIP/1863-00000245", "FAXOPT(ecm)=no") in new stack
    -- Executing [1991@janson:6] Set("SIP/1863-00000245", "FAXOPT(modem)=v27,v29") in new stack
    -- Executing [1991@janson:7] Set("SIP/1863-00000245", "FAXOPT(minrate)=2400") in new stack
    -- Executing [1991@janson:8] Set("SIP/1863-00000245", "FAXOPT(maxrate)=9600") in new stack
    -- Executing [1991@janson:9] Set("SIP/1863-00000245", "FAXOPT(localstationid)=1991") in new stack
    -- Executing [1991@janson:10] Set("SIP/1863-00000245", "FAXOPT(headerinfo)=Testfax Server") in new stack
    -- Executing [1991@janson:11] Set("SIP/1863-00000245", "FAXOPT(debug)=yes") in new stack
[2025-09-07 20:12:13] WARNING[13630][C-00002ce9]: res_fax.c:4664 acf_faxopt_write: channel 'SIP/1863-00000245' set FAXOPT(debug) to 'yes' is unhandled!
    -- Executing [1991@janson:12] Set("SIP/1863-00000245", "FAXOPT(t38timeout)=5000") in new stack
    -- Executing [1991@janson:13] Set("SIP/1863-00000245", "TRYCOUNT=0") in new stack
    -- Executing [1991@janson:14] Set("SIP/1863-00000245", "FAXDEST=/var/spool/asterisk/fax/testfax") in new stack
    -- Executing [1991@janson:15] Set("SIP/1863-00000245", "FAXFILE=/var/spool/asterisk/fax/testfax/1757268730.1050.tif") in new stack
    -- Executing [1991@janson:16] Set("SIP/1863-00000245", "SENDER_NUMBER=1863") in new stack
    -- Executing [1991@janson:17] Set("SIP/1863-00000245", "TRYCOUNT=1") in new stack
    -- Executing [1991@janson:18] NoOp("SIP/1863-00000245", "Fax-Empfangsversuch 1 von 1863") in new stack
    -- Executing [1991@janson:19] Wait("SIP/1863-00000245", "2") in new stack
       > 0x73fc3300 -- Strict RTP learning complete - Locking on source address 5.150.201.25:7082
    -- Executing [1991@janson:20] ReceiveFAX("SIP/1863-00000245", "/var/spool/asterisk/fax/testfax/1757268730.1050.tif") in new stack
    -- Channel 'SIP/1863-00000245' receiving FAX '/var/spool/asterisk/fax/testfax/1757268730.1050.tif'
    -- Executing [1991@janson:21] NoOp("SIP/1863-00000245", "STATUS: SUCCESS") in new stack
    -- Executing [1991@janson:22] NoOp("SIP/1863-00000245", "RESOLUTION: 8031x3850") in new stack
    -- Executing [1991@janson:23] NoOp("SIP/1863-00000245", "RATE: 9600") in new stack
    -- Executing [1991@janson:24] NoOp("SIP/1863-00000245", "PAGES: 1") in new stack
    -- Executing [1991@janson:25] NoOp("SIP/1863-00000245", "ERROR: ") in new stack
    -- Executing [1991@janson:26] GotoIf("SIP/1863-00000245", "1?faxsuccess") in new stack
    -- Goto (janson,1991,35)
    -- Executing [1991@janson:35] NoOp("SIP/1863-00000245", "Fax erfolgreich empfangen: 1 Seiten von 1863") in new stack
    -- Executing [1991@janson:36] NoOp("SIP/1863-00000245", "Fax gespeichert als: /var/spool/asterisk/fax/testfax/1757268730.1050.tif") in new stack
    -- Executing [1991@janson:37] System("SIP/1863-00000245", "echo "Channel: SIP/1863" > /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:38] System("SIP/1863-00000245", "echo "CallerID: \"Testfax Ruecksendung\" <1991>" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:39] System("SIP/1863-00000245", "echo "Context: janson" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:40] System("SIP/1863-00000245", "echo "Extension: 1991-send" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:41] System("SIP/1863-00000245", "echo "Priority: 1" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:42] System("SIP/1863-00000245", "echo "SetVar: ORIGINAL_FAXFILE=/var/spool/asterisk/fax/testfax/1757268730.1050.tif" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:43] System("SIP/1863-00000245", "echo "SetVar: ORIGINAL_SENDER=1863" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:44] System("SIP/1863-00000245", "echo "MaxRetries: 3" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:45] System("SIP/1863-00000245", "echo "RetryTime: 30" >> /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:46] System("SIP/1863-00000245", "touch -t $(date -d '+60 seconds' +%Y%m%d%H%M.%S) /tmp/testfax_1757268730.1050.call") in new stack
    -- Executing [1991@janson:47] System("SIP/1863-00000245", "mv /tmp/testfax_1757268730.1050.call /var/spool/asterisk/outgoing/") in new stack
    -- Executing [1991@janson:48] NoOp("SIP/1863-00000245", "Testfax-Rückversand geplant für 1863 in 60 Sekunden") in new stack
    -- Executing [1991@janson:49] Goto("SIP/1863-00000245", "faxend") in new stack
    -- Goto (janson,1991,51)
    -- Executing [1991@janson:51] Hangup("SIP/1863-00000245", "") in new stack
  == Spawn extension (janson, 1991, 51) exited non-zero on 'SIP/1863-00000245'
    -- Attempting call on SIP/1863 for 1991-send@janson:1 (Retry 1)
  == Using SIP RTP TOS bits 184
  == Using SIP RTP CoS mark 5
    -- Called 1863
    -- SIP/1863-00000246 is ringing
       > 0x73d10bc0 -- Strict RTP learning after remote address set to: 5.150.201.25:7078
    -- SIP/1863-00000246 answered
    -- Executing [1991-send@janson:1] NoOp("SIP/1863-00000246", "Testfax-Rückversand startet") in new stack
    -- Executing [1991-send@janson:2] NoOp("SIP/1863-00000246", "Sende Fax /var/spool/asterisk/fax/testfax/1757268730.1050.tif zurück an 1863") in new stack
    -- Executing [1991-send@janson:3] Answer("SIP/1863-00000246", "") in new stack
    -- Executing [1991-send@janson:4] Wait("SIP/1863-00000246", "3") in new stack
       > 0x73d10bc0 -- Strict RTP switching to RTP target address 5.150.201.25:7078 as source
    -- Executing [1991-send@janson:5] Set("SIP/1863-00000246", "FAXOPT(ecm)=yes") in new stack
    -- Executing [1991-send@janson:6] Set("SIP/1863-00000246", "FAXOPT(maxrate)=9600") in new stack
    -- Executing [1991-send@janson:7] Set("SIP/1863-00000246", "FAXOPT(minrate)=2400") in new stack
    -- Executing [1991-send@janson:8] Set("SIP/1863-00000246", "FAXOPT(headerinfo)=Testfax Ruecksendung") in new stack
    -- Executing [1991-send@janson:9] Set("SIP/1863-00000246", "FAXOPT(localstationid)=1991") in new stack
    -- Executing [1991-send@janson:10] Set("SIP/1863-00000246", "FAXOPT(debug)=yes") in new stack
[2025-09-07 20:14:01] WARNING[13651][C-00002cea]: res_fax.c:4664 acf_faxopt_write: channel 'SIP/1863-00000246' set FAXOPT(debug) to 'yes' is unhandled!
    -- Executing [1991-send@janson:11] GotoIf("SIP/1863-00000246", "1?sendfax:nofile") in new stack
    -- Goto (janson,1991-send,12)
    -- Executing [1991-send@janson:12] NoOp("SIP/1863-00000246", "Sende Fax-Datei: /var/spool/asterisk/fax/testfax/1757268730.1050.tif") in new stack
    -- Executing [1991-send@janson:13] SendFAX("SIP/1863-00000246", "/var/spool/asterisk/fax/testfax/1757268730.1050.tif") in new stack
    -- Channel 'SIP/1863-00000246' sending FAX:
    --    /var/spool/asterisk/fax/testfax/1757268730.1050.tif
       > 0x73d10bc0 -- Strict RTP learning complete - Locking on source address 5.150.201.25:7078
  == Spawn extension (janson, 1991-send, 13) exited non-zero on 'SIP/1863-00000246'
[2025-09-07 20:14:29] NOTICE[13651][C-00002cea]: pbx_spool.c:463 attempt_thread: Call completed to SIP/1863

Beispiel für ein Testfax zum Ausdrucken und Versenden:

Wichtig: In dieser Form funktioniert das Skript nur, wenn das Faxgerät bzw. die SIP- oder IAX-Extension, von der Du sendest, direkt auf demselben Asterisk-Server registriert ist. Nur dann kann Asterisk den Rückruf selbst aufbauen und das Fax zurückschicken. Über externe Leitungen oder fremde Provider funktioniert das nicht ohne zusätzliche Konfiguration.

So kannst Du ohne externe Faxnummer testen, ob Deine Faxgeräte, Gateways oder SIP-Trunks sauber funktionieren. Du schickst einfach ein Fax an 1991 und bekommst kurze Zeit später genau dasselbe Dokument zurück. Praktisch für Fehlersuche, Tests und Demos.

Wie bin ich bei der Entwicklung des Skripts vorgegangen? Claude Sonnet hatte mir dabei etwas geholfen und mir ein paar Stunden Arbeit eingepart ( https://claude.ai/share/f08f55bd-ae71-499b-b945-334b108df344 ). Ich hatte bereits drei Skripte als Ausgangsbasis:

1. Skript zum Versenden von Faxen
2. Skript zum Empfangen von Faxen
3. Skript für einen zeitversetzten automatischen  Rückruf (Klingeltest)

Nun veranlasste ich die KI Claude Sonnet daraus einen Faxempfang mit automatischer zeitversetzter Rücksendung zu schreiben. Der Prompt mit all seinen Rechtschreibfehlern lautet:

„Aufgabe: Ein Testfax soll verschickt werden und an den Versender nach 1 Minute Pause nach dem vollständigen Empfang wieder an den Empfänger zurückgeschickt werden. Skript soll in der extensions.conf meines Asterisk realisiert ohne macros realisiert werden. Im Anhang habe ich schon Code-Schnipsel und Gedanken vorbereitet. man muss die nur richtig zusammensetzen. Das alles muss nur funktionieren für die SIP-Accounts meines eigenen Asterisk-Server“.

Damit hat sich dann die KI ans Werk gemacht und innerhalb weniger Minuten ein funktionsfähiges Skript geliefert.  Vor ein paar Jahren war das noch mit dieser Leistungsfähigkeit nicht möglich. Ich wollte noch eine Variante ohne zusätzlichen Context in der extensions.conf und das hat er mir dann auch geliefert.

Bildschirmfoto zu 2025 09 08 06 14 11
Claude Sonnet nimmt einem eine Menge Arbeit beim Coding ab und kennt sich sogar mit relativ unbekannten Tool wie Asterisk aus. Übrigens verwende ich die kostenlose Version, bei der ich mich einfach mit meinem Google Account angemeldet habe.

Wer braucht so ein Skript? Fast niemand. Das ist mir bewusst. Man benötigt einen eigenen Asterisk-Server und beschäftigt sich noch mit alten Faxgeräten, die man warten und reparieren möchte.  Die gemeinsame Schnittmenge tendiert gegen Null. Wenn man ein Hobby mit sozialen Interaktionen sucht, dann sollte man sich nicht gerade Faxgeräte aussuchen. Man ist ziemlich einsam auf breiter Bühne.

Alternative mit dem öffentlichen Telefonnetz: https://simple-fax.de/test-fax-empfangen. Fax an eine Nummer schicken und auf einer Webseite begutachten.

.