next up previous contents
Next: Umsetzung und praktische Ergebnisse Up: Studienarbeit Previous: Soll-Analyse für den Einsatz   Contents

Subsections


Lösungsansätze

Aus den allgemeinen Forderungen an ein verteiltes Zugangskontrollsystem und den speziellen für den Einsatz an der TU Chemnitz ergeben sich Überlegungen bzgl. Architektur, Hardware und Kommunikationssystem, welche im folgenden Abschnitt diskutiert werden sollen.


Ziel bei der Entwicklung der verteilten Zugangssteuerung ist es, ein System zu entwickeln, welches allgemein anwendbar ist. Dennoch müssen Umstände, welche bei dem praktischen Einsatz eines solchen System entstehen, bei der Entwicklung beachtet werden.

Da das System als Erstes[*] an der TUC eingesetzt werden soll, versuche ich die Lösungsansätze ausgehend von diesen Gegebenheiten (siehe Soll-Analyse) zu entwickeln. Neben den nominellen Bedingungen (z.B. Anzahl der Nutzer) sind finanzielle und hardwarespezifische Bedingungen für die Entwicklung sehr von Bedeutung, da diese meist nicht abänderbar sind. Aus diesem Grund folgen im nächsten Abschnitt als erstes Überlegungen zur vorhandenen und anzuschaffenden Hardware.


Hardwarekomponenten

Bei einer Umstellung auf eine neue Zugangssteuerung an der TU Chemnitz muss vorerst der vorhandene Datenbus (RS485) weiter genutzt werden, da es bei einer Umstellung aufwendig wäre, zusätzlich zu jeder Tür Twisted-Pair-Kabel für Ethernet zu verlegen. Weiterhin ist es denkbar, dass das Zugangssystem in anderen Einrichtungen eingesetzt werden soll, wo der Datennetzausbau nicht so weit gediehen ist, wie an der TU Chemnitz. Dann ist es unter Umständen unumgänglich, auf preiswerte 2-Draht-Bussysteme (oder beliebige andere Kommunikationssysteme z.B. GSM) zurückzugreifen.

Solche preiswerten Bussysteme sind meist nicht so zuverlässig und performant wie Ethernet, da ihre Spezifikation geringe Bandbreiten über ungeschützte Kabel vorsieht.

Da eine Vorgabe (siehe Kapitel 4.1) die Ausfallsicherheit ist, müssen die Steuereinheiten autark (Offline-System) arbeiten können, um bei eventuellen Kommunikationsstörungen trotzdem noch Anfragen beantworten zu können. Weiterhin könnte es passieren, dass ein Benutzer des Systems die Steuereinheiten nicht mit einer permanenten Datenverbindung arbeiten lassen kann (z.B. Filiale über GSM angebunden). Dann ist es Voraussetzung, dass die Steuereinheit über einen Controller mit eigenen Speicher besitzen.


Client-Controller

Aus diesen Überlegungen ist zu schlussfolgern, dass die Steuereinheit alle relevanten Zugangsdaten vorhalten müssen. Deshalb benötigen die Controller genügend Speicher und die entsprechende Rechenleistung, um diese Daten zu verarbeiten. Da jede Tür, welche gesteuert werden soll, in sinnvoller Entfernung eine Steuereinheit benötigt, zeichnet sich ab, dass fast jede zu steuernde Tür einen solchen autarken Controller benötigt. An der TUC sollen ca. 50 Türen durch eine verteilten Zugangssteuerung gesichert werden. Aus diesem Grund dürfen die Kosten pro Gerät nicht zu hoch werden. Die maximalen Kosten dürfen schätzungsweise 1000 EUR pro Tür nicht übersteigen. Dies haben verschiedene Gespräche mit der URZ-Leitung ergeben.

Eine weitere Anforderung ist, dass die Geräte in öffentlichen Räumen angebracht werden müssen, wo viele Personen Zugriff darauf haben. Dies erfordert, dass alle elektronischen Geräte in einem kompakten Gehäuse untergebracht sind.

Ein weiterer Aspekt für den Einsatz eines solchen Systems an der TUC ist, dass diese Eigenentwicklung auf allgemein bekanntem Know-How basieren muss, damit sie später weiterentwickelt und gepflegt werden kann. Deshalb wird als Betriebssystemplattform für den Controller in den Steuereinheiten Linux empfohlen.

Dieses setzt jedoch voraus, dass als Controller-Hardware ein Prozessor gewählt wird, welcher die nötige Rechenleistung besitzt und unter Linux lauffähig ist. Weiterhin ist es für die Entwicklung sinnvoll, eine Standardplattform[*] zu nutzen. Somit ist es möglich, auf herkömmlichen Arbeitsplatzrechnern Programme zu entwickeln, welche ohne Aufwand auf den Controllern lauffähig sind.

Aus diesen Überlegungen und den Forderungen, welche gestellt worden sind, schlage ich eine Intel x86-kompatible Plattform mit mindestens 66 MHz Taktfrequenz vor. Diese Leistung ist für Linux und voraussichtlich für den Teil der Zugangssoftware, welcher auf dem Controller zum Einsatz kommen soll, ausreichend. Bei der Auswahl eines entsprechenden Boards ist die Leistungsaufnahme, die Abwärme und die Höhe der Kosten mit zu beachten. Weiterhin sollte das einzusetzende Board die Möglichkeit bieten, den Permanentspeicher einfach auszutauschen, um Betriebssystemupdates oder Wartungsarbeiten zu vereinfachen. Es ist sinnvoll, einen steckbaren ATA-Flash (auf 2.5 Zoll Basis) zu nutzen. Dieser ist ohne bewegliche Teile, erzeugt geringe Abwärme, ist ohne Werkzeug austauschbar und erschütterungsunempfindlich.

Die geforderten Schnittstellen (2 x seriell, 1 x parallel) stellt ein handelsübliches [*] x86-embedded Board zur Verfügung. Weiterhin muss die Möglichkeit vorhanden sein, den Türöffnungsmagneten im Türschloss (max. Last 12V/1A) zu steuern. Dies könnte durch ein elektronisches Lastrelais, ein normales Relais mit vorgeschalteter Verstärkungsschaltung oder ein Reed-Relais erfolgen. Um die Modularität zu erhöhen und den Anteil der Produktion von speziellen Schaltungen zu minimieren, empfehle ich die Verwendung von elektronischen Lastrelais.


