Linux NetMag #5
Titel: Dial-In-Server: ISDN
URL: http://www.linuxnetmag.de/de/issue5/m5disisdn1.html

Dial-In-Server Ziel ist es, einen Linux Rechner als Dial-In-Server (Einwahlrechner) zu konfigurieren. Dabei ist gemeint, Anrufern den Zugriff auf den Linux-Rechner über eine ISDN-Leitung (B-Kanal) zu ermöglichen.


Autor: Matthias Kranz

Themen:

1. Einleitung

Es soll hierbei kein Terminal-Zugang ermöglicht werden, sondern ausschließlich der Zugang auf den (lokalen) Web-Server des Linux Rechners.

Als Protokoll soll das PPP-Protokoll (Point-to-Point-Protocol) verwendet werden, zur Authentifizierung der Berechtigung soll PAP (Password Authentication Protocol) oder CHAP (Cryptographic Handshake Autehntication Protocoll) verwendet werden.

Aus Sicherheitsgründen sollen die Anrufer nicht Benutzer des Linux Rechners sein. Bei dem hier vorgestellten Konfigurationsweg ist es aber bedeutungslos, ob die Anrufer einen Benutzer-Account auf dem Linux Rechner haben oder nicht.
Der hier beschriebene Weg wird für SuSE Linux 6.3 beschrieben, ist aber auf anderen Linux Systemen analog. Es sind ggf. nur die Pfade zu den Dateien entsprechend den lokalen Gegebenheiten anzupassen.

2. Voraussetzungen

Ein ISDN-Anschluß eines Telefonanbieters seiner Wahl - das muß nicht unbedingt die ... naja Ihr wißt schon wer ... sein und eine von Linux unterstützte ISDN-Karte/ISDN-Modem.

Es wird vorausgesetzt, daß auf dem Linux Rechner die PPP-Unterstützung gegeben ist - entweder in den Kernel kompiliert oder als Modul. Auf meinem Rechner ist die PPP-Unterstützung als Modul realisiert. Ist das nicht der Fall, sollte man jetzt mal kurz in eine Shell wechseln und man pppd und die PPP-HOWTO lesen.

Des weiteren wird vorausgesetzt, daß die ISDN-Hardware korrekt installiert und eingebunden ist und z.B. mit isdnctrl dial ippp0 eine funktionierende Verbindung zu einem ISP (Internet Service Provider) nach Wahl aufgebaut werden kann. Ist das nicht der Fall, sollte man jetzt die ISDN-HOWTO lesen.
Noch da? Dann kann es ja losgehen.

3. Konfiguration
Net-Device anlegen

Zuerst muß ein NETDEV in der /etc/rc.config angelegt werden und dafür eine IP-Adresse vergeben werden. Das von uns angelegte Device wird durch die Kommentare am Ende der Zeilen deutlich gemacht. Wir nehmen als NETDEV "ippp2" was ausschließlich daran liegt, daß ich "ippp0" und "ippp1" verwende um mich selbst mit meinen Internet-Providern zu verbinden. Wenn Ihr keine "ippp0" und "ippp1" habt, dann könnt Ihr die natürlich auch nehmen - wenn nicht, ist es auch egal, wenn Ihr (um Verwirrungen zu vermeiden) einfach trotzdem "ippp2" verwendet.

Es ist natürlich möglich, das NETDEV mit YAST anzulegen - wir machen das einfach mal selbst.

Eine entsprechende Konfiguration könnte so aussehen:

Ausschnitt /etc/rc.config
 # Kommentare werden durch eine Raute/Gatter eingeleitet und werden ignoriert.
 # Leerzeilen werden ebenfalls ignoriert.
 # NETZWERK-Konfiguration:
 # Anzahl der Netzwerk-Devices, hier sind die Devices 0 bis 3 definiert
 #
 NETCONFIG="_0 _1 _2 _3"
 #  
 # IP Adressen der zugehörigen Devices
 # 
 IPADDR_0="192.168.0.1"     # Das ist meine Netzwerkkarte
 IPADDR_1="192.168.0.99"	   # darauf hört NETDEV 1
 IPADDR_2="192.168.0.98"    # darauf hört NETDEV 2
 IPADDR_3="192.168.0.97" # DAS NEUE NETDEV: darauf hört NETDEV 3
 # 
 # Namen der NETDEVs:
 # 
 NETDEV_0="eth0"		   # eth0 = Netzwerkkarte
 NETDEV_1="ippp0"	   # uninteressant, EINWAHL bei einem ISP
 NETDEV_2="ippp1"	   # uninteressant, EINWAHL bei einem anderen ISP
 NETDEV_3="ippp2"	   # DAS NEUE NETDEV: soll ippp2 heissen
 #  
 # Parameter für ifconfig (Infos dazu gibt es mit "man ifconfig" ;-)
 # 
 IFCONFIG_0="192.168.0.1 broadcast 192.168.0.255 netmask 255.255.255.0 up"# uninteressant
 IFCONFIG_1="192.168.0.99 dynamic  pointopoint 192.168.0.1 up"            # uninteressant
 IFCONFIG_2="192.168.0.98 dynamic  pointopoint 192.168.0.1 up"		 # uninteressant
 IFCONFIG_3="192.168.0.97 pointopoint 192.168.0.1 metric 1"		 # DAS NEUE NETDEV

Nachdem wir das geändert haben, müssen wir noch "SuSEconfig" laufen lassen um die Änderungen wirksam zu machen.

Jetzt sagen wir das ganze auch i4l. Die Konfigurationsdateien für ISDN4Linux liegen bei SuSE unter
/etc/rc.config.d/i4l_default.rc.config
/etc/rc.config.d/i4l_option.rc.config

Bei anderen Linuxen ist das teilweise ebenfalls in der /etc/rc.config. Nunja, in der default werden allgemeine Geschichten festgelegt, in der Option wird das noch weiter konkretisiert - für jedes Device seperat.

In der /etc/rc.config.d/i4l_default.rc.config sollte das ungefähr so aussehen:

Ausschnitt /etc/rc.config.d/i4l_default.rc.config
 # Kommentare werden durch eine Raute/Gatter eingeleitet und werden ignoriert.
 # ISDN4LINUX starten ? (yes/no) 
 I4L_START="yes"
 # In Deutschland wird zwar teilweise noch 1TR6 verwendet, gebräuchlicher ist 
 # aber Euro-ISDN.
 # D-channel protocol 1=1TR6, 2=EDSS1(Euro-ISDN) for HiSax
 I4L_PROTOCOL="2"  
 # 
 # Optionen sind: "auto", "off" oder "manual". Ganz kurz dazu:
 # off: Überhaupt keine Verbindungen machen - weder raus noch rein
 # manual: User baut Verbindungen selbst auf - z.B. wählen mit "isdnctrl dial ippp0"
 # auto: Verbindung aufbauen, wenn es notwendig ist. 
 # Mehr Infos in der Doku zu i4l ;-).
 I4L_DIALMODE_0="auto"		# bezieht sich auf andere Geräte
 I4L_DIALMODE_1="auto"		# bezieht sich auf andere Geräte
 I4L_DIALMODE_2="auto"		# bezieht sich auf andere Geräte
 I4L_DIALMODE_3="auto"	# DAS NEUE NETDEV

Und jetzt die i4l_option.rc.config:

