Kommunikation von A nach B

Im Internet existieren eine Reihe von Diensten und Applikationen. Eine der wichtigsten Dienste, wenn nicht die Killerapplikation des Internets als es noch das ARPANET war, ist E-Mail. Zeit, ein wenig auf die Hintergründe dieses Systems zu blicken.

Einleitung

Zur Kommunikation existieren unterschiedlichste Dienste, welche das Internet nutzen, um Nachrichten von A nach B zu übermitteln. So sind im privaten Umfeld Messenger wie WhatsApp und Co nicht mehr wegzudenken. Daneben ist einer der wichtigsten Dienste für die Kommunikation die klassische E-Mail.

Der durchschnittliche Nutzer wird meist ein E-Mail-Programm auf dem Rechner, dem Mobilgerät oder ein Web-Mailer im Browser nutzen. Für den Nutzer ist es nicht wichtig wie das System funktioniert, allerdings lohnt es sich einen Blick hinter die Kulissen zu werfen und zu sehen, wie das System funktioniert und welche Herausforderungen der Betrieb eines E-Mail-Servers in der heutigen Zeit mit sich bringt.

Geschichte

Die Idee Nachrichten von A nach B zu verschicken gab es schon in der Frühzeit der Computertechnik, sogar noch früher, wenn elektrische Telegrafen einbezogen werden. So gab es ab dem Jahr 1962 mit dem Automatic Digital Network des US-Militärs bereits ein System, um Nachrichten an unterschiedlichste Standorte zu verteilen.

1968, mit der Erfindung des ARPANET, einem Forschungsprojekt im Auftrag des US-Militärs, wurden nicht nur die Grundlagen für unsere heutige Internetarchitektur geschaffen, sondern einige Jahre später, im Jahr 1971, die erste E-Mail versendet. Wobei hier der Terminus Network Mail genutzt wurde.

Für den Transfer der E-Mail wurde das Programm SNDMSG genutzt, welches es ermöglichte Nachrichten bzw. E-Mails von einem Nutzer zu einem anderen Nutzer auf dem gleichen System zu schicken.

Technisch war eine Mailbox nicht mehr als eine Datei, welche nur vom berechtigten Nutzer gelesen werden konnte, aber von unterschiedlichen Nutzern über SNDMSG geschrieben werden konnte.

Die Neuerung war nun die Idee, SNDMSG so zu erweitern, dass es E-Mails auch zu anderen Hosts senden konnte. Dafür wurde das At-Zeichen als Trennzeichen gewählt, um den eigentlichen Nutzer vom entsprechenden Host zu trennen. Daneben wurde READMAIL zum Lesen der Mails genutzt. Beide Programme, SNDMSG und READMAIL, wurden damals mit dem Betriebssystem TENEX genutzt.

Parallel zur ARPANET-Implementation und Vorstellung von Network Mail entstanden im Laufe der Zeit einige kommerzielle E-Mail-Systeme, sowie der X.400-Standard, welche bereitstanden, die Vorherrschaft der E-Mail-Systeme anzunehmen.

Bedingt durch die Öffnung des Internets gegenüber der kommerziellen Nutzung, genauer gesagt der Aufhebung der Restriktionen im Jahr 1995, mauserten sich SMTP, POP3 und IMAP zu den vorherrschenden Protokollen für das Senden und Abfragen von E-Mails.

Vorher war die kommerzielle Nutzung der damals im Rahmen des National Science Foundation Network-Programmes bereitgestellten Netzwerke durch entsprechende Richtlinien stark eingeschränkt. Grundsätzliche sollten diese Netzwerke hauptsächlich der Forschung und Lehre genutzt werden.

Auch wenn es heutzutage noch einige Bereiche gibt, in denen andere Standards genutzt werden, wie der X.400-Standard bei der Rufnummernportierung, hat sich der aktuelle E-Mail-Standard durchgesetzt.

Damit die Systeme trotzdem miteinander verbunden sein können, gab und gibt es unterschiedlichste Gateways, welche andere Netzwerke und E-Mail-Systeme miteinander verbinden.

Trennzeichen gesucht

Die Idee Nachrichten über Rechnergrenzen hinweg zu versenden führte zu dem Problem, dass diese Rechner adressiert werden müssen. Als Trennzeichen wurde das At-Zeichen (@) gewählt, welches nicht nur von der Bedeutung ideal war, sondern auch das Zeichen als solches war größtenteils ungenutzt. Damit war der Weg zu Adressen nach dem Schema nutzer@host frei.

Auf heutigen Tastaturen ist das At-Zeichen selbstverständlich

Bei der Auswahl des Zeichens war das Kriterium, dass das Zeichen auf den damaligen Tastaturen vorhanden war, aber auf keinen Fall ein Bestandteil eines Namens sein dürfte.

Der Erfinder der E-Mail, Ray Tomlinson sagte dazu selbst:

The primary reason was that it made sense. at signs didn’t appear in names so there would be no ambiguity about where the separation between login name and host name occurred. (Of course, this last notion is now refuted by the proliferation of products, services, slogans, etc. incorporating the at sign.) The at sign also had no significance in any editors that ran on TENEX. I was later reminded that the Multics time-sharing system used the at sign as its line-erase character. This caused a fair amount of grief in that community of users. Multics used IBM 2741 terminals which used EBCDIC character coding. They did not have a „control“ modifier key and didn’t have many (any?) non-printing characters beyond space, backspace, tab, and return. The designers of Multics were constrained to using printing characters for line-editing.

Während das Zeichen zuvor hauptsächlich zur Trennung von Mengen und Preisen genutzt wurde, hielt das Zeichen damit Stück für Stück Einzug in die moderne Welt und wurde praktisch zu einem unverkennbaren Zeichen der vernetzten Welt.

E-Mail, email, Mail?

Neben der eigentlichen Technik hinter dem E-Mail-System wurden im Laufe der Zeit auch andere Dinge, wie die Terminologie und Schreibweise, verhandelt. Während die Schreibweise im Deutschen als E-Mail definiert ist, sind im englischen Formen wie email, e-mail, E-mail, EMAIL und weitere Schreibweisen bekannt. Gebräuchlich ist hier meist die Schreibweise email bzw. e-mail. Bei RFCs hingegen wird im Author’s Adressblock die historisch bedingte Form EMail genutzt.

Dezentral wie das Netz

Das E-Mail-System an sich ist als dezentrales System für asynchrone Kommunikation konzipiert.

Das bedeutet, dass es nicht ein großer Betreiber existiert, welcher für alle E-Mail-Adressen der Welt zuständig ist. In der Theorie kann jeder Nutzer eines Rechners, welcher mit dem Internet verbunden ist, einen solchen E-Mail-Server betreiben.

Die Asynchronität definiert unter anderem dadurch, dass E-Mails abgeschickt werden können, ohne dass der Mail-Server des Empfängers erreichbar sein muss.

Systeme mit drei Buchstaben

Wer sich näher mit dem E-Mail-System auseinandersetzt, wird feststellen, dass es den E-Mail-Server an sich nicht gibt, sondern es sich um eine Ansammlung von Systemen, Diensten oder Programmen handelt.

Diese tragen überwiegend Abkürzungen bestehend aus drei Buchstaben wie MUA, MSA, MTA und MDA. Ordnung lässt sich in die Begriffe bringen, wenn der Weg einer E-Mail vom Sender zum Empfänger verfolgt wird.

Grundsätzlich geht es darum, eine E-Mail bzw. eine Nachricht von einem Rechner zu einem anderen Rechner zu transferieren und sie dort in der Mailbox des entsprechenden Nutzers zu hinterlegen.

Eine E-Mail wird in einem E-Mail-Client geschrieben

Wird eine E-Mail geschrieben, so geschieht das in einem E-Mail-Client, welcher im Kontext der Architektur des E-Mail-Systems als Mail User Agent (MUA) bezeichnet wird.

Manchmal wird das Wort Mail in den entsprechenden Begrifflichkeiten durch Message ersetzt. Je nach RFC findet sich eine unterschiedliche Terminologie in dieser. Die Begriffe werden dabei synonym verwendet. So bezeichnen beispielhaft Mail User Agent und Message User Agent das Gleiche.

Nachdem die Mail fertig geschrieben und ein Empfänger eingetragen wurde, kann die E-Mail versandt werden. Je nach Konfiguration sind hier unterschiedliche Wege denkbar.

Vom MUA zum MSA

So kann die entsprechende Mail per Simple Mail Protocol (SMTP) an den sogenannten Mail Submission Agent (MSA) gesendet werden. Gewöhnlich geschieht dies über den Port 587. Die Idee hinter dem Mail Submission Agent ist, dass dieser die E-Mails vom Endbenutzer entgegennimmt und diese an den Mail Transfer Agent (MTA) weiterleitet.