Als Gefäßsystem empfehle ich ein montierbares, abschließbares und geschlossenes Wandgehäuse (z.B. Rital). Es bietet sich weiterhin an, DIN-Schienenkomponenten zu nutzen. Dies hätte den Vorteil, dass die Steuereinheiten modular aufbaubar ist und defekte Komponenten leicht austauschbar sind. Bei dem Gehäuse ist darauf zu achten, dass die vom Gehäusehersteller vorgegebene Abwärmekapazität eingehalten wird. Die produzierte Abwärme steht im direkten Bezug zur aufgenommen Leistung und ist somit einfach messbar.


Daraus ergeben sich Anforderungen an die Steuereinheiten für den Einsatz an der TUC, welche in Tabelle 1 zusammengefasst sind.

Es ist anzustreben, die Produktion der Steuereinheiten anhand der präzisierten Anforderungen aus Tabelle 1, einem Unternehmen zu überlassen. Die Konzeption der Controller könnte in kooperativer Arbeit aufgrund meiner Überlegungen geschehen.


Table 1: Mindestanforderungen an die Steuereinheiten
Rechensystem Intel x86-kompatibel
Rechenleistung 66 MHz
persistenter Speicher 16 MByte
flüchtiger Speicher 16 MByte
Schnittstellen 2 x RS232
  1 x LPT
sonstige Anforderungen kompaktes Gehäuse
  integriertes Netzteil
  Möglichkeit zum Schalten von 12V/1A



Kommunikationshardware

Wie schon im letzten Abschnitt erläutert, muss es möglich sein, den vorhandenen RS485-Bus zu nutzen. Dies setzt voraus, dass in den Steuereinheiten eine Schnittstelle existiert, welche für RS485 spezifiziert ist.

Viele x86-embedded Boards besitzen schon eine für RS485 spezifizierte Schnittstelle. Auf den Boards werden dazu von den Herstellern RS485-Leitungstreiber (wie z.B. der IC 75176) an einen seriellen Controller angeschlossen. Da an einem RS485-Bus nur jeweils 1 Gerät senden kann, werden die Leitungstreiber über die interne RTS-Leitung des seriellen Controller freigeschaltet (enabled). Dies geschieht, in dem die RST-Leitung auf ,,high'' gesetzt wird und somit der Leitungstreiber einen niederohmigen Zustand einnimmt. [22]

Leider hat sich gezeigt, dass die integrierten Leitungstreiber auf den mir zur Verfügung stehenden Boards (miniPC und Bisquit-PC) so geschaltet sind, dass sie während des Bootvorganges den Treiber aktivieren und somit die gesamte Kommunikation auf dem Bus stören.

Eine robustere Alternative ist ein externer Wandler zwischen RS232 und RS485, welcher automatisch den Leitungstreiber auf Senden schaltet, sobald über die RS232-Schnittstelle wirklich etwas gesendet wird. Somit kann es nicht passieren, dass der Leitungstreiber den Bus ,,aus versehen'' stört.

Es ist sinnvoll, einen Protokolltreiber für RS485 zu nutzen, welcher transparent IP zur Verfügung stellt. Dadurch verringert sich der Aufwand sowohl beim Implementieren der Client- als auch der Server-Komponenten, da nur eine Kommunikationstechnologie zum Einsatz kommt, welche darüber hinaus weltweit im Einsatz ist. Ein weiterer Vorteil ist, dass die zu entwickelnden Softwarekomponenten hardwareunabhängig programmiert und getestet werden können.


Weiterhin ist es sinnvoll, eine Ethernetschnittstelle in den Steuereinheiten vorzusehen. Bei weiteren Installationen von elektronischen Türsteuerungen kann im Rahmen des Baugeschehens an der TUC Twisted-Pair-Verkabelung bis zur Tür mit vorgesehen werden. Zukünftig sollen die Controller ausschließlich mit Ethernet an das Datennetz der TUC angebunden werden. Dies ist vorteilhafter als RS485, da IP über Ethernet an der TUC flächendeckend zur Verfügung steht, es ausfallsicherer als RS485 ist, eine hohe Bandbreite zur Verfügung stellt, es einfacher nutzbar ist und man sich Brücken (Bridges) zwischen RS485 und IP sparen kann[*].


Eine weitergehende Überlegung ist, dass man mittels eventuell vorhandenen Erweiterungsslots (z.B. PC/104 welche meist auf embedded Boards verfügbar sind) einen PC-Card-Adapter integrieren könnte, in welchen eine Wireless-Lan-Karte (Wavelan) gesteckt werden könnte. Da zukünftig die Steuereinheiten flächendeckend an der TUC eingesetzt werden sollen und perspektivisch auch alle mit Ethernet angebunden werden, ist es denkbar, dass diese Geräte auch die Aufgabe eines Wavelan-Access-Points übernehmen könnten. Mittels der Unterstützung des Linux-Kernels für 802.1q (Virtuelle LAN´s) und Bridging wäre es möglich, die Steuereinheiten als Acesspoint einfach in die vorhandene Wavelan-Struktur zu integrieren.


Server

Für die zentrale Bereitstellung von Diensten der verteilten Zugangssteuerung ist es sinnvoll, Intel x86-kompatible Computer zu verwenden, welcher für den Einsatz als Server geeignet sind, da diese relativ preiswert sind und keine außergewöhnlichen Anforderungen gestellt werden.

An der TUC ist es darüber hinaus sinnvoll, mindestens 2 Server vorzusehen, auf denen die zentralen Dienste redundant zur Verfügung gestellt werden. Diese Server sollten vom Universitätsrechenzentrum zentral gewartet und überwacht werden.


Architekturen

Die Architektur eines Systems wird durch die Verteilung der aktiven Komponenten beschrieben. Im folgenden Abschnitt werden diese Elemente, welche die Türen direkt steuern als Clienten, alle zentralen Elemente als Server und die Bediener, welche das System über Administrationsschnittstellen steuern als Administratoren bezeichnet.


Das System wird seine Wirkung räumlich verteilt entfalten müssen, da die zu steuernden Türen, die beteiligten Server und der Administrator nicht alle an einem Ort sind. Somit ist nur eine verteilte Architektur möglich.