Ausschnitt /etc/rc.config.d/i4l_default.rc.config
 # IDLE-Zeit bevor aufgehängt wird, in Sekunden:
 # 
 I4L_IDLETIME_0="60"
 I4L_IDLETIME_1="120"
 I4L_IDLETIME_2="120"
 I4L_IDLETIME_3="60"
 # 
 # Anzahl d. Wählversuche, bevor aufgegeben wird. Ist für NETDEV 3 egal !
 I4L_DIALMAX_0="5"
 I4L_DIALMAX_1="5"
 I4L_DIALMAX_2="5"
 I4L_DIALMAX_3="5"
 # 
 # Die MSN oder EAZ. Für i4l ist das das gleiche (fast zumindest).
 # Nun ist es wichtig: Habt Ihr eine Telefonanlage oder nicht ? 
 # Ich habe eine. Die weist einer (externen) Rufnummer von mir eine (interne) 
 # Nummer zu. Wenn Ihr keine habt: einfach die Nummer angeben, auf die das 
 # NETDEV hören soll.
 # Je nachdem müßt Ihr das anpassen.
 I4L_LOCALMSN_0=""
 I4L_LOCALMSN_1="123456"
 I4L_LOCALMSN_2="123456"
 I4L_LOCALMSN_3="18"
 # 
 # Welche Nr. soll bei ausgehenden Rufen gewählt werden ?
 # Für das NETDEV das DIALIN machen soll, ist da natürlich keine angegeben.
 I4L_REMOTE_OUT_0=""
 I4L_REMOTE_OUT_1="meinProvider 1"
 I4L_REMOTE_OUT_2="meinProvider 2"
 I4L_REMOTE_OUT_3=""
 # 
 # Welche Nummern sollen sich einwählen können ? 
 # Nachdem wir mit PAP/CHAP die Berechtigungen prüfen, lasse ich das mal weg - 
 # Probleme gibt es an anderen Stellen noch genug ;-)))
 I4L_REMOTE_IN_0=""
 I4L_REMOTE_IN_1=""
 I4L_REMOTE_IN_2=""
 I4L_REMOTE_IN_3=""
 # 
 # Protokoll ? Synchrones PPP oder ... ? -> i4l Doku ! 
 I4L_ENCAP_0="syncppp"
 I4L_ENCAP_1="syncppp"
 I4L_ENCAP_2="syncppp"
 I4L_ENCAP_3="syncppp"
 # 
 # Optionen:
 # "on" : nur die angegebenen Nummern dürfen anrufen
 # "off" : alle Nummern dürfen anrufen 
 I4L_SECURE_0="off"
 I4L_SECURE_1="off"
 I4L_SECURE_2="off"
 I4L_SECURE_3="off"

Jetzt müssen wir noch für das NETDEV ippp2 eine Konfigurationsdatei schreiben. Die bei der Installation mitgelieferten Dateien von Klaus Franken ([email protected]) dienen dabei als Grundlage.
Die sind bei der i4l-Installation mit YAST dabei, also laßt den armen Mann in Ruhe. Ausführlichste Erläuterungen finden sich dazu in der lokalen Supportdatenbank die ebenfalls mittels YAST installiert werden kann !

Die Dateien für die ISDN-Devices finden sich unter /etc/ppp/. Dort gibt es (u.a.)
/etc/ppp/options - globale Einstellungen für PPPD (man ppp)
/etc/ppp/ioptions - globale Einstellungen für IPPP (man pppd)
/etc/ppp/options.ippp2 - Einstellungen für das von uns ausgewählte NETDEV

Für die Authentifizierung brauchen wir auch noch die PAP und CHAP Dateien:
/etc/ppp/pap-secrets - Wir verwenden hier nur PAP Authentifizierung;
/etc/ppp/chap-secrets - Kann man natürlich auch noch verwenden (zusätzlich oder ausschließlich )
Über Authentifizierung wird ausführlich in den Manpages zu PPPD und IPPPD gesprochen. Es empfiehlt sich wenigstens ein Blick...

Je nachdem, wie viele ISDN-Devices und analoge Devices Ihr habt, gibt es auch noch andere Dateien. Gehen wir die Dateien Schritt für Schritt durch:

Ausschnitt /etc/ppp/ioptions
 # fuer mehr Informationen bei tail -f /var/log/messages 
 # Zur Fehlersuche genau das Richtige.
 debug 
 # um das Passwort in tail mitzuloggen kann man die nächste Zeile 
 # einkommentieren - daß das nicht gerade zur Systemsicherheit beiträgt,
 # brauche ich hoffentlich keinem zu sagen !
 # +pwlog