Damit stellt er in der Theorie die Schnittstelle zwischen dem Mail User Agent und dem Mail Transfer Agent dar. Im Gegensatz zum Mail Transfer Agent darf der Mail Submission Agent die eingelieferte E-Mail noch bearbeiten. So kann das E-Mail-Format überprüft und gegebenenfalls repariert sowie unvollständige E-Mail-Adressen vervollständigt werden. Dies ist z. B. dann der Fall, wenn die Domain des Absenders nicht voll qualifiziert angegeben wurde.

In der Theorie kann ein Mail User Agent ergo das E-Mail-Programm E-Mails auch direkt an einen Mail Transfer Agent senden. Allerdings nimmt dieser keine der obigen Prüfungen vor.

Mail Transfer Agent

Nachdem die E-Mail an den Mail Transfer Agent weitergeleitet wurde, entscheidet dieser, was mit der E-Mail geschieht. Im Grunde ist der MTA ist dafür zuständig, die E-Mail zum Ziel zu transportieren und die Nachricht schlussendlich an den Mail Delivery Agent (MDA) zu übergeben.

Eine Möglichkeit wie eine E-Mail zum Empfänger übertragen wird

Der Mail Transfer Agent führt in seiner Konfiguration eine Liste von Domains bzw. Hosts, für die er lokal zuständig ist. E-Mails, welche zu diesen Domains führen, werden direkt über den Mail Delivery Agent zugestellt.

Der MTA verändert die Mail beim Transfer im Grundsatz nicht, außer dass einige Headerfelder wie Received oder Return-Path, welche laut der entsprechenden RFC benötigt werden, hinzugefügt werden.

In der Frühzeit des E-Mail-Systems waren die meisten MTAs als sogenannte offene Relays (Open Relays) konfiguriert. Das bedeutete, dass sie von beliebigen Clients entsprechende E-Mails entgegennahmen und weiterleiten.

Diese Funktionalität konnte z. B. von Systemen genutzt werden, welche nur sporadisch am Netz waren und somit ihre E-Mail an ein Relay weiterleiten konnten, welches sich anschließend um die Zustellung kümmerte.

Dies führte schlussendlich zum Problem des Spams, da diese Relays missbraucht wurden, um Empfänger mit unerwünschten Mails zu belästigen. Infolgedessen finden sich heutzutage nur noch wenige offene Relays im Internet. Meist handelt es sich dabei um Fehlkonfigurationen. Ein MTA sollte in der heutigen Zeit nur nach einer entsprechenden Authentifizierung E-Mails entgegennehmen.

Auf Linux-Systemen wird gerne Postfix für diesen Teil des E-Mail-Systems genutzt. Je nach Konfiguration kann Postfix hier sowohl als MSA als auch als MTA verwendet werden.

Von MTA zu MTA

Ist die Empfänger-Domain nicht im Einflussbereich des Absender-MTAs, so wird die Mail an den zuständigen MTA gesendet.

Hierzu wird die Domain per DNS aufgelöst und es werden die entsprechenden MX-Records ausgewertet. In diesen sind die für die Domain zuständigen Mail Transfer Agents hinterlegt.

Ein solcher MX-Record könnte wie folgt aussehen:

	@		IN	MX	10 mail.example.org.

Es können pro Domain mehrere MX-Records angelegt werden. Der MTA, versucht diese nun nacheinander, sortiert nach ihrer Priorität, zu erreichen und die entsprechende E-Mail auf dem MTA der Empfänger-Domain einzuliefern.

Kann die E-Mail nach einer gewissen Zeit nicht eingeliefert werden oder erhält der MTA eine entsprechende Fehlermeldung, wird der ursprüngliche Absender der E-Mail informiert, damit dieser darauf reagieren kann.

Ist die Einlieferung der E-Mail hingegen erfolgreich gewesen, leitet der MTA der Empfänger-Domain die Mail an den Mail Delivery Agent weiter. Der MDA hat die Aufgabe, die E-Mails an die jeweiligen Nutzerkonten bzw. Mailboxen weiterzuleiten.

Beispiele für einen solchen MDA ist die Software Dovecot unter Linux. Daneben bietet Dovecot die Funktionalität mittels der Protokolle IMAP und POP3 auf die Mails der jeweiligen Nutzer über ein Netzwerk zuzugreifen.

Über diesen Weg können die E-Mails von den Nutzern vom Server geladen und gelesen werden. Damit landen die E-Mails beim Nutzer im Mail User Agent, dem E-Mail-Programm auf dem Endgerät des Empfängers.

Mailboxen

Die Mailboxen der Nutzer können auf dem Server in unterschiedlichen Formaten gespeichert werden. Die bekanntesten und am häufigsten genutzten Formate sind Maildir und Mbox.

Beim Speicherverfahren Maildir wird jede Mail in einer separaten Datei, innerhalb der durch Maildir festgelegten Verzeichnisstruktur, abgelegt. Beim Verfahren Mbox hingegen, befinden sich die Mails in einer großen Datei und werden in dieser Datei nacheinander gespeichert.

Anatomie einer E-Mail

Damit ist geklärt, wie eine Mail ihren Weg vom Absender zum Empfänger findet. Doch wie sieht eine solche E-Mail eigentlich aus? Dies definiert die RFC 5322. Eine simple E-Mail, gemäß der RFC, könnte wie folgt aussehen:

Return-Path: <>
Delivered-To: 
Received: by mail.example.org (Postfix, from userid 33)
        id 81FC87EE09FD; Sat,  1 Jan 2022 00:19:10 +0100 (CET)
From:  (Cron Daemon)
To: 
Subject: Update cronjob successfully
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
X-Cron-Env: 
Message-Id: <>
Date: Sat,  1 Jan 2022 00:19:10 +0100 (CET)

Update cronjob successfully executed.

Im Groben besteht eine E-Mail aus einem Header, in welchem sich unterschiedlichste Header-Felder befinden, welche Auskunft darüber geben, woher die E-Mail kam, wohin sie gehen soll und welche MTAs sie empfangen haben.

Daneben befinden sich weitere Informationen in der E-Mail, einige davon wie Subject, oder Date werden für die Anzeige der E-Mail im E-Mail-Programm herangezogen. Anschließend folgt der Message Body, in welchem die eigentliche Nachricht kodiert ist.

Da E-Mails an sich nur 7-Bit-ASCII-Zeichen unterstützen, müssen andere Zeichen und Typen von Inhalten wie Binärdateien erst umkodiert werden. Dazu wurden unter anderem die Multipurpose Internet Mail Extensions definiert, welche regeln, wie die entsprechenden Codierungen auszusehen haben.

Protokolle

Während sich bis zum Jahr 1980, innerhalb des ARPANET und dem dortigen E-Mail-System Protokolle wie SNDMSG und FTP mail hielten, haben sich im Laufe der Zeit einige Standardprotokolle herauskristallisiert, welche bis zur heutigen Zeit, mit einigen Erweiterungen genutzt werden.

Es handelt sich um die Protokolle SMTP, POP3 und IMAP. Während SMTP dem Transfer der E-Mail vom E-Mail-Client zum MSA bzw. dem Weiterversand von E-Mails von einem MTA zum nächsten dient, werden die Protokolle POP3 und IMAP zur Kommunikation des E-Mail-Servers mit dem E-Mail-Client genutzt.

SMTP

Das Simple Mail Transfer Protocol kurz SMTP nimmt beim E-Mail-System eine gehobene Stellung ein.

Während die E-Mails, welche auf dem eigenen E-Mail-Server empfangen wurden, theoretisch mit einem entsprechenden Shellzugriff direkt auf dem Server gelesen werden können, wird ein Protokoll benötigt, welches die E-Mails von einem Mail Transfer Agent zum nächsten MTA transportiert.

Hierfür wurde SMTP in der RFC 821 im August 1982 spezifiziert. Diese Version kam noch ohne Authentifizierung aus, sodass jedermann eine E-Mail bei einem MTA einliefern konnte, was im Laufe der Zeit zu einem Spam-Problem führte.

Deshalb wurde SMTP mit der RFC 1869 so erweitert, dass das Protokoll über einen Mechanismus verfügte, über welchen der Server den Client informieren konnte, über welche Service extensions der Server verfügt.

Dies ermöglichte es Authentifizierung und Verschlüsselungen über Erweiterungen wie STARTTLS durchzuführen und somit neben der Authentifizierung auch die Verschlüsselung zu gewährleisten.

Heutzutage sollten SMTP allerdings nicht mehr über STARTTLS, sondern direkt über TLS durchgeführt werden, da Technologien wie STARTTLS gegenüber Man-in-the-Middle-Angriffen anfällig sind.

POP3

Nachdem die E-Mails auf dem E-Mail-Server gelandet sind, wird ein Protokoll benötigt, um diese vonseiten des meist externen E-Mail-Clients wieder abzuholen.

Mit dem Post Office Protocol, welches in der aktuellen Version als POP3 abgekürzt wird, können die entsprechenden Mails vom E-Mail-Server heruntergeladen und vom Server gelöscht werden.

Mit POP4 sollte eine Weiterentwicklung des Protokolls verbunden sein, allerdings scheint diese seit 2003 nicht mehr gepflegt zu werden.

IMAP

Während sich POP3 gut dafür eignet, E-Mails vom Server zu holen, um die Postfächer im eigenen E-Mail-Client lokal zu verwalten, eignet sich das Internet Message Access Protocol kurz IMAP dazu, die entsprechenden E-Mails direkt auf dem Server zu verwalten.

IMAP unterstützt Funktionalitäten wie unterschiedliche Verzeichnisstrukturen oder die Benachrichtigung über neue E-Mails per Push-Verfahren.

Wie bei POP3 müssen auch bei IMAP zwei Protokolle unterstützt werden, da das Senden der Mails wiederum über SMTP erfolgt. Mit dem Simple Mail Access Protocol gab es Ansätze dies zu ändern, allerdings hat sich dieses bisher nicht durchgesetzt.

Ausfallsicherheit

Während wir heute daran gewöhnt sind, dass eine E-Mail meist innerhalb weniger Minuten beim Empfänger ankommt, war dies historisch gesehen nicht immer so. So konnte es schon einmal Tage dauern, bis eine entsprechende E-Mail schlussendlich beim Empfänger ankam.

Dies war unter anderem dadurch bedingt, dass nicht alle E-Mail-Server immer eine permanente Verbindung zum Internet hatten und es auch vorkommen konnte, dass Server für einige Zeit nicht verfügbar waren.

Das zeigt aber auch auf, wie resilient das E-Mail-System gestaltet wurde. Wenn ein MTA auf Empfängerseite nicht verfügbar ist, versuchen die sendenden MTAs die E-Mail später zuzustellen. Meist wird eine E-Mail erst nach einiger Zeit z. B. 48 Stunden als unzustellbar angesehen und der Absender entsprechend informiert.

Das bedeutet, wenn der eigene E-Mail-Server einmal ausfällt, so ist dies im ersten Moment kein dramatisches Ereignis, weil im Idealfall trotzdem alle E-Mails zugestellt werden.

Einen E-Mail-Server aufsetzen

Wer seine Domain bei einem Webhoster untergestellt hat, bekommt meist einen entsprechenden, vom Anbieter gewarteten E-Mail-Server dazu.

Interessanter wird es, wenn ein solcher E-Mail-Server selbst aufgesetzt werden soll. In einem solchen Fall muss ein MTA und MDA ausgewählt werden. Unter Linux ist eine beliebte Kombination für diese Funktionalitäten Postfix und Dovecot.

Grundsätzlich ist der Markt an Server-Anwendungen breit gestreut. Neben den Linux-Varianten und Servern wie Postfix und Dovecot existieren auch proprietäre Lösungen wie der Microsoft Exchange Server.

Nachdem die passende Lösung gewählt wurde, sollte diese für den jeweiligen Anwendungsfall konfiguriert oder entsprechend vorkonfektionierte Pakete genutzt werden.

Betrieb des Servers

Ist der E-Mail-Server aufgesetzt, fangen die eigentlichen Probleme an. Dies fängt damit an, dass es praktisch unmöglich ist, einen E-Mail-Server zu Hause zu betreiben. Die Einlieferung von E-Mails von Servern, welche in dynamischen DSL-IP-Adressbereichen unterwegs sind, wird von den meisten Betreibern von E-Mail-Servern unterbunden, meist um Spam zu verhindern.

Damit bleibt als Lösung der Betrieb eines Servers in einem Rechenzentrum, mit entsprechend fixer IP-Adressen oder entsprechenden Tarifen im gewerblichen Umfeld.

Ist der E-Mail-Server eingerichtet, der MX-Record korrekt gesetzt und sind die entsprechenden Nutzer angelegt, kann der Nutzer in der Theorie Mails senden und empfangen.

Neben dem Setzen des MX-Records ist es mittlerweile auch hilfreich, die DNS-Records für die automatische Erkennung durch E-Mail-Clients zu konfigurieren. Geregelt wird das Verfahren in der RFC 6186. Dies ermöglicht es den Clients, die Konfiguration für den E-Mail-Server schnell und unkompliziert vorzunehmen.

In der Praxis ist das erfolgreiche Senden von E-Mails eine kleine Herausforderung. So müssen entsprechende PTR-Records für die Auflösung der IP-Adresse zur entsprechenden Domain hinterlegt werden.

Andere E-Mail-Server überprüfen, ob der Name der IP-Adresse (Reverse DNS) zum eigenen E-Mail-Server passt. Wird etwa die IP-Adresse 192.168.10.1 genutzt und deren Reverse DNS-Name lau­tet mail.example.com, so muss auch der Host­name mail.example.com in der Konfiguration des Mailservers dementsprechend konfiguriert sein.

Sendet der Server die E-Mails auch per IPv6, so muss überprüft werden, dass ein entsprechender PTR-Record für die Adresse gesetzt ist, ansonsten kann es zu solchen Meldungen im E-Mail-Verkehr kommen:

host mail.example.com[2001:db8:a0b:abf0::1]
said: 550-Inconsistent/Missing DNS PTR record (RFC 1912 2.1)
(example.org) 550 [2001:db8:a0b:12f0::1]:34865 (in reply to RCPT TO command)

Selbst wenn der Eintrag zur Auflösung der IP-Adresse (Reverse DNS) korrekt gesetzt ist, kann es passieren, dass bei der Nutzung von IPv6 diese Meldung erscheint. Hintergrund ist meist, dass der entsprechende Server ein IPv6-Subnetz erhält und z. B. Postfix dann eine beliebige Adresse aus diesem Subnetz zum Senden benutzt. Hier bietet es sich an, die entsprechende Interface-Adresse für den Server fest zu definieren.

E-Mails sinnvoll zuzustellen ist insbesondere bei größeren Anbietern wie Gmail problematisch, weil eine Reihe von Voraussetzungen erfüllt sein müssen.

Hier ist es neben den normalen Maßnahmen wie dem korrekten Setzen der DNS-Einträge (Forward und Reverse), meist auch notwendig Verfahren wie SPF, DKIM und DMARC zu implementieren, welche die Komplexität für den entsprechenden E-Mail-Server steigen lassen.

SPF

Mit dem Sender Policy Framework (SPF), wurde ein Verfahren geschaffen, welches sicherstellen sollte, dass E-Mails mit bestimmten Absendern nur von berechtigten E-Mail-Server versendet werden können.

SPF wird auf der Empfängerseite geprüft

Dazu wird bei SPF im DNS eine entsprechende Konfiguration hinterlegt, welche festlegt, welche Server berechtigt sind, für die Absender-Domain E-Mails zu versenden. Die entsprechend notwendigen DNS-Records können über unterschiedlichste Tools erzeugt werden, z. B. über die Webseite spf-record.de.

DKIM

Bei DomainKeys Identified Mail (DKIM) wird die jeweilige E-Mail um eine Signatur ergänzt, über welche der empfangende MTA feststellen kann, ob die E-Mail wirklich vom MTA der Absender-Domain stammt.

Dazu wird über einen im DNS hinterlegten öffentlichen Schlüssel für die Absender-Domain überprüft, ob die Signatur in der E-Mail valide ist.

DMARC

Aufbauend auf SPF und DKIM existiert mit Domain-based Message Authentication, Reporting and Conformance (DMARC) eine Spezifikation, mit welcher festgelegt wird, wie mit entsprechenden E-Mails, welche durch die SPF- und DKIM-Prüfung durchgefallen sind, reagiert werden soll.

Auch hier werden DNS-Records der Absender-Domain genutzt, um entsprechende Informationen für die Richtlinie zu hinterlegen.

Eine Besonderheit bei DMARC ist, dass der im DNS-Record hinterlegte DMARC-Admin über fehlgeschlagene DMARC-Prüfungen informiert werden kann und somit erfährt, dass die entsprechende Domain für Spam missbraucht wird.

Klein anfangen

Bei kleinen E-Mail-Servern, mit geringen Volumen an E-Mails, reicht es meist aus SPF zu aktivieren. Spätestens bei der Nutzung von IPv6 müssen einige Maßnahmen wie SPF eingerichtet werden, um E-Mails sicher versenden können. Andernfalls kann es vorkommen, dass solche E-Mails abgelehnt werden.

Auch ist es nicht ratsam sofort mit großen E-Mail-Volumina auf die Server von Google zu feuern, hier wird ein langsames Ansteigen der Last über einen längeren Zeitraum bevorzugt, um nicht von eventuellen Anti-Spam-Maßnahmen betroffen zu sein.

Dann gibt es auch noch speziellere Fälle, wie bei T-Online, in deren Dokumentation sich folgender Abschnitt findet:

