Internet Service Provider con Debian

Da Guide@Debianizzati.Org.
Vai alla navigazione Vai alla ricerca

Introduzione

In questa guida cercheremo di raccogliere tutte le informazioni per arrivare a un'installazione di Debian che fornisca i seguenti servizi, comuni presso qualsiasi Internet Service Provider:

  • hosting di più domini web sullo stesso server
  • accesso via FTP alle directory root di ogni dominio in maniera separata
  • fornitura di indirizzi mail personalizzati "@nomedominio.tld"
  • fornitura di un sistema di webmail

Nota: questa guida non è adatta per chi ha necessità di installare un solo dominio e un solo servizio di posta sul suo server, ma è pensata per chi ha necessità di agire come un Virtual Internet Service Provider, con fornitura di servizi a terzi.

Prerequisiti

Si consideri di partire con un'installazione minimale di Debian effettuata da CD netinstall. Il server dovrà possedere un indirizzo IP pubblico e un FQDN (vedi Wikipedia).
Si configuri il file /etc/apt/sources.list in modo che contenga solo i repository ufficiali (vedi guide sul wiki) e si aggiorni il server con le ultime patch:

# apt-get update
# apt-get upgrade

Può essere utile impostare anche un server NTP esterno per sincronizzare l'ora del nostro server con un'autorità nazionale: Impostare e modificare data e ora.
Poichè il server andrà quasi sicuramente gestito da remoto occorrerà installare e configurare anche l'accesso SSH (OpenSSH: configurazione di base) con autenticazione via chiave: Ssh e autenticazione tramite chiavi.

Installazione ambiente LAMP

Un ambiente LAMP è un acronimo per indicare un ambiente composto da Linux + Apache + MySQL + PHP. Per l'installazione e la configurazione di un ambiente LAMP si segua la guida omonima presente sul wiki: Installare un ambiente LAMP: Linux, Apache2, SSL, MySQL, PHP5.
Nota: il resto della guida sarà basato sulla precedente configurazione, si consiglia quindi di annotare le eventuali modifiche apportate.

Installazione Virtual Host di Apache

Arrivati a questo punto ci troviamo con un server web perfettamente funzionante, ma che ancora non sa come gestire i diversi domini che andranno ospitati sul server.
Per configurare Apache con il supporto ai Virtual Hosts si segua la guida sul wiki: Apache e Virtual Hosts: configurare Apache2 per ospitare più siti web.
Nota: il resto della guida sarà basato sulla precedente configurazione, si consiglia quindi di annotare le eventuali modifiche apportate.

Protezione del web server Apache

Poichè il nostro server sarà esposto al web 24 ore al giorno dovremo premunirci installando alcune protezioni. Un buono spunto per incominciare può essere la guida: Hardening di un web server Apache.
Potrebbe essere una buona idea implementare anche alcuni sistemi di monitoraggio, ad esempio quelli trattati nelle guide seguenti:
Fail2ban
Impedire attacchi SSH brute-force con Denyhosts

Configurazione dei record DNS

Per fare in modo che i PC connessi a internet possano sapere che tutti i siti configurati sono ospitati su un server che risponde a un solo indirizzo IP pubblico (che supponiamo sia 1.2.3.4) è necessario configurare i record DNS di ogni dominio in questo modo:

www => 1.2.3.4 A
ftp => 1.2.3.4 A
@   => 1.2.3.4 A
mail => 1.2.3.4 MXE

Con questa configurazione attiveremo quindi tre sottodomini, uno per il web (www), uno per l'FTP (ftp) e uno per il mailserver del dominio (mail).

Installazione FTP server

L'installazione di un server FTP con utenti virtuali permetterà ad ogni proprietario di un dominio ospitato sul nostro server di accedere via FTP allo spazio web a sua disposizione, senza poter navigare all'interno del filesystem del server e all'interno degli spazi web riservati agli altri domini. Per l'installazione di un server FTP con utenti virtuali si segua la guida: Installare un server FTP con utenti virtuali su MySQL.

Installazione del server di posta

Schema di funzionamento

I software utilizzati per configurare il server di posta saranno i seguenti:

  • Postfix (2.5.5) per inviare e ricevere mail da internet e effettuare i primi controlli basilari
  • Dovecot (1.0.15) per archiviare le mail sul server e fornire agli utenti accesso alle loro caselle tramite POP3 e IMAP
  • Squirrelmail (1.4.15) come interfaccia Webmail
  • MySQL (5.0.51a) come database backend per archiviare informazioni su domini, account utente e email forwarding
  • AMaViS (2.6.1) per effetuare la scansione delle mail in arrivo utilizzando ClamAV e SpamAssassin
  • Clam Antivirus (0.94) come controllo antivirus
  • SpamAssassin (3.2.5) come filtro antispam

Una volta a regime, il server di posta sarà configurato in questa maniera:

  • una email viene spedita attraverso il nostro SMTP sulla porta 25. Postfix accetta la connessione e effettua alcuni controlli:
    • il mittente è in blacklist o in whitelist?
    • la mail proviene da un utente autenticato sul server e può superare i controlli di relay?
    • il destinatario è un utente valido del sistema?
  • Postfix inoltra la mail sul protocollo TCP alla porta 10024, dove AMaViS effettua il controllo del contenuto. AMaViS è configurato per aggiungere alcuni header alla mail, in modo che gli utenti possano filtrarla o meno come spam.
  • La mail viene poi girata a SpamAssassin per un controllo antispam più accurato
  • Poi interviene ClamAV, che ne controlla il contenuto alla ricerca di virus
  • Dopo questi controlli AMaViS restituisce la mail a Postfix sulla porta TCP 10025
  • Postfix è configurato per non controllare il traffico in arrivo su questa porta e gira la mail a Dovecot senza ulteriori controlli
  • Dovecot salva la mail sul server in formato Maildir
  • L'utente può ora leggere la sua email attraverso i protocolli POP3 o IMAP


Domini locali e virtuali

Normalmente Postfix lavora con i cosiddetti Domini Locali, configurati nella direttiva mydestination del suo file di configurazione, e con gli utenti di sistema, elencati nel file /etc/passwd.
Questo comporta che ogni utente possa ricevere la posta di tutti i domini. Supponiamo di avere la direttiva:

mydestination = example1.com, example2.com, example3.com

Questo semplice setup fa sì che l'utente di sistema johndoe riceva le email indirizzate a:

johndoe@example1.com
johndoe@example2.com
johndoe@example3.com

Non è possibile impedire la ricezione della posta indirizzata a un singolo dominio e questo, unitamente al fatto che gestire molti utenti in questa maniera è inefficiente, rende il sistema poco pratico.

Questi problemi possono essere evitati facendo uso dei cosiddetti Domini Virtuali, che a loro volta gestiranno utenti virtuali e alias virtuali di posta. Nel corso della guida vedremo come questa tecnica sarà implementata attraverso alcune direttive Postfix e con il supporto di un database MySQL.

Installazione dei pacchetti necessari

Incominciamo con l'installare il server Postfix con la sua estensione per il supporto a MySQL:

# aptitude install postfix-mysql

Questo comando installerà automaticamente anche il pacchetto postfix e rimuoverà Exim, il mail server installato di default da Debian.
Quando richiesti dall'installer di Postfix, scegliete "Sito internet" come tipo di configurazione e inserite il FQDN (Fully Qualified Domain Name) del vostro server.
Poichè intendiamo offrire ai nostri utenti anche i servizi POP3 e IMAP dobbiamo installare il demone Dovecot:

# aptitude install dovecot-pop3d dovecot-imapd

Alcuni pacchetti utilizzati in questa guida per la scansione degli allegati di posta elettronica non sono inclusi nella sezione main dei repository di Debian (ad esempio unrar e lha); per poterli installare dobbiamo prima modificare il nostro /etc/apt/sources.list aggiungendo la sezione non-free:

deb http://ftp.debian.org/debian/ lenny main contrib non-free

Aggiorniamo la lista dei pacchetti disponibili:

# aptitude update

e installiamo i pacchetti necessari al filtraggio dello spam e alla scansione delle email:

# aptitude install amavisd-new spamassassin clamav-daemon lha arj unrar zoo nomarch cpio lzop cabextract

AMaViS è ora installato nel nostro sistema, insieme a una serie di pacchetti per la scansione delle email.
Dato che vogliamo offrire anche un servizio di Webmail, installeremo anche il pacchetto Squirrelmail:

# aptitude install squirrelmail

Infine installiamo il client mail Pop3 / Imap mutt, che funziona da console e che può essere utile per testare la nostra configurazione strada facendo

# aptitude install mutt

Ora che tutti i pacchetti base sono stati installati, è tempo di preparare il database di appoggio.

Preparazione del database

Creazione del database

Come prima cosa creeremo un nuovo database MySQL, che chiameremo mailserver:

# mysqladmin -p create mailserver

Ci verrà chiesta la passord dell'utente root di MySQL e poi sarà creato il nuovo database.

Aggiunta di un utente MySQL con privilegi limitati

Per ragioni di sicurezza creiamo un nuovo utente mySQL con privilegi limitati verso il database mailserve:

# mysql -p

Vedremo il prompt trasformarsi in mysql>, la shell di MySQL, e saremo pronti per creare l'utente mailuser con password mailuser2009:

mysql> GRANT SELECT ON mailserver.*
       TO 'mailuser'@'127.0.0.1'
       IDENTIFIED BY 'mailuser2009';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye

Creazione delle tabelle del database

A questo punto dobbiamo creare all'interno del database le tabelle per archiviare le informazioni sui domini, sugli alias, i forwarding e le mailbox degli utenti.
Connettiamoci di nuovo a MySQL e scegliamo il database mailserver e creiamo la prima tabella, per registrare i domini virtuali:

# mysql -p mailserver
mysql>
CREATE TABLE `virtual_domains` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

la tabella successiva conterrà le informazioni sugli utenti virtuali di Postfix; sarà utilizzata per autenticare le richieste POP3, SMTP, IMAP e Webmail. L'indirizzo email dell'utente sarà utilizzato anche come username per il login:

mysql>
CREATE TABLE `virtual_users` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `password` varchar(32) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `email` (`email`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Il campo email conterrà l'indirizzo mail/username; il campo password conterrà un hash MD5 della password degli utenti. L'attributo unique key sul campo email ci eviterà di creare per errore due indirizzi email identici.
Come ultima cosa creiamo una tabella per gli alias, necessaria per forwardare le email da un indirizzo a un altro:

mysql>
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
  `id` int(11) NOT NULL auto_increment,
  `domain_id` int(11) NOT NULL,
  `source` varchar(100) NOT NULL,
  `destination` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Sono state impostate alcune foreign keys: servono per collegare i record delle tabelle virtual_aliases e virtual_users con i record nella tabella virtual_domains. Questo ci permetterà di mantenere consistenti i dati nel database, perchè non potremo creare utenti virtuali o alias virtuali non collegati ad alcun dominio virtuale.
Il suffisso ON DELETE CASCADE significa che rimuovendo un dominio virtuale saranno cancellate anche tutti gli utenti virtuali e gli alias collegati al dominio, evitando di lasciare nel database dei record orfani.

Esempio di contenuto delle tabelle

-----------------
virtual_domains
-----------------
id 	|	name
-----------------
1	|	example.com
2	|	foobar.org


---------------------------------
virtual_users
---------------------------------
id	|	domain_id	|	email			|	password
1	|	1		|	john@example.com	|	14cbfb845af1f030e372b1cb9275e6dd
2	|	1		|	steve@example.com	|	a57d8c77e922bf756ed80141fc77a658
3	|	2		|	kerstin@foobar.org	|	5d6423c4ccddcbbdf0fcfaf9234a72d0


-----------------------------------
virtual_aliases
-----------------------------------
id	|	domain_id	|	source			|	destination
1	|	1		|	steve@example.com	|	devnull@workaround.org
2	|	2		|	kerstin@foobar.org	|	kerstin42@yahoo.com
3	|	2		|	kerstin@foobar.org	|	kerstin@mycompany.com

The black magic "email-to-email" mapping

Before you define the virtual_alias_maps setting there is a small quirk you need to take care of. There is a special kind of forwarding: the "catchall" alias. Catchalls catch all emails for a domain if there is no specific user account. A catchall alias looks like "@example.com" and forwards email for the whole domain to one account. We have created the 'john@example.com' user and would like to forward all other email on the domain to 'kerstin@gmail.com'. So we would add a catchall alias like:

source destination @example.com kerstin@gmail.com Now imagine what happens when Postfix receives an email for 'john@example.com'. Postfix will first check if there are any aliases in the virtual_alias_maps table. (It does not look at the virtual_mailbox_maps table at the moment.) It finds the catchall entry as above and since there is no more specific alias the catchall account matches and the email is redirected to 'kerstin@gmail.com'. This is probably not what you wanted. So you need to make the table rather look like this:

email destination @example.com kerstin@gmail.com john@example.com john@example.com More specific aliases have precedence over general catchall aliases. Postfix will lookup all these mappings for each of:

john@example.com (most specific) john (only works if "example.com" is the $myorigin domain) @example.com (catchall - least specific) Postfix will find an entry for 'john@example.com' first and sees that email should be "forwarded" to 'john@example.com' - the same email address. This trickery may sound weird but it is needed if you plan to use catchall accounts. So the virtual_alias_maps mapping must obey both the "view_aliases" view and this "john-to-himself" mapping. This is outlined in the virtual(5) man page in the TABLE SEARCH ORDER section.

Create a ".cf" file /etc/postfix/mysql-email2email.cf for the latter mapping:

user = mailuser password = mailuser2009 hosts = 127.0.0.1 dbname = mailserver query = SELECT email FROM virtual_users WHERE email='%s' Check that you get John's email address back when you ask Postfix if there are any aliases for him:

$> postmap -q john@example.com mysql:/etc/postfix/mysql-email2email.cf The result should be the same address:

john@example.com Now you need to tell Postfix that these two mappings should be searched by adding this line to your main.cf:

$> postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf The order of the two mappings is not important here.

You did it! All mappings are set up and the database is generally ready to be filled with domains and users. Make sure that only 'root' and the 'postfix' user can read the ".cf" files - after all your database password is stored there:

$> chgrp postfix /etc/postfix/mysql-*.cf $> chmod u=rw,g=r,o= /etc/postfix/mysql-*.cf