Zur Realisierung verteilter Architekturen existieren mehrere Ansätze: [3]

Eine Möglichkeit wäre die Client-Server-Architektur. Bei dieser liegen alle beteiligten Daten zentral auf einem Server und die Clienten (in diesem Falle die Steuereinheit) fragen diese Daten ab. Das heißt auch, dass alle Programmlogik bei den Controllern der Steuereinheiten liegt. Ein Nachteil ist, dass das System nicht robust ist, da das System bei einem Serverausfall oder bei Netzausfall nicht mehr arbeitsfähig ist. Hinzu kommt, dass man mit dieser Architektur nur eine Online-Zugangssteuerung entwickeln kann.


Eine weiterführende Überlegung wäre, die Daten zu verteilen. Einerseits kann der Client einen Datencache anlegen, um bei Datennetzausfällen trotzdem arbeitsfähig zu bleiben, und andererseits wäre es denkbar, die Datenbankserver redundant zu installieren.

Eine weitere Möglichkeit wäre eine kooperative Verarbeitung. Dabei bekommen die Server neben der Aufgabe, die Daten zu verwalten, noch Programmlogik (Prozesslogik). Somit ist es möglich, dass der Client komplizierte Anfragen stellen kann und der Server die Ergebnismenge vorverarbeiten kann. Durch diese Verlagerung der Programmlogig in einen Server wir auch erreicht, dass die Clienten weniger Rechenleistung und Speicher benötigen und somit preiswerter werden.

Trotz der Vorteile durch die Verteilung von Daten und Programmlogik gibt es bei diesem Konzept einige Nachteile. Alle Clienten müssen die Adressen der Server kennen. Eine Adressänderung oder ein Hinzufügen eines Servers würde Änderungen der Konfiguration an allen Clienten erfordern. Weiterhin sind die Server (zentrale Steuerung) nur passiv und können die Clienten nicht direkt steuern. Dies wäre jedoch wünschenswert.

Es zeichnet sich außerdem ab, dass in dem zukünftigen System zahlreiche unabhängige Teilprobleme behandelt werden müssen, um den Nutzer sicher zu identifizieren und den entsprechenden Zugang zu erlauben. Zum Beispiel:

Es bietet sich an, diese Teilaufgaben sinnvoll in Teilprozesse (Dienste) aufzuteilen. Somit wären disjunkte Teilprobleme sowohl logisch als auch räumlich entkoppelbar. Eine Weiterentwicklung von Teilprogrammen hätte keinen Einfluss auf andere Teilprozesse. Die Teilprozesse sind unabhängig voneinander konfigurierbar.

Jedoch bringt diese Architektur auch Nachteile mit sich. Je feiner die Verteilung ist, desto größer ist der Kommunikations-Overhead. Die Verwaltung und Adressierung vieler Teilserver ist aufwändig. Weiterhin verursachen zu große Abhängigkeiten zwischen Diensten Seiteneffekte, welche nicht vorher absehbar sind. So können sich z.B. bei Kreisen in der Abhänigkeitskette Livelocks bilden und die Antwortzeit kann bei einer zu großen Abhängigkeitskette von Diensten u.U. zu groß werden. Weiterhin multipliziert sich die Wahrscheinlichkeit, dass eine Anfrage nicht bearbeitet werden kann, pro beteiligtem Dienst mit dessen Ausfallwahrscheinlichkeit. [4]

Dennoch habe ich mich für eine voll verteilte Architektur entschieden, da ich mir davon erhoffe, dass man flexibler bei der Gestaltung des Systems ist und dass man vor allem die zahlreichen Clienten, mit all ihren gewünschten Eigenschaften (Überwachung, Administration, Steuerung) einfacher in das System einbinden und steuern kann.

Jedoch ist für dieses voll verteilte System ein geeignetes Hilfssystem zu entwerfen, welches sich um folgende Dinge kümmert, um die oben genannten Probleme so weit wie möglich zu kompensieren:

Für derartige Aufgaben wurde unter anderem CORBA entwickelt, welches es auch ermöglicht, lokale und entfernte Klassen transparent zu nutzen. Ich habe mich dennoch für die Entwicklung eines eigenen Hilfssystems und nicht für den Einsatz von CORBA entschieden, da die Erstellung ressourcenschonender[*]Anwendungen für mich im Vordergrund steht. [13]


Kommunikation in verteilten Systemen

Im Kapitel 7.1.2 ist festgestellt worden, dass es sinnvoll ist, ausschließlich über IP zu kommunizieren, obwohl eine proprietäre Speziallösung für den RS485-Bus effektiver wäre.

Im folgenden Kapitel sollen Kommunikationsprotokolle auf ihre Ressourcennutzung untersucht werden, um zu entscheiden, welche von ihnen für den späteren Einsatz zu empfehlen sind.


Bei den Untersuchungen wurde besonders auf Eigenschaften geachtet, welche für leistungsarme Systeme und Kommunikation über Kanäle mit geringer Bandbreite relevant sind.

Die entstehenden Dienste müssen sowohl auf embedded Controllern als auch auf Server-Systemen lauffähig sein. Daher dürfen die Programme inclusive der benötigten Bibliotheken nicht mehr Ressourcen benötigen, als ein embedded Controler zur Verfügung stellt.

Da die Clienten unter anderem auch über einen RS485-Bus kommunizieren, darf für die Datenkommunikation nicht zu viel Bandbreite ,,verschwendet'' werden. Die Kommunikation über RS485 ist aufgrund seiner Master-Slave-Architektur sehr träge. Aus diesem Grund sollte es eine Möglichkeit geben, für zeitkritische Kommunikationsaufträge mit so wenig wie möglich IP-Paketen auszukommen.


Untersucht wurden die Kommunikationsstandards XML-RPC [11], SunRPC [21] und zusätzlich die einfache Kommunikation über die Protokolle TCP und UDP.

Um zeitkritische Anfragen zu simulieren (z.B. Online-Anfrage von Rechten) wurden jeweils 10 Integer-Zahlen zwischen Quelle und Senke in beide Richtungen ausgetauscht. Diese Datenmenge könnten schätzungsweise der Menge der Daten entsprechen, welche bei einer Online-Anfrage an das System bei einer Identifikation und der Abfrage der entsprechenden Rechte gestellt werden. Um den Austausch von großen Datenmengen zu simulieren (z.B. um die Caches der Clienten zu erneuern) wurde 1 MByte Binärdaten in eine Richtung übertragen.