Insbesondere empfehlen wir, den Hostnamen so zu wählen, dass seine Nutzung als Mailserver für Außenstehende erkennbar ist (z. B. mail.example.com), und sicherzustellen, dass die Domain zu einer Website führt, die eine Anbieterkennzeichnung mit sämtlichen Kontaktdaten beinhaltet.

Bei solchen Regeln ist es damit praktisch unmöglich einen reinen E-Mail-Server zu konfigurieren, da zumindest ein Webserver mit dem Impressum vorhanden sein muss. Ansonsten erhält der Betreiber des E-Mail-Servers entsprechende Meldungen im Log:

Dec  6 19:07:26 host42 postfix/smtp[3017216]: ED2DA7EE0104: to=<>, relay=mx00.t-online.de[194.25.134.8]:25, delay=0.33, delays=0.16/0.02/0.14/0, dsn=4.0.0, status=deferred (host mx00.t-online.de[194.25.134.8] refused to talk to me: 554 IP=192.168.9.1 - A problem occurred. (Ask your postmaster for help or to contact  to clarify.))

Spam, Spam, Spam

Monty Python schenkte uns nicht nur Silly Walks, sondern auch Spam. Der berühmte Sketch führte schlussendlich dazu, dass wir ungewollte E-Mails als Spam bezeichnen. Das Problem selbst wurde relativ früh erkannt und in die RFC 706, welche den schönen Titel On the Junk Mail Problem trägt, gegossen.

Spam ist in unserer heutigen Zeit allgegenwärtig und wird leider massenhaft versendet. Ohne zumindest minimale Maßnahmen, um Spam zu unterdrücken, sollte ein E-Mail-Server nicht betrieben werden. Hier muss auch immer die Abwägung getroffen werden zwischen der Filterung unerwünschter Mails und dem Abweisen von legitimen Mails, welche fälschlicherweise als Spam erkannt worden sind.

Greylisting

Eine der einfachsten und effektivsten Maßnahmen gegen Spam ist das sogenannte Greylisting. Beim Greylisting wird eine Mail von einem unbekannten Absender im ersten Schritt nicht angenommen und stattdessen ein technischer Fehler kommuniziert.

Sep  4 09:12:26 lexa postfix/smtpd[2761177]: NOQUEUE: reject: RCPT from unknown[213.209.159.56]: 450 4.2.0 <>: Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/example.org.html; from=<> to=<> proto=ESMTP helo=

Standardkonforme E-Mail-Server senden eine solch zurückgewiesene E-Mail nach einer Wartezeit noch einmal. Ist die eingestellte Greylisting-Zeit abgelaufen, wird die E-Mail anschließend angenommen.

Bei einer Spamnachricht, welche an viele Millionen Empfänger gesendet wird, findet dieses abermaliges Versenden der E-Mail in den meisten Fällen nicht statt. Damit kann mittels Greylisting ein Großteil von Spam-E-Mails gefahrlos aussortiert werden.

Problematisch wird Greylisting dann, wenn z. B. Zwei-Faktor-Authentifizierungscodes empfangen werden sollen, welche nur eine gewisse Zeit gültig sind und durch die Verzögerung beim Greylisting ihre Gültigkeit verlieren.

Weitere Filter

Neben dem Greylisting, gibt es eine Reihe von kleineren Überprüfungen, welche vorgenommen werden können, bevor eine E-Mail angenommen wird. Je nach eingesetzter Software können diese Direkten aktiviert werden und somit E-Mails, welche den Direktiven widersprechen, abzuweisen.

So existiert unter Postfix z. B. die Direktive reject_unknown_sender_domain. Diese Direktive weist E-Mails zurück, welche Adressen nutzen, für welche kein MX- oder A-Record vergeben wurde. Dies ist dann der Fall, wenn entsprechender Spam von Adressen versendet wird, welche in Wirklichkeit nicht existieren oder von Servern kommen, welche nicht als E-Mail-Server konfiguriert sind.

In einer Postfix-Konfiguration werden diese Direktiven nacheinander abgearbeitet:

smtpd_relay_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  defer_unauth_destination
  reject_unknown_sender_domain
  reject_unknown_reverse_client_hostname
  reject_rbl_client zen.spamhaus.org=127.0.0.[2..11]
  reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99]
  reject_rhsbl_helo dbl.spamhaus.org=127.0.1.[2..99]
  reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99]
  warn_if_reject reject_rbl_client zen.spamhaus.org=127.255.255.[1..255]
  check_policy_service inet:127.0.0.1:10023

Durch diese Direktiven, welche gewisse Prüfungen auf Standardkonformität durchführen, wird idealerweise ein Großteil des Spams abgewiesen.

DNS-based blocklists

Daneben sind zur Bekämpfung von Spam auch DNS basierte Blocklisten in Gebrauch. Bei einer solchen Liste wird die IP-Adresse des Senders per DNS gegenüber dem Anbieter der Blockliste aufgelöst. Über den Rückgabecode kann damit ermittelt werden, ob das entsprechende sendende System als Spam eingestuft wird und die entsprechende Mail zurückgewiesen werden.

Auf dem Markt sind einige größere Listen verfügbar, z. B. von Spamhaus. Für den eigenen E-Mail-Server, sollte hier eine sinnvolle Abwägung getroffen werden, welche Liste(n) zur Prüfung hinterlegt werden sollen, da diese Listen im schlimmsten Fall darüber entscheiden ob eine E-Mail abgewiesen wird.

E-Mail-Server goes Cloud

Wer diesen Aufwand nicht treiben möchte, kann seine eigene Domain mit einem E-Mail-Server aus der Cloud versorgen. Unter anderem Google unterstützt dies.

So kann mit Google Workspace eine eigene Domain für die Nutzung von Gmail eingerichtet werden. Damit wird das E-Mail-System von Google benutzt und in der Theorie hält sich der Wartungs- und Verwaltungsaufwand in Grenzen.

Problematisch ist allerdings, dass sich in eine entsprechende Abhängigkeit begeben wird und auch datenschutzrechtliche Aspekte eine Rolle spielen, was z. B. den Transfer von Daten in das Nicht-EU-Ausland angeht.

Technisch realisiert wird dies so, dass die entsprechenden MX-Records für die eigene Domain auf die E-Mail-Server von Google zeigen und somit die offiziellen E-Mail-Server für die Domain sind.

Rechtliche und weitere Anforderungen

Neben den technischen Anforderungen kommen je nach Größe des E-Mail-Servers noch weitere rechtliche Anforderungen hinzu. So müssen ab einer bestimmten Nutzeranzahl unter Umständen Abhörschnittstellen eingerichtet werden, was sich aus der Telekommunikations-Überwachungsverordnung ergibt.

Auch ist es sinnvoll bestimmte E-Mail-Adressen, wie sie in der RFC 2142 definiert werden, bereitzuhalten. Daneben sollten auch Prozesse eingerichtet werden, um Anfragen an diese E-Mail-Adressen, wie. z. B. Abuse-Adressen, zu bearbeiten.

Re­sü­mee

Auch wenn der Betrieb eines E-Mail-Servers mit gewissen Anforderungen verbunden ist, bietet er durchaus Vorteile. So können private Daten auf der eigenen Infrastruktur gehalten und verarbeitet werden und es löst Abhängigkeiten von großen Infrastrukturanbietern.

Außerdem trägt ein solcher Server zum Grundgedanken des E-Mail-Systems bei, dass es sich um ein dezentrales System handelt.

Wer einen E-Mail-Server für private Zwecken einrichten möchte, kann sich z. B. der Top-Level-Domain .email annähern, mit welcher sich angenehm kurze E-Mail-Adressen für die eigene Familie (z. B. ) realisieren lassen.

Auch wenn heutzutage die firmeninterne Kommunikation in vielen Fällen über andere Systeme wie Slack oder Teams läuft und wir in persönlichen Kontakten meist auf Messenger à la WhatsApp oder Signal setzen, wird E-Mail, auch wenn sie ein in die Jahre gekommenes Medium ist, uns in der Zukunft begleiten.

Dieser Artikel erschien ursprünglich auf Golem.de und ist hier in einer alternativen Variante zu finden.

Von Codierungen und Vereinheitlichung

Unicode erblickte vor knapp dreißig Jahren das Licht der Welt und brachte ein wenig Ordnung in die babylonische Vielfalt der Kodierungsstandards. Auch wenn er oft genutzt wird, gibt es doch viel Halbwissen rund um diesen Standard.

Wenn eine Datei mit einem Text eingelesen wird, so besteht diese für den Computer nur aus einer Abfolge von Daten, ohne eine wirkliche Bedeutung. Dass wir am Ende in dieser Datei Eine Geschichte zweier Städte von Charles Dickens finden, ist dem Umstand geschuldet, dass sich auf die Codierung dieser Daten geeinigt wurde.

Für die Codierung von Text wurden viele Codierungen erdacht und in der Praxis eingesetzt, vom Morsecode über den Baudot-Murray-Code, welcher als 5-Bit-Code die Tastenstellung eines Telegrafengerät kodierte, bis zum American Standard Code for Information Interchange, kurz ASCII, der für viele Jahre das Fundament der Textkodierung in der IT darstellte.

Eine Telegraphen-Tastatur

Mit Unicode, welcher vor etwa 30 Jahren das Licht der Welt erblickte, wurde ein wenig Ordnung in die babylonische Vielfalt der Codierungsstandards gebracht, was wegen der Internationalisierung der IT dringend nötig war. Und damit ist dieser Standard aus der Vergangenheit gleichzeitig die Zukunft.

ASCII und EBCDIC

Wie vieles in der IT, baut auch Unicode auf einem historischen Erbe auf, in diesem Fall dem ASCII-Standard. In diesem 1963 verabschiedeten Standard waren in einer 7-Bit-Codierung 128 Zeichen kodiert. Neben dem lateinischen Alphabet, also den Zeichen von A bis Z, jeweils in Groß- und Kleinschreibung, den Ziffern und einigen Sonderzeichen, befanden sich in diesem auch etliche Steuerzeichen.

Zu diesen Steuerzeichen gehören bekannte Zeichen wie der Tabulator oder der Zeilenvorschub, als auch weniger bekannte Zeichen wie die Glocke (Bell). Genutzt wurden diese Zeichen zur Steuerung der Geräte, welche mit dem ASCII-Code umgehen sollten.

Technisch betrachtet wurden im ASCII-Code eigentlich nur 126 Zeichen kodiert. Der Hintergrund hierfür ist historisch begründet. Das Zeichen 0 (kodiert als Bits 0000000) wird genutzt, um die Nichtexistenz von Daten anzuzeigen. Im Kontext einer Lochkarte werden keine Löcher im entsprechenden Bereich gestanzt.

Das Gegenteil hiervon ist das Zeichen 127 (1111111), welches festlegt, dass die Daten auf diesem Feld als gelöscht gelten; auch hier wieder der Lochkarten-Hintergrund, bei welchem im Fehlerfalle bestehende Löcher nicht mehr geschlossen werden können bzw. sollten und somit alle Löcher gelocht werden, um ein gelöschtes Datum zu symbolisieren.

Eine ASCII-Tabelle in einem Drucker von General Electric aus den 70er Jahren

Da sie in dieser Form nicht mehr benötigt wurden, wurden diese Zeichen teilweise anders genutzt. In vielen Programmiersprachen stellt das Zeichen 0 das Ende einer Zeichenkette dar. Somit können in diesen Sprachen, wie z. B. C, Zeichenketten abgespeichert werden, ohne dass die entsprechende Länge bekannt sein muss, im Gegensatz zu Sprachen wie z. B. Pascal.

In seiner heutigen Form wurde der ASCII-Code nach einigen kleineren Änderungen schließlich 1968 verabschiedet. Neben dem ASCII-Code wurde von IBM der Extended Binary Coded Decimal Interchange Code (EBCDIC) entwickelt, welcher vorwiegend auf Großrechnern genutzt wurde. Diese Entwicklung fand zwischen 1963 und 1964 statt und wurde mit dem System/360 der Öffentlichkeit vorgestellt.

Im Westen nichts Neues

Aus Sicht der westlichen Welt war der ASCII-Code für viele Dinge gut genug. So können Umlaute im Deutschen leicht ersetzt werden, z. B. das Zeichen ä durch ae. Allerdings wurde dies nicht immer gemacht und war auch nicht immer gewünscht.

Um andere Zeichen wie Umlaute oder Akzentzeichen abzubilden, entstanden 8-Bit Codes basierend auf dem ASCII-Code, welche somit die doppelte Zeichenanzahl unterbringen konnten.

In Westeuropa hat sich hierbei insbesondere der Standard ISO/IEC 8859-1 etabliert, besser bekannt unter dem Namen Latin-1. Ziel dieses Standards war es, möglichst viele Zeichen westeuropäischer Sprachen abzubilden. Unter Windows wurde eine abgewandelte Form dieses Zeichensatzes unter dem Namen Windows-1252 genutzt.

Durch die ISO standardisiert sind daneben Zeichensätze für weitere europäische Regionen wie Griechisch, aber auch Kyrillisch, Arabisch, Thai und Hebräisch.

Daneben existieren andere 8-Bit-Codierungen, welche teilweise nur mit ihren jeweiligen Anwendungen bzw. Betriebssystemen kompatibel waren und nicht standardisiert sind. Ein Beispiel für eine solche Codierungen ist CBM-ASCII, in welcher unter anderem Zeichen für Blockgrafik enthalten waren und welche bei vielen Heimcomputern von Commodore zum Einsatz kam.

Zeichensalat

Die Nutzung unterschiedlicher Codierungen führt aber auch zu Problemen. Wird ein Dokument z. B. mit der falschen Codierung geöffnet, so erhält der Nutzer in solchen Fällen sogenannten Zeichensalat:

Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.

Auch Texte, in denen mehrere Sprachen vorhanden sind, ließen sich mit diesen bestehenden Codierungen nicht einfach umsetzen.

Noch ein Standard?

Mit der Globalisierung und dem Austausch von Dokumenten über Sprach- und Systemgrenzen hinweg entwickelte sich die Vielfalt an Codierungen zu einem Problem.

Die ISO/IEC 2022 versuchte dieses Problem zu lösen. Bei diesem Standard kann unter Zuhilfenahme verschiedener Escape-Sequenzen zwischen den unterschiedlichen Zeichensätzen umgeschaltet werden. Durchgesetzt hat sich dieser Standard nur in Japan, Korea und China, in erster Linie im Kontext E-Mail; da der Standard auch entsprechende 7-Bit-Codierungen definiert.

Schlussendlich kam es zur Entwicklung von Unicode. Wie so viele Entwicklungen, die die IT weiter brachten, hatten sie etwas mit Xerox zu tun. Vom PARC Universal Packet, welches maßgeblich das Design von TCP/IP beeinflusste, bis zum WIMP-Paradigma (Windows, Icons, Menus, Pointer), dem wir unsere modernen Desktop-Oberflächen und Interface-Konzepte verdanken.

Dort entstand der Xerox Character Code Standard, welcher als inoffizieller Vorgänger des Unicode-Standards betrachtet werden kann. Joseph D. Becker, welcher sich bei Xerox schon länger mit multilingualer Software befasste und unter anderem 1984 das Paper Multilingual Word Processing dazu verfasste, ist einer der Erfinder und Gestalter von Unicode.

Die eigentliche Entwicklung von Unicode begann 1987. Neben Joseph D. Becker arbeiteten Lee Collins und Mark Davis, damals bei Apple angestellt, ebenfalls an dem neuen Standard, welcher ein universelles Set von Zeichen darstellen sollte, in welchem die aktuellen Schriftsysteme der Zeit enthalten sein sollten. In der damaligen Entwurfsphase war es noch nicht das erklärte Ziel historische Schriftsysteme abzubilden:

Unicode gives higher priority to ensuring utility for the future than to preserving past antiquities. Unicode aims in the first instance at the characters published in modern text (e.g. in the union of all newspapers and magazines printed in the world in 1988), whose number is undoubtedly far below 2^14 = 16,384. Beyond those modern-use characters, all others may be defined to be obsolete or rare; these are better candidates for private-use registration than for congesting the public list of generally-useful Unicodes.

Im Laufe des Jahres 1989 stießen zur Gruppe um Becker, Mitarbeiter von Metaphor, RLG und Sun Microsystems hinzu. 1990 wurde das Team um Mitstreiter von Microsoft und NEXT erweitert.

Ende desselben Jahres war der Standard dann so weit gediehen, dass am 3. Januar 1991 das Unicode Consortium gegründet wurde. Dieses setzte einige Monate später im Oktober des Jahres den ersten Unicode-Standard in die Welt.

Allerdings wurde dies nicht überall so verstanden. In der TrueType Spezifikation in Version 1.0 für das entsprechende Font-Format erhielt der Standard die Plattform-ID Apple Unicode, was allerdings ein Irrtum war, welcher mittlerweile korrigiert wurde.

Beim Unicode Consortium selbst handelt es sich um eine gemeinnützige Organisation, mit Sitz in Mountain View in Kalifornien. Sie sorgt für die Weiterentwicklung des Standards und die Aufnahme weiterer Zeichen. Zu den Mitgliedern gehören unter anderem Adobe, Apple, Google und Netflix, aber auch Institutionen wie das Bangladesh Computer Council.

Aufbau

Grundsätzlich definiert der Unicode-Standard einen sogenannten Codespace. Jedem Zeichen wird eine Nummer innerhalb dieses Codespace zugewiesen. Ein vergebener Wert für ein Zeichen innerhalb dieses Codespace wird als Code Point bezeichnet und stellt die Grundlage von Unicode dar. So entspricht z. B. der Code Point 2126 dem Omega-Zeichen (Ω). Der Umfang dieses Codespace erstreckt sich von 0 bis 10FFFF.

Genau betrachtet stellt ein Code Point aber nicht unbedingt ein Zeichen dar, da es Zeichen gibt, welche sich aus mehreren Code Points zusammensetzen. So könnte ein Ä als A mit einem Trema (die Punkte über dem Ä), also mit zwei Code Points, dargestellt werden.

Auch werden keine Repräsentationen der Zeichen durch den Unicode-Standard vorgegeben. Stattdessen handelt es sich um abstrakte Zeichen, welche definiert werden. Ihre jeweilige Ausgestaltung ist z. B. entsprechenden Fonts vorbehalten.

Allerdings ist der Adressraum von Unicode nicht flach, sondern in sogenannte Planes unterteilt. Eine Plane entspricht hierbei 2^16, also 65.536 Code Points. Insgesamt sind 17 Planes (Plane 0 bis 16) im Standard definiert. Damit ist das aktuelle Limit an Zeichen in Unicode auf 1.114.112 festgelegt. Nach dem Abzug von Regionen für die private Nutzung bleiben am Ende in etwa 970.000 Code Points für die öffentliche Nutzung übrig.

Die Planes sind nach bestimmten Kriterien unterteilt und definiert. Aktuell genutzt respektive definiert sind sieben dieser Planes, wobei zwei davon für die private Nutzung definiert sind und somit im Unicode-Standard keinerlei Zeichen zugewiesen bekommen.

Die wichtigste und zuerst definierte Plane ist die Basic Multilingual Plane (BMP) mit der ID 0. In dieser sind die Zeichen für die meisten aktuell genutzten Sprachen, definiert. Grundsätzlich sollten in dieser Plane alle Zeichen definiert werden, welche in modernen Schriftsystemen rund um die Welt Verwendung finden. Hier finden sich neben Symbolen und lateinischen Buchstaben hauptsächlich die Zeichen aus der chinesischen, japanischen und koreanischen Sprache.

Die Basic Multilingual Plane

Innerhalb der Planes werden die Code Points in sogenannten Blöcken gruppiert. So existieren in der BMP 164 solcher Blöcke. In diesen Blöcken werden Schriftzeichen thematisch gruppiert, so z. B. der Block für lateinische Buchstaben, für Thai, für mathematische Operatoren oder geometrische Formen. Die Größe eines Blockes hängt von der Anzahl der zu kodierenden Code Points ab, ist aber immer ein Vielfaches von 16.

Neben dieser Plane existieren noch die Supplementary Multilingual Plane mit der ID 1, die Supplementary Ideographic Plane mit der ID 2, die Tertiary Ideographic Plane mit der ID 3 und die Supplementary Special-purpose Plane mit der ID 14.

In der Supplementary Multilingual Plane finden sich weitere Schriftsysteme, auch historischer Natur, wie ägyptische Hieroglyphen oder Zeichen zur Notation von Musik. Auf der Supplementary Ideographic Plane finden sich weitere sogenannte CJK-Zeichen also Schriftzeichen aus dem Chinesischen, Japanischen, Koreanischen und Vietnamesischen. Neben einigem historischen Schriftsystemen wie dem Oracle bone script, einem Vorgänger der chinesischen Schrift, welcher auf Orakelknochen gefunden wurde, ist die Tertiary Ideographic Plane größtenteils leer. Die Supplementary Special-purpose Plane wird für bestimmte Spezialzeichen genutzt, die z. B. im Zusammenhang mit Emojis zum Tragen kommen.

Die Planes 4 bis 13 sind im Moment nicht belegt und somit für zukünftige Erweiterungen verfügbar. Die Planes 15 und 16 sind sogenannte Private Use Area Planes, mit welchen Zeichen kodiert werden können, welche nicht im Unicode-Standard definiert sind. Hierbei müssen sich die Anwendungen über die Bedeutung der einzelnen Zeichen bewusst sein, um diese korrekt darstellen zu können.

Teilweise sind die Zeichen innerhalb einer Plane und entsprechender Blöcke fragmentiert, da Blöcke bereits komplett belegt waren und Zeichen erst später dazukamen.

Altlasten

Neben besagter Fragmentierung befinden sich auch historische Altlasten im Unicode.

Damit bestehende Zeichensätze wie die Latin-Familie, aber auch asiatische Systeme, sinnvoll übernommen werden und einfach konvertiert werden konnten, wurden diese als Ganzes in den Standard übernommen. So entsprechen die ersten 256 Zeichen im Unicode-Standard exakt dem Standard ISO/IEC 8859-1, besser bekannt als Latin-1.

Dies führt stellenweise zu doppelten Zeichen im Unicode-Standard und auch Zeichen wie dem Ä, welches eigentlich ein zusammengesetztes Zeichen ist und als solches nach den heutigen Kriterien wohl nicht im Standard aufgenommen würde. Die meisten dieser Zeichensätze sind in der Basic Multilingual Plane gelandet.

Im Standard selbst mag dies zu einigen Problemen geführt haben und wie ein Makel wirken, aber es war eine pragmatische Entscheidung, welche die Umstellung auf Unicode vereinfachen sollte.

Im Reich der Codierungen

Um ein Unicode-Zeichen zu codieren, existieren unterschiedliche Unicode-Codierungen, sogenannte Unicode Transformation Formats (UTF). Diese unterscheiden sich in grob in Codierungen mit fester Länge wie UTF-32 und Codierungen variabler Länge wie UTF-8.

Im Standard existieren drei Geschmacksrichtungen dieser UTFs: UTF-8, UTF-16 und UTF-32. Die Zahl gibt die Minimalbits an, welche zur Codierung eines Zeichens benötigt werden. Auch wenn dies historisch betrachtet nicht immer der Fall war, da es Codierungen wie UTF-1 oder UTF-7 gab.

Im Falle von Buchstaben aus dem ASCII-Zeichensatz benötigt ein Zeichen in der Codierung UTF-8 ein Byte, kann aber bis zu 4 Byte beanspruchen, je nach dem auf welches Unicode-Zeichen verwiesen werden soll. Somit können alle Zeichen des Unicode-Standards entsprechend kodiert werden. Werden nur ASCII-Zeichen genutzt, so ist diese Codierung kompatibel mit ASCII.

Die Geschichte von UTF-8 ist eng mit der des Betriebsystems Plan-9 verbunden, welches in den 80er-Jahren in den Bell Laboratories entwickelt wurde. Die ursprüngliche Umsetzung sah vor 16-Bit breite Zeichen in Plan 9 zu nutzen. Allerdings waren die Entwickler damit unzufrieden. Ein Anruf von IBM, zu einem bevorstehenden Meeting des X/Open Komitees, führte dazu, dass Rob Pike und Ken Thompson an einem Mittwochabend die UTF-8 Codierung entwickelten und sie Plan 9 von Mittwoch zu Freitag auf UTF-8 umstellten. Ein weiterer Anruf beim X/Open Komitee und dem Eingeständnis, dass der Vorschlag von Pike und Thompson wesentlich besser war als der eigene, begann UTF-8 seinen Siegeszug.

Doch wie wird das Ganze technisch gelöst? Da es sich bei ASCII um eine 7-Bit-Codierung handelt, wird das Bit mit dem Index 7 nicht genutzt. Es ist immer Null. So wäre das Zeichen F wie folgt kodiert:

[0 1 0 0 0 1 1 0]
 7 6 5 4 3 2 1 0

Dieser Umstand wird nun für UTF-8 genutzt. Ist das Bit (Index 7) Null, so handelt es sich um ein ASCII-Zeichen, ist es Eins, so liegt eine UTF-8 Codierung vor. Das Zeichen Ä (196) sähe in der UTF-8-Codierung wie folgt aus:

[11 00 00 11] [10 00 01 00]

Die Bitfolge 11 im ersten Byte zeigt dabei an, dass es sich um das Startbyte des Zeichens handelt. Die Anzahl der Einsen am Anfang gibt hierbei an, in wie vielen Bytes das Zeichen kodiert ist. Das Yen-Zeichen ¥ würde in UTF-8 wie folgt kodiert werden:

[11 10 11 11] [10 11 11 11] [10 10 01 01]

Hier zeigt das Startbyte drei Einsen am Anfang. Damit ist klar, dass dieses Zeichen in drei Byte kodiert wird. Die folgenden Bytes sind die sogenannten Folgebytes und sind an der Bitfolge 10 am Anfang zu erkennen.

Nach den aktuellen Unicode-Regeln darf ein UTF-8-Zeichen maximal 4 Byte in Anspruch nehmen, auch wenn die Art der Codierung in der Theorie mehr Bytes nutzen könnte. Zu den jeweiligen Codierungen zählen weiterhin bestimmte Feinheiten, die im Rahmen dieses Artikels nicht im Detail besprochen werden sollen, da sie für das Grundprinzip der Codierung unerheblich sind. So dürfen unter anderem bestimmte Bitfolgen nicht genutzt werden, da sie im Rahmen der UTF-8 Codierung als ungültig angesehen werden. Ein Vorteil dieser Codierung ist, dass immer klar ist, wo ein neues Zeichen beginnt und daher defekte Daten in der UTF-8-Codierung problemlos übersprungen werden können.

Bei UTF-16 wird ein Zeichen durch 16 Bit abgebildet, wenn es sich um ein Zeichen aus der Basic Multilingual Plane handelt. Bei Codierungen außerhalb der BMP werden jeweils zwei 16-Bit-Pärchen genutzt. Dies sollte allerdings nicht mit der UTF-32 Codierung verwechselt werden, da es sich trotzdem um zwei UTF-16 codierte Entitäten handelt.

UTF-32 kodiert jeden Code Point immer in vier Byte und stellt damit die speicherintensivste Codierung dar. Im gewissen Rahmen, mit Ausnahme zusammengesetzter Zeichen, bietet sie einen wahlfreien Zugriff auf die Zeichen einer Zeichenkette an. Damit kann auf Zeichen innerhalb der Zeichenkette zugegriffen werden, indem ihre Position berechnet wird, anstatt die komplette Zeichenkette von Anfang an decodieren zu müssen.

Im Zusammenhang mit den Codierungen fallen gelegentlich auch die Begriffe UCS-2 und UCS-4. Bei UCS-2 handelt es sich um eine obsolete Codierung, welche nur die Code Points der Basic Multilingual Plane codieren konnte. UCS-4 hingegen ist gleichbedeutend mit UTF-32. Die Begrifflichkeit UCS kommt vom Universal Coded Character Set aus der Norm ISO/IEC 10646.

Daneben gibt es Codierungen wie UTF-EBCDIC, welche dafür gedacht waren, Unicode auf entsprechende Mainframe-Rechnern, welche mit der EBCDIC-Codierung arbeiten, zu bringen. In der Praxis wird auf solchen Systemen, wie z/OS, aber meist UTF-16 genutzt.

Der Unterschied zwischen Codierungen fester Breite gegenüber denen variabler Breite liegt im Aufwand, die entsprechende Codierung auszuwerten. Bei den Codierungen variabler Breiten, muss ein entsprechender Rechenaufwand in das Lesen der Codierungen gesteckt werden. Dieser entfällt bei Codierungen fester Breite, allerdings ist hier der Speicherbedarf höher als bei den Codierungen variabler Breite.

Byte Order Mark

Doch wie wird erkannt, in welcher Codierung ein Dokument vorliegt? Dafür existiert das Byte Order Mark, kurz BOM. Dieses steht am Anfang einer Datei und teilt die genutzte Codierung mit.

Für UTF-8 haben viele ein solches BOM sicherlich schon einmal gesehen:



Als hexadezimale Repräsentation sieht dieses dann wie folgt aus:

EF BB BF

Bei den UTF-16 und UTF-32 Codierungen muss die Endianness, also die Reihenfolge der Bytes berücksichtigt werden. Dies wird mit dem Byte Order Mark, wie der Name es andeutet, bewerkstelligt. Ein Beispiel eines UTF-16 BOM:

 FE FF (Big Endian)
 FF FE (Little Endian)

Die Nutzung des Byte Order Mark ist optional. Ist keines gesetzt, so wird automatisch davon ausgegangen, dass die Byte-Reihenfolge Big-Endian ist.

ISO und Unicode

Mit dem Standard ISO/IEC 10646, dem Universal Coded Character Set sind die Zeichen des Unicodes auch in einem ISO-Standard verewigt. Mittlerweile werden der ISO-Standard und Unicode synchronisiert; das bedeutet, sie definieren die gleichen Zeichen.

Allerdings existieren Unterschiede zwischen diesem Standard und Unicode. Während die Namen und Code Points in beiden Standards gleich sind, spezifiziert der Unicode Standard Regeln zur Interoperabilität und liefert weitere Dinge wie entsprechende Algorithmen mit. Im Vergleich dazu stellt der ISO-Standard nur eine Zeichentabelle dar.

Im Laufe der Zeit

Während im Oktober 1991 die Unicode-Version 1.0.0, mit 7129 Code Points, veröffentlicht wurde, ist die aktuelle Version 14.0 im September 2021 erschienen und definiert ein Vielfaches an Code Points im Standard.

Dabei sind von Version zu Version immer wieder neue Zeichen hinzugekommen. Der Unicode-Standard legt fest, dass einmal eingebrachte Zeichen nie wieder aus dem Standard entfernt werden dürfen. Das bedeutet, dass sich gut überlegt werden muss, ob ein Zeichen wirklich dem Standard zugeschlagen wird.

Allerdings ist dies nicht immer so gewesen. In der Frühzeit des Standards bis einschließlich Version 2.0, welche im Juli 1996 erschien, wurden unter anderem das koreanische Alphabet in Version 2.0 entfernt und durch neue Zeichen an einer anderen Stelle in der Codeplane ersetzt. Auch in den vorherigen Versionen 1.1 und 1.0.1 wurden Zeichen entfernt.

Ab der Version 2.1 des Standards wurde sich von dieser Praxis gelöst und seitdem wird der Standard nur noch erweitert. Wird nun von der Nutzung eines Zeichens abgeraten, so wird dieses im Unicode-Standard als deprecated gekennzeichnet.

Im Oktober 2010 wurden mit dem Unicode-Standard 5.2 nicht nur Symbole für Spielkarten und weitere Schriftsysteme hinzugefügt, sondern auch Emojis feierten ihr Debüt in dieser Version. Gab es ursprünglich 722 definierte Emojis, sind diese mittlerweile angewachsen und verfügen auch über die Unterstützung unterschiedliche Hautfarben anzeigen zu können.

Mit Version 1.40 sind 144.697 Code Points definiert. Damit ist in etwa ein Siebtel des Codespace belegt. Dass das klingonische Schriftsystem darunter ist, ist im Übrigen ein Gerücht. Allerdings werden klingonische Zeichen über die privaten Bereiche des Unicode-Codespaces genutzt. Für diese privaten Bereiche innerhalb des Codespace gibt es mit der Under-ConScript Unicode Registry eine Art informelle Registry für diese.

Umsetzung in der IT

Standards und damit auch der Unicode-Standard sind nur dann sinnvoll, wenn sie umgesetzt und genutzt werden. Aktuelle Windows-Versionen und macOS-Versionen nutzen für die interne Repräsentation von Unicode UTF-16, bei Linux ist es UTF-8. Damit ist die grundlegende Nutzung in den entsprechenden Betriebssystemen gegeben.

In den Betriebssystemen selbst gibt es für den Nutzer unterschiedliche Möglichkeiten Unicode-Zeichen einzusetzen. Viele Varianten arbeiten mit der Eingabe der entsprechenden ID des Code Points in dezimaler oder hexadezimaler Repräsentation in Verbindung mit einer Taste. Unter Windows kann die Alt-Taste in Verbindung mit der entsprechenden ID zur Eingabe genutzt werden. Auch unter Linux und macOS sind solche Eingaben möglich, wobei diese unter macOS explizit aktiviert werden müssen.

Die Zeichentabelle unter Windows 10

Daneben existieren in den Betriebssystemen auch entsprechende Applikationen, wie die Zeichentabelle unter Windows, mit der Unicode-Zeichen über ein entsprechendes Interface herausgesucht und genutzt werden können.

Bei Programmiersprachen wie Java oder den auf .NET basierenden Sprachen wird intern ebenfalls mit UTF-16 gearbeitet. Unter Rust kann der primitive Typ einen sogenannten Unicode scalar value speichern. Dieser entspricht einem Code Point; allerdings sind die sogenannten Low- und High-Surrogate, welche für UTF-16 benötigt werden, hier nicht mit eingeschlossen.

Interessant ist auch die Betrachtung von Fonts in Bezug auf Unicode. Die erste Frage, die sich hier vielleicht stellt, ist ob ein Font existiert, welcher alle Unicode-Zeichen unterstützt.

Aus technischen Gründen ist dies schon nicht möglich. So kann eine TrueType-Schriftart maximal 65.535 Glyphen enthalten. Auch im OpenType-Format ist eine solche Beschränkung enthalten.

Einer der Fonts aus der Noto-Familie

Allerdings gibt es Font-Familien wie Noto, welche von Google beauftragt wurde und mittlerweile über 77.000 Code Points des Unicodes-Standards abdeckt. Daneben gibt es eine Reihe weiterer Fonts wie GNU Unifont oder WenQuanYi, welche ebenfalls eine Vielzahl an Zeichen aus dem Unicode-Zeichensatz unterstützen.

Der Name der Schriftartfamilie Noto steht für No Tofu und spielt auf das Kästchen an, welches angezeigt wird, wenn ein Font ein entsprechendes Unicode-Zeichen nicht enthält. Früher wurde hierbei häufig der Replacement Character, welcher sich in der Basic Multilingual Plane befindet, genutzt. Dieser zeigt eigentlich an, dass ein Zeichen nicht als valides Unicode-Zeichen erkannt werden konnte, also ein Kodierungsfehler vorliegt. Heutzutage wird für den Fall, dass ein valides Unicode-Zeichen vom Font nicht dargestellt werden kann, die .notdef Glyphe des entsprechenden Fonts angezeigt.

Auch bei der softwareseitigen Unterstützung von Unicode gibt es hier und da Probleme. So wurden bis in die 2000er-Jahre hauptsächlich die Code Points aus der Basic Multilingual Plane unterstützt. Andere Planes waren nicht wirklich zugänglich.

Auch die Zusammensetzung von Zeichen aus mehreren Code Points wird von vielen Anwendungen nicht richtig beherrscht. Gebessert hat sich dies unter anderem durch den Standard GB 18030 der chinesischen Regierung, welcher ebenfalls die entsprechenden Zeichen aus der Codeplane unterstützt und damit ein Unicode Transformation Format darstellt.

Dieser Standard definiert, welche Zeichen zwingend in entsprechenden Betriebssystemen und Anwendungen unterstützt werden müssen und brachte damit die Unicode-Unterstützung jenseits der Basic Multilingual Plane voran.

Auch in anderen Anwendungen, wie E-Mail kann Unicode dank des MIME-Standards seit vielen Jahren genutzt werden. Für die Codierungen von Domainnamen, mit Nicht-ASCII-Zeichen, waren ebenfalls Unicode Transformation Formate in der Entwicklung (UTF-5, UTF-6), allerdings hat sich hier Punnycode durchgesetzt.

Trotz der Durchdringung der Unicode-Standards, kommt es immer wieder zu kleineren und größeren Problemen mit ihm. So akzeptierte Outlook 2016 keine Passwörter mit Unicode-Zeichen und ein Schriftzeichen der Sprache Telugu führte zu Problemen unter iOS und macOS.

Kritik

Der Unicode-Standard ist nicht perfekt und so gab und gibt es immer wieder Kritik an diesem. Einer dieser Punkte ist die Han-Vereinheitlichung. Bei dieser ging und geht es darum, die Zeichen aus den unterschiedlichen ostasiatischen Sprachen auf ihre Grundformen zurückzuführen und diese entsprechend im Unicode-Standard abzubilden. Dies führte zu einiger Kritik, obwohl hierbei möglichst alle betroffenen Sprachgruppen eingebunden wurden, da teilweise Zeichen vereinheitlicht wurden, welche nicht unbedingt dieselbe Bedeutung hatten.

Auch das besagte Mapping bestehender Zeichensätze in den Unicode-Standard, wie im Abschnitt über die Altlasten beschrieben, war ein solcher Kritikpunkt.

Aus der Sicht der IT-Sicherheit wird manchmal die Nutzung von Homoglyphen kritisiert, da dort bestimmte Zeichen durch andere, ähnliche aussehende Zeichen ausgetauscht werden, um z. B. eine Domain einer Bank zu imitieren und den Kunden so um seine Zugangsdaten zu bringen. Ein bekanntes Beispiel hier ist der Austausch des Buchstabens O durch eine 0, welches schon beim ASCII-Standard funktionierte. Mit dem Unicode-Standard sind viele weitere Möglichkeiten für solche Homoglyphen dazugekommen.

Auch die Sortierung und Groß- und Kleinschreibung kann sich im Codespace von Unicode und entsprechender lokaler Regelungen manchmal als schwierig erweisen, da sich z. B. die Sortierreihenfolge nicht unbedingt aus der Anordnung der Zeichen innerhalb des Codespace ergibt.

Die Zukunft

Unicode ist bisher nicht überall angekommen. So wird der Standard ISO/IEC 8859-15 respektive Latin-9 als 8-Bit-Code weiterhin verwendet. Genutzt wird diese Codierung unter anderem bei amtlichen Werken wie der elektronischen Gesundheitskarte.

Im Internet sind mittlerweile über 97,6 % aller Webseiten als UTF-8 kodiert, 1,1 % als ISO-8859-1 und noch mal knapp ein Prozent entfallen auf die Codierungen Windows-1251 und Windows-1252.

Alte Zeichensätze und Codierungen werden über kurz oder lang ein Nischendasein führen und zum Großteil durch Unicode ersetzt werden, zumindest was moderne System angeht.

Im Rahmen der Script Encoding Initiative von Deborah Anderson, welche sie seit 2002 an der University of California in Berkeley betreibt, werden neue Schriftsysteme für den Standard vorgeschlagen, sodass auch in Zukunft weitere Zeichen in den Standard aufgenommen werden.

So zog 2016, mit Adlam, ein ungewöhnliches Schriftsystem in den Standard ein. Ungewöhnlich deshalb, weil dieses System erst seit 1989 existiert. Zwei Brüder entwickelten dieses System, um ihre Sprache, Fulani, phonetisch in einem Schriftsystem abbilden zu können. Etliche Jahre später wurde das System dank der Unterstützung der Script Encoding Initiative schließlich in den Unicode-Standard übernommen und wird mittlerweile unter Windows, Chrome OS sowie Android unterstützt.

Dieses Beispiel zeigt, wie Unicode eine Grundlage für die Nutzung und Überführung von Schriftsystemen in die digitale Welt ist. Noch einige Jahrzehnte zuvor war ein Großteil des Internets und der IT auf einige lateinische Buchstaben reduziert. Dank Unicode ist es möglich in seiner jeweiligen Muttersprache und in seinem angestammten Schriftsystem digital zu kommunizieren, sich zu informieren und teilzuhaben.

Das Unicode Consortium wird seine Arbeit fortsetzen und sich dabei auch in einem teilweise politischen Spannungsfeld bewegen. Wie Randall Munroe, Autor des xkcd-Comics, dazu einmal sagte:

I am endlessly delighted by the hopeless task that the Unicode Consortium has created for themselves. […] They started out just trying to unify a couple different character sets. And before they quite realized what was happening, they were grappling with decisions at the heart of how we use language, no matter how hard they tried to create policies to avoid these problems. It’s just a fun example of how weird language is and how hard human communication is and how you really can’t really get around those problems.

So bietet uns Unicode lateinische Schrift, Spielkarten, Operatoren, Emojis, Schriftzeichen aus vielen menschlichen Kulturen und mehr. Und da sich Schrift und Sprache im Laufe der Zeit verändern, wird der Unicode-Standard wohl nie fertiggestellt, sondern ein lebendiger und sich weiterentwickelnder Standard sein.

Mit seinen 144.697 Zeichen und der Abbildung von über 150 Schriftsystemen liefert er einen Beitrag zur Erhaltung der Schriftkultur und der Daten über die Jahrzehnte. In Zeiten von Globalisierung und weltweit miteinander interagierenden Systemen ist ein gemeinsamer Zeichensatz sicherlich nicht die schlechteste Idee gewesen.

Dieser Artikel erschien ursprünglich auf Golem.de und ist hier in einer alternativen Variante zu finden.

Base64 kodierte Daten in Binärdateien umwandeln

Base64 ist eine Kodierung, welche es ermöglicht binäre Daten in ASCII-Zeichen zu kodieren. Genutzt wird diese Art der Kodierung unter anderem beim Versenden von Anhängen in Mails. Manchmal ist es notwendig solche Daten im Terminal wieder in ihre binäre Form zu verwandeln. Dazu kann unter Linux und macOS das Werkzeug base64 genutzt werden:

base64 base64.txt --decode > binary.dat

Mit diesem Befehl wird der Inhalt der Datei base64.txt dekodiert und in die Datei binary.dat geschrieben.

Unicode-Tabelle im Web

Unicode besteht mittlerweile aus über 137.000 Zeichen. Während ASCII mit seinen 128 Zeichen noch übersichtlich daherkam, ist dies bei Unicode etwas komplexer. Abhilfe schafft hier das Webprojekt der Unicode-Zeichentabelle. In dieser Tabelle lassen sich Unicode-Zeichen betrachten, kopieren und einzeln aufrufen. In der Einzelansicht werden verschiedene technische Angaben zu dem jeweiligen Zeichen dargestellt.

Die Unicode-Tabelle stellt die Unicode-Zeichen übersichtlich da

Zu finden ist das Projekt unter unicode-table.com. Die Seite steht in unterschiedlichen Sprachen, unter anderem Russisch, Englisch, Polnisch und Deutsch zur Verfügung. Die Daten, welche vom Projekt genutzt werden, sind auf GitHub zu finden.