Servidor XMPP com Prosody

Na sequência da minha última postagem, vamos subir nosso próprio servidor XMPP utilizando o software Prosody IM.
O Prosody IM é um software de código aberto para hospedar servidores XMPP. Ele consiste de arquivos de configuração na linguagem Lua, que permitem customizar o servidor da forma que o usuário quiser. É uma alternativa legal para quem não quer depender de ferramentas proprietárias como Whatsapp ou Facebook Messenger, ou que querem ter uma alternativa pro caso de alguma dessas ferramentas dar problema.
Um servidor XMPP é muito semelhante a um servidor HTTP como o Apache ou o NGINX. O próprio XMPP funciona utilizando XML, uma linguagem parecida com o HTML, mas que pode ser extendida para fazer mais coisas além de apresentar páginas web. Um servidor XMPP utiliza de pacotes XML para enviar e receber mensagens entre diferentes clientes, como descrito na postagem anterior. O servidor cria uma interface entre a linguagem de programação e as mensagens do protocolo de envio e recebimento de mensagens, de modo que quem configura o servidor não precisa se preocupar com o protocolo subjacente.
Instalação do Prosody⌗
O Prosody está disponível na maioria das distribuições GNU mais utilizadas, a exemplo de Debian e Arch Linux. Para instalar o programa em uma máquina Arch Linux, basta buscar o programa com o pacman (ou o instalador de sua escolha):
sudo pacman -S prosody
Após instalado, prossiga para a configuração.
Requisitos necessários⌗
Se você tem intenção que qualquer pessoa utilize seu servidor, o jeito mais simples é alugar uma máquina virtual, ou VPS, em um provedor de nuvem pública, como Amazon Web Services, Google Cloud Plaform ou Digital Ocean. Também é possível utilizar VPSs de provedores mais alinhados com ideais de software livre. Além disso, é necessário configurar um servidor web e um firewall, para que as requisições para o servidor XMPP possam ser recebidas corretamente.
Além disso, de modo a realizar resolução de nome, é necessário conseguir um domínio para que requisições de DNS sejam mapeadas para o endereço IP da VPS utilizada. Alguns serviços para comprar domínios são Namecheap ou GoDaddy. Alguns domínios são muito baratos, e podem ser conseguidos por valores tão baixos quanto 5 reais por ano. Para fins de demonstração, utilizaremos o domínio fictício dominio.com.
Arquivo de configuração⌗
O site do Prosody oferece um bom arquivo de configuração inicial, que no servidor se encontra na pasta /etc/prosody/prosody.cfg.lua. Entretanto, para alguém iniciando no mundo do XMPP e mensageiros livres, a configuração pode ser um tanto complexa. Essa postagem busca condensar a configuração para tornar o processo um pouco mais fácil. Um servidor funcional oferece três funcionalidades principais.
- Configurações do servidor;
- Configurações de chat individual e em grupo;
- Configurações de salas públicas.
Cada parte será explicada abaixo.
Configurações do servidor⌗
Inicialmente, é necessário definidr um usuário administrador para realizar as tarefas de super usuário (criar e remover salas, usuários, etc). Para isso, o Prosody mantém uma lista admins de administradores. Adicione ao menos um usuário na lista
-- Example: admins = { "user1@example.com", "user2@example.net" }
admins = { "superusuario@dominio.com" }
Além disso, é necessário selecionar os módulos que serão carregados ao iniciar o servidor. Módulos servem para extender a funcionalidade do servidor Prosody com contribuições da comunidade. A documentação dos módulos pode ser encontrada no site do Prosody. Abaixo estão as configurações que utilizo em meu servidor
modules_enabled = {
-- Generally required
"roster"; -- Allow users to have a roster. Recommended ;)
"saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
"tls"; -- Add support for secure TLS on c2s/s2s connections
"dialback"; -- s2s dialback support
"disco"; -- Service discovery
-- Not essential, but recommended
"carbons"; -- Keep multiple clients in sync
"pep"; -- Enables users to publish their mood, activity, playing music and more
"private"; -- Private XML storage (for room bookmarks, etc.)
"blocklist"; -- Allow users to block communications with other users
"vcard"; -- Allow users to set vCards
-- Nice to have
"version"; -- Replies to server version requests
"uptime"; -- Report how long server has been running
"time"; -- Let others know the time here on this server
"ping"; -- Replies to XMPP pings with pongs
"register"; -- Allow users to register on this server using a client and change passwords
"mam"; -- Store messages in an archive and allow users to access it
-- Admin interfaces
"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
-- HTTP modules
"http_files"; -- Serve static files from a directory over HTTP
-- Other specific functionality
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
"groups"; -- Shared roster support
"announce"; -- Send announcement to all online users
}
Também existe uma variável modules_disabled que desabilita módulos que são carregados por padrão.
Em seguida, é necessário configurar requisitos mínimos para funcionamento do servidor:
allow_registration = false
daemonize = true;
pidfile = "/var/run/prosody/prosody.pid";
Em seguida é necessário configurar um certificado SSL para comunicação criptografada entre o usuário e o servidor e entre servidores. Essa é a etapa mais importante do processo, visto que muitos clientes XMPP não permitem comunicação com servidores sem criptografia, para proteger a privacidade do usuário. O Prosody espera um certificado e uma chave SSL, que podem ser geradas pelo administrador do sistema utilizando o openssl ou gerada por uma entidade confiável como o Let’s Encrypt. O site do Prosody mostra como realizar essa configuração.. Após gerar chaves e certificados, é necessário passar esses arquivos em uma variável ssl, que é padrão da configuração do Prosody:
ssl = {
key = "/etc/letsencrypt/live/dominio.com-0001/privkey.pem";
certificate = "/etc/letsencrypt/live/dominio.com-0001/fullchain.pem";
}
Além disso, é necessário definir se será utilizada criptografia entre cliente e servidor (c2s) e entre servidores (s2s). Isso é necessário para permitir federação entre servidores.
c2s_require_encryption = true
s2s_secure_auth = true
authentication = "internal_hashed"
Em seguida, é necessário configurar armazenamento das mensagens. Eu prefiro utilizar armazenamento em arquivos sqlite, que podem ser guardado facilmente em backup. Também é definido o tempo que arquivos são armazenados (eu deixo em 1 semana).
storage = "sql" -- Default is "internal" (Debian: "sql" requires one of the
sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename.
archive_expires_after = "1w" -- Remove archived messages after 1 week
Configuração de envio de arquivos⌗
O Prosody utiliza de métodos fora do protocolo XMPP para envio de arquivos de forma confiável. É utilizado o protocolo HTTP para enviar arquivos entre clientes, dado que é um protocolo próprio para isso. Para que o envio de arquivos funcione, é necessário definir configurações de tamanho para o envio de arquivos. Além disso, é necessário definir um arquivo combinado de chave e certificado para criptografar o envio de arquivos, assim como o envio de mensagens é criptografado. Chave e certificado devem ser combinadas em um arquivo pem.
https_certificate = "/etc/letsencrypt/live/dominio.com/key-and-cert.pem"
http_upload_file_size_limit = 10485760
http_max_content_size = 31457280
Hosts virtuais⌗
É possível manter diversos servidores XMPP virtuais em um mesmo servidor físico. Isso é feito por meio dos hosts virtuais. Eles definem algum tipo de separação lógica entre conjuntos de chats XMPP. Para fins didáticos, apenas dois hosts virtuais serão definidos
- Host para conversar privadas (dominio.com)
- Host para salas de conversa públicas ou MUCs (grupos.dominio.com)
Cada host virtual deve ser armazenado em uma pasta conf.d na raiz da sua configuração do prosody. Portanto, se o arquivo principal do Prosody (prosody.cfg.lua) está em /etc/prosody, as configurações de hosts virtuais fica em /etc/prosody/conf.d. Cada host virtual também deve ser configurado em um arquivo separado, de forma a manter o sistema modular. Os arquivos de configuração para salas privadas e públicas fica em /etc/prosody/conf.d/dominio.com.cfg.lua e /etc/prosody/conf.d/grupos.dominio.com.cfg.lua.
Cada arquivo de host virtual deve conter um único objeto VirtualHost, que contém as configurações necessárias para funcionamento do host virtual. Para simplicidade, a única configuração do host de salas privadas são as chaves SSL:
VirtualHost "dominio.com"
ssl = {
key = "/etc/letsencrypt/live/dominio.com-0001/privkey.pem";
certificate = "/etc/letsencrypt/live/dominio.com-0001/fullchain.pem";
}
A configuração do host de salas públicas é mais complexa, dado que é necessário realizar diversas configurações. Tais configurações são aplicadas no arquivo /etc/prosody/conf.d/grupos.dominio.com.cfg.lua. As configurações são melhor explicadas na documentação do módulo MUC (mod_muc) do Prosody. As configurações que utilizo em meu servidor se encontram abaixo:
Component "grupos.dominio.com" "muc"
ssl = {
key = "/etc/letsencrypt/live/grupos.dominio.com/privkey.pem";
certificate = "/etc/letsencrypt/live/grupos.dominio.com/fullchain.pem";
}
modules_enabled = { "mam_muc" }
storage = { muc_log = "sql"; }
name = "Salas XMPP públicas para dominio.com"
restrict_room_creation = false -- Qualquer um pode criar salas
component_admins_as_room_owners = false -- Admins de muc não são donos dos grupos
max_history_messages = 0 -- Número de mensagens que novos usuários recebem ao entrar
room_locking = false -- Salas devem ser configuradas antes de utilização
muc_room_lock_timeout = 300 -- 5 minutes
muc_tombstones = true -- Salas removidas não podem ser recriadas antes de expirar o período
muc_tombstone_expiry = 86400 * 31 -- Dias para poder recriar sala: 31 dias
muc_room_cache_size = 100 -- Quantidade de salas mantidas em memória de cada vez
muc_max_rooms = 100 -- Número máximo de salas no servidor
-- Defaults
muc_room_default_public = true
muc_room_default_persistent = false
muc_room_default_members_only = false
muc_room_default_moderated = false
muc_room_default_public_jids = false
muc_room_default_change_subject = false
muc_room_default_history_length = 20
muc_room_default_language = "en"
Após realizadas essas configurações, adicione a referência para conf.d no arquivo prosody.cfg.lua:
Include "conf.d/*.cfg.lua"
Por fim, reinicie o Prosody para que as configurações sejam aplicadas:
sudo systemctl restart prosody
Considerações finais⌗
Ao realizar as configurações acima, você terá um servidor XMPP funcional. Você pode então se conectar ao servidor por um cliente XMPP como o Conversations ou o Gajim. Entretanto, o modelo utilizado nesta configurações não permite cadastro de usuário, que deve ser feito de antemão pelo administrador do servidor.
Minha configuração pode requisitada diretamente a mim por XMPP, em mlemosf@matheuslemos.com.