Die Testumgebung sollte den Worst Case, das heißt die Kommunikation über RS485, simulieren. Deshalb wurde auf den Kommunikationsinterfaces zwischen Quelle und Senke eine MTU von 150 Byte eingestellt. Da die Kommunikation über RS485 fehleranfällig ist, wählt man eine geringe MTU, um den Gesammtdatenverlust durch ein fehlerhaftes Byte zu minimieren. Weiterhin würde eine zu hohe MTU die Zeit zwischen zwei aufeinanderfolgenden Paketen eines Clienten vergrößern, was eine zu hohe Latenz auf dem Kommunikationskanal nach sich ziehen würde. Diese kommt auf Grund der Master-Slave-Architektur des RS485-Bus zu Stande. Im Worst Case muss der Master jeden Clienten (bis zu 32) mit einer Payload, welche der MTU entspricht bedienen. Wenn die MTU zu hoch ist, so wird die Zeit, zwischen der ein Client abgefragt wird, sehr groß. Die Zeit zwischen zwei aufeinanderfolgenden Paketen eines Clienten ergibt sich aus der Anzahl der restlichen Clienten, multipliziert mit der Übertragungsdauer eines Paketes, wobei die Paketlänge durch die MTU bestimmt wird.

Gemessen wurden jeweils die Anzahl der IP-Pakete[*], also die Gesamtgröße der übertragenen Daten. Die Übertragungszeit wurde nicht gemessen da diese von der Anzahl der IP-Pakete und der übertragenen Datenmenge abhängt und durch die Geschwindigkeit des Übertragungsmedium nahezu proportional skaliert wird.

Für diese Messungen wurden jeweils C-Programme und Python-Programme geschrieben und deren Binärgrösse und die Größe der benötigten Bibliotheken, Interpreter und Packages festgehalten. Da alle Testprogramme gleichermaßen Standard-C-Bibliothek benötigen, ist deren Binärgröße nicht mit in die Bilanz eingeflossen.


Table 2: Bandbreitennutzung verschiedener Kommunikationssysteme
10 Integer-Zahlen        
  IP        
Protokoll Pakete Größe in Byte        
XML-RPC (tcp) 45 3725        
SunRPC 4 (2[*]+2[*]) 396 (168+228)        
TCP 10 696        
UDP 2 216        
1 MByte Binärdaten        
  IP        
Protokoll Pakete Größe in MByte        
XML-RPC 22104 2.46        
SunRPC -[*] -[*]        
TCP 16138 1.80        
UDP -[*] -[*]        


Die C-Programme für SunRPC, TCP und UDP sind übersetzt nur 7 KByte groß und benötigen keine zusätzliche Bibliotheken. Das Testprogramm für die Kommunikation unter XML-RPC [12] ist 4 KByte gross, benötigt jedoch weitere Bibliotheken zum Parsen von XML-Files für die Kommunikation über http. Diese zusätzlichen Bibliotheken benötigen einen Gesamtspeicherplatz von 202 KByte. Für die Kommunikation über CORBA (Implementierung ,,TAO'' aus dem ACE-Projekt [15] ) existieren mehrere Bibliotheken. Die derzeit ausgereifteste benötigt eine dynamische Biblotek mit einer Größe von 9 MByte, zusätzliche Hilfsbibliotheken aus dem ACE-Umfeld mit einer Gesamtgröße von 2 MByte und zusätzliche Systembibliotheken mit einer Größe von ca. 1 MByte. Auch andere CORBA-Projekte (z.B. Orbit) benötigen eine sehr große Anzahl an Bibliotheken, welche auch recht groß sind.

Alle Implementationen der Testprogramme in Python benötigen den Python-Interpreter (500 KByte), zusätzliche Python-Module (ca. 3 MByte) und zusätzlich Speicherplatz für Kompilate.

Zusammenfassend ist festzustellen, dass sowohl Python als auch Implementierungen einer CORBA-Umgebung sehr viele Resourcen fordern. Da die Controller jedoch nur wenig Festspeicher und RAM haben, ist der Einsatz solcher Programmierumgebungen nicht zu empfehlen. Weiterhin ist CORBA recht komplex und kompliziert zu nutzen. Ein weiteres Argument gegen CORBA im Einsatz mit dem Zugangsystem ist, dass das URZ kein Know-How auf diesem Gebiet besitzt, um eventuell auftretende Fehler zu beheben.

Aus den Messwerten schlussfolgere ich, dass es zumindest für die Kommunikation über den RS485-Bus sinnvoll ist, alle Informationen in reines UDP einzupacken da dieses Protokoll ohne implementierungsbedingte Latenzen oder Overhead auskommt.

Jedoch muss man sich dabei um fehlerhafte Bits in den Datenpaketen und verlorengegangene IP-Pakete selbst kümmern, was eine Verkomplizierung des Quellcodes nach sich zieht. Deshalb setze ich letztendlich doch TCP ein, da dieses eine Fehlersicherung durch Checksummen und Flusskontrolle implementiert. Dabei ist es wiederum sinnvoll, zwischen den Kommunikationspartnern persistente TCP-Verbindungen zu nutzen, um sich den 3-Wege-Handshake (3 Pakete ohne Nutzlast) beim Verbindungsaufbau zu sparen. [23]


Zum Serialisieren der Daten, welche für die Kommunikation zwischen den Diensten nötig sind, bietet sich ein leichtgewichtiges Codierungs-Verfahren wie ASN.1/BER oder XDR an.[24]

Jedoch benötigen diese Kodierungen eine Anzahl zusätzliche Bytes im serialisierten Datenstrom. Da ich jedoch zum Entwicklungsbeginn noch nicht abschätzen konnte, wie effizient die Kommunikation über den schmalbandigen RS485-Bus funktionieren würde und eine Vergrößerung der Daten signifikant mehr Übertragungsdauer bedeutet, habe ich eine eigene Kodierung implementiert, welche meinen Ansprüchen entsprach. XDR ist nicht zum Einsatz gekommen, da für die meisten Implementierungen des Kodieralgorithmuses die Datenstruktur zur Entwicklungszeit bekannt sein muss. Das Protokoll, welches zwischen den Diensten vermittelt, soll sich jedoch (ähnlich zu XML-RPC) selbst beschreiben und nicht statisch sein.

Es empfiehlt sich jedoch, über den Einsatz von BER erneut nachzudenken, nachdem die Entwicklung gezeigt hat, dass nahezu die vollständige Bandbreite des RS485-Buses genutzt werden kann.

Eine andere Alternative wäre die Nutzung von XML-RPC. Dieser Standard beschreibt, wie man einen generischen Datenaustausch zwischen zwei Datenkommunikationsendpunkten realisiert und spezifiziert die meiste Funktionalität, welche ein Dienstesystem (siehe Kapitel 4.1) benötigt. Weiterhin gibt es für jede Programmierumgebung entsprechende Schnittstellen. Jedoch ist durch die Codierung der Daten in XML der Kommunikationsoverhead sehr hoch. Deshalb nutze ich dieses Protokoll nicht. Jedoch ist es sinvoll, eine Abstraktion der Kommunikation zu implementieren, um den Umstieg auf beliebige Kodierungen zu ermöglichen. Dies ist möglich, falls die Konfiguration des Zugangssystems keine Engpässe in der Datenkommunikation besitzt.


Dienstesystem

Wie in Abschnitt 7.2 beschrieben, bietet es sich an, ein voll verteiltes System auf Dienstebasis zu nutzen. Da es keine freie Entwicklung gibt, welche unsere Ansprüche erfüllt, müssen wir ein eigenes Kommunikationssystem entwickeln.

Das zu entwickelnde System soll vollständig dienstebasiert arbeiten. Dies bedeutet, dass es für jede sinnvoll kapselbare Teilaufgabe einen Dienst im System gibt, welcher an einem beliebigen Ort seine Aufgabe erfüllen kann.

Ein Dienst ist dabei ein Server-Prozess, welcher auf Anfragen in einem definierten Protokoll antwortet. Dieses Kommunikationsprotokoll soll für alle Dienste gleich sein, um die Flexibilität zu erhöhen. Ein Dienst stellt als Schnittstelle Variablen und Funktionen zur Verfügung. Die Funktionen können, ähnlich wie bei RPC, gerufen werden. Um die Dienste zu vereinfachen, kann man auf Variablen nicht direkt zugreifen [*], sondern muss Wrapper-Funktionen nutzen (set_var, get_var). Weiterhin ist es für die Arbeit (z.B. für Administrations-Tools) sinnvoll, Metafunktionen zu implementieren, welche Auskunft über bereitgestellte Dienste und vorhandene Variablen geben (get_functions, get_variables). Es ist auch wichtig, Funktionen in jeden Dienst zu implementieren, welche Überwachungsfunktionalität bieten. Dies kann eine einfache RPC-Funktion - z.B. Ping - realisieren.

Um das System flexibler zu gestalten, nimmt der Dienste Anfragen auf einem frei wählbaren TCP-Port auf dem jeweiligen Host entgegen. Die Adressierung der Dienste erfolgt über IP-Adresse und Portnummer.

Um den Diensten Funktionalität hinzuzufügen, muss eine RPC-Funktion implementiert werden, welche die entsprechende Aufgabe erfüllt.

Ein System, bestehend aus Diensten, welche diese Grundfunktionalität implementiert haben, ist prinzipiell schon funktionstüchtig. Jedoch muss jeder Dienst, welcher einen anderen in Anspruch nehmen möchte, den genauen Ort (IP-Adresse und Portnummer), des Kommunikationspartners wissen.

Um die Dienste auch noch ortsunabhängig zu machen, bietet es sich an, einen Namensdienst zu implementieren, welcher folgende Funktionalität zur Verfügung stellt:

Dieser Namensdienst sollte zusätzlich noch redundant konfigurierbar sein. Dies kann man einfach realisieren, in dem jeder zentrale Namensdienst alle nötigen Informationen an alle andere zentralen Namensdienste repliziert.

Ein weiteres Problem ist die sinnvolle Bezeichnung (Name im Namensdienst) der Dienste. Eine Variante wäre, Diensten, welche eine identische Aufgabe erfüllen, jeweils einen eindeutigen Namen zu geben. Diese Methode der Dienstebezeichung beziehungsweise Auffindung ist jedoch nicht sehr flexibel, da es u.a. nicht möglich ist, alle Dienste zu suchen, welche eine Aufgaben-Klasse bedienen (z.B. Finden aller Dienste, welche eine Tür steuern).

Um solch eine Flexibilität zu erlangen, ist es sinnvoll, Dienste durch ihre Fähigkeiten zu identifizieren. Eine Möglichkeit wäre in Anlehnung an X.500[5], jeden Dienst durch eine Liste von Eigenschaften zu identifizieren. Die Eigenschaften werden durch die Zuordnung von Schlüsselname (key) und Wert (value) gebildet.

Weiterhin ist es sinnvoll, gleichnamige Schlüsselnamen mit unterschiedlichen Werten zuzulassen um die Flexibilität zu erhöhen. Durch dieses Konzept ist es auch möglich, Flags oder Metainformationen in die Dienstespezifikation einfliessen zu lassen. Somit kann man gleichzeitig detailliertere Auskunft über einen Dienst vom Namensdienst erhalten.


Table 3: Spezifikation eines Dienstes
Schlüssel (key) Wert (value)
name mcarddb
id mcarddb1
description Zuordnung von Magnetkarten zu Personen
class db
provide mcard_table


Durch diese recht flexible Spezifikation eines Dienstes ist es einerseits möglich, einen oder mehrere Dienste eindeutig zu finden und andererseits Metainformationen (z.B. eine Beschreibung) eines Dienstes mitzugeben, um ihn mit generischen Administrationstools zu nutzen.

Die Suche nach einem oder mehreren Diensten kann auch flexibel gestaltet werden, in dem man nach Schlüsseln und dazugehörigen Werten sucht. (z.B. ,,Suche einen Dienst der Klasse Datenbank class=db welcher eine Magnetkarten-Tabelle provide=mcard_table zur Verfügung stellt!'') Alle nicht spezifizierten Schlüssel in der Suche werden dabei nicht ausgewertet. Somit ist es möglich, einen speziellen Dienst zu finden in dem man alle relevanten Schlüssel bei der Suche spezifiziert. Es ist jedoch auch möglich, alle Dienste einer beliebigen Gruppe zu finden (z.B. alle Dienste der Klasse ,,db'').

Durch diese Spezifikation des Dienstes ist er durch seine Fähigkeiten und nicht durch seinen Ort definiert. Dies hat den Vorteil, dass man viele Dienste, welche die selbe Aufgabe erfüllen, in einem System laufen lassen kann. Somit ist theoretisch Lastteilung und Ausfallsicherheit möglich.

Ein Dienst muss sich nun beim Start mit all seinen Attributen bei einem Namensdienst anmelden.

Jeder Dienst greift dabei auf andere Dienstleistungen anderer Dienste über ein einheitliches Protokoll zu. Das dabei zu nutzende Protokoll wird in Kapitel 8.1.1 diskutiert.


Schnittstellen

Um mit dem Zugangssystem zu kommunizieren und die Aufgaben, welche in Abschnit 7.3 spezifiziert wurden zu erfüllen, sind Schnittstellen notwendig.


Eine Möglichkeit, alle Daten, welche für das System relevant sind, zu ändern, ist der direkte Zugriff auf das DBMS, welches von den Datenbankdiensten genutzt wird. Jedoch umgeht man damit die Mechanismen der Replikation, welche das Konzept der verteilten Dienste vorsieht.

Eine weitere Möglichkeit, mit dem System zu kommunizieren, besteht in der Nutzung der vorhandenen Schnittstellen zur Kommunikation zwischen den Diensten (siehe Kapitel 7.4). Jedoch wird dies nicht von allen Programmierumgebungen von Haus aus unterstützt (z.B. PHP). Dieses Problem würde wegfallen, wenn als zentrales Kommunikationsprotokoll XML-RPC eingesetzt würde (Gründe gegen den Einsatz von XML-RPC wurden in Kapitel 7.3 erläutert).

Da dies jedoch nur bedingt (siehe Kapitel 7.1.2) möglich ist, muss ein Ausweg gesucht werden. Einer wäre, jeden Dienst, welcher von Endnutzern angesprochen werden soll und über einen breidbandigen Kanal ansprechbar ist, mit einer zweiten Schnittstelle auszustatten. Dies könnte mit XML-RPC realisiert werden. Gleichzeitig könnte diese separate Schnittstelle Konfigurationsfehler des Administartors abfangen.

Eine weitere Möglichkeit wäre, einen Dienst zu entwickeln, welcher zwischen den zwei Protokollen transparent vermittelt.


Implementierungsumgebung

Alle entstehende Software sollte sowohl in ihrem Resourcenverbrauch (CPU-Leistung, Speicherverbrauch) als auch in der Größe des Programm incl. dazugehöriger Bibliotheken oder Interpreter nicht sehr fordernd sein, da sie gleichfalls auf embedded Systemen und Serversysteme lauffähig sein soll.

Die Auswertung der Messungen aus Kapitel 7.3 hat gezeigt, dass Skriptsprachen größere Ressourcenforderungen stellen als kompilierte C-Programme. Aus diesem Grund habe ich mich für C++ als Programmiersprache entschieden. Ich verwende C objektorientiert, da sich das Dienstekonzept welches in Kapitel 7.4 beschrieben worden ist, in einer objektorientierten Sprache einfach abbilden lässt.

Ein weiterer Grund für den Einsatz von C++ ist, dass man im Gegensatz zu Skriptsprachen Einfluss auf das Speichermanagement hat. Benutzt man während der Entwicklung spezialisierte Debugger (valgrind, dmalloc), so ist es möglich, Speicherlecks nahezu auszuschließen. Alle Fehler in Systembibliotheken (z.B. glibc) betreffen sowohl Skriptsprachen als auch C++.

Weiterhin benötigen Skriptsprachen mehr Rechenleistung, da sie den Quelltext interpretieren und danach erst auf der CPU ausführen. Es gibt inzwischen modernere Skriptsprachen, welche den Quelltext zur Ausführungszeit kompilieren, diese benötigen wiederum mehr Speicherplatz (für Kompilate) oder mehr RAM (für Just in Time Compiler).

Als Entwicklungsplattform empfehle ich eine Standard gcc-Umgebung. Somit ist es möglich, die benötigte Software auf herkömmlichen Arbeitsplatzsystemen zu entwickeln.


Zugangssystem

Nachdem Überlegungen zur Architektur des Kommunikationssystems angestellt wurden, sollen in diesem Abschnitt Überlegung zur Implementierung des Zugangssystems gemacht werden. Wie die Dienste im Detail genau miteinander kommunizieren wird in Kapitel 8 erläutert.


Es ist ein System zu entwickeln, welches Objekte[*] sicher identifiziert und entsprechende Berechtigungen für diese geltend macht, in dem der Zugang zu einem Raum gewährt wird.

Weiterhin ist bei der Überlegung zu beachten, dass alle relevanten Daten lokal auf den Clienten vorgehalten werden müssen (oder im Cache gehalten werden). Weiterhin müssen Ereignisse (Events) zentral protokolliert werden. Falls die Datenverbindung gestört ist, dürfen trotzdem keine Ereignisse verloren gehen.


Figure 2: Dienste-Szenario
\includegraphics[]{scenario}

Im Folgenden sollen Dienste aufgezählt werden, welche für ein funktionierendes Zugangskontrollsystem nötig sind. Es sind jeweils Dienstname, verbale Beschreibung der Aufgaben, benötigte Diensterbringer, Dienstnutzer und eine mögliche Spezifikation des Dienstes für den Namensdienst aufgezählt.

door

Dieser Dienst kümmert sich um die Ansteuerung der Tür-Relais und die Auswertung der Türsensoren. Gleichzeitig kann dieser Dienst akustische Warnungen absetzen, oder Events protokollieren lassen, falls eine Tür unerwartet geöffnet wird oder zu lange offen bleibt. Die entsprechenden Funktionen und Timeouts müssen zentral konfigurierbar sein. Jeder dieser Dienste sollte durch einen eindeutigen Ort identifizierbar sein.


Name: door
benötigte Dienste: log, locator
Dienstnutzer: controller
Spezifikation: class=door
  location=Eindeutiger Ort der Tür

controller

Dieser Dienst liest Identifikations- oder Autorisationsdaten von der entsprechenden Hardware (z.B. Magnetkartenleser) und befragt die entsprechende Datenbank, welche Identität sich hinter den Daten (z.B. Hashes, Magnetkarten-ID) verbirgt. Nach sicherer Identifikation werden durch Abfrage des Dienstes acl die entsprechenden Rechte für die Identität an dieser Tür abgefragt. Der Dienst controller kann für die Datenbankabfragen den Dienst proxy nutzen, welcher die Ergebnisse in einer geeigneten Form in einem Cache ablegt.


Name: controller
benötigte Dienste: door, log, locator, mcard, acl
Spezifikation: class=crontroller
  location=Eindeutiger Ort der Tür

log

Dieser Dienst speichert alle ihm zugesandten Events in einer geeigneten Form. Weiterhin benachrichtigt er bei kritischen Meldungen auf Wunsch den Administrator per E-Mail.


Name: log
Dienstnutzer: door, controller
Spezifikation: class=db
  provide=log

mcard

Dieser Datenbankdienst speichert die Zuordnung zwischen dem Identifikationshash der Magnetkarten (z.B. Magnetkarten-ID) und der realen Person. Die Antwort auf eine solche Abfrage sollte so ausgegeben werden, dass sie durch den Dienst proxy in einem Cache ablegbar ist.


Dienstnutzer: controller
Spezifikation: class=db
  provide=mcardid

acl

Dieser Dienst speichert alle Rechte von Individuen in Form von ACLs. Alle Anfragen nach Berechtigungen sollten so ausgegeben werden, dass sie in einem Cache speicherbar sind und soviele Zusatzinformationen enthalten, dass die entsprechende Steuereinheit alle weiteren Rechte (z.B. zu anderen Zeit an der selben Tür) für diese Tür errechnen kann. Dies hätte den Vorteil, dass bei einer erneuten Anfrage dieses Nutzers keine weitere Kommunikation zwischen Steuereinheit und zentralem Server stattzufinden braucht.


Name: acl
Dienstnutzer: controller
Spezifikation: class=db
  location=acl

locator

Dieser Systemdienst sucht anhand von Spezifikationen Dienste und antwortet mit dem eindeutigen Ort im Netz (IP-Adresse und Portnummer). Alle Dienste müssen sich bei diesem zentralen Dienst anmelden. Es soll möglich sein, dass dieser Dienst seine Daten mit anderen Namensdiensten abgleicht (Replikation). Dieser Dienst sollte auch so konfigurierbar sein, dass er als Namens-Cache fungiert.


Name: locator
Dienstnutzer: alle Dienste
Spezifikation: class=locator

proxy

Dieser Dienst gibt sich als Datenbankdienst aus (z.B. class=db, provide=acl), nimmt Anfragen entgegen, stellt diese an den eigentlichen Datenbankdienst und speichert die Ergebnisse in einem Cache ab. Die einzelnen Objekte im Cache werden durch einen kollisionsresistenten Hash über die Anfrage wiedergefunden. Jedes Objekt besitzt ein individuelles Verfallsdatum. Bei einer entsprechenden weiteren identischen Anfrage werden die Daten aus dem Cache benutzt. Das Verfallsdatum wird durch den eigentlichen Datenbankdienst vorgeschrieben.


Name: proxy
Diensterbringer: alle Dienste der Klasse db
Dienstnutzer: controller
Spezifikation: class=db
  provide=flexibel einstellbar


Rechtedatenbasis und Datenverwaltung

Im folgenden Abschnitt soll überlegt werden, wie Daten zur Definition von Rechten gespeichert werden können und wie diese Daten genutzt werden sollen. Dabei soll die Datenbasis folgenden Anforderungen genügen:


Eine Möglichkeit zur Realisierung wäre, alle Rechte in einer definierten Form als XML zu speichern. Somit wäre es möglich, Gruppen zu bilden und jedem Nutzer eine oder mehrere Gruppen zuzuordnen. Zusätzliche Rechte könnte man jedem Nutzer zusätzlich hinzufügen. Es wären auch beliebige andere Eigenschaften der XML-Objekte nutzbar.

Jede dieser einzelnen Definitionen (Gruppen- und Rechtedefinition pro Nutzer) könnte man auf dem zentralen Server in separaten Files abspeichern. Falls eine Anfrage für einen Nutzer bearbeitet werden muss, so kann das komplette XML-File inclusive aller abhängigen Definitionen vollständig auf den Clienten übertragen werden. Die Clienten würden diese XML-Daten in ihrem Cache ablegen.

Jedoch hat diese Methode auch Nachteile. Suchanfragen würden signifikant mehr Ressourcen benötigen, wodurch die Antwortzeit steigen würde. Der Kommunikationsoverhead ist sehr hoch. Da wir jedoch auch über schmalbandige Kommunikationskanäle kommunizieren, würde dies auch wieder die Latenz erhöhen. Weiterhin müssen die Clienten XML speichern und parsen, was wiederum mehr Rescourcenanforderungen auf den Clienten bedeutet.


Eine andere Möglichkeit ist das Konzept der Raum-Zeit-Zonen (siehe Beispiel 1), welche das jetzige Zugangssystem realisiert. Dabei werden Zonen definiert, welche eine Menge von Türen und Zeiträume definieren. Jeder Person können nun beliebig viele dieser Zonen zugewiesen werden, zu welchen sie die Berechtigung hat. Der Vorteil dieser Methode besteht darin, dass die Berechnung der Berechtigung einfach ist, da nur wenige Datenstrukturen ausgewertet werden müssen. Ein weiterer Vorteil ist, dass sich diese Datenstruktur gut für ein Offline-System eignet, da einerseits die Definition der Raum-Zeitzonen einfach und vollständig auf den Steuereinheiten vorgehalten werden kann und zum anderen die personengebundenen Daten nicht kompliziert sind.


\begin{example}
% latex2html id marker 258
[htb]
\begin{Verbatim}[frame=single,f...
... . . ..:.. ..:.. ..:.. ..:..\end{Verbatim}\caption{
Raum-Zeit-Zone}\end{example}

Nachteilig an dieser Methode ist, dass die Definition von Zeitzonen eingeschränkt[*] ist, um die Struktur der Daten einfach zu halten. Falls man eine detailliertere Beschreibung realisieren möchte, so werden die Datenstrukturen wieder komplizierter und die oben beschriebenen Vorteile wären nicht mehr gegeben. Ein weiterer Nachteil ist, dass außerordentliche Rechte jeweils in einer separaten Raum-Zeit-Zone definiert werden müssen. Bei einer großen Anzahl von überschneidenden Benutzergruppem führt dies zu einer hohen Anzahl von Raum-Zeit-Zonen.



\begin{example}
% latex2html id marker 264
[htb]
\begin{Verbatim}[frame=single,f...
...a \vert \vert\end{Verbatim}\caption{Abbildung der ACLs als Tabelle}\end{example}

Während der Entwicklung habe ich mich für die Umsetzung der Rechtedatebasis in Form von ACLs entschieden, welche tabellarisch in einer SQL-Datenbank abgebildet werden. Jede Zeile in dieser Tabelle stellt ein bedingte Aktion dar. Wenn die Bedingung erfüllt ist, so wird eine Aktion ausgeführt.

Die Berechnung der Berechtigung basiert darauf, dass rekursiv Rechtedefinitionen (Zeile) aufgelöst werden und jeweils in weitere Gruppen (chain) verzweigt wird, oder eine terminierende Aktion ausgelöst wird, falls die Bedingung erfüllt ist. Falls kein Vergleich erfolgreich durchgeführt werden kann, so ist die Standardpolitik, dass keine Zugang gewährt wird. Die Spezifikation, auf welche Eigenschaft in jeder Zeile überprüft werden soll, steht in der Spalte key. Diese können z.B. subject sein, um auf eine Person zu prüfen. Weitere mögliche Vergleiche sind in der Tabelle 4 aufgezählt. Falls bei dieser Spezifikation angegeben ist, dass auf eine Gruppe getestet wird, so wird die angegebene Aktion ausgeführt, sobald in dieser Gruppe eine Zeile positiv verglichen worden ist.

Die zu vergleichenden Zeilen werden gefunden, in dem alle Zeilen, welche in der relevanten Gruppe sind, anhand des Ranges (rank) sortiert werden und in dieser Reihenfolge abgearbeitet werden.


Table: Vergleichsmöglichkeiten
key Beschreibung
chain Verzweigung in eine weitere Gruppe
subject eindeutige Kennung eines Subjektes (z.B. Person)
object eindeutiges Objekt (z.B. eine Tür)
dayofweek Tag der Woche (Mo..So)
day ein bestimmter Tag (yyyy-mm-dd)
dayrange ein bestimmter Zeitraum (yyyy-mm-dd to yyyy-mm-dd)
timerange ein bestimmter Zeitraum (hh-mm to hh-mm)


In der ersten Rekursionstiefe werden Zeilen gesucht, welche zu keiner speziellen Gruppe gehören. Falls eine Zeile die Bedingung erfüllt, so wird eine Aktion ausgeführt, welche in der Spalte action spezifiziert ist.

Dabei unterscheidet man Schlüsselaktionen (terminierende Aktion) und frei definierbare Aktionen, welche eine neue Gruppe darstellen. Die terminierende Aktion accept bedeutet, dass der Zugang gewährt wird, deny bedeutet, dass der Zugang verwehrt bleibt. Die Schlüsselaktion break bedeutet, dass alle Vergleiche in der aktuellen Rekursionstiefe abgebrochen werden.

Diese Art der Rechtedefinition bietet eine sehr große Flexibilität und ist trotzdem schnell zu berechnen.

Eine weitere Forderung ist, dass die Einsicht und Vergabe der Rechte nur bestimmten Personen erlaubt sein darf. Dazu muss eine weitere Relation beschreiben, welche Administratoren welche Tür zur Vergabe von Rechten nutzen darf. Diese Relation könnte von der Administrationsschnittstelle des Dienstes acl ausgewertet werden.


Jedoch hat die Methode der Access Control Listen den Nachteil, dass sie nicht so einfach handhabbar ist, wie Raum-Zeit-Zonen. Ein weiterer Nachteil ist, dass die Berechnung eines Datensatzes, welcher alle Rechte für eine Tür und eine Person beinhaltet, kompliziert ist. Die Berechnung aller relevanten Rechte ist jedoch gefordert, da die Datenbankabfragen auf den Steuereinheiten in einem Cache abgelegt werden sollen und somit alle türrelevanten Rechteinformationen für einen beliebigen Zeitpunkt beinhalten muss.

Um dieses Problem zu lösen, gibt es mehrere Ansätze. Eine Variante wäre[*], dass für jede Rekursionstiefe eine separate Datenbankanfrage gestellt werden müsste, welche später jedoch auf den Steuereinheiten im Cache liegen würde. Dies hätte den Nachteil, dass anfangs das Kommunikationsaufkommen recht hoch wäre, jedoch später, falls alle Gruppendefinitionen im Cache lägen, nur noch das Resultat einer Zeile übertragen werden müsste.

Eine weitere Möglichkeit wäre, alle Informationen, welche eine spezielle Tür betreffen, rekursiv aufzulösen und zu normalisieren. Dies ist jedoch recht kompliziert.

Die letzte Variante wäre, alle Schritte, welche zu einer Berechnung eines Rechts relevant sind, in einer Liste einzutragen. Diese Liste (siehe Beispiel 3) enthält zeilenweise die Nummer eines Abbarbeitungsblockes, um die Schlüsselaktion break auszuwerten, Bedingung und Aktion. Aus diesen Angaben ist die Berechnung der Rechte möglich. Diese Liste könnte auf die Steuereinheit übertragen werden und könnte einfach ausgewertet werden.


\begin{example}
% latex2html id marker 295
[htb]
\center
\begin{Verbatim}[frame=...
...4 accept
...\end{Verbatim}\caption{
Normalisierte Rechtedefinition}\end{example}


next up previous contents
Next: Umsetzung und praktische Ergebnisse Up: Studienarbeit Previous: Soll-Analyse für den Einsatz   Contents
Ronald Schmidt 2002-10-07