Mehr braucht nicht enthalten zu sein.

Jetzt konfigurieren wir das zu unserem NETDEV gehörige ippp-Device.

Ausschnitt /etc/ppp/ioptions
 # /etc/ppp/options.ippp2
 # basierend auf dem Originalskript von 
 # Klaus Franken, [email protected] 
 # 
# Das zu verwendende Gerät: # naja, das sage ich nun zum letzten Mal. /dev/ippp2 # # debug ? debug # Infos zu proxyarp gibt es in man ipppd # Kurz: soll Zugriff auf die anderen Rechner im LAN sein ? # Bei mir jedenfalls nicht ! # proxyarp # # IP Addressen: # "0.0.0.0:" für dynamische IP-Adressen # In der /etc/rc.config haben wir dem Gerät die 192.168.0.97 gegeben. # Das soll auch so bleiben. # Der Rechner, der sich einwählt, soll die 192.168.0.240 bekommen. # Das Ganze kann man auch anders machen, aber das paßt gerade in meine # LAN-Konfiguration hinein. Ihr könnt das ja ändern, wenn es erst mal # geklappt hat. 192.168.0.97:192.168.0.240 # # Defaultroute setzen ? Dazu unbedingt in man ipppd nachlesen ! # defaultroute # # Benutzername desjenigen, der sich einwählen können soll ? user ich # # Erzwingen der Authetifizierung mittels PAP +pap # # Ob Ihr das braucht - ich nicht. DAZU man ipppd # ipcp-accept-local # ipcp-accept-remote # noipdefault # useifip # # disable header-compression #-vj #-vjccomp #-ac #-pc #-bsdcomp # # max receive unit mru 1524 # max transmit unit mtu 1500

Die Authentifizierung erfolgt in unserer Konfiguration ausschließlich über PAP. Deshalb betrachten wir nun die
/etc/ppp/pap-secrets :

testuser	*	test
Ende /etc/pap-secrets.

Der Aufbau ist dabei: username, remote-host-Einschränkungen, plain-text-Paßwort, jeweils durch Tabulator getrennt.

Jetzt kann sich z.B. ein Windows-98 Rechner über das DFÜ-Netzwerk einwählen, ohne irgendwelche zusätzlichen Scripte für die Einwahl zu definieren.

Jetzt mal das System neu starten. (Eigentlich würde es reichen, i4l neu zu starten. Da erfahrungsgemäß nicht gleich beim ersten mal alles klappt, kann man sich ja folgendes Script in z.B. /usr/bin/ ablegen:

restart-isdn
/sbin/init.d/i4l stop 
/sbin/init.d/i4l_hardware stop
/sbin/init.d/i4l_hardware start
/sbin/init.d/i4l start

(download)

Die Rechte sind so zu setzen, daß nur root bzw. möglicherweise die Mitglieder der Gruppe dialout das Script ausführen können. Man kann die Befehle aber natürlich auch in dieser Reihenfolge an der Shell absetzen.)

Jetzt ist es mal an der Zeit, die Einwahl auszuprobieren. Mit tail -f /var/log/messages kann man nachvollziehen ob alles geklappt hat.

Wenn alles gut gegangen ist, dann sieht der Verbindungsaufbau so aus:
Kleiner Hinweis: ich habe das intern getestet, deshalb steht da **18 als MSN! Aber wenn das erst mal geht, dann geht es auch von extern.

Ausschnitt aus tail -f /var/log/messages
isdnlog: Dec 30 18:03:08 * Call to tei 127 from TN **11 on +49 1234/18, meinWohnort  RING (Data)
isdnlog: Dec 30 18:03:08   Call to tei 67 from TN **11 on +49 1234/18, meinWohnort  CONNECT (Data)
isdnlog: Dec 30 18:03:08 tei 65 calling TN **18 with ?  COLP TN **18
isdnlog: Dec 30 18:03:08 tei 65 calling TN **18 with ?  CONNECT
isdnlog: Dec 30 18:03:08 tei 65 calling TN **18 with ?  CHARGE: free of charge - internal call
kernel: isdn_net: ippp2 connected
kernel: isdn_net: chargetime of ippp2 now 2805504
ipppd[188]: Local number: 18, Remote number: , Type: incoming
ipppd[188]: PHASE_WAIT -> PHASE_ESTABLISHED, ifunit: 2, linkunit: 0, fd: 7
ipppd[188]: sent [0][LCP ConfReq id=0x1 <mru 1524> <auth pap> <magic 0xb45a62> <pcomp> <accomp>]
ipppd[188]: rcvd [0][LCP ConfReq id=0x1 <magic 0x58468> <pcomp> <accomp> <callback 6>]
ipppd[188]: sent [0][LCP ConfRej id=0x1 <callback 6>]
ipppd[188]: rcvd [0][LCP ConfAck id=0x1 <mru 1524> <auth pap> <magic 0xb45a62> <pcomp> <accomp>]
ipppd[188]: rcvd [0][LCP ConfReq id=0x2 <magic 0x58468> <pcomp> <accomp>]
ipppd[188]: sent [0][LCP ConfAck id=0x2 <magic 0x58468> <pcomp> <accomp>]
ipppd[188]: lcp layer is UP
ipppd[188]: rcvd [0][PAP AuthReq id=0x1 user="testuser" password not logged for security reasons! 
  Use '+pwlog' option to enable full logging.]
ipppd[188]: Check_passwd called with user=testuser
ipppd[188]: sent [0][PAP AuthAck id=0x1msg="Login ok"]
ipppd[188]: MPPP negotiation, He: No We: No
ipppd[188]: sent [0][IPCP ConfReq id=0x1 <addr 192.168.0.97> <compress VJ 0f 01>]
ipppd[188]: CCP enabled! Trying CCP.
ipppd[188]: CCP: got ccp-unit 0 for link 0 (protocol: 0x80fd)
ipppd[188]: ccp_resetci!
ipppd[188]: rcvd [0][IPCP ConfReq id=0x1 <compress VJ 0f 01> <addr 192.168.0.240> 
  <ms-dns1 0.0.0.0> <ms-wins1 0.0.0.0> <ms-dns2 0.0.0.0> <ms-wins2 0.0.0.0>]
ipppd[188]: sent [0][IPCP ConfRej id=0x1 <ms-dns1 0.0.0.0> <ms-wins1 0.0.0.0> 
  <ms-dns2 0.0.0.0> <ms-wins2 0.0.0.0>]
ipppd[188]: rcvd [0][IPCP ConfAck id=0x1 <addr 192.168.0.97> <compress VJ 0f 01>]
ipppd[188]: rcvd [0][IPCP ConfReq id=0x2 <compress VJ 0f 01> <addr 192.168.0.240>]
ipppd[188]: sent [0][IPCP ConfAck id=0x2 <compress VJ 0f 01> <addr 192.168.0.240>]
ipppd[188]: local  IP address 192.168.0.97
ipppd[188]: remote IP address 192.168.0.240

Und wenn die Verbindung vom (Windows-)Remote-Rechner getrennt wird, sollte das dann so aussehen:

Ausschnitt aus tail -f /var/log/messages
ipppd[188]: rcvd [0][LCP TermReq id=0x3]
ipppd[188]: LCP terminated by peer
ipppd[188]: sent [0][LCP TermAck id=0x3]
isdnlog: Dec 30 18:03:43   Call to tei 67 from TN **11 on +49 1234/18, meinWohnort
Normal call clearing (User) kernel: isdn_net: local hangup ippp2 kernel: ippp2: Chargesum is 0 ipppd[188]: Modem hangup ipppd[188]: Connection terminated. ipppd[188]: taking down PHASE_DEAD link 0, linkunit: 0 ipppd[188]: LCP is down ipppd[188]: closing fd 7 from unit 0 ipppd[188]: link 0 closed , linkunit: 0 ipppd[188]: reinit_unit: 0 kernel: ippp, open, slot: 2, minor: 2, state: 0000 kernel: ippp_ccp: allocating reset data structure ipppd[188]: Connect[0]: /dev/ippp2, fd: 7 isdnlog: Dec 30 18:03:45 Call to tei 67 from TN **11 on +49 1234/18, meinWohnort
HANGUP ( 0:00:35 I=250.0 b O=144.0 b) isdnlog: Dec 30 18:03:45 tei 65 calling TN **18 with ? Normal call clearing (User) isdnlog: Dec 30 18:03:45 tei 65 calling TN **18 with ? HANGUP ( 0:00:37)

Ein paar Hinweise habe ich noch:

Problem:
Verbindung wird nach ein paar Sekunden gleich wieder getrennt. Verwendet wird ein Hybrid-Modem (ELSA Microlink ISDN/TL V.34)
tail -f /var/log/messages liefert:

Ausschnitt aus tail -f /var/log/messages
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: sent [0][LCP ConfReq id=0x1 <mru 1524> <auth pap> <magic 0x93b35c1e> <pcomp> <accomp>]
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: sent [0][LCP ConfReq id=0x1 <mru 1524> <auth pap> <magic 0x93b35c1e> <pcomp> <accomp>]
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: rcvd [0][proto=0x801] af 82 00 03 01 01 03
ipppd[188]: rcvd [0][proto=0x801] 7f
ipppd[188]: sent [0][LCP ConfReq id=0x1 <mru 1524> <auth pap> <magic 0x93b35c1e> <pcomp> <accomp>]
isdnlog: Dec 30 18:11:52   Call to tei 67 from TN **11 on +49 1234/18, meinWohnort 
   Normal call clearing (User)
isdnlog: Dec 30 18:11:52 tei 65 calling TN **18 with ?  HANGUP ( 0:00:10)
kernel: ippp2: remote hangup
kernel: ippp2: Chargesum is 0
ipppd[188]: Modem hangup
ipppd[188]: Connection terminated.
ipppd[188]: taking down PHASE_DEAD link 0, linkunit: 0
ipppd[188]: sent [0][LCP TermReq id=0x2 6c 69 6e 6b 20 63 6c 6f 73 65 64]
ipppd[188]: LCP is down
ipppd[188]: closing fd 7 from unit 0
ipppd[188]: link 0 closed , linkunit: 0
ipppd[188]: reinit_unit: 0
ipppd[188]: Connect[0]: /dev/ippp2, fd: 7
kernel: ippp, open, slot: 2, minor: 2, state: 0000
kernel: ippp_ccp: allocating reset data structure
isdnlog: Dec 30 18:11:52   Call to tei 67 from TN **11 on +49 1234/18, meinWohnort 
   HANGUP ( 0:00:11 I=108.0 b O=104.0 b)

Ursache:
Das Hybrid-Modem verwendet falsche Init-Strings, so wird ein "falsches" Protokoll für die Einwahl verwendet.
Man ändere den Init-String so, daß das Hybrid-Modem angewiesen wird, explizit eine ISDN-Verbindung aufzubauen (AT \N10 tut es). Oder man gibt einfach keinen \Nxx Parameter an.

Habt Ihr weitere Probleme (und Lösungen)? Dann bitte unten in die Kommentar-Box eintragen!

Und wenn was nicht geht? Dann als erstes das Ganze überprüfen, die Ausgaben von tail ansehen. Die Doku nochmal lesen, Ihr habt die Dokus doch gelesen ... ?

Und wenn es aber immer noch nicht geht? Wenn ich Zeit habe, werde ich versuchen, Euch zu helfen. Aber es gibt da ja auch noch die Newsgroup alt.de.comm.isdn4linux wo Ihr Fragen stellen könnt. Allerdings solltet Ihr dann die Ausgaben von tail etc. und Eure Konfiguration (in Auszügen) mitsenden, so daß nachvollziehbar ist, was Ihr gemacht habt).

4. Dokumentation: