Hauptmenü

Modul 96_SIP

Begonnen von Wzut, 19 Februar 2017, 19:10:09

Vorheriges Thema - Nächstes Thema

Flachzange

Hallo zusammen,

ich glaube hier mal wieder ein klassisches Docker-Problem zu haben. Das Wiki zum Thema habe ich bereits gelesen, komme aber nicht weiter bzw. brauche eure Experten-Meinung.

- Ich habe FHEM von dedizierter Harware in ein Docker-Image umgezogen. Es läuft soweit alles, außer SIP.
- Das Docker-Image wird in einem Kubernetes auf einem Truenas Scale gehostet.
- Kubernetes erlaubt mir nicht die Nutzung von Ports kleiner 9000
- sip_ip ist gesetzt auf die IP-Adresse des Gastes, hier 172.16.0.194. Das Binding funktioniert.
- sip_port ist gesetzt auf 9060
- im Docker-Container ist Port 9060(TCP) und 9070 (UDP) weitergeleitet (9060:9060 bzw. 9070:9070)
- Die im Wiki genannten Ports 2xxx habe ich nicht weitergeleitet. Kann ich aufgrund der Port-Einschränkung von Kubernetes auch nicht.
- in der Fritzbox wurde eine statische Route für das Kubernetes-Netz gepflegt. Ich kann aus meinem regulären Heimnetz auch den Gast über seine Adresse erreichen

Beim ausgehenden Call passiert folgendes:

Zitat2022.08.11 19:47:50 4: mySIP, calling 0175xxxxxx, ringtime: 30 , no message
2022.08.11 19:47:50 4: mySIP, mySIP|0175xxxxxx|30||0
2022.08.11 19:47:50 4: mySIP, call -> mySIP|0175xxxxxx|30||0|0
2022.08.11 19:47:50 5: mySIP, call has pid 10348
2022.08.11 19:47:50 4: mySIP[10348], my parent is 6824
2022.08.11 19:47:50 4: mySIP[10348], trying to use port 9070
2022.08.11 19:48:52 4: mySIP, CALLDone -> mySIP|0|CallRegister: Failed with error 110|0
2022.08.11 19:48:52 5: mySIP, fifo is empty
2022.08.11 19:48:52 5: mySIP, no elbc


Ein netstat im Container ergibt folgendes:
Zitat
root@fhemsignal-ix-chart-64fdc4fdd8-8sjrq:/tmp# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name   
tcp        0      0 0.0.0.0:8083            0.0.0.0:*               LISTEN      6061       21271590   -                   
tcp        0      0 0.0.0.0:8084            0.0.0.0:*               LISTEN      6061       21271591   -                   
tcp        0      0 0.0.0.0:8085            0.0.0.0:*               LISTEN      6061       21271592   -                   
tcp        0      0 0.0.0.0:1883            0.0.0.0:*               LISTEN      6061       21271631   -                   
tcp        0      0 127.0.0.1:7072          0.0.0.0:*               LISTEN      6061       21268714   -                   
udp        0      0 172.16.0.194:9070       0.0.0.0:*                           6061       21436491   -                   

Auffällig: Es wird port 9070 UDP gebunden aber der state ist nicht "LISTEN"


Stelle ich auf Host-Networking um, Container ist also mit eigener IP-Adresse nach außen offen, funktioniert es genau so wie auf der alten dedizierten Maschine.

Die Fragen, die sich mir ergeben:
1) Kann ich überhaupt von Port 5060 abweichen und muss dieser in jedem Fall am Host exposed sein?
2) Warum funktioniert eine ausgehende Verbindung zu Fritzbox nicht? Das hat ja weder etwas mit Portweiterleitung oder Firewall zu tun? Hier verstehe ich schlicht nicht, wie SIP-funktioniert. Ist Port 9060 ausgehend während 9070 der dann eingehende ist?
3) Fall es auch mit meinen Ports funktionieren müsste: Braucht es TCP oder UDP? Kubernetes wil das spezifiziert haben
4) Brauche ich die 2xxx Ports?

Danke schon mal für jeglichen Support!

Chris

Wzut

IMHO sind die Ports 50xx nicht dein Problem, bzw lassen sich ja relativ leicht nach oben (9000+)  verschieben.
Knackpunkt werden aktuell die Ports RTP Ports 20xx sein, aber auch die lassen sich wie im Wiki https://wiki.fhem.de/wiki/SIP-Client#Docker beschrieben irgendwo nach weiter oben legen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

plin

Konkret: In der Util.pm kannst Du
our $RTP_MIN_PORT = 2000;
our $RTP_MAX_PORT = 12000;

nach oben legen
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

Flachzange

Danke für eure Hinweise. Ich habe nun testweise die RTP-Ports auf 20000-20007 gelegt:
- Ports weitergeleitet
- Ports in Util.pm angepasst
- FHEM neugestartet

Hängt leider mit dem selben Fehlerbild. Müsste ich nicht auch irgendeine Aktivität in der Fritzbox sehen? Da kommt im Ereignislog nichts an.


Flachzange

So, Dank tcpdump die Ursache gefunden: Der Server hat zwei Ethernet-Schnittstellen. Ausgehende-Kubernetes-Pakete gingen über en01, aber die Portweiterleitung in die Container funktioniert nur über eno2.

Darüber hinaus:
- Die Portrange für die Calls (5060..) ist UDP
- Die RTP-Ports (2000.. UDP) werden nicht für die Anrufsignalisierung benötigt.
- Der unter sip_port angegegebene Port ist einerseits die Startnummer für die Anrufsignalisierung und wird darüber hinaus für "listen" verwendet, falls sip_listen konfiguriert ist. Dieser muss also auch nur weitergeleitet werden, falls man listening benötigt.
- Für ausgehende Calls wird dann sip_port + 10 verwendet. Dieser muss weitergeleitet werden, falls man anrufen möchte

Ich habe die Doku im Wiki in diesem Rahmen etwas präzisiert.

Es bleiben aber noch zwei Fragen:

1) Wie persistiere ich am besten die Änderung an /usr/share/perl5/Net/SIP/Util.pm?
2) Der Docker-Container bekommt mit jedem Start eine neue interne IP, die SIP-Client benötigt. Wie kann ich das geschickt lösen?


Danke!

rob

Hi.
Zitat von: Flachzange am 14 August 2022, 20:07:15
...
1) Wie persistiere ich am besten die Änderung an /usr/share/perl5/Net/SIP/Util.pm?
2) Der Docker-Container bekommt mit jedem Start eine neue interne IP, die SIP-Client benötigt. Wie kann ich das geschickt lösen?
...
1) ggf. mit den Skripten arbeiten: das gewünschte rauspicken und damit die Änderung automatisieren lassen (https://github.com/fhem/fhem-docker#make-any-other-changes-during-container-start) - vielleicht hat da schon jmd. was fertiges; oder die geänderte Util.pm von außen in den Container hineinreichen (-v /hostpath/Util.pm:/containerpath/Util.pm:ro ) - habe aber beides nicht gebraucht/ versucht, deshalb nur als möglicher Ansatz ohne Gewähr :)

2) Du könntest ein Docker-Netzwerk anlegen, sofern noch nicht geschehen, und lässt FHEM Mitglied sein + gibst FHEM einen net-alias z.B. myfhem - diesen Alias trägst Du in "sip_ip" ein
Bsp.:

...
--net testnet
--name fhem
--network-alias myfhem
...

Über den Namen aus "--name fhem" müsste es auch gehen, ich finde es mit alias halt leichter zu handhaben. Mit dem Namen/Alias auf andere Container zuzugreifen ist imho der Standardweg lt. Docker (bspw. Zugriff Webserver --> SQL-Backend etc. pp.), weil sich eben die IPs ändern können.

Läuft bei mir zwar mit Asterisk, sollte aber im Zusammenspiel mit der Fritte auch keinen Unterschied machen.

VG
rob

Flachzange

Danke für den Input!

zu 2). Das funktioniert in meiner Kubernetes-Umgebung (scheinbar) nicht. Dort gibt es Services, die es mir erlauben zwischen Containern zu kommunizieren (analog dem network alias). Diese Services liegen bei Kubernetes aber in einem anderen Subnetz und ich kann  gegen diese IP dann logischerweise keinen Port binden.

Was ich nicht verstehe: Warum gehört das überhaupt zusammen? Warum wird der Port nicht an 0.0.0.0 gebunden und dem Registrar erklärt, dass man unter w.x.y.z zu erreichen ist?

Ich habe mir dazu mal die Methodenaufrufe angeschaut und folgenden Anpassungvorschlag in SIP_Register[338-368]:

if ($port)
  {
   $port +=10 if ($type eq "calling");
   Log3 $name,4,"$logname, trying to use port $port";

   $leg = IO::Socket::INET->new(Proto => 'udp', LocalPort => $port);

   # if  port is already used try another one
   if (!$leg)
   {
    Log3 $name,1,"$logname, cannot open port $port at $ip : ".$!;
    $port += 10;
    $leg = IO::Socket::INET->new(Proto => 'udp', LocalPort => $port) || return "can't open port $port at $ip : ".$!;
    Log3 $name,2,"$logname, using secundary port $port with IP $ip";
   }

   close($leg);
   #$leg = $ip.":".$port;
   $leg = Net::SIP::Leg->new(
  addr => '0.0.0.0',
          host => $ip,
          port => $port);
  }
  else
  {
    #$leg = $ip;
$leg = Net::SIP::Leg->new(
           addr => '0.0.0.0',
           host => $ip);
    Log3 $name,4,"$logname, using Leg.pm to find a free port";
  }


Damit wird der Port an 0.0.0.0 gebunden und die unter sip_ip angegebene Adresse als externe Adresse announced. Das funktioniert in einem ersten Test bei mir und ich umgehe viele Probleme.

Any thoughts?

rob

Naja schade eigentlich. Mir scheinen die Küberneten-Dinger damit unnötig umständlich zu funktionieren, wenn man keine Aliase nehmen kann. Dann wäre für jeden Dienst irgendein Workaround nötig - den Du für Dich schon gefunden zu haben scheinst. Wie sich der Vorschlag auf andere Installationen auswirkt, kann ich nicht beurteilen.

Ansonsten hätte ich noch versucht die Host-IP zu binden, weil die Ports ja zum Host nach außen gemappt werden. Bei manchen Diensten klappt das, wenn sie z.B. den Alias nicht auflösen wollen.

Ein anderer grob gedachter Workaround wäre ggf. ein notify, das auf den FHEM-Neustart triggert, sich die aktuelle IP im Container holt (sysmon-reading oder {qx(hostname -I)}), mit sip_ip vergleicht und neu reinschreibt, falls abweichend. Man müsste nur drauf achten, dass z.B. sysmon bereits aktualisiert ist - also ggf. durch ein at etwas später auslösen. Müsste ggf. weiter ausgefeilt werden, aber so müsste nichts weiter an Modulen geändert werden. Ganz ohne basteln geht es wohl nicht  ;)

Flachzange

Mein Punkt ist ja eher, dass die Art und Weise wie der Port an sip_ip gebunden wird, nicht ideal ist, da sip_ip ja eigentlich einen anderen Zweck hat. Mit der Anpassung oben (entfallen) möglicherweise diverse Workaroundüberlegungen. Bei mir funktioniert es jetzt jedenfalls so.

plin

FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

Wzut

