Elektronická pošta

Marek Lipovčan, xlipovc@informatics.muni.cz


Obsah


Formát zprávy

Formát zpráv elektronické pošty byl prvně definován v RFC 822 (STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES, August 13, 1982). Později byla tato norma plně nahrazena dokumentem RFC 2822 (Internet Message Format).
Tento standard popisuje pouze syntax pro textové zprávy, pro zprávy obsahující netextová data (obrázky, binární data) existují jeho rozšíření označované jako MIME

Každá zpráva musí mít právě 2 části - obálku a obsah.

Obálka

obsahuje informace nutné pro přenos a doručení zprávy. Její popis je obsažen v RFC 2821 (SMTP).

Obsah:

Dle RFC 2822 může obsahovat pouze znaky z US-ASCII. Musí obsahovat hlavičku a může obsahovat tělo. Obě části jsou odděleny prázdným řádkem. Řádek nesmí být delší než 998 znaků.

Hlavička:

Řádek hlavičky má formát
název_položky:tělo položky

Tělo položky může být rozděleno na více řádků - pak každý navazující řádek musí začínat bílým znakem.

Musí obsahovat minimálně datum vytvoření zprávy (Date:) a informace o odesilateli (From:, Sender: a Reply-To:). Možné další položky jsou: (To:, Cc:, Bcc:, Message-ID:, In-Reply-To:, References:, Subject:, Comments:, Keywords:, Resent-Date:, Resent-From:, Resent-Sender:, Resent-To:, Resent-Cc:, Resent-Bcc:, Resent-Message-ID:, Return-Path:, Received:).

Tělo:

Řádky znaků z US-ASCII, jejichž délka nesmí přesáhnout 998 znaků. Znaky CR a LF se nesmí vyskytovat odděleně.

MIME rozšíření:


Původně definované v RFC 934, 1049, nyní v RFC 2045 (Format of Internet Message Bodies), 2046 (Media Types), 2047 (Message Header Extensions for Non-ASCII Text), 2048 (Registration Procedures), 2049(Conformance Criteria and Examples), později ještě rozšířené v RFC 2231 (MIME Parameter Value and Encoded Word Extensions: Character Sets, Languages, and Continuations), 2646 (The Text/Plain Format Parameter), 3023(XML Media Types). MIME je zkratka pro Multipurpose Internet Mail Extensions. Rozšiřují formát zpráv elektronické pošty o tyto schopnosti:
Přidává tyto položky do hlavičky zprávy:
MIME-Version: - použitá verze MIME, např. MIME-Version: 1.0
Content-Type: - Má tvar typ/podtyp; atribut1=hodnota1; atribut2=hodnota2..., kde typ může být např. message, multipart, text, image, audio, video, application a podtyp může být lib. řetězec k tomuto účelu registrovaný u IANA nebo lib. řetězec začínající na X-. Příklad: Content-type: text/plain; charset=us-ascii
Content-Transfer-Encoding: - použité kódování pro přenos. Např. 7bit, 8bit, binary, base64...
Content-ID: - identifikátor těla.
Content-Description: - popis obsahu.

Příklad zprávy:

From: "Alice" 
Message-Id: <199711131704.MAA18447@wonderland.com>
Subject: Have you seen my white rabbit?
To: bob@dobbs.org (Bob)
Date: Thu, 13 Nov 1997 12:04:05 -0500 (EST)
Content-Type: text

I'm most concerned.  I fear he may have fallen down a hole.
-- 
alice

Jak funguje elektronická pošta

Vezměme v úvahu příklad uvedený na konci předchozí kapitoly. Následující schéma popisuje způsob, jakým se tato zpráva dostane ke svému příjemci.

Legenda:
MUA - Mail User Agent - uživatelský klient elektronické pošty.
MTA - Mail Tranport Agent - server pro přenos zpráv.
LDA - Local Delivery Agent - server pro lokální doručování zpráv.

Řešení 1

Přímé spojení - Bob je stále připojen k síti.
                   +------------+          +------------+
+-------+  použije | posílající |  volá    | posílající |  
| Alice |--------->|     MUA    |--------->|    MTA     |::::>::::
+-------+          |            |          |            |       ::     na
                   +------------+          +------------+       ::   straně
                                                                :: odesilatele
..............................................................................
                                                                ::
                             SMTP                               ::
 ::::::::::::::::::::::::::::<::::::::::::::::::::::::::::::::::::
 ::
 ::   +-----------+        +-----+             +--------+
 ::   |přijímající|  volá  |     |  doručí do  | Bobova |
 ::::>|    MTA    |------->| LDA |============>|schránka|           na
      |           |        |     |             |        |         straně
      +-----------+        +-----+             +--------+        příjemce
                                                 |   |
                                                 |   |
                     +----------------<----------+   |
                     |                               |
                +---------+         +-------+        |
                |  Bobův  |         | Bobův |<-------+
                |oznamovač|         |  MUA  |
                +---------+         +-------+
                     |                 |
                     |     +-----+     |
                     +---->| Bob |<----+
                           +-----+
Alice chce poslat e-mail Bobovi. Spustí si tedy svůj oblíbený MUA, napíše v něm zprávu a odešle ji.V té chvíli tento MUA předá vytvořenou zprávu posílajícímu MTA (může být buď lokální nebo vzdálený), ten se poté pomocí protokolu SMTP spojí s přijímajícím MTA (určí ho podle zprávy). Ten zprávu přijme a vyvolá LDA, který zprávu doručí do Bobovy poštovní schránky. Bob je poté upozorněn na příchozí zprávu.

Řešení 2

"Nepřímé" spojení - Bob se připojuje k síti jen občas.
                   +------------+          +------------+
+-------+  použije | posílající |  volá    | posílající |  
| Alice |--------->|     MUA    |--------->|    MTA     |::::>::::
+-------+          |            |          |            |       ::     na
                   +------------+          +------------+       ::   straně
                                                                :: odesilatele
                                                                ::
                             SMTP                               ::
 ::::::::::::::::::::::::::::<::::::::::::::::::::::::::::::::::::
 ::
..............................................................................
 ::
 ::   +---------+          +-----+             +----------+
 ::   |přijímací|   volá   |     |    doručí   |  Bobova  |
 ::::>|   MTA   |--------->| LDA |============>| schránka |:>::::
      |         |          |     |      do     |na serveru|    ::    na  
      +---------+          +-----+             +----------+    ::  straně
                                                               ::  serveru
                          POP nebo IMAP                        ::
 ::::::::::::::::::::::::::::<:::::::::::::::::::::::::::::::::::
 ::
.::........................................................................
 ::
 ::                  +-----------+                  s fetchmailem
 ::                  |           |
 :::::::>::::::::::::| fetchmail |::::::::                 na  
 ::                  |           |      ::               straně  
 ::                  +-----------+      ::               Bobova  
 ::                                     ::               stroje      
 ::   ::::::::::::::::<:::::::::::::::::::
 ::   :: 
 ::   ::   +---------+          +-----+                +--------+
 ::   ::   |přijímací|   volá   |     |  doručí do     | Bobova |
 ::   ::::>|   MTA   |--------->| LDA |===============>|schránka|
 ::        |         |          |     |                |        |
 ::        +---------+          +-----+                +--------+
 ::                                                      |   |
 ::                                                      |   |
 ::                       +----------------<-------------+   |
 ::                       |                                  |
 ::                  +---------+         +-------+           |
 ::                  |  Bobův  |         | Bobův |<----------+
 ::                  |oznamovač|         |  MUA  |
 ::                  +---------+         +-------+
 ::                       |                  |
.::........................................................................
 ::                   .   |                  |
 ::                   .   |                  |         bez fetchmailu
 ::                   .   |                  |
 ::                   .   |      +-----+     |
 ::   +----------+    .   +----->|     |<----+
 ::   |  Bobův   |    .          | Bob |
 :::::| POP/IMAP |----.--------->|     |
      |   MUA    |    .          +-----+
      +----------+    .
Tato varianta se od předchozí liší v tom, že Bobova stanice není trvale připojena k síti. Zprávy pro Boba se tedy ukládají na serveru, odkud si je Bob stahuje buď pomocí MUA s podporou POP nebo IMAP, nebo pomocí fetchmailu.

SMTP

SMTP je zkratka pro Simple Mail Transfer Protocol. Původně definován v RFC 821 a 974, nyní v RFC 2821, které aktualizuje RFC 1123.
Tento protokol slouží pro přenos zpráv mezi stanicemi. Z tohoto pohledu se tedy posílající stanice označuje jako klient a přijímající stanice jako server. Pro přenos se vyžaduje spolehlivá, sekvenční, proudová, obousměrná služba, nejčastěji se používá TCP (pro SMTP je vyhrazen well-known port 25)

Základní schéma:

                                 SMTP
 +--------+    +----------+    příkazy     +----------+
 |Uživatel|<-->|          |--------------->|          |
 +--------+    |          |      SMTP      |          |
               |  Klient  |    odpovědi    |  Server  |
 +--------+    |   SMTP   |<---------------|    SMTP  |    +------+
 |  File  |<-->|          |                |          |<-->| File |
 | System |    |          |--------------->|          |    |System|
 +--------+    +----------+     zpráva     +----------+    +------+
                SMTP klient                SMTP server
Když má klient zprávu k odeslání, vytvoří si obousměrné spojení s SMTP serverem. Klient musí buď přenést zprávu nebo ohlásit chybu. SMTP klient nejprve určí cílové doménové jméno. Poté buď jednoznačně určí cílový stroj nebo zprostředkovatelský SMTP server (podle MaileXchanger záznamu v dané doméně). V prvém případě se přenos uskuteční pomocí jednoho spojení přímo s SMTP serverem cílového stroje. V druhém případě naváže spojení s daným SMTP serverem, jímž může být buď "relay" server (pokračuje pak dále s protokolem SMTP) nebo "gateway" (může zprávu dále přenést jiným protokolem než SMTP). V každém případě tento server převezme tuto zprávu a také plnou zodpovědnost za její doručení. Tento server se pak stane SMTP klientem a naváže SMTP spojení dále. Takto se zpráva může "skokově" přenášet přes více serverů až k adresátovi.
Po vytvoření spojení klient posílá serveru SMTP příkazy a ten mu posílá zpět odpovědi. Klient také může přenést zprávu. Po přenosu zprávy může klient spojení uzavřít nebo iniciovat dalsí operace.

SMTP přepravuje zprávu jako objekt, který musí obsahovat obálku a obsah. Obálka je poslána jako série příkazů SMTP. Skládá se z adresy odesilatele, jednoho nebo více adres příjemců a případné další rozšíření. Obsah musí odpovídat výše popsanému standardu pro emailové zprávy (zejména tedy musí obsahovat řádnou hlavičku).

SMTP příkazy mají striktní syntax. Skládají se z řádek znaků US-ASCII zakončených pomocí <CRLF>. Každý příkaz začíná slovesem specifikujícím daný příkaz. Každá odpověd začíná 3-číselným numerickým kódem eventuálně následovaným textovým popisem. Některé příkazy a odpovědi musí obsahovat parametry, jiné nesmí. Příkazy a odpovědi nerozeznávají malá a velká písmena (kromě rozšíření a např. lokálních mailboxů).

Jak probíhá SMTP spojení

  1. Inicializace:
  2. Klient otevře spojení na server a ten pošle úvodní odpověď.
    S: 220 angel.local ESMTP Sendmail 8.12.5/8.12.5; Sun, 23 Mar 2003 12:07:24 +0100
    
  3. Identifikace klienta
  4. Klient pošle EHLO Doména příkaz. Server odpoví a vypíše podporovaná rozšíření.
    K: ehlo local
    S: 250-angel.local Hello angel.localhost [127.0.0.1], pleased to meet you
    S: 250-ENHANCEDSTATUSCODES
    S: 250-PIPELINING
    S: 250-8BITMIME
    S: 250-SIZE
    S: 250-DSN
    S: 250-ETRN
    S: 250-DELIVERBY
    S: 250 HELP
    
  5. Přenos zprávy
  6. Klient pošle nejprve MAIL FROM:<odesilatel> příkaz.
    K: mail from:<marek@angel.local>
    S: 250 2.1.0 <marek@angel.local>... Sender ok
    
    Poté klient pošle RCPT TO:<příjemce> příkaz.
    K: rcpt to:<marek@angel.local>
    S: 250 2.1.5 <marek@angel.local>... Recipient ok
    
    Posledním příkazem před přenosem zprávy je příkaz DATA .
    K: data
    S: 354 Enter mail, end with "." on a line by itself
    
    Následuje přenos vlastní zprávy. Přenos se ukončí řádkem obsahujícím pouze ".".
    K: From: marek@angel.local
    K: Date: Sun, 23 Mar 2003 12:43:10 +0100
    K: To: marek@angel.local
    K: Subject: Psycho
    K: 
    K: Ach jo, uz zase pisu sam sobe...
    K: .
    S: 250 2.0.0 h2NBaR2g002011 Message accepted for delivery
    
    Klient poté může zahájit další SMTP transakce nebo ukončit spojení pomocí příkazu QUIT .
    K: quit
    S: 221 2.0.0 angel.local closing connection
    
Kromě příkazů pro přenos zpráv protokol SMTP umožňuje také ověření existence uživatele (příkaz VRFY ) nebo získání adres mailing-listu/expanzi aliasů (příkaz EXPN ).

V protokolu SMTP se mohou používat pouze plně kvalifikovaná doménová jména, tedy záznamy získané z DNS jako MX nebo A záznamy (případně CNAME které lze finálně vyhodnotit). Z tohoto pravidla existují pouze 2 výjimky:
1. Pokud stroj nemá jméno, pak lze použít jinou identifikaci (například IP adresu).
2. Lze použít řetězec "postmaster" bez doménového jména.

V minulosti se používala metoda "source routing" pro určení trasy přenosu (přes relay/gateway servery). Nyní je tato technika označena jako zastaralá a neměla by se používat (SMTP servery ji musí akceptovat, ale měly by ji ignorovat).

Když SMTP server přijme zprávu, musí na počátek jejího obsahu vložit záznam o zpracování (záznam "Received" v hlavičce, případně "Return-Path" v případě doručení).

SMTP servery na linuxu

Asi nejznámějším je sendmail. Bývá výchozím poštovním serverem ve většině distribucí. Kořeny Sendmailu sahají až k počátkům elektronické pošty, k dobám před vznikem ARPANETU, kdy byly zprávy uchovávány v jednom souboru pro každého uživatele, a ten ho mohl pouze číst. Sendmail byl jedním z prvních pravých MTA (a asi jediným, který přežil tak dlouho). Někteří administrátoři jej také nazývají "pravou noční můrou", a to zejména pro svou komplikovanost, obtížnou konfiguraci a zejména díky spooustě bezpečnostních děr. Sendmail je monolitický program, který pro svůj běh vyžadoval superuživatelské oprávnění (od verze 8.12 toto již není pravda). Je uvolněn pod licencí podobnou BSD. Výhodou Sendmailu je vysoká konfigurovatelnost. Sendmail běží na všech možných platformách - Linux, Solaris, Irix, XXX-BSD, NeXT, AIX, System V, Mac OS ...

Jedním z prvních vážných pokusů nahradit sendmail byl smail. Je jednodušší a má podstatně srozumitelnější konfiguraci. Je také bezpečnější. Výhodou je dobrá podpora jak TCP/IP tak UUCP. Je ale méně efektivnější při více spojeních než Sendmail.

Poslední dobou se stále častěji setkáváme také se serverem qmail. Je kompatibilní se sendmailem (aplikace k němu mohou přistupovat jako k sendmailu). Jedním z hlavních cílů při jeho návrhu byla bezpečnost. Qmail je modulární a je rychlejší než Sendmail. Používá jinou strukturu uživatelských schánek než Sendmail.

Dalším MTA, se kterým se můžete setkat, je exim. Je podobný smailu, ale "umí" toho více. Umožňuje částečnou obranu proti spamu a má podporu pro více virtuálních hostitelů.

Zajímavou alternativou k Sendmailu je také postfix. Je opět kompatibilní se Sendmailem, je ale rychlejší, bezpečnější a má jednodušší administraci. Jeho autorem je Wietse Venema. Původně se tento projekt jmenoval VMailer nebo také IBM Secure Mailer. Umožňuje běžet v chrootovaném prostředí.


Sendmail

Instalace Sendmailu

Vzhledem k tomu, že Sendmail bývá často výchozím MTA na většině současných distribucí, s největší pravděpodobností ho již na svém systému máte. Jestliže není přímo nainstalovaný, je pravděpodobné, že k vaší distribuci existuje příslušný balíček. Tato metoda je doporučována, protože tyto balíčky již mají Sendmail nakonfigurovaný podle vaší distribuce. Pak tedy můžete přeskočit na konfiguraci. Nicméně pokud chcete, můžete si Sendmail stáhnout z webu. V současnosti je aktuální verze 8.12.8.
Rozbalte balík sendmail.X.Y.Z.tar.gz
Přepněte se do nově vzniklého adresáře/sendmail.
Spusťte sh Build
Možné parametry Buildu jsou:
-Icesta - cesta k dalším adresářům s hlavičkovými soubory
-Lcesta - cesta k dalším adresářům s knihovnami
-f soubor.m4 - cesta k souboru, který obsahuje nastavení pro lokální stroj
-c - způsobí kompletní rekompilaci

Konkrétní nastavení pro danou platformu najdete v adresáři devtools/OS/platforma.
Přepněte se do adresáře cf/cf/
Vyberte vhodný soubor něco.mc na sendmail.mc a editujte ho podle svých potřeb.
Spusťte sh Build sendmail.cf
Spusťte sh Build install-cf
Spusťte sh Build install v každém adresáři obsahující část sendmailu.
Případně přidejte nového uživatele/skupinu pro sendmail a upravte příslušné konfigurační soubory (implicitně v /etc/mail/).

Konfigurace Sendmailu

Hlavní konfigurační soubor Sendmailu je sendmail.cf umístěný implicitně v /etc/mail/. Od verze 8.12 Sendmail používá 2 konfigurační soubory pro 2 různé režimy, výše uvedený pro režim MTA, soubor submit.cf pro režim lokálních služeb. Pokud jste již dlouho nenavšívili svou oblíbenou psychiatrickou léčebnu, můžete se vrhnout na editaci tohoto souboru ručně... Většina uživatelů raději zvolí konfiguraci pomocí nástrojů založených na makroprocesoru m4.

Lehký úvod do m4

m4 je makroprocesor, který čte vstup, získává z něj definice maker a nahrazuje následné výskyty názvů těchto maker jejich hodnotami.
Definice makra vypadá následovně:
define(macro,value)
Příklad: Mějme soubor obahující
define(A,B)
A A C
Po zpracování makroprocesorem m4 získáme:
 
B B C
Je doporučováno uzavřít názvy a hodnoty do komentářů. Pokud se chceme zbavit prázdných řádků, které zůstaly po definicích maker, přidáme za makro řetězec dnl (Delete trough New Line).
Příklad: Mějme soubor obahující
define(`A',`B')dnl
A A C
Po zpracování makroprocesorem m4 získáme:
B B C

Vytvoření vlastní konfigurace

V zdrojovém balíku sendmailu (nebo v balíčku obsaženém ve vaší distribuci) najdete spoustu vzorových souborů pro konfiguraci sendmailu (soubory s příponou .mc). Vyberte nejvhodnější a ten si upravte podle vlastních požadavků. Pak spusťte:
$ m4  cesta_k_souboru/cf.m4 moje_nastavení.mc > sendmail.cf
Soubor cf.m4 obsahuje výchozí informace.

Soubor moje_nastavení.mc musí obsahovat minimálně:
OSTYPE() - podpora pro operační systém: DOMAIN(linux)
MAILER() - aplikace pro doručování: MAILER(local), MAILER(smtp)
Důležité další položky jsou:
DOMAIN() - konfigurace pro konkrétní doménu: DOMAIN(default)
FEATURE() - další vlastnosti:
FEATURE(`always_add_domain') - v případě, že odesilatel neobsahuje doménové jméno, přiřadí se mu tohle
FEATURE(`local_procmail', `/admin/mail/bin/procmail') - použít procmail pro lokální doručování.
FEATURE(`access_db',`hash -T -o /etc/mail/access.db') - umožní specifikovat chování sendmailu pro dané odesilatele
FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db') - umožní specifikovat chování pro dané adresáty.
FEATURE(`blacklist_recipients') - umožňuje odmítnout zprávu pro uživatele z daného souboru

Pro účely úkolu se bude hodit právě použití access.db a mailertable.db. Nezapomeňte po změně tohoto souboru spustit makemap hash /etc/mail/access.db < /etc/mail/access.
Příklad souboru /etc/mail/access:
localhost.localdomain           RELAY
localhost                       RELAY
127.0.0.1                       RELAY
spammer.com			ERROR:"550 We hate spammers"
good.spammer.com		OK
192.168.1			ERROR:"550 We don't accept local network"
Příklad souboru /etc/mail/mailertable:
.localdomain			smtp:mail.localdomain
mail.localdomain		smtp:relay.provider.com
Pobrobnější popis jednotlivých položek najdete v README v adresáři cf/