Feche estas portas antes de a sua equipa entrar no Mattermost
Uma instalação nova do Mattermost está afinada para pôr uma equipa a conversar depressa. As definições a rever antes do primeiro dia, e como as provar a partir de fora.

Uma instalação nova do Mattermost foi feita para pôr uma equipa a conversar em cinco minutos, por isso algumas definições merecem uma decisão antes de o primeiro utilizador real iniciar sessão. Esta é a lista que percorremos antes de um único utilizador real entrar, com as definições pelo nome e uma forma de provar cada uma a partir de fora.
A primeira conta é a perigosa
Num servidor Mattermost novo, a primeira pessoa a criar conta torna-se administrador do sistema. Se o servidor estiver acessível a partir da internet antes de iniciar sessão, quem o encontrar primeiro pode ficar com ele. Os scanners encontram certificados TLS novos minutos depois de serem emitidos, porque os logs de certificate transparency são públicos e há quem os vigie.
Por isso a ordem importa: levante o servidor num endereço privado ou atrás de uma allow list, crie a conta de administrador, e só depois abra-o às pessoas que precisam dele.
Logo a seguir, feche o registo aberto. No config.json ou com o mmctl:
mmctl --local config set TeamSettings.EnableOpenServer false
mmctl --local config set TeamSettings.RestrictCreationToDomains "example.com"
Com o open server desligado, as pessoas novas chegam apenas por convite ou porque um administrador lhes criou a conta. Restringir a criação ao seu próprio domínio de correio é uma segunda fechadura, para o caso de uma ligação de convite viajar mais longe do que o previsto.
Decida o que sai do edifício numa notificação push
O push móvel é a definição que a maioria das pessoas nunca olha. Quando chega uma mensagem para um telemóvel, o Mattermost entrega uma notificação a um push proxy, que a passa ao serviço de notificações da plataforma do telemóvel. Com a definição de conteúdo por omissão, o texto da mensagem segue junto.
Para equipas que tratam de assuntos confidenciais, altere-a:
mmctl --local config set EmailSettings.PushNotificationContents generic_no_channel
O generic_no_channel envia «tem uma mensagem nova» e nada mais. Nas edições que o suportam, o id_loaded é ainda melhor: a notificação transporta apenas um ID de mensagem, e o telemóvel vai buscar o conteúdo ao seu próprio servidor por TLS. O mesmo raciocínio aplica-se às notificações por e-mail: se o seu relay de correio estiver fora do seu controlo, configure as notificações por e-mail para enviar o mínimo.
Sessões, MFA e a longa cauda da confiança
Algumas definições decidem durante quanto tempo um portátil roubado ou uma palavra-passe obtida por phishing continuam a ser úteis:
mmctl --local config set ServiceSettings.EnableMultifactorAuthentication true
mmctl --local config set ServiceSettings.EnforceMultifactorAuthentication true
mmctl --local config set ServiceSettings.SessionLengthWebInHours 168
mmctl --local config set ServiceSettings.SessionLengthMobileInHours 720
mmctl --local config set ServiceSettings.SessionIdleTimeoutInMinutes 480
A imposição do MFA depende da sua edição. A sua ativação está disponível em todas e é o mínimo. Escolha durações de sessão que os seus utilizadores tolerem, mas escolha-as deliberadamente. Bots e integrações devem usar personal access tokens em contas de bot dedicadas, não a palavra-passe de uma pessoa, para que o MFA nas pessoas nunca quebre uma integração.
Feche as portas laterais
A maioria dos comprometimentos não entra pela página de início de sessão. Entra por funcionalidades que ninguém usa:
mmctl --local config set FileSettings.EnablePublicLink false
mmctl --local config set PluginSettings.EnableUploads false
mmctl --local config set ServiceSettings.EnableInsecureOutgoingConnections false
mmctl --local config set RateLimitSettings.Enable true
As ligações públicas de ficheiros permitem a qualquer pessoa com um URL descarregar um anexo sem iniciar sessão. O upload de plugins permite a qualquer conta de administrador, incluindo uma comprometida, executar código arbitrário no servidor. Instale plugins a partir do sistema de ficheiros, como uma alteração, não a partir do browser. As ligações de saída inseguras permitem que webhooks e pré-visualizações de ligações aceitem certificados maus. O rate limiting dá à API alguma resistência ao password spraying.
Verifique também o ServiceSettings.AllowCorsFrom. Deve estar vazio, a menos que tenha uma aplicação web específica que precise dele, e nesse caso deve nomear exatamente essa origem, nunca um wildcard.
O mmctl --local fala com o servidor por um socket Unix na própria máquina e precisa de ServiceSettings.EnableLocalMode a true. Mantenha o local mode ligado para administração a partir do servidor, e mantenha apertado o acesso shell a esse servidor, porque o local mode dispensa a autenticação por desenho.
Decida quem pode sequer chegar até ele
Um team chat é usado por um grupo conhecido de pessoas a partir de um conjunto conhecido de locais. A internet no seu todo não precisa de chegar até ele. Opções, da mais aberta à menos aberta:
- Público, atrás de uma firewall que descarta as redes que os seus logs de scanning mostram como fontes de abuso.
- Público, limitado aos países a partir dos quais a sua equipa realmente trabalha.
- Acessível apenas pela sua VPN ou a partir dos endereços do seu escritório.
- Apenas numa rede privada.
Os filtros por país e por fornecedor pertencem à firewall, não ao Mattermost, para que o tráfego indesejado nunca chegue à aplicação. Se estiver atrás de um reverse proxy, defina ServiceSettings.TrustedProxyIPHeader para que o Mattermost registe e limite o endereço real do cliente em vez do endereço do seu proxy.
Prove-o a partir de fora
Uma definição que alterou é uma hipótese. Um teste a partir de fora da sua rede é evidência. A partir de uma máquina que não esteja na sua rede nem na sua allow list:
# What does the logged-out client see?
curl -s 'https://chat.example.com/api/v4/config/client?format=old' \
| jq '{EnableOpenServer, EnableSignUpWithEmail, EnableMultifactorAuthentication}'
# Is plain HTTP redirected?
curl -sI http://chat.example.com/ | head -n 3
# Does a public file link work without a session? (use a link created before you disabled them)
curl -s -o /dev/null -w '%{http_code}\n' 'https://chat.example.com/files/<id>/public?h=<hash>'
Se filtra por país ou por fornecedor, teste a partir de vários pontos: uma máquina num país permitido, uma num país bloqueado, uma numa gama de endereços de um fornecedor de cloud. Faça-o depois de cada alteração à política, não uma única vez na instalação. As regras de firewall desviam-se, e uma regra errada no sentido de abrir não levanta nenhum alarme.
Depois ponha os valores importantes sob monitorização. Um trabalho noturno que leia o mmctl config get para as chaves acima e o compare com os valores que escolheu dir-lhe-á no próprio dia em que alguém carregar no interruptor errado na System Console.
As atualizações fazem parte do hardening
Antes de atualizar, verifique que os seus plugins suportam a versão de destino. Mantenha as atualizações na linha de versões que pretendia: um «upgrade to latest» a partir de um pacote ou de uma tag de container pode levá-lo para um ramo diferente do que planeou.
A lista de verificação curta
- Administrador criado antes de o servidor estar acessível.
- Open server desligado, criação restrita ao seu domínio.
- Conteúdo das notificações push reduzido a genérico ou apenas ID.
- MFA ativado, imposto onde a sua edição o permite, durações de sessão sensatas.
- Ligações públicas, upload de plugins e ligações de saída inseguras desligados. Rate limiting ligado.
- Exposição de rede escolhida de propósito e imposta na firewall.
- Cada definição provada a partir de fora, e vigiada quanto a desvios.
Operamos o Mattermost desta forma para os nossos clientes, em instâncias dedicadas nos nossos próprios datacenters. Se quiser um segundo par de olhos sobre o seu, teremos todo o gosto em ajudar.
Related
Relacionados: Managed team chat em Mattermost · Managed Request Tracker com pontes para parceiros · Source control gerido em GitLab
Publicado em 25 de setembro de 2026.
Todas as notas de campo