Zitat von: Flachzange am 16 August 2022, 06:19:23
Warum wird der Port nicht an 0.0.0.0 gebunden
weil vermutliche damals die Beispiele von Net::SIP es auch nicht getan haben und wir/ich es auch nicht besser wussten bzw. bis heute kein Grund vorhanden war das in irgend einer Weise in Frage zu stellen.
Ich habe kein Problem damit das in der vorgeschlagenen Art zu übernehemen, allerdings hätte ich gern noch Rückmeldung von jemand der das Modul in einem System einsetzt wo mehr als eine IP bzw. mehr als ein Netzwerkinterface vorhanden ist.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

plin

#1211
Mein Test war nicht erfolgreich. Ich habe die Änderung eingebaut und aktiviert. Wenn ich die FritzFon App anrufe und den Anruf annehme höre ich "die Verbindung wird gehalten". Mit dem Original-Modul kann ich DTMF-Töne in der App hören.

x86 Server mit OpenSUSE und
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
veth40a1b93: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
veth43be765: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
vethc647e20: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
vethd6e55a3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500


Eigentlich nicht wirklich verständlich ...

Gleicher Effekt beim Fritz!FON C5.
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

Flachzange

Zitat von: plin am 20 August 2022, 12:40:59
Mein Test war nicht erfolgreich. Ich habe die Änderung eingebaut und aktiviert. Wenn ich die FritzFon App anrufe und den Anruf annehme höre ich "die Verbindung wird gehalten". Mit dem Original-Modul kann ich DTMF-Töne in der App hören.
In der Tat ist das bei mir genauso. Ich hatte es darauf geschoben dass ich die RTP-Ports nicht durchgereicht habe. Da ich nur die Anrufsignalisierung brauche, habe ich jetzt auch nicht weiternachgeschaut. Jedenfalls brachte auch die Änderung der Ports in der Util.pm nichts.

Vielleicht könnte es noch jemand testen, der mit einem nativen Interface arbeitet und nicht über NAT o.ä. im Docker oder bei dem es definitv vorher funktionierte mit den RTP-Ports.

amehl

Ich habe gerade SIP und T2S eingerichtet um meine Fritz Telefone als Ausgabegeräte für Mitteilungen zu nutzen. (z.B. "Das Fenster im Bad ist offen") Jetzt hab ich ein kleines Problem und eine Grundsatzfrage.

1. Ist es überhaut möglich Text am Telefon auszugeben ohne das es klingelt und man abheben muss?

2. SOC erstellt nur eine mp3 Date und wandelt diese dann nicht um (siehe log) Wenn Punkt eins nicht geht hat es sich erledigt, da es für meine Zwecke dann nicht geeignet ist.

2022.08.31e] 09:34:22 4: FritzSprecher, wait_for_t2s file : mp3/d742838fdcc54447e89ca66f9d75f007.mp3
2022.08.31 09:34:22 4: FritzSprecher, new T2S file mp3/d742838fdcc54447e89ca66f9d75f007.mp3
2022.08.31 09:34:22 5: FritzSprecher, /usr/bin/sox mp3/d742838fdcc54447e89ca66f9d75f007.mp3 -t raw -r 8000 -c 1 -e a-law alaw/d742838fdcc54447e89ca66f9d75f007.mp3 2>&1
2022.08.31 09:34:22 5: FritzSprecher, sox output : /usr/bin/sox FAIL formats: can't open output file `alaw/d742838fdcc54447e89ca66f9d75f007.mp3': No such file or directory

Wzut

Zitat von: amehl am 31 August 2022, 09:50:48
Ist es überhaut möglich Text am Telefon auszugeben ohne das es klingelt und man abheben muss?
Das ist keine Job für das Modul sondern für das benutzte Telefon.
Ich kenne z.b. kein Telefon das so etwas machen würde, das ist eher ein Job für einen echten Anrufbeantworter.

Bei mir läuft das mit zweimal FHEM - FHEM 1 ist das Hauptsystem im Keller und ruft FHEM 2 an. FHEM 2 ist ein Raspi in meiner Wohnung mit USB Lautsprechern.
Das SIP Modul läuft da mit attr sip_listen am. 
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher