[HowTo] Asterisk als SPAM-AB mit tellows-Abfrage

scorp51

Neuer User
Mitglied seit
27 Jul 2006
Beiträge
29
Punkte für Reaktionen
0
Punkte
0
Hi,

da es keine fertigen Lösungen gab, ich aber mein Telefon-SPAM-Problem in den Griff bekommen wollte, ohne die Rufnummer zu wechseln, immer händisch mit Rufsperren zu arbeiten oder gleich komplett auf Asterisk umzusteigen, hab ich mich dran gesetzt und Asterisk als Nebenstelle der FritzBox mit Anti-SPAM-Funktion eingerichtet. Ich zeige euch nun, wie.
Verbesserungsvorschläge sind jederzeit willkommen. :)

Voraussetzungen:
  • Linux- und Asterisk-Grundkenntnisse (dafür sehr empfehlenswert Das-Asterisk-Buch.de)
  • Installierter Asterisk in Version 1.6 oder neuer (egal, ob als Mod auf der FB oder als separates Gerät, hauptsache die FB ist per Netzwerk erreichbar)
  • Textbrowser Lynx auf dem Asterisk-Server installiert
  • Funktionierender E-Mail-Versand auf dem Asterisk-Server (z.B. mit Postfix in der "Satellite"-Konfiguration)
  • FritzBox Fon oder jede andere TK-Anlage, die interne SIP-Apparate verwalten kann. Ich werde mich im How-To auf die FBF 7390 beschränken.

FritzBox
Wir legen im Bereich Telefonie einen neuen Apparat vom Typ "LAN/WLAN" an, merken uns die interne Nebenstellennnummer (z.B. 621) und das vergebene Passwort. Im weiteren Verlauf werde ich mit Nebenstelle 621 und Passwort test1234 arbeiten. Diesem Apparat weisen wir bei "Auf diese Rufnummern reagieren" alle Nummern zu, für die wir den SPAM-Schutz aktiveren möchten.

Asterisk-Konfiguration

AGI-Skript
Zuerst legen wir das Skript an, das später die Tellows-Abfrage macht. Dieses sollte im AGI-Verzeichnis des Asterisk liegen (Default: /val/lib/asterisk/agi-bin/), da wir uns später diese Asterisk-Erweiterung zu Nutze machen. In meinem Fall ist es ein einfaches Linux-Bash-Skript und heißt tellows.agi. Es gibt dann als Rückgabe den Asterisk-Befehl zum Setzen einer lokalen Variable $SPAMSCORE zurück, welche einen Wert zwischen 1 und 9 haben kann (7-9 sind relativ sicher Telefon-Spammer, s. tellows.de).
Dieses Skript macht folgendes:
  • Es bekommt von Asterisk als Parameter 1 die Rufnummer des Anrufers übergeben.
  • Zuerst wird dann geprüft, ob überhaupt eine Nummer übergeben wurde, wenn nicht wird $SPAMSCORE auf 5 (neutral) gesetzt.
  • Wurde "anonymous" übergeben (das macht der Asterisk, wenn keine Rufnummer übermittelt wird), wird $SPAMSCORE auf 5 gesetzt (hier einfach auf 7, 8 oder 9 ändern, wenn anonyme Anrufer geblockt werden sollen)
  • Anonsten wird mit der übergebenen Rufnummer eine tellows-Abfrage gestartet und das Ergebnis in $SPAMSCORE gespeichert. Der Timeout von Lynx ist dabei auf 5 Sekunden gesetzt, damit's nicht zu lange dauert.
  • Anschließend wird geprüft, ob $SPAMSCORE einen gültigen Wert (zw. 1 und 9) enthält, wenn nicht, wird $SPAMSCORE wieder auf 5 gesetzt.
  • Abschließend wird der Asterisk-Befehl zum Setzen der Variable im STDOUT ausgegeben.
Code:
#!/bin/sh
#
#read agi_request
#read agi_language
#read agi_channel
#read agi_type
#read agi_uniqueid
#read agi_callerid
#read agi_dnid
#read agi_rdnis
#read agi_context
#read agi_extension
#read agi_priority
#read agi_enhanced
#read agi_accountcode
#read emptyline
 
if [ "$1" = " " ] || [ -z "$1" ]; then
  SPAMSCORE=5
else
  NUMBER=`echo $1 | sed -e "s/\ //g" -e "s/+49/0/"`
  #Asterisk sets CALLERID(num) to "anonymous" if no number passed.
  if [ "$NUMBER" = "anonymous" ]; then
    #If you want to block anonymous calls, simply set SPAMSCORE to 9 instead of 5
    SPAMSCORE=5
  else
    SPAMSCORE=$(lynx -connect_timeout=5 -dump http://www.tellows.de/basic/num/$NUMBER | sed -ne '/Score:/{s/.*.: //p}')
    if ! [[ $SPAMSCORE =~ ^[1-9]$ ]]; then
      SPAMSCORE=5
    fi
  fi
fi
 
#return this:
echo 'SET VARIABLE SPAMSCORE '"\"$SPAMSCORE\"">/dev/stdout
 
exit 0
Das Skript muss für den User, unter dem Asterisk läuft, ausführbar sein (also das X-Flag gesetzt), erreichbar z.B. mit 'chmod +x tellows.agi'.

indications.conf
Wir müssen Asterisk erstmal die deutschen Töne (Freizeichen, etc.) beibringen, daher setzen wir in der indications.conf im Asterisk-Config-Verzeichnis (default: /etc/asterisk/) den Wert country auf "de":
Code:
[...]
country=de
[...]

sip.conf
Jetzt geht es ans Konfigurieren des Asterisk als Nebenstelle der FritzBox. Dazu erstellen wir eine sip.conf im Asterisk-Config-Verzeichnis mit folgendem Inhalt:
Code:
[general]
port = 5060
transport = udp
bindaddr = 0.0.0.0
context = default
language = de
register => 621:[email protected]/621
 
[621]
type=peer
defaultuser=621
fromuser=621
secret=test1234
host=fritz.box
insecure=port,invite
canreinvite=no
dtmfmode=rfc2833
qualify=no
nat=no
context=von-fritzbox
Hier passiert folgendes:
Asterisk wird mit den Daten, die wir oben für die Nebenstelle an der FritzBox definiert haben, an dieser angemeldet.
Dann wird eine Ressource angelegt, die quasi als "Virtuelles Telefon" fungiert, der Einfachheit halber habe ich sie genauso genannt, wie die Nebenstelle an der FritzBox.

voicemail.conf
Nun konfigurieren wir den AB. Dazu erstellen wir eine Datei voicemail.conf im Asterisk-Config-Verzeichnis mit folgendem Inhalt:
Code:
[general]
format = wav
[email protected]
attach=yes
emailsubject = New Voicemail from ${VM_CALLERID}
pbxskip = no
emailbody = There is a new voicemail from ${VM_CIDNUM}, recordet at ${VM_DATE} with a length of ${VM_DUR}.
maxsecs = 180
maxsilence = 5
newzonename=Europe/Berlin|R
 
[default]
621 => 1234,Theo Tester,[email protected]
Am Anfang kommt die Grundkonfiguration der Voicemail inkl. Absenderadresse und Vorlage für die E-Mail-Benachrichtigung. Ihr bekommt dann später für jede neue Nachricht eine E-Mail mit der Nachricht als Anhang.
Für den eben angelegten Apparat definieren wir dann eine Mailbox mit PIN 1234, Name und der Empfänger-E-Mail-Adresse.

extensions.ael
Jetzt fehlt noch der wichtigste Teil, der Dialplan, also quasi die Anweisung an den Asterisk, was er wann tun soll. Ich habe mich hier für die sog. AEL-Sprache entschieden, da diese flexiblere Skripte ermöglicht, als die klassische extensions.conf.
Wir löschen daher eine evtl. bestehende extensions.conf oder benennen sie um und erstellen anschließend eine Datei namens extensions.ael im Asterisk-Config-Verzeichnis:
Code:
context von-fritzbox {
  621 => {
    switch (${CALLERID(num)}) { //Goto VoiceMailMain, if Caller is from internal
      pattern **6[1-2][0-9]: //DECT and VoIP phones on FritzBox
        Answer();
        VoiceMailMain(621);
        break;
      pattern **5[0-9]: //ISDN phones on FritzBox
        Answer();
        VoiceMailMain(621);
        break;
      pattern **[1-2]: //Analog phones on FritzBox
        Answer();
        VoiceMailMain(621);
        break;
      default: //In all other cases start regular tellows routine
        Ringing();
        AGI(tellows.agi, ${CALLERID(num)});
        NoOp(SPAMSCORE is ${SPAMSCORE});
        switch (${SPAMSCORE}) { //redirect to voicemail if spamscore 7-9, othwerwise wait 35 secs, then hangup
          pattern [7-9]:
            Answer();
            System(echo "${CALLERID(num)} has been redirected to the SPAM VoicemailBox: tellows SPAMSCORE ${SPAMSCORE} (see http://www.tellows.de/num/${CALLERID(num)})." | mail -s "Asterisk: Suspect call" [email protected]);
            VoiceMail(621,su);  //u: Unavailable message (record your unavailable message before using), s: skip the default "Leave your message after the tone..."
            NoOp(SPAMSCORE 7-9);
            break;
          default:
            Wait(35);
            NoOp(Kein SPAM oder unbekannt.);
        }
    }
    Hangup();
  }
}
Hier passiert folgendes:
  • Wenn die anrufende Nummer eine interne Nummer der FritzBox ist (also ein DECT- (**61x), SIP- (**62x), ISDN- (**5x) oder analoges (**1 oder **2) Telefon an der FritzBox), wird man direkt zur MailBox-Verwaltung geleitet, gibt seine PIN ein und kann dann Nachrichten abhören oder z.B. auch einen Ansagetext aufsprechen.
  • In allen anderen Fällen "klingelt" der vituelle Apparat, parallel wird das AGI-Skript tellows.agi aufgerufen und ihm die Anrufernummer ("${CALLERID(num)}") übergeben.
  • Das AGI-Skript gibt die Variable SPAMSCORE zurück. Diese wird dann geprüft. Wenn sie 7, 8, oder 9 ist, wird der Anrufer direkt zur MailBox durchgestellt und bekommt die eingestellte Ansage zu hören und anschließend die Möglichkeit, eine Nachricht aufzusprechen (falls doch mal einer fälschlicherweise dort landet). Außerdem bekommt ihr eine Mail, dass ein unseriöser Anrufer angerufen hat.
  • In allen anderen Fällen wartet der Asterisk einfach nur eine Weile (35 Sekunden) und legt dann wieder auf. In der Zeit kann dann z.B. auch der normale FritzBox-AB rangehen oder man kann natürlich den Anruf entgegennehmen.

Testen
Das war die Konfiguration, jetzt kommt das Testen.
Dazu auf dem Asterisk-Server in die Asterisk-CLI wechseln und gleich die Verbosity etwas hochsetzen, damit wir mehr Ausgaben haben:
Code:
user@asterisk:~# asterisk -r -vvvvv
Dort lasst ihr die gesamte Konfiguration neu einlesen mit dem Befehl
Code:
reload
Es sollten keine ERRORs auf der CLI erscheinen. Man kann jetzt von einem Telefon an der FritzBox die **621 anufen und sollte direkt im Voicemail-Menü landen (nach Eingabe der PIN).
Wenn ein Anruf von außen kommt, sollte auf der CLI zu sehen sein, wie der Asterisk den Dialplan abarbeitet.

Tipps
  • Für deutsche Ansagetexte, etc, braucht man deutsche Sprachfiles. Diese liegen normalerweise unter /var/lib/asterisk/sounds/, die deutschen dann dort im Unterordner de/. Um diese zu finden, muss man evtl. etwas googlen (z.B. die der Stadt Pforzheim). Aufpassen muss man bei der Ordnerstrukur. Ab Asterisk 1.4 müssen die deutschen Texte für Ziffern (digits), Buchstaben (letters) und Laute (phonetic) unterhalb von de/ liegen, manche Pakete verwenden aber noch das alte Schema, wo diese Ordner direkt unter /var/lib/sounds/ lagen und dann jeweils noch einen Unterordner de/ beinhalteten. Hier muss man u.U. umkopieren oder symlinken.
  • Wenn man eine Distribution wie z.B. Ubunu vewendet, sind einige Pfade anders, z.B liegen sounds und agi-bin unter /usr/share/asterisk/.
  • Wenn das AGI-Skript nicht läuft, könnte es sein, dass /bin/sh auf die falsche Shell veweist, dann Testweise mal in der ersten Zeile mit /bin/bash vesuchen.
  • Bei der Mailboxansage kann man sich austoben und den Anrufer mit einer Ansage à la "Hallo? ... Haallooo? ... Ich verstehe Sie ganz schlecht! ... Spaß beiseite: Ihre Rufnummer ist als unseriös eingestuft, Sie können aber nach dem Signal eine Nachicht hinterlassen." auch kräftig ärgern. :D
  • Man könnte natürlich anstatt der Voicemail auch einfach ein 'Answer(); Hangup();' machen, dann wird der Anruf angenommen und anschließend sofort wieder aufgelegt. Würde aber dann bedeuten, dass "false positives" auch einfach "abgewürgt" werden.
  • Sicherheitshinweis: Diese einfache Config gilt nur, wenn der Asterisk in einem vertrauenswürdigen Netz steht und keiner von außen dran kommt! Andernfalls müssen weitere Maßnahmen zu Sicherung ergriffen werden, sonst habt ihr u.U. schnell eine sehr hohe Telefonrechnung!

Quellen
Hier hab ich mich bedient bzw. mir Anregungen geholt, ein riesen Dankeschön an alle Autoren!
https://blog.simonszu.de/2011/03/asterisk-als-sip-voicemail-an-fritzbox-anbinden/
http://www.voip-info.org/wiki/view/Reverse+Lookup+in+Germany
http://www.ip-phone-forum.de/showthread.php?t=223492
http://www.ip-phone-forum.de/showthread.php?t=213127

Gruß
Matthias
 
Zuletzt bearbeitet:
Ich hab hier noch ein Problem, dass im Dialplan die ${SPAMSCORE} leer ist, obwohl das Script korrekt ausgeführt wird
 
Hm, starte es doch mal direkt auf der Shell '<pfad-zum-script>/tellows.agi 080012345678' und schau, was es ausgibt. Es sollte eigenlich eine Zeile nach dem Schema 'SET VARIABLE SPAMSCORE 5' ausgegeben werden.
 
Er hat hier den Else-Teil angemosert. Hab es etwas angepasst und nun läuft es :)
 
Kannst du sagen, was nicht gepasst hat?
Ich hab das oben aus einem größeren Script rausgefrickelt (ich nutze noch etliche Log-Ausgaben sowie Abfrage einer Black- und Whitelist), daher kann es gut sein, dass da irgendwo Syntaxfehler o.ä. drin sind.

edit: OK, selber rausgefunden: Der innere if-Teil war ungültig, da ja außer einem Kommentar gar nix drin stand. Hab das Script im Originalbeitrag angepasst.

Alt:
Code:
  if [[ $SPAMSCORE =~ ^[1-9]$ ]]; then
    [COLOR="#FF0000"]#do nothing[/COLOR]
  else
    SPAMSCORE=5
  fi

Neu:
Code:
  if [COLOR="#008000"]![/COLOR] [[ $SPAMSCORE =~ ^[1-9]$ ]]; then
    SPAMSCORE=5
  fi
 
Zuletzt bearbeitet:
Ich habe das AGI-Scipt noch etwas erweitert, da der Asterisk anscheinend, wenn vom Anrufer keine Rufnummer übermittelt wird, $CALLERID(num) = "anonymous" setzt.
 

Zurzeit aktive Besucher

Keine Mitglieder online.

Statistik des Forums

Themen
246,146
Beiträge
2,246,880
Mitglieder
373,654
Neuestes Mitglied
hstoff
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.