As últimas três partes da série foram muito chatas. Só texto, sem comandos, nenhuma emoção. Vamos agitar isso um pouco.

Agora vamos instalar, configurar e iniciar o nosso serviço de agendas. A base dele é o Horde, um framework para aplicações colaborativas.

Antes de falar do Horde e que você pergunte, eu testei praticamente todas as soluções FOSS para agendas que eu consegui encontrar: Baïkal, DAVical, DCS (Darwin Calendar Server), radicale... Todas elas funcionam muito bem e o nível de dificuldade para instalar e manter varia de uma para outra. O prolema de todas exceto o DCS, que é o mais chato de instalar e manter, é que nenhuma suporta convites para eventos gerenciados pelo servidor.

Em geral, os clientes para o Linux como o KOrganizer e o Tunderbird (com o Lightning) dão conta dos convites. O mesmo não ocorre nos clientes do Mac OS X (Calendar) e do Android (DAVDroid). Eles dependem do suporte a convites no servidor. Não dá pra imaginar um serviço de agendas que você não consegue enviar ou receber convites.

O Horde foi o único que eu encontrei, já em desespero, que suporta isso e ao mesmo tempo é leve e fácil de manter. Por isso ele é a solução que eu adotei. Os serviços de Cal/CardDAV no Horde são tão bons porque eles são implementados com o SabreDAV, que eu considero o melhor framework livre disponível para construção de aplicações de agendas.

O Horde faz muito mais do que prover agendas de eventos e contatos e sincronizar tudo isso. Ele é um framework para groupware completo. Mas para nossas aspirações, as agendas serão suficientes, e isso é um ponto forte do Horde. Ele permite que tenhamos só as aplicações que precisamos.

Ah sim, tem os Zimbra, ownCloud e Zarafa da vida também. Mas essas soluções são gigantescas e não dá para quebrá-las em partes menores. Nós só precisamos de umas agendinhas.

Atualização em 31/05/2014: o caso do groupware não se encaixa na abordagem de instalação do Horde que eu apresento abaixo. Se você pretende implementar um serviço de calendários funcional para múltiplos usuários, e eles precisam compartilhar calendários, contatos e enviar e receber convites para eventos entre os usuários do domínio e externos, então você vai precisar instalar o Horde Groupware Webmail Edition. Essa versão do Horde já instala tudo que é necessário para o Horde funcionar corretamente, incluindo o IMP, o aplicativo de webmail do Horde. A abordagem que uso aqui só funciona bem nos casos onde você é o único usuário do domínio e não vai compartilhar nada com ninguém. Por sorte, a instalação que proponho aqui é bastante similar a do Webmail Edition, mas é claro que você vai precisar adaptar algumas coisas, o que deixo por sua conta.

Sem mais delongas, vamos ao que interessa.

Horde

O Horde é instalado através do PEAR, o repositório de pacotes do PHP. Então, a primeira coisa a fazer é atualizar o PEAR e adicionar o canal de onde o Horde virá.

# pear upgrade PEAR
# pear channel-discover pear.horde.org

Agora definimos onde queremos instalar o Horde. Vamos instalá-lo em /opt/horde.

# pear install horde/horde_role
# pear run-scripts horde/horde_role
Filesystem location for the base Horde application : /opt/horde

Agora podemos iniciar a instalação do Horde. Isso vai demorar um pouco. Apenas acompanhe, já que vai instalar um montão de coisas. Felizmente o Horde é um software bem escrito e sua instalação é bem comportada, não devem haver surpresas. Se houver, já sabe né? RTFM.

# pear install -a -B horde/horde

Agora precisamos criar uns diretórios, ajustar umas permissões e criar a configuração inicial.

# mkdir /var/lib/horde
# chmod 700 /var/lib/horde
# chown nobody /var/lib/horde
# chown nobody /var/lib/nginx /var/lib/php
# cd /opt/horde/
# cp config/conf.php.dist config/conf.php
# chown nobody config/ static/

Edite o arquivo de configuração e altere os parâmetros abaixo conforme é mostrado

$conf['use_ssl'] = 1;
$conf['testdisable'] = false;

O próximo passo da instalação do Horde requer o acesso a sua inteface web. Para chegar nela precisamos resolver umas pendências antes.

A primeira delas é que o Horde requer a extensão GD do PHP para rodar. Ela já está instalada, mas as suas dependências não. Isso é verdade se você instalou um Slackware mínimo como eu proponho no meu guia do Slackware no AWS. Se você instalou o Slackware de outro modo, então talvez isso não se aplique a você. Enfim, você tem que verificar por si mesmo.

Para instalar as dependências do GD, rode:

# slackpkg install libX11 libXau libXdmcp libXpm libxcb

Agora precisamos configurar o PHP para o Horde. Edite o arquivo /etc/php/fastcgi.ini e insira o bloco a seguir no final dele.

; Set some global security things
; See http://www.horde.org/apps/horde/docs/INSTALL#prerequisites
expose_php = Off
register_globals = Off
session.gc_divisor = 10000

Reinicie o PHP-FPM.

# /etc/rc.d/rc.php-fpm restart

Agora precisamos contar ao nginx que o Horde existe. Copie e cole a configuração a seguir no arquivo /etc/nginx/conf.d/20-horde.conf. Não deixe de alterar os parâmetros específicos ao seu ambiente, como o nome do servidor e caminhos para os certificados

# Horde server
server {
    listen      8443 ssl spdy rcvbuf=1k sndbuf=128k backlog=12;                    # The HTTPS server on port 8443.
    server_name mail.exemplo.com;

    # SSL settings
    # According to security recommendations from:
    # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
    ssl_certificate           /etc/ssl/private/certificate.crt;
    ssl_certificate_key       /etc/ssl/private/certificate.key;

    ssl_ciphers               'AES128+EECDH:AES128+EDH:!aNULL';
    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_timeout       5m;
    ssl_session_cache         shared:SSL:5m;

    ssl_stapling              on;
    ssl_stapling_verify       on;
    ssl_prefer_server_ciphers on;
    ssl_dhparam               /etc/ssl/private/dhparam.pem;

    add_header                Strict-Transport-Security "max-age=63072000; includeSubDomains";
    add_header                X-Frame-Options DENY;
    add_header                X-Content-Type-Options nosniff;

    # Server settings
    root        /opt/horde;                                                        # The document root.
    index       index.php;                                                         # Set default indexes.
    limit_req   zone=server burst=200 nodelay;                                     # Limit requests per IP.
    add_header  Cache-Control public;                                              # Tell clients/proxies it's OK to cache.
    expires     max;                                                               # Cache as long as possible.
    access_log  /var/log/nginx/horde.access.log;                                   # Specfic log to Horde.

    # Load extensions
    include     php;                                                               # Load php in this server.
    include     restrictions;                                                      # Load per server restrictions.

    # Disable HtmlStripModule and PageSpeed Module
    strip       off;
    pagespeed   off;

    # Horde specific settings
    keepalive_timeout 0;

    # Frontend is reached only if the user knows a full path, e.g.: /login.php
    location / {
        # Set special headers for static contents
        location ^~ /static/ {
            expires    4w;
            add_header Cache-Control public;
        }
        location ^~ /themes/ {
            expires    4w;
            add_header Cache-Control public;
        }
        try_files      $uri $uri/ /rampage.php?$args;
    }

    # Return RPC service for a root only request.
    location = / {
        return         301 /rpc.php;
    }

    # Service discovery rewrites
    # See: http://sabre.io/dav/service-discovery/
    location /.well-known/caldav {
        return         301 /rpc/;
    }
    location /.well-known/carddav {
        return         301 /rpc/;
    }
}

A configuração do nginx para o Horde é muito semelhante à configuração que foi feita para acesso ao ViMbAdmin. As principais diferenças são:

  • Porta: o Horde vai rodar na porta 8443. É necessário que seja nessa porta em função do esquema de autoconfiguração utilizado por alguns clientes, sendo o Calendar do Mac OS X um deles.
  • Arquivo de log: separamos o arquivo de log do Horde para podermos ter mais controle sobre esse serviço, que estará disponível na internet pública.
  • Blocos location: aqui configuramos coisas específicas ao Horde e também já preparamos as coisas para a autoconfiguração funcionar. IMPORTANTE: a raiz do servidor web (https://mail.exemplo.com:8443/) será usada exclusivamente para o Cal/CardDAV. Os usuários que quiserem acessar a inteface web do Horde precisam obrigatoriamente digitar o endereço completo da página de login (https://mail.exemplo.com:8443/login.php).

Uma vez configurado o nginx, reinicie-o.

# /etc/rc.d/rc.nginx restart

Agora acesse o endereço https://mail.exemplo.com:8443/test.php. Você deve ver alguns avisos de extensões que não estão instaladas. Especificamente, devem haver avisos sobre essas extensões: GeoIP, LZ4, Imagick, LZF, MongoDB, PAM, PostgreSQL e Tidy.

Você também verá esse aviso: Cannot find PHP command-line binary on your system. Syntax checking of configuration files is disabled.. Isso não é verdade. O seu PHP CLI está lá, mas o Horde usa um método de detecção que não o encontra no Slackware.

Como nada disso impede o uso do Horde, podemos continuar.

Hora de criar o usuário e o banco de dados que serão usados pelo Horde e fazer com que ele seja capaz de enxergar o banco do ViMbAdmin, mas apenas a parte que importa.

# mysql -u root -p
(digite a senha do root do MariaDB conforme definida na parte III.)
MariaDB [(none)]> CREATE DATABASE `horde`;
MariaDB [(none)]> GRANT ALL ON `horde`.* TO `horde`@`localhost` IDENTIFIED BY '<senha fodona do horde>';
MariaDB [(none)]> GRANT SELECT (`username`, `password`, `active`) ON `vimbadmin`.`mailbox` TO 'horde'@'localhost';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [vimbadmin]> SELECT username FROM mailbox WHERE active = 1;
+---------------------------+
| username                  |
+---------------------------+
| administrador@exemplo.com |
| eumesmo@exemplo.com       |
+---------------------------+
2 rows in set (0.00 sec)
MariaDB [(none)]> <CTRL+D>

A última query verifica se o usuário do Horde consegue acessar o banco do ViMbAdmin.

Toda a preparação para o Horde está concluída. Acesse o endereço https://mail.exemplo.com:8443/admin/config. É nela que vamos configurá-lo.

Você verá alguns avisos no topo da tela. Pode ignorá-los já que logo estarão resolvidos. Na lista de aplicações, clique no link de Horde (horde). A configuração do Horde será carregada. É um montão de coisa, mas por enquanto vamos nos preocupar com poucas.

Na aba 'General', a que você está agora, altere o que vem abaixo. Só vou falar do que precisa ser alterado. As configurações que não comento é porque ficam em seus valores padrão. Não mexa neles a menos que você esteja se sentindo aventureiro.

tmpdir: /var/lib/horde

Na aba 'Database' configure deste modo:

phptype: MySQL/PDO
username: horde
password: <senha fodona do horde>
socket: /var/run/mysql/mysql.sock
database: horde

Lembra que lá na instalação do ViMbAdmin, ainda na parte VI, criamos uma conta administrador@exemplo.com? Vamos usá-la agora. Na aba 'Authentication', altere isso:

admins: administrador@exemplo.com
resetpassword: no
list_users: Show an input field
driver: SQL authentication w/custom made queries
phptype: MySQL (mysqli)
socket: /var/run/mysql/mysql.sock
username: horde
password: <senha fodona do horde>
database: vimbadmin
query_auth: SELECT username, password FROM mailbox WHERE username = \L AND password = \P AND active = 1
query_getpw: SELECT password FROM mailbox WHERE username = \L AND active = 1
query_list: SELECT username FROM mailbox WHERE active = 1
query_exists: SELECT 1 FROM mailbox WHERE username = \L AND active = 1
encryption: crypt-sha512
count_bad_logins: <marcado>
login_block: <marcado>
login_block_count: 3
login_block_time: 60

Só pra constar, as configurações que fizemos em 'Authentication' integra o Horde com o backend do ViMbAdmin. É isso que permite uma conta única para todos os serviços, email e agendas, igualzinho é no Google. Não é lindo?

Agora clique no botão 'Gerar Configuração do Horde'. Você vai ver um erro:

Um erro fatal ocorreu
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'horde.horde_perms' doesn't exist
Os detalhes foram gravados em log para o administrador.

Tá tudo bem! Sem pânico! As tabelas do Horde precisam ser criadas. Volte para o terminal e rode:

# horde-db-migrate

Vai aparecer um montão de coisas. É normal. Só não pode aparecer erro. Ao final, rode:

# mysql -u root -p horde
(digite a senha do root do MariaDB conforme definida na parte III.)
Enter password:
MariaDB [horde]> SHOW TABLES;
<lista com um montão de tabelas...>
46 rows in set (0.00 sec)

Essa query verifica se as tabelas do Horde foram criadas. Se você viu resultados semelhantes, então está tudo ok e podemos continuar.

Volte na página do Horde e recarregue-a ou digite o endereço https://mail.exemplo.com:8443/login.php. Agora temos uma tela de login. Isso é um ótimo sinal!

Você DEVE fazer o login com o usuário administrador@exemplo.com.

Ah muleke! Habemus Horde!

Vá no ícone da engrenagem no canto superior direito, escolha 'Administração' > 'Configuração'. Você vai ver que os avisos iniciais desapareceram e os bancos de dados estão todos prontos. Isso indica que o Horde está operando bem.

Clique no link de Horde (horde) e revise as configurações que fizemos acima. Pode ocorrer de algumas delas terem voltado aos seus valores padrão. Corrija com os valores que foram passados acima.

Pule direto para a aba 'Caching'. Lembra que instalamos o Memcached para o ViMbAdmin? Vamos usá-lo no Horde também. Altere os parâmetros:

driver: Use a Distributed Hash Table server
cachecss: Yes
driver: Horde Cache
cachejs: Yes
driver: Horde Cache
cachethemes: Yes

Agora vamos seguir com as abas que terão alterações.

Aba 'General':

testdisable: <marcado>

Aba 'Tokens':

timeout: 30

Aba 'Mailer':

type: SMTP server (HIGLY RECOMMENDED)
host: localhost
port: 587
secure: tls
localhost: localhost
auth: No

Um adendo: lembra que nosso Postfix permite o uso não autenticado do serviço submission para máquinas em nossa rede? Usamos esse benefício aqui, por isso auth é no.

Aba 'Spell Cheker':

driver: aspell (command line)
path: /usr/bin/aspell

Aba 'OpenSSL':

cafile: /etc/ssl/certs/ca-certificates.crt
path: /usr/bin/openssl

Aba 'Image Manipulation':

driver: The PHP GD2 extensions (not recommended)

Aba 'Problem Reporting':

email: eumesmo@exemplo.com
maildomain: exemplo.com

Aba 'Menu':

help: Authenticated users
prefs: Authenticated users
problem: Authenticated users
login: Never

Aba 'User Capabilities and Constraints':

select_view: No
force_view: Dynamic

Aba 'Distributed Hash Table':

driver: Memcache Server
persistent: <marcado>
compression: Yes
large_items: true

Clique no botão 'Gerar Configuração do Horde' e está feito. Seu Horde está configurado.

Se você quer que o resultado do test.php sejam todos verdinhos, então você terá que seguir a documentação do Horde para instalar as extensões opcionais.

Tudo muito bonito, mas até agora ele não faz nada além de nos mostrar uma interface bonitinha. Precisamos pendurar aplicações nele. As que vamos pendurar são: Kronolith (calendário), Turba (contatos) e Nag (tarefas).

Como nós já fizemos as principais configurações no Horde, instalar outras aplicações nele será uma baba. Todas as aplicações que funcionam sob o Horde tem a mesma filosofia de instalação que o próprio Horde: instala o código via pear, configura, cria as tabelas, verifica configurações. O Horde só é mais complicado porque ele está mais próximo do sistema operacional que o resto.

Kronolith

O Kronolith (adoro esse nome!) é o aplicativo de calendários construído com o Horde Framework. Ele vai nos prover uma interface web bacana para calendários e também os serviços de CalDAV que vamos usar em nossos clientes (KOrganizer, OS X Calendar, DAVDroid e qualquer outro).

Primeiro, vamos instalar uns calendários de feriados. Gostamos de feriados. Uma curiosidade: preste atenção no tempo que demora pra instalar cada calendário de feriados e veja se procede a lenda que 'brasileiro é preguiçoso com esse tanto de feriado'.

# pear install Date_Holidays-alpha#all

Depois instalamos o Kronolith propriamente dito:

# pear install horde/kronolith

Quando finalizar, precisamos ajustar algumas permissões.

# chown -R nobody /opt/horde/kronolith/config

Retorne à interface web do Horde e vá nas configurações. Veja que o calendário já está instalado. Clique em Calendário (kronolith). Altere as seguintes opções:

from_addr: naorespoda@exemplo.com.br

Clique no botão 'Gerar Configuração de Calendário'.

Vamos criar as tabelas. Agora é mais fácil. Basta clicar nos links 'Esquema SQL DB desatualizado' e estará feito.

Ao recarregar, você verá que um novo menu apareceu no canto superior direito, entre o nome 'Horde' e a engrenagem no menu de configuração. Esse é o Kronolith prontinho para ser usado. Mole, mole.

Turba e Nag

O Turba implementa nossa aplicação de contatos e os serviços de CardDAV. É com ele que vamos manter nossos contatos sincronizados entre os diversos dispositivos que temos.

O Nag é a aplicação para tarefas. Ele está relacionado ao Kronolith, pois tarefas nada mais são do que eventos especializados. Mas como já pegamos o jeitão da instalação de aplicações no Horde, vamos instalá-lo junto com o Turba.

Nenhuma dessas aplicações possuem pré-requisitos ou pacotes opcionais além do Horde. Então é mais fácil instalá-las.

# pear install horde/turba
# pear install horde/nag
# chown -R nobody /opt/horde/{turba,nag}/config

Voltemos para a tela de configuração do Horde. Nossas duas novas aplicações já estarão listadas. Entre nas configurações das duas e gere-as com os valores padrão, se bem que eu desabilito o import_export das duas. Teremos Cal/CardDAV para sincronizar nossas agendas e contatos para quê afinal?

Clique no 'Esquema SQL DB desatualizado' das duas. As aplicações 'Contatos' e 'Tarefas' vão parecer no menu. Mais mole que defecar depois da feijoada.

Bug

Tem um bugzinho chato no Turba que é o seguinte: o recurso 'destinatários favoritos' gera um erro nos clientes CardDAV. Esse bug não é exclusivo do Turba. O Gmail tem o mesmo problema com os contatos frequentes.

Isso ocorre porque o cliente CardDAV (KAddressBook ou Contatos do OS X e Android) espera poder ler e gravar nas agendas que são do usuário. Só que essa agenda de 'favoritos' não permite a gravação. O conteúdo dela vem das pessoas que você troca emails com frequencia. Para esse conteúdo existir, a aplicação de webmail do Horde precisa estar instalada e você precisa enviar emails por ela, duas coisas que nós não vamos fazer. O Turba não é capaz de saber com quem nos comunicamos com frequencia quando usamos só o nosso cliente de email conectado diretamente ao Postfix.

Felizmente tem uma saída para esse impasse. Edite o arquivo /opt/horde/turba/config/backends.php e faça essa alteração:

--- backends.php.default        2015-05-26 03:19:54.380092809 -0300
+++ backends.php        2015-05-26 03:20:22.876092809 -0300
@@ -766,7 +766,7 @@
  */
$cfgSources['favourites'] = array(
    // ENABLED by default
-    'disabled' => false,
+    'disabled' => true,
    'title' => _("Favourite Recipients"),
    'type' => 'favourites',
    'params' => array(

Pronto! Agora você pode recarregar o Horde e, no menu 'Contatos', a opção de 'destinatários favoritos' terá desaparecido.

A chatice é que você vai ter que fazer isso toda vez que atualizar o Turba. Depois eu vou apontar isso como bug para os devs do Horde pra ver se eles topam corrigir.

Falando em Atualizar

O Horde é um projeto maduro e bastante ativo. Praticamente todo mês tem uma atualização pra ele. Para atualizar o Horde e suas aplicações, basta ir nas configurações e clicar em 'Procurar novas versões'. Se houver alguma, você precisa rodar isso no terminal:

# pear upgrade -a -B -c horde

Para saber quando novas versões do Horde se tornam disponíveis, sugiro que você assine o feed RSS do projeto.

E pra fechar a conta das agendas, vamos ajustar o cron para o Horde e seus amiguinhos? Facinho! Coloque isso depois das entradas do ViMbAdmin no cron do root, com o contab -e:

## Horde tasks
# Check and send alarms every five minutes
*/5 * * * * /usr/bin/horde-alarms
# Kronolith reminders every two hours
0 2 * * * /usr/bin/kronolith-agenda
#

Com tudo pronto podemos fechar os arquivos de configuração do Horde. Se você precisar alterar alguma coisa, ou edita os arquivos diretamente no servidor como root ou altera as permissões, edita no Horde e depois volta as permissões. Não deixe os arquivos de configuração do Horde desprotegidos.

chown -R root:nobody /opt/horde/config
find /opt/horde/config/ -type f -exec chmod 0440 '{}' \;
chown -R root:nobody /opt/horde/{kronolith,nag,turba}/config
find /opt/horde/kronolith/config/ -type f -exec chmod 0440 '{}' \;
find /opt/horde/nag/config/ -type f -exec chmod 0440 '{}' \;
find /opt/horde/turba/config/ -type f -exec chmod 0440 '{}' \;

Aproveitando que estamos mexendo nos arquivos de configuração, vamos criar um atalho para chegarmos neles com mais facilidade e para mantê-los onde ficam todas as condigurações do sistema, assim como fizemos com o ViMbAdmin.

# cd /etc
# mkdir horde
# cd horde/
# ln -s /opt/horde/config horde
# ln -s /opt/horde/kronolith/config kronolith
# ln -s /opt/horde/nag/config nag
# ln -s /opt/horde/turba/config turba

E é isto, meu caro, minha cara! Seu servidor de agenda com contas integradas está prontíssimo!

Na próxima parte vamos aquele tapa em detalhes necessários para a vida útil e segura do nosso querido servidor de emails e agendas.