
Guia passo a passo para endurecer um servidor Linux, abordando segurança SSH, firewalls, detecção de intrusão, auditoria e configuração do sistema para reduzir a superfície de ataque e melhorar a defesa.
Um guia em evolução para proteger um servidor Linux que, esperamos, também lhe ensine um pouco sobre segurança e por que ela é importante.
(TOC feito com nGitHubTOC)
O objetivo deste guia é ensinar como proteger um servidor Linux.
Há muitas coisas que podem ser feitas para proteger um servidor Linux e este guia tentará cobrir o maior número possível delas. Mais tópicos/materiais serão adicionados conforme eu aprender ou conforme as pessoas contribuírem.
Playbooks Ansible deste guia estão disponíveis em How To Secure A Linux Server With Ansible por moltenbit.
(Índice)
Presumo que você esteja usando este guia porque, esperançosamente, já entende por que uma boa segurança é importante. Esse é um tópico pesado por si só e detalhá-lo está fora do escopo deste guia. Se você não sabe a resposta para essa pergunta, recomendo que pesquise primeiro.
Em alto nível, no momento em que um dispositivo, como um servidor, está no domínio público — ou seja, visível para o mundo exterior — ele se torna um alvo para agentes mal-intencionados. Um dispositivo não protegido é um parque de diversões para agentes mal-intencionados que desejam acessar seus dados ou usar seu servidor como mais um nó para seus ataques DDOS em larga escala.
O que é pior: sem uma boa segurança, você pode nunca saber se seu servidor foi comprometido. Um agente mal-intencionado pode ter obtido acesso não autorizado ao seu servidor e copiado seus dados sem alterar nada, então você nunca saberia. Ou seu servidor pode ter feito parte de um ataque DDOS, e você não saberia. Veja muitas das violações de dados em larga escala nas notícias — as empresas frequentemente não descobriram o vazamento de dados ou a intrusão até muito depois que os agentes mal-intencionados haviam ido embora.
Ao contrário da crença popular, agentes mal-intencionados nem sempre querem mudar algo ou bloquear seu acesso aos seus dados por dinheiro. Às vezes, eles só querem os dados do seu servidor para seus data warehouses (há muito dinheiro em big data) ou para usar seu servidor secretamente para seus propósitos nefastos.
(Índice)
Este guia pode parecer redundante/desnecessário porque existem inúmeros artigos online que dizem como proteger Linux, mas a informação está espalhada por diferentes artigos, que cobrem coisas diferentes e de maneiras diferentes. Quem tem tempo de vasculhar centenas de artigos?
Enquanto fazia pesquisa para minha build Debian, mantive anotações. No final, percebi que, junto com o que já sabia e o que estava aprendendo, tinha os ingredientes para um guia prático. Decidi colocá-lo online na esperança de ajudar outros a aprender e economizar tempo.
Nunca encontrei um guia que cobrisse tudo — este guia é minha tentativa.
Muitas das coisas abordadas neste guia podem ser bastante básicas/triviais, mas a maioria de nós não instala Linux todos os dias, e é fácil esquecer essas coisas básicas.
(Índice)
Existem muitos guias fornecidos por especialistas, líderes da indústria e pelas próprias distribuições. Não é prático, e às vezes é contra os direitos autorais, incluir tudo desses guias. Recomendo que você os consulte antes de começar com este guia.
(Índice)
(Índice)
Este guia...
(Índice)
Existem muitos tipos de servidores e diferentes casos de uso. Embora eu queira que este guia seja o mais genérico possível, haverá algumas coisas que podem não se aplicar a todos/outros casos de uso. Use seu bom senso ao percorrer este guia.
Para ajudar a contextualizar muitos dos tópicos abordados neste guia, meu caso de uso/configuração é:
(Índice)
Sou muito preguiçoso e não gosto de editar arquivos manualmente se não for necessário. Também presumo que todos os outros são como eu. :)
Então, sempre que possível, forneci trechos de código para fazer rapidamente o que é necessário, como adicionar ou alterar uma linha em um arquivo de configuração.
Os trechos de código usam comandos básicos como echo, cat, sed, awk e grep. Como os trechos de código funcionam, como o que cada comando/parte faz, está fora do escopo deste guia — as páginas man são suas amigas.
Nota: Os trechos de código não validam/verificam se a alteração foi feita — ou seja, se a linha foi realmente adicionada ou alterada. Deixarei a parte de verificação em suas mãos capazes. As etapas neste guia incluem fazer backups de todos os arquivos que serão alterados.
Nem todas as alterações podem ser automatizadas com trechos de código. Essas alterações precisam de uma edição manual à moda antiga. Por exemplo, você não pode simplesmente adicionar uma linha a um arquivo do tipo INI. Use seu editor de texto Linux favorito.
(Índice)
Quis colocar este guia no GitHub para facilitar a colaboração. Quanto mais pessoas contribuírem, melhor e mais completo este guia se tornará.
Para contribuir, você pode fazer um fork e enviar um pull request ou abrir uma nova issue.
(Índice)
Antes de começar, você vai querer identificar quais são seus Princípios. Qual é o seu modelo de ameaça? Algumas coisas para pensar:
Estas são apenas algumas coisas para pensar. Antes de começar a proteger seu servidor, você vai querer entender contra o que está tentando se proteger e por que, para saber o que precisa fazer.
(Índice)
Este guia pretende ser agnóstico em relação à distribuição, para que os usuários possam usar qualquer distribuição que desejarem. Dito isso, há algumas coisas a ter em mente:
Você quer uma distribuição que...
(Índice)
Instalar Linux está fora do escopo deste guia porque cada distribuição faz isso de forma diferente e as instruções de instalação geralmente são bem documentadas. Se precisar de ajuda, comece pela documentação da sua distribuição. Independentemente da distribuição, o processo de alto nível geralmente é assim:
Quando aplicável, use a opção de instalação especialista para ter um controle mais rigoroso sobre o que está sendo executado no seu servidor. Instale apenas o que for absolutamente necessário. Eu, pessoalmente, não instalo nada além de SSH. Além disso, marque a opção de Criptografia de Disco.
(Índice)
sudo apt update && sudo apt upgrade em sistemas baseados em Debian)./etc/fstabman(Índice)
apt apropriados que devem funcionar em todas as distribuições baseadas em Debian. Se alguém estiver disposto a fornecer os comandos respectivos para outras distribuições, irei adicioná-los.(Índice)
Playbooks Ansible deste guia estão disponíveis em How To Secure A Linux Server With Ansible.Certifique-se de editar as variáveis de acordo com suas necessidades e leia todas as tarefas de antemão para confirmar que não quebram seu sistema. Após executar os playbooks, verifique se todas as configurações estão de acordo com suas necessidades!
5. Altere todas as variáveis em *group_vars/variables.yml* de acordo com suas necessidades.
6. Ative o acesso root SSH antes de executar os playbooks: ```
nano /etc/ssh/sshd_config
[...]
PermitRootLogin yes
[...]
Execute o playbook de requisitos usando a senha de root que você especificou ao instalar o servidor:
ansible-playbook --inventory hosts.yml --ask-pass requirements-playbook.yml
Execute o playbook principal com a senha do novo usuário que você especificou no arquivo variables.yml:
ansible-playbook --inventory hosts.yml --ask-pass main-playbook.yml
Se você precisar executar os playbooks várias vezes, lembre-se de usar a chave SSH e a nova porta SSH:
ansible-playbook --inventory hosts.yml -e ansible_ssh_port=SSH_PORT --key-file /PATH/TO/SSH/KEY main-playbook.yml
(Índice)
É altamente recomendável manter um segundo terminal aberto para o seu servidor antes de fazer e aplicar alterações de configuração do SSH. Dessa forma, se você se trancar para fora da sua primeira sessão de terminal, ainda terá uma sessão conectada para poder corrigir.
Agradecimento ao Sonnenbrand por esta ideia.
Usar chaves públicas/privadas SSH é mais seguro do que usar uma senha. Também torna mais fácil e rápido conectar-se ao nosso servidor, pois não é necessário digitar uma senha.
Consulte as referências abaixo para mais detalhes, mas, em alto nível, as chaves públicas/privadas funcionam usando um par de chaves para verificar a identidade.
Para SSH, uma chave pública e privada é criada no cliente. Você deve manter ambas as chaves seguras, especialmente a chave privada. Embora a chave pública seja destinada a ser pública, é prudente garantir que nenhuma das chaves caia em mãos erradas.
Quando você se conecta a um servidor SSH, o SSH procurará por uma chave pública que corresponda ao cliente a partir do qual você está se conectando no arquivo ~/.ssh/authorized_keys no servidor ao qual está se conectando. Observe que o arquivo está na pasta pessoal do ID com o qual você está tentando se conectar. Então, após criar a chave pública, você precisa anexá-la a ~/.ssh/authorized_keys. Uma abordagem é copiá-la para um pen drive e transferi-la fisicamente para o servidor. Outra abordagem é usar ssh-copy-id para transferir e anexar a chave pública.
Após as chaves terem sido criadas e a chave pública ter sido anexada a ~/.ssh/authorized_keys no host, o SSH usa as chaves pública e privada para verificar a identidade e, em seguida, estabelecer uma conexão segura. Como a identidade é verificada é um processo complicado, mas a Digital Ocean tem uma excelente explicação de como funciona. Em alto nível, a identidade é verificada pelo servidor criptografando uma mensagem de desafio com a chave pública e, em seguida, enviando-a ao cliente. Se o cliente não conseguir descriptografar a mensagem de desafio com a chave privada, a identidade não pode ser verificada e uma conexão não será estabelecida.
Elas são consideradas mais seguras porque você precisa da chave privada para estabelecer uma conexão SSH. Se você definir PasswordAuthentication no em /etc/ssh/sshd_config, o SSH não permitirá que você se conecte sem a chave privada.
Você também pode definir uma frase secreta para as chaves, o que exigiria que você digitasse a frase secreta ao se conectar usando chaves públicas/privadas. Lembre-se de que fazer isso significa que você não pode usar a chave para automação, pois não terá como enviar a frase secreta em seus scripts. ssh-agent é um programa que vem em muitas distribuições Linux (e geralmente já está em execução) que permite manter sua chave privada descriptografada na memória por uma duração configurável. Basta executar ssh-add e ele solicitará sua frase secreta. Você não será solicitado a digitar sua frase secreta novamente até que a duração configurável tenha passado.
Usaremos chaves Ed25519 que, de acordo com https://linux-audit.com/:
Ela usa um esquema de assinatura de curva elíptica, que oferece melhor segurança que ECDSA e DSA. Ao mesmo tempo, também tem bom desempenho.
man ssh-keygenman ssh-copy-idman ssh-addA partir do computador que você usará para se conectar ao seu servidor, o cliente, não o servidor em si, crie uma chave Ed25519 com o ssh-keygen:
ssh-keygen -t ed25519
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_ed25519. Your public key has been saved in /home/user/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client The key's randomart image is: +--[ED25519 256]--+ |xxxx x | |o.o +. . | | o o oo . | |. E oo . o . | | o o. o S o | |... .. o o | |.+....+ o | |+.=++o.B.. | |+..=**=o=. | +----[SHA256]-----+
Nota: Se você definir uma frase secreta, precisará digitá-la toda vez que se conectar ao seu servidor usando esta chave, a menos que esteja usando o ssh-agent.
Agora você precisa anexar a chave pública ~/.ssh/id_ed25519.pub do seu cliente ao arquivo ~/.ssh/authorized_keys no seu servidor. Como presumivelmente ainda estamos em casa na LAN, provavelmente estamos seguros contra ataques , então usaremos para transferir e anexar a chave pública:
Agora seria um bom momento para realizar quaisquer tarefas específicas da sua configuração.
(Índice)
Para facilitar o controle de quem pode fazer SSH no servidor. Usando um grupo, podemos rapidamente adicionar/remover contas ao grupo para permitir ou não rapidamente o acesso SSH ao servidor.
Usaremos a opção AllowGroups no arquivo de configuração do SSH /etc/ssh/sshd_config para informar ao servidor SSH que apenas permita que usuários façam SSH se eles forem membros de um determinado grupo UNIX. Qualquer pessoa que não estiver no grupo não poderá fazer SSH.
/etc/ssh/sshd_config para limitar quem pode fazer SSH no servidorAllowGroup definida em Segurança /etc/ssh/sshd_config.man groupaddman usermodCrie um grupo:
sudo groupadd sshusers
Adicione conta(s) ao grupo:
sudo usermod -a -G sshusers user1
sudo usermod -a -G sshusers user2
sudo usermod -a -G sshusers ...
Você precisará fazer isso para cada conta no seu servidor que precise de acesso SSH.
(Índice)
/etc/ssh/sshd_configSSH é uma porta de entrada para o seu servidor. Isso é especialmente verdadeiro se você estiver abrindo portas no seu roteador para poder fazer SSH no servidor de fora da sua rede doméstica. Se não estiver protegido adequadamente, um agente mal-intencionado pode usá-lo para obter acesso não autorizado ao seu sistema.
/etc/ssh/sshd_config é o arquivo de configuração padrão que o servidor SSH usa. Usaremos este arquivo para informar quais opções o servidor SSH deve usar.
man sshd_configFaça uma cópia de segurança do arquivo de configuração do servidor OpenSSH /etc/ssh/sshd_config e remova os comentários para facilitar a leitura:
sudo cp --archive /etc/ssh/sshd_config /etc/ssh/sshd_config-COPY-$(date +"%Y%m%d%H%M%S")
sudo sed -i -r -e '/^#|^$/ d' /etc/ssh/sshd_config
Edite /etc/ssh/sshd_config e então encontre e edite ou adicione estas configurações que devem ser aplicadas independentemente da sua configuração/setup:
Nota: SSH não gosta de configurações duplicadas contraditórias. Por exemplo, se você tiver ChallengeResponseAuthentication no e depois ChallengeResponseAuthentication yes, SSH respeitará a primeira e ignorará a segunda. Seu arquivo /etc/ssh/sshd_config pode já ter algumas das configurações/linhas abaixo. Para evitar problemas, você precisará revisar manualmente seu arquivo /etc/ssh/sshd_config e resolver quaisquer configurações duplicadas contraditórias.
Nota: Se você estiver usando OpenSSH 9.1 ou posterior, descomente a linha RequiredRSASize 3072 na configuração abaixo. Isso impõe um tamanho mínimo de chave RSA de 3072 bits e rejeitará chaves RSA menores durante a autenticação. Isso afeta apenas chaves RSA. Se você usar chaves ED25519 ou ECDSA, não é afetado. Você pode verificar o tipo e tamanho da sua chave com . Em versões mais antigas do OpenSSH, deixe a linha comentada, pois impedirá o sshd de iniciar.
(Índice)
De acordo com as Diretrizes OpenSSH da Mozilla para OpenSSH 6.7+, "todos os módulos Diffie-Hellman em uso devem ter pelo menos 3072 bits de comprimento".
O algoritmo Diffie-Hellman é usado pelo SSH para estabelecer uma conexão segura. Quanto maior o módulo (tamanho da chave), mais forte a criptografia.
man moduliFaça uma cópia de segurança do arquivo de módulos SSH /etc/ssh/moduli:
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")
Remova módulos curtos:
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
(Índice)
Embora o SSH seja um guarda de segurança muito bom para suas portas e janelas, ainda é uma porta visível que agentes mal-intencionados podem ver e tentar forçar a entrada. Fail2ban monitorará essas tentativas de força bruta, mas não existe segurança demais. Exigir dois fatores adiciona uma camada extra de segurança.
Usar Autenticação de Dois Fatores (2FA) / Autenticação Multifator (MFA) exige que qualquer pessoa que entre tenha duas chaves para entrar, o que dificulta a ação de agentes mal-intencionados. As duas chaves são:
Sem ambas as chaves, eles não conseguirão entrar.
Muitas pessoas podem achar a experiência inconveniente ou irritante. Além disso, o acesso ao seu sistema depende do aplicativo autenticador que gera o código.
No Linux, o PAM é responsável pela autenticação. Existem quatro tarefas do PAM que você pode ler em https://en.wikipedia.org/wiki/Linux_PAM. Esta seção trata da tarefa de autenticação.
Quando você faz login em um servidor, seja diretamente do console ou via SSH, a porta pela qual você entrou enviará a solicitação para a tarefa de autenticação do PAM e o PAM solicitará e verificará sua senha. Você pode personalizar as regras que cada porta usa. Por exemplo, você pode ter um conjunto de regras ao fazer login diretamente do console e outro conjunto de regras para quando fizer login via SSH.
Esta seção alterará as regras de autenticação para quando fizer login via SSH, exigindo tanto uma senha quanto um código de 6 dígitos.Usaremos o módulo PAM libpam-google-authenticator do Google para criar e verificar uma chave TOTP. https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/ e https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/ têm boas explicações de como o TOTP funciona.
O que faremos é instruir a configuração PAM do SSH do servidor a pedir ao utilizador a sua palavra-passe e depois o seu token numérico. O PAM verificará então a palavra-passe do utilizador e, se estiver correta, encaminhará o pedido de autenticação para o libpam-google-authenticator, que solicitará e verificará o seu token de 6 dígitos. Se, e somente se, tudo estiver correto, a autenticação será bem-sucedida e o utilizador poderá iniciar sessão.
Instale o libpam-google-authenticator.
Em sistemas baseados em Debian:
sudo apt install libpam-google-authenticator
Certifique-se de que está autenticado com o ID para o qual deseja ativar o 2FA/MFA e execute google-authenticator para criar os dados do token necessários:
google-authenticator
Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@host%3Fsecret%3DR4ZWX34FQKZROVX7AGLJ64684Y%26issuer%3Dhost ... Your new secret key is: R3NVX3FFQKZROVX7AGLJUGGESY Your verification code is 751419 Your emergency scratch codes are: 12345678 90123456 78901234 56789012 34567890 Do you want me to update your "/home/user/.google_authenticator" file (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, tokens are good for 30 seconds. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of +-1min (window size of 3) to about +-4min (window size of 17 acceptable tokens). Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
O sudo permite que contas executem comandos como outras contas, incluindo root. Queremos garantir que apenas as contas que pretendemos podem usar sudo.
O Debian cria o grupo sudo. Para ver os utilizadores que fazem parte deste grupo (portanto, com privilégios sudo):
cat /etc/group | grep "sudo"
O RedHat cria o grupo wheel
sudo não exija palavra-passe. Obrigado a sbrl por partilhar.Crie um grupo:
sudo groupadd sudousers
Adicione conta(s) ao grupo:
sudo usermod -a -G sudousers user1
sudo usermod -a -G sudousers user2
sudo usermod -a -G sudousers ...
Terá de fazer isto para cada conta no seu servidor que precise de privilégios sudo.
Faça uma cópia de segurança do ficheiro de configuração do sudo /etc/sudoers:
sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
Edite o ficheiro de configuração do sudo /etc/sudoers:
sudo visudo
Indique ao sudo para permitir apenas utilizadores no grupo sudousers a usar sudo adicionando esta linha se ainda não estiver presente:
%sudousers ALL=(ALL:ALL) ALL
O su também permite que contas executem comandos como outras contas, incluindo root. Queremos garantir que apenas as contas que pretendemos podem usar su.
Crie um grupo:
sudo groupadd suusers
Adicione conta(s) ao grupo:
sudo usermod -a -G suusers user1
sudo usermod -a -G suusers user2
sudo usermod -a -G suusers ...
Terá de fazer isto para cada conta no seu servidor que precise de privilégios su.
Faça com que apenas utilizadores neste grupo possam executar /bin/su:
sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
É absolutamente melhor, para muitas aplicações, executá-las numa sandbox.
Os navegadores (ainda mais os de código fechado) e os clientes de e-mail são altamente recomendados.
Instale o software:
sudo apt install firejail firejail-profiles
Nota: para o Debian 10 Stable, o Backport oficial é recomendado:
sudo apt install -t buster-backports firejail firejail-profiles
Permita que uma aplicação (instalada em /usr/bin ou /bin) seja executada apenas numa sandbox (veja alguns exemplos abaixo):
sudo ln -s /usr/bin/firejail /usr/local/bin/google-chrome-stable
sudo ln -s /usr/bin/firejail /usr/local/bin/firefox
sudo ln -s /usr/bin/firejail /usr/local/bin/chromium
sudo ln -s /usr/bin/firejail /usr/local/bin/evolution
sudo ln -s /usr/bin/firejail /usr/local/bin/thunderbird
Execute a aplicação como habitual (via terminal ou lançador) e verifique se está a correr numa jaula:
firejail --list
Permita que uma aplicação em sandbox volte a ser executada como antes (exemplo: firefox)
sudo rm /usr/local/bin/firefox
Muitos protocolos de segurança dependem da hora. Se a hora do seu sistema estiver incorreta, pode ter impactos negativos no seu servidor. Um cliente NTP pode resolver esse problema mantendo a hora do seu sistema sincronizada com servidores NTP globais
NTP significa Network Time Protocol. No contexto deste guia, um cliente NTP no servidor é usado para atualizar a hora do servidor com a hora oficial obtida de servidores oficiais. Consulte https://www.pool.ntp.org/en/ para todos os servidores NTP públicos.
Nota: A partir do Debian 13 (Trixie), o pacote clássico
ntpfoi removido. Executarsudo apt install ntpfalhará com "Package ntp has no installation candidate". Como este guia usa apenas o NTP como cliente (para sincronizar o relógio do servidor), a abordagem recomendada no Debian 13+ é usarsystemd-timesyncd, que já está pré-instalado e não requer pacotes adicionais. Veja os passos para Debian 13+ abaixo.
systemd-timesyncd é um cliente SNTP leve que já está incluído no Debian. Ao contrário do daemon completo ntpd, não escuta em nenhuma porta, o que reduz a superfície de ataque. Para os fins deste guia - manter o relógio do seu servidor sincronizado - é tudo o que precisa.
Ative a sincronização NTP:
sudo timedatectl set-ntp true
Verifique se está a funcionar:
timedatectl status
Deverá ver NTP service: active e System clock synchronized: yes na saída.
Configure servidores NTP confiáveis. Faça uma cópia de segurança do ficheiro de configuração e depois edite-o:
sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")
Edite /etc/systemd/timesyncd.conf e descomente/defina a secção [Time]:
[Time]
NTP=pool.ntp.org
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org
sudo sed -i -r -e "s/^#?NTP=.*$/NTP=pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
sudo sed -i -r -e "s/^#?FallbackNTP=.*$/FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
Nota: Estes passos aplicam-se apenas ao Debian 12 e anteriores. No Debian 13+, o pacote
ntpjá não está disponível -- use os passos do systemd-timesyncd acima.
Instale o ntp.
Em sistemas baseados em Debian:
sudo apt install ntp
Faça uma cópia de segurança do ficheiro de configuração do cliente NTP /etc/ntp.conf:
sudo cp --archive /etc/ntp.conf /etc/ntp.conf-COPY-$(date +"%Y%m%d%H%M%S")
A configuração predefinida, pelo menos no Debian, já é bastante segura. A única coisa que queremos garantir é que usamos a diretiva pool e não quaisquer diretivas server. A diretiva pool permite que o cliente NTP pare de usar um servidor se este não responder ou fornecer hora errada. Faça isto comentando todas as diretivas server e adicionando o seguinte ao /etc/ntp.conf.
pool pool.ntp.org iburst
sudo sed -i -r -e "s/^((server|pool).*)/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/ntp.conf
echo -e "\npool pool.ntp.org iburst # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ntp.conf
Para citar https://linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/:
Ao olhar para
/proc, descobrirá muitos ficheiros e diretórios. Muitos deles são apenas números, que representam a informação sobre um determinado ID de processo (PID). Por predefinição, os sistemas Linux são implementados para permitir que todos os utilizadores locais vejam toda esta informação. Isto inclui informação de processo de outros utilizadores. Isto pode incluir detalhes sensíveis que pode não querer partilhar com outros utilizadores. Ao aplicar alguns ajustes na configuração do sistema de ficheiros, podemos alterar este comportamento e melhorar a segurança do sistema.
Nota: Isto pode quebrar em alguns sistemas systemd. Consulte https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37 para mais informações. Obrigado a nlgranger por partilhar.
/proc montado com hidepid=2 para que os utilizadores possam ver apenas informações sobre os seus próprios processosFaça uma cópia de segurança do /etc/fstab:
sudo cp --archive /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")
Adicione esta linha ao /etc/fstab para que /proc seja montado com hidepid=2:
proc /proc proc defaults,hidepid=2 0 0
echo -e "\nproc /proc proc defaults,hidepid=2 0 0 # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/fstab
Reinicie o sistema:
sudo reboot now
Nota: Alternativamente, pode remontar /proc sem reiniciar com sudo mount -o remount,hidepid=2 /proc
Por predefinição, as contas podem usar qualquer palavra-passe que desejem, incluindo más. O pwquality/pam_pwquality resolve esta lacuna de segurança fornecendo "uma forma de configurar os requisitos de qualidade de palavra-passe predefinidos para as palavras-passe do sistema" e verificando "a sua força contra um dicionário do sistema e um conjunto de regras para identificar más escolhas."
No Linux, o PAM é responsável pela autenticação. Existem quatro tarefas do PAM que pode ler em https://en.wikipedia.org/wiki/Linux_PAM. Esta secção aborda a tarefa de palavra-passe.Quando há necessidade de definir ou alterar a senha de uma conta, a tarefa de senha do PAM lida com a solicitação. Nesta seção, diremos à tarefa de senha do PAM para passar a nova senha solicitada para o libpam-pwquality, a fim de garantir que ela atenda aos nossos requisitos. Se os requisitos forem atendidos, ela é usada/definida; se não atender, gera erro e avisa o usuário.
Instale o libpam-pwquality.
Em sistemas baseados em Debian:
sudo apt install libpam-pwquality
Faça um backup do arquivo de configuração de senha do PAM /etc/pam.d/common-password:
sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
Diga ao PAM para usar o libpam-pwquality para impor senhas fortes editando o arquivo /etc/pam.d/common-password e altere a linha que começa assim:
password requisite pam_pwquality.so
para isto:
password requisite pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec
As opções acima são:
retry=3 = solicitar ao usuário 3 vezes antes de retornar com erro.minlen=10 = o comprimento mínimo da senha, levando em consideração quaisquer créditos (ou débitos) destes:
dcredit=-1 = deve ter pelo menos (Índice)
É importante manter um servidor atualizado com as correções e atualizações críticas de segurança mais recentes. Caso contrário, você corre o risco de vulnerabilidades de segurança conhecidas que malfeitores poderiam usar para obter acesso não autorizado ao seu servidor.
A menos que você planeje verificar seu servidor todos os dias, você vai querer uma maneira de atualizar automaticamente o sistema e/ou receber e-mails sobre atualizações disponíveis.
Você não deseja fazer todas as atualizações porque a cada atualização há o risco de algo quebrar. É importante fazer as atualizações críticas, mas todo o resto pode esperar até que você tenha tempo para fazê-lo manualmente.
Atualizações automáticas e não supervisionadas podem quebrar seu sistema e você pode não estar perto do servidor para corrigi-lo. Isso seria especialmente problemático se quebrasse seu acesso SSH.
Em sistemas baseados em Debian, você pode usar:
Usaremos unattended-upgrades para aplicar correções críticas de segurança. Também podemos aplicar atualizações estáveis, pois já foram minuciosamente testadas pela comunidade Debian.
/etc/apt/apt.conf.d/50unattended-upgradesInstale unattended-upgrades, apt-listchanges e apticron:
sudo apt install unattended-upgrades apt-listchanges apticron
Agora precisamos configurar unattended-upgrades para aplicar automaticamente as atualizações. Isso geralmente é feito editando os arquivos /etc/apt/apt.conf.d/20auto-upgrades e /etc/apt/apt.conf.d/50unattended-upgrades que foram criados pelos pacotes. No entanto, como esses arquivos podem ser sobrescritos em uma atualização futura, criaremos um novo arquivo. Crie o arquivo /etc/apt/apt.conf.d/51myunattended-upgrades e adicione isto:
// Ativar o script de atualização/upgrade (0=desabilitar)
APT::Periodic::Enable "1";
// Executar "apt-get update" automaticamente a cada n-dias (0=desabilitar)
APT::Periodic::Update-Package-Lists "1";
// Executar "apt-get upgrade --download-only" a cada n-dias (0=desabilitar)
APT::Periodic::Download-Upgradeable-Packages "1";
// Executar "apt-get autoclean" a cada n-dias (0=desabilitar)
APT::Periodic::AutocleanInterval "7";
// Enviar relatório por e-mail para root
// 0: sem relatório (ou string nula)
// 1: relatório de progresso (na verdade qualquer string)
// 2: + saídas de comandos (remove -qq, remove 2>/dev/null, adiciona -d)
// 3: + trace on APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";
// Atualizar automaticamente pacotes destes
Unattended-Upgrade::Origins-Pattern {
"o=Debian,a=stable";
"o=Debian,a=stable-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
// Você pode especificar seus próprios pacotes para NÃO atualizar automaticamente aqui
Unattended-Upgrade::Package-Blacklist {
};
// Executar dpkg --force-confold --configure -a se um estado sujo do dpkg for detectado como verdadeiro para garantir que as atualizações sejam instaladas mesmo quando o sistema foi interrompido durante uma execução anterior
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
// Realizar o upgrade quando a máquina estiver em execução, pois não desligaremos nosso servidor com frequência
Unattended-Upgrade::InstallOnShutdown "false";
// Enviar um e-mail para este endereço com informações sobre os pacotes atualizados.
Unattended-Upgrade::Mail "root";
// Sempre enviar um e-mail
Unattended-Upgrade::MailOnlyOnError "false";
// Remover todas as dependências não utilizadas após o término do upgrade
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// Remover quaisquer novas dependências não utilizadas após o término do upgrade
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Reiniciar automaticamente SEM CONFIRMAÇÃO se o arquivo /var/run/reboot-required for encontrado após o upgrade.
Unattended-Upgrade::Automatic-Reboot "true";
// Reiniciar automaticamente mesmo se houver usuários logados.
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
(Índice)
WIP
WIP
WIP
Instale o rng-tools.
Em sistemas baseados em Debian:
sudo apt-get install rng-tools
Agora precisamos definir o dispositivo de hardware usado para gerar números aleatórios adicionando isto ao /etc/default/rng-tools:
HRNGDEVICE=/dev/urandom
echo "HRNGDEVICE=/dev/urandom" | sudo tee -a /etc/default/rng-tools
Reinicie o serviço:
sudo systemctl stop rng-tools.service
sudo systemctl start rng-tools.service
Teste a aleatoriedade:
(Índice)
Uma ferramenta interessante para adicionar segurança extra de senha contra ataques físicos (presencialmente) métodos de roubo/assalto/resgate.
O pamduress adicionará ao usuário X uma senha secundária (senha de pânico). Quando essa senha for correspondida, iniciará um script (este script faz o que você quer que o usuário faça quando fizer login com ESSA senha de pânico).
Exemplo prático e real: "Um ladrão invade uma casa e rouba o servidor (contendo backups importantes de negócios, memórias pessoais e blablabla). Não existe criptografia de disco/boot. O ladrão liga o servidor em sua 'zona segura' e inicia um ataque de força bruta. Ele conseguiu quebrar a senha local via SSH de um usuário sudoer 'admin' com sucesso, sim, uma senha fraca, não a forte/primária. Ele inicia uma sessão SSH/física com essa senha quebrada fraca/de pânico com 'admin' sudoer. Ele começa a sentir que o servidor parece muito ocupado em menos de 2 minutos até travar.. 'que droga!? Vamos reiniciar e continuar roubando informações..'.. desculpe amigo. todos os dados e sistema foram destruídos.". Conclusão, o ladrão quebrou a senha de pânico/secundária/falsa, e com essa senha está associado um script que irá deletar todos os arquivos, configurações, sistema, boot e depois começar a sobrecarregar a RAM e CPU para forçar o ladrão a reiniciar o sistema.
Impedir o acesso de pessoas maliciosas às informações do servidor quando obtiverem uma senha de forma forçada (assalto, arma, resgate, …). Claro que isso é útil em outras situações.
cat > "$ScriptFile" <<-EOF #!/bin/bash sudo rm -rf /home
EOF ####################################################### } echo "Lets Config a PANIC PASSWORD ;)" && sleep 1 read -r -p "Want you REALLY configure A PANIC PASSWORD?? Write [ OK ] : " PAMDUR if [[ "$PAMDUR" = "OK" ]]; then echo "Lets Config a PANIC USER, PASSWORD and SCRIPT ;)" && sleep 1 while [ -z "$PANICUSR" ] do read -r -p "WRITE a Panic User to your pam-duress user [ root ]: " PANICUSR PANICUSR=${PANICUSR:=root} done if [ -z "$ScriptLoc" ]; then read -r -p "SET Script Directory with FULL PATH [ /root/.duress ]: " ScriptLoc ScriptLoc=${ScriptLoc:=/root/.duress} ScriptFile="$ScriptLoc/PanicScript.sh" fi else echo "NOT Use PAM DURESS aKa Panic Password!!! Bye" exit 1 fi
sudo apt install -y git build-essential libpam0g-dev libssl-dev
cd "$HOME" || exit 1 git clone https://github.com/nuvious/pam-duress.git cd pam-duress || exit 1 make sudo make install make clean #make uninstall
mkdir -p $ScriptLoc sudo mkdir -p /etc/duress.d myownscript duress_sign $ScriptFile chmod -R 500 $ScriptLoc chmod 400 $ScriptLoc/*.sha256 chown -R $PANICUSR $ScriptLoc
sudo cp --preserve /etc/pam.d/common-auth /etc/pam.d/common-auth.bck
echo " auth [success=2 default=ignore] pam_unix.so nullok_secure auth [success=1 default=ignore] pam_duress.so auth requisite pam_deny.so auth required pam_permit.so " | sudo tee /etc/pam.d/common-auth
read -r -p "Press Key to Finish PAM DURESS Script!" exit 0
([Índice](#table-of-contents))
## A Rede
### Firewall com UFW (Uncomplicated Firewall)
#### Porquê
Pode me chamar de paranoico, e não precisa concordar, mas eu quero negar todo o tráfego de entrada e saída do meu servidor, exceto o que eu permitir explicitamente. Por que meu servidor estaria enviando tráfego para fora que eu não conheço? E por que o tráfego externo estaria tentando acessar meu servidor se eu não sei quem ou o que é? Quando se trata de boa segurança, minha opinião é rejeitar/negar por padrão e permitir por exceção.
Claro, se você discorda, tudo bem, e pode configurar o UFW de acordo com suas necessidades.
De qualquer forma, garantir que apenas o tráfego que permitimos explicitamente passe é tarefa de um firewall.
#### Como Funciona
O kernel Linux fornece capacidades para monitorar e controlar o tráfego de rede. Essas capacidades são expostas ao usuário final por meio de utilitários de firewall. No Linux, o firewall mais comum é o [iptables](https://en.wikipedia.org/wiki/Iptables). No entanto, o iptables é bastante complicado e confuso (IMHO). É aqui que entra o UFW. Pense no UFW como um front-end para o iptables. Ele simplifica o processo de gerenciamento das regras do iptables que informam ao kernel Linux o que fazer com o tráfego de rede.
**UFW** funciona permitindo configurar regras que:
- **permitir** ou **negar**
- tráfego de **entrada** ou **saída**
- para portas **de** ou **para**
Você pode criar regras especificando explicitamente as portas ou com configurações de aplicação que especificam as portas.
#### Objetivos
- todo o tráfego de rede, entrada e saída, bloqueado, exceto aqueles que permitirmos explicitamente
#### Notas
- À medida que instalar outros programas, precisará ativar as portas/aplicações necessárias.
#### Referências
- https://launchpad.net/ufw
#### Passos
1. Instale o ufw.
Em sistemas baseados em Debian:
``` bash
sudo apt install ufw
```
1. Negue todo o tráfego de saída:
``` bash
sudo ufw default deny outgoing comment 'deny all outgoing traffic'
```
> ```
> Default outgoing policy changed to 'deny'
> (be sure to update your rules accordingly)
> ```
Se você não é tão paranoico quanto eu e não quer negar todo o tráfego de saída, pode permiti-lo:
``` bash
sudo ufw default allow outgoing comment 'allow all outgoing traffic'
```
1. Negue todo o tráfego de entrada:
``` bash
sudo ufw default deny incoming comment 'deny all incoming traffic'
```
1. Obviamente, queremos conexões SSH de entrada. Usar limit em vez de allow negará automaticamente conexões de um endereço IP se ele tentar iniciar 6 ou mais conexões em uma janela de 30 segundos:
``` bash
sudo ufw limit in ssh comment 'allow SSH connections in'
```
> ```
> Rules updated
> Rules updated (v6)
> ```
1. Permita tráfego adicional conforme suas necessidades. Alguns casos de uso comuns:
``` bash
# allow traffic out to port 53 -- DNS
sudo ufw allow out 53 comment 'allow DNS calls out'
# allow traffic out to port 123 -- NTP
sudo ufw allow out 123 comment 'allow NTP out'
# allow traffic out for HTTP, HTTPS, or FTP
# apt might needs these depending on which sources you're using
sudo ufw allow out http comment 'allow HTTP traffic out'
sudo ufw allow out https comment 'allow HTTPS traffic out'
sudo ufw allow out ftp comment 'allow FTP traffic out'
# allow whois
sudo ufw allow out whois comment 'allow whois'
# allow mails for status notifications -- choose port according to your provider
sudo ufw allow out 25 comment 'allow SMTP out'
sudo ufw allow out 587 comment 'allow SMTP out'
# allow traffic out to port 68 -- the DHCP client
# you only need this if you're using DHCP
sudo ufw allow out 67 comment 'allow the DHCP client to update'
sudo ufw allow out 68 comment 'allow the DHCP client to update'
```
**Nota**: Você precisará permitir HTTP/HTTPS para instalar pacotes e muitas outras coisas.
1. Inicie o ufw:
``` bash
sudo ufw enable
```
> ```
> Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
> Firewall is active and enabled on system startup
> ```
1. Se quiser ver o status:
``` bash
sudo ufw status
```
> ```
> Status: active
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> Mail submission ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> Mail submission (v6) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
ou
``` bash
sudo ufw status verbose
```
> ```
> Status: active
> Logging: on (low)
> Default: deny (incoming), deny (outgoing), disabled (routed)
> New profiles: skip
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT IN Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT IN Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> 587/tcp (Mail submission) ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> 587/tcp (Mail submission (v6)) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
7. Se precisar apagar uma regra
``` bash
sudo ufw status numbered
[...]
sudo ufw delete 3 #line number of the rule you want to delete
```
#### Aplicações Padrão
o ufw vem com algumas aplicações padrão. Pode vê-las com:``` bash
sudo ufw app list
```
> ```
> Aplicações disponíveis:
> AIM
> Bonjour
> CIFS
> DNS
> Deluge
> IMAP
> IMAPS
> IPP
> KTorrent
> Kerberos Admin
> Kerberos Full
> Kerberos KDC
> Kerberos Password
> LDAP
> LDAPS
> LPD
> MSN
> MSN SSL
> Mail submission
> NFS
> OpenSSH
> POP3
> POP3S
> PeopleNearby
> SMTP
> SSH
> Socks
> Telnet
> Transmission
> Transparent Proxy
> VNC
> WWW
> WWW Cache
> WWW Full
> WWW Secure
> XMPP
> Yahoo
> qBittorrent
> svnserve
> ```
Para obter detalhes sobre a aplicação, como as portas que inclui, digite:``` bash
sudo ufw app info [app name]
```
> ``` bash
> sudo ufw app info DNS
> ```
>
> ```
> Profile: DNS
> Title: Internet Domain Name Server
> Description: Internet Domain Name Server
>
> Port:
> 53
> ```
#### Aplicação Personalizada
Se você não quiser criar regras fornecendo explicitamente o(s) número(s) da(s) porta(s), pode criar suas próprias configurações de aplicação. Para isso, crie um arquivo em `/etc/ufw/applications.d`.
Por exemplo, aqui está o que você usaria para [Plex](https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/):``` bash
cat /etc/ufw/applications.d/plexmediaserver
```
> ```
> [PlexMediaServer]
> title=Plex Media Server
> description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
> ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp
> ```
Depois, pode ativá-lo como qualquer outra aplicação:```bash
sudo ufw allow plexmediaserver
```
([Table of Contents](#table-of-contents))
### Deteção e Prevenção de Intrusão no iptables com PSAD
#### Porquê
Mesmo que tenha uma firewall para proteger as suas portas, é possível tentar forçar a entrada em qualquer uma das portas protegidas. Queremos monitorizar toda a atividade de rede para detetar potenciais tentativas de intrusão, como tentativas repetidas de entrada, e bloqueá-las.
#### Como Funciona
Não consigo explicar melhor do que o utilizador [FINESEC](https://serverfault.com/users/143961/finesec) do https://serverfault.com/ fez em: https://serverfault.com/a/447604/289829.
> O Fail2BAN analisa ficheiros de log de várias aplicações como apache, ssh ou ftp e bane automaticamente IPs que apresentem sinais maliciosos, como tentativas automatizadas de login. O PSAD, por outro lado, analisa as mensagens de log do iptables e ip6tables (tipicamente /var/log/messages) para detetar e, opcionalmente, bloquear scans e outros tipos de tráfego suspeito, como tentativas de DDoS ou de fingerprinting do SO. É aceitável usar ambos os programas ao mesmo tempo porque operam a níveis diferentes.
E, como já estamos a usar [UFW](#ufw-uncomplicated-firewall), vamos seguir as excelentes instruções do [netson](https://gist.github.com/netson) em https://gist.github.com/netson/c45b2dc4e835761fbccc para fazer o PSAD funcionar com o UFW.
#### Referências
- http://www.cipherdyne.org/psad/
- http://www.cipherdyne.org/psad/docs/config.html
- https://www.thefanclub.co.za/how-to/how-install-psad-intrusion-detection-ubuntu-1204-lts-server
- https://serverfault.com/a/447604/289829
- https://serverfault.com/a/770424/289829
- https://gist.github.com/netson/c45b2dc4e835761fbccc
- Agradecimentos ao [moltenbit](https://github.com/moltenbit) por detetar o problema ([#61](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/61)) com o `psadwatchd`.
#### Passos
1. Instalar o psad.
Em sistemas baseados em Debian:
``` bash
sudo apt install psad
```
1. Criar uma cópia de segurança do ficheiro de configuração do psad `/etc/psad/psad.conf`:
``` bash
sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Rever e atualizar as opções de configuração em `/etc/psad/psad.conf`. Prestar atenção especial a estas:
|Definição|Definir Para
|--|--|
|[`EMAIL_ADDRESSES`](http://www.cipherdyne.org/psad/docs/config.html#EMAIL_ADDRESSES)|o(s) seu(s) endereço(s) de e-mail|
|`HOSTNAME`|o hostname do seu servidor|
|`EXPECT_TCP_OPTIONS`|`EXPECT_TCP_OPTIONS Y;`|
|`ENABLE_PSADWATCHD`|`ENABLE_PSADWATCHD Y;`|
|[`ENABLE_AUTO_IDS`](http://www.cipherdyne.org/psad/docs/config.html#ENABLE_AUTO_IDS)|`ENABLE_AUTO_IDS Y;`|
|`ENABLE_AUTO_IDS_EMAILS`|`ENABLE_AUTO_IDS_EMAILS Y;`|
Consulte a documentação do psad para o ficheiro de configuração em http://www.cipherdyne.org/psad/docs/config.html para mais detalhes.
1. <a name="psad_step4"></a>Agora precisamos de fazer algumas alterações ao ufw para que funcione com o psad, instruindo o ufw a registar todo o tráfego para que o psad o possa analisar. Faça isto editando **dois ficheiros** e adicionando estas linhas **no final, mas antes da linha COMMIT**.
Fazer cópias de segurança:
``` bash
sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
```
Editar os ficheiros:
- `/etc/ufw/before.rules`
- `/etc/ufw/before6.rules`
E adicionar **no final, mas antes da linha COMMIT**:
```
# log all traffic so psad can analyze
-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
```
**Nota**: Estamos a adicionar um prefixo de log a todos os logs do iptables. Iremos precisar disto para [separar os logs do iptables para o seu próprio ficheiro](#separate-iptables-log-file).
Por exemplo:
> ```
> ...
>
> # log all traffic so psad can analyze
> -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
> -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
>
> # don't delete the 'COMMIT' line or these rules won't be processed
> COMMIT
> ```
1. Agora precisamos de recarregar/reiniciar o ufw e o psad para que as alterações tenham efeito:
``` bash
sudo ufw reload
sudo psad -R
sudo psad --sig-update
sudo psad -H
```
1. Analisar as regras do iptables para detetar erros:
``` bash
sudo psad --fw-analyze
```
> ```
> [+] Parsing INPUT chain rules.
> [+] Parsing INPUT chain rules.
> [+] Firewall config looks good.
> [+] Completed check of firewall ruleset.
> [+] Results in /var/log/psad/fw_check
> [+] Exiting.
> ```
**Nota**: Se houver algum problema, receberá um e-mail com o erro.
1. Verificar o estado do psad:
``` bash
sudo psad --Status
```
> ```
> [-] psad: pid file /var/run/psad/psadwatchd.pid does not exist for psadwatchd on vm
> [+] psad_fw_read (pid: 3444) %CPU: 0.0 %MEM: 2.2
> Running since: Sat Feb 16 01:03:09 2019
>
> [+] psad (pid: 3435) %CPU: 0.2 %MEM: 2.7
> Running since: Sat Feb 16 01:03:09 2019
> Command line arguments: [none specified]
> Alert email address(es): root@localhost
>
> [+] Version: psad v2.4.3
>
> [+] Top 50 signature matches:
> [NONE]
>
> [+] Top 25 attackers:
> [NONE]
>
> [+] Top 20 scanned ports:
> [NONE]
>
> [+] iptables log prefix counters:
> [NONE]
>
> Total protocol packet counters:
>
> [+] IP Status Detail:
> [NONE]
>
> Total scan sources: 0
> Total scan destinations: 0
>
> [+] These results are available in: /var/log/psad/status.out
> ```
([Table of Contents](#table-of-contents))
### Deteção e Prevenção de Intrusão em Aplicações com Fail2Ban
#### Porquê
O UFW diz ao seu servidor quais as portas para tapar para que ninguém as veja, e quais as portas para permitir a passagem de utilizadores autorizados. O PSAD monitoriza a atividade de rede para detetar e prevenir potenciais intrusões — tentativas repetidas de entrada.
Mas e quanto às aplicações/serviços que o seu servidor está a executar, como SSH e Apache, onde a sua firewall está configurada para permitir o acesso? Embora o acesso possa ser permitido, isso não significa que todas as tentativas de acesso sejam válidas e inofensivas. E se alguém tentar forçar a entrada numa aplicação web que está a executar no seu servidor? É aqui que entra o Fail2ban.
#### Como Funciona
O Fail2ban monitoriza os logs das suas aplicações (como SSH e Apache) para detetar e prevenir potenciais intrusões. Irá monitorizar o tráfego de rede/logs e prevenir intrusões bloqueando atividade suspeita (ex.: múltiplas falhas de conexão sucessivas num curto espaço de tempo).
#### Objetivos
- monitorização de rede para atividade suspeita com banimento automático de IPs infratores
#### Notas
- Neste momento, a única coisa em execução neste servidor é o SSH, por isso vamos querer que o Fail2ban monitorize o SSH e banir conforme necessário.
- À medida que instalar outros programas, precisará de criar/configurar as jails apropriadas e ativá-las.
#### Referências
- https://www.fail2ban.org/
- https://blog.vigilcode.com/2011/05/ufw-with-fail2ban-quick-secure-setup-part-ii/
- https://dodwell.us/security/ufw-fail2ban-portscan.html
- https://www.howtoforge.com/community/threads/fail2ban-and-ufw-on-debian.77261/
#### Passos
1. Instalar o fail2ban.
Em sistemas baseados em Debian:
``` bash
sudo apt install fail2ban
```
1. Não queremos editar `/etc/fail2ban/fail2ban.conf` ou `/etc/fail2ban/jail.conf` porque uma futura atualização pode sobrescrevê-los, por isso vamos criar uma cópia local. Criar o ficheiro `/etc/fail2ban/jail.local` e adicionar isto, substituindo `[LAN SEGMENT]` e `[your email]` pelos valores apropriados:
```
[DEFAULT]
# the IP address range we want to ignore
ignoreip = 127.0.0.1/8 [LAN SEGMENT]
# who to send e-mail to
destemail = [your e-mail]
# who is the email from
sender = [your e-mail]
# since we're using exim4 to send emails
mta = mail
# get email alerts
action = %(action_mwl)s
```
**Nota**: O seu servidor precisará de conseguir enviar e-mails para que o Fail2ban possa informá-lo sobre atividade suspeita e quando banir um IP.
1. Precisamos de criar uma jail para o SSH que diga ao fail2ban para olhar para os logs do SSH e usar o ufw para banir/desbanir IPs conforme necessário. Crie uma jail para o SSH criando o ficheiro `/etc/fail2ban/jail.d/ssh.local` e adicionando isto:
```
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
```
[Para os preguiçosos](#editing-configuration-files---for-the-lazy):
``` bash
cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
EOF
```
1. No exemplo acima, dizemos ao fail2ban para usar o ufw como `banaction`. O Fail2ban vem com um ficheiro de configuração de ação para o ufw. Pode vê-lo em `/etc/fail2ban/action.d/ufw.conf`
1. Ativar o fail2ban:
``` bash
sudo fail2ban-client start
sudo fail2ban-client reload
sudo fail2ban-client add sshd # Isto pode falhar em alguns sistemas se a jail sshd foi adicionada por omissão
```
1. Para verificar o estado:
``` bash
sudo fail2ban-client status
```
> ```
> Status
> |- Number of jail: 1
> `- Jail list: sshd
> ```
``` bash
sudo fail2ban-client status sshd
```
> ```
> Status for the jail: sshd
> |- Filter
> | |- Currently failed: 0
> | |- Total failed: 0
> | `- File list: /var/log/auth.log
> `- Actions
> |- Currently banned: 0
> |- Total banned: 0
> `- Banned IP list:
> ```
#### Jails Personalizadas
Ainda não precisei de criar uma jail personalizada. Assim que precisar e descobrir como, atualizarei este guia. Ou, se souber como, ajude a [contribuir](#contributing).
#### Desbanir um IP
Para desbanir um IP, use este comando:``` bash
fail2ban-client set [jail] unbanip [IP]
```
`[jail]` é o nome da jail que contém o IP banido e `[IP]` é o endereço IP que você deseja desbanir. Por exemplo, para desbanir `192.168.1.100` do SSH você faria:``` bash
fail2ban-client set sshd unbanip 192.168.1.100
```
([Índice](#table-of-contents))
### Detecção e Prevenção de Intrusão em Aplicações com CrowdSec
#### Motivação
O UFW diz ao seu servidor quais portas devem ser fechadas para que ninguém possa vê-las, e quais portas permitir que usuários autorizados passem. O PSAD monitora a atividade de rede para detectar e prevenir potenciais intrusões — tentativas repetidas de entrar.
O CrowdSec é semelhante ao Fail2Ban, pois monitora os logs de suas aplicações (como SSH e Apache) para detectar e prevenir potenciais intrusões. No entanto, o CrowdSec é integrado a uma comunidade que compartilha inteligência de ameaças de volta para a CrowdSec, que então distribui uma Lista de Bloqueio Comunitária para todos os usuários.
#### Como Funciona
O CrowdSec monitora os logs de suas aplicações (como SSH e Apache) para detectar e prevenir potenciais intrusões. Ele monitora o tráfego/logs de rede e previne intrusões bloqueando atividades suspeitas (por exemplo, múltiplas falhas de conexão sucessivas em um curto período de tempo). Uma vez detectado um IP malicioso, ele será adicionado à sua lista de decisão local e as informações de ameaça são compartilhadas com a CrowdSec para atualizar a Lista de Bloqueio Comunitária sobre endereços IP maliciosos. Quando um endereço IP atinge um certo limite de atividade maliciosa, ele é automaticamente propagado para todos os outros usuários do CrowdSec para bloqueio proativo.
#### Objetivos
- monitoramento de rede para atividades suspeitas com banimento automático de IPs infratores
#### Notas
- Atualmente, a única coisa em execução neste servidor é SSH, então queremos que o CrowdSec monitore SSH e bane conforme necessário.
- Conforme você instalar outros programas, será necessário instalar coleções adicionais e configurar as aquisições apropriadas.
#### Referências
- https://www.crowdsec.net/
- [Leia como a CrowdSec administra a Lista de Bloqueio Comunitária](https://www.crowdsec.net/our-data)
- [Leia quais informações de inteligência de ameaças são compartilhadas com a CrowdSec](https://docs.crowdsec.net/docs/next/central_api/intro#signal-meta-data)
- https://docs.crowdsec.net/
#### Passos
1. Instale o Mecanismo de Segurança do CrowdSec. (IDS)
Em qualquer distribuição Linux (incluindo sistemas baseados em Debian)
Instale o repositório do CrowdSec:
``` bash
curl -s https://install.crowdsec.net | sudo sh
```
Instale o Mecanismo de Segurança do CrowdSec:
``` bash
sudo apt install crowdsec
```
> [!TIP]
> se `curl | sh` não é a sua preferência, você pode encontrar métodos de instalação adicionais [aqui](https://docs.crowdsec.net/u/getting_started/installation/linux).
Por padrão, enquanto o CrowdSec está instalando o Mecanismo de Segurança, ele descobrirá automaticamente suas aplicações instaladas e instalará os parsers e cenários apropriados para elas. Como sabemos que a maioria dos servidores Linux está executando ssh pronto para uso, o CrowdSec configurará isso automaticamente para você.
2. Instale um Componente de Remediação. (IPS)
O CrowdSec por si só é um mecanismo de detecção; como na maioria das infraestruturas modernas você pode ter um firewall upstream ou WAF, o CrowdSec não bloqueará os endereços IP por conta própria. Você pode instalar um Componente de Remediação para bloquear os endereços IP detectados pelo CrowdSec.
```bash
sudo apt install crowdsec-firewall-bouncer-iptables
```
> [!TIP]
> Se sua instalação do UFW não estiver usando `iptables` como backend, você pode alternativamente instalar o `crowdsec-firewall-bouncer-nftables`. Não há diferença nos binários instalados, apenas o arquivo de configuração é diferente.
Por padrão, enquanto o Componente de Remediação está sendo instalado, ele configurará automaticamente as configurações necessárias para funcionar com o Mecanismo de Segurança se implantado no mesmo host (e se o mecanismo de segurança não estiver em um ambiente de contêiner).
3. Verifique se a detecção e remediação estão funcionando conforme o esperado:
```bash
sudo cscli metrics
```
```bash
Acquisition Metrics:
╭────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────╮
│ Source │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/var/log/auth.log │ 5 │ 4 │ 1 │ 10 │ - │
│ file:/var/log/syslog │ 30 │ - │ 30 │ - │ - │
╰────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯
Local API Decisions:
╭────────────────────────────────────────────┬────────┬────────┬───────╮
│ Reason │ Origin │ Action │ Count │
├────────────────────────────────────────────┼────────┼────────┼───────┤
│ crowdsecurity/http-backdoors-attempts │ CAPI │ ban │ 73 │
│ crowdsecurity/http-bad-user-agent │ CAPI │ ban │ 4836 │
│ crowdsecurity/http-path-traversal-probing │ CAPI │ ban │ 87 │
│ crowdsecurity/http-probing │ CAPI │ ban │ 2010 │
│ crowdsecurity/thinkphp-cve-2018-20062 │ CAPI │ ban │ 88 │
│ crowdsecurity/CVE-2019-18935 │ CAPI │ ban │ 7 │
│ crowdsecurity/CVE-2023-49103 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-admin-interface-probing │ CAPI │ ban │ 91 │
│ ltsich/http-w00tw00t │ CAPI │ ban │ 3 │
│ crowdsecurity/apache_log4j2_cve-2021-44228 │ CAPI │ ban │ 18 │
│ crowdsecurity/nginx-req-limit-exceeded │ CAPI │ ban │ 280 │
│ crowdsecurity/ssh-slow-bf │ CAPI │ ban │ 3412 │
│ crowdsecurity/spring4shell_cve-2022-22965 │ CAPI │ ban │ 1 │
│ crowdsecurity/ssh-cve-2024-6387 │ CAPI │ ban │ 24 │
│ crowdsecurity/CVE-2023-22515 │ CAPI │ ban │ 2 │
│ crowdsecurity/http-cve-2021-41773 │ CAPI │ ban │ 172 │
│ crowdsecurity/netgear_rce │ CAPI │ ban │ 14 │
│ crowdsecurity/ssh-bf │ CAPI │ ban │ 2000 │
│ crowdsecurity/CVE-2022-35914 │ CAPI │ ban │ 1 │
│ crowdsecurity/http-cve-2021-42013 │ CAPI │ ban │ 2 │
│ crowdsecurity/jira_cve-2021-26086 │ CAPI │ ban │ 9 │
│ crowdsecurity/http-sensitive-files │ CAPI │ ban │ 166 │
│ crowdsecurity/http-wordpress-scan │ CAPI │ ban │ 272 │
│ crowdsecurity/CVE-2022-26134 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-generic-bf │ CAPI │ ban │ 7 │
│ crowdsecurity/http-open-proxy │ CAPI │ ban │ 948 │
│ crowdsecurity/http-crawl-non_statics │ CAPI │ ban │ 339 │
│ crowdsecurity/http-cve-probing │ CAPI │ ban │ 5 │
│ crowdsecurity/CVE-2017-9841 │ CAPI │ ban │ 117 │
│ crowdsecurity/CVE-2022-37042 │ CAPI │ ban │ 1 │
│ crowdsecurity/fortinet-cve-2018-13379 │ CAPI │ ban │ 5 │
╰────────────────────────────────────────────┴────────┴────────┴───────╯
Local API Metrics:
╭──────────────────────┬────────┬──────╮
│ Route │ Method │ Hits │
├──────────────────────┼────────┼──────┤
│ /v1/alerts │ GET │ 2 │
│ /v1/decisions/stream │ GET │ 5 │
│ /v1/usage-metrics │ POST │ 2 │
│ /v1/watchers/login │ POST │ 4 │
╰──────────────────────┴────────┴──────╯
Local API Bouncers Metrics:
╭────────────────────────────────┬──────────────────────┬────────┬──────╮
│ Bouncer │ Route │ Method │ Hits │
├────────────────────────────────┼──────────────────────┼────────┼──────┤
│ cs-firewall-bouncer-1729025592 │ /v1/decisions/stream │ GET │ 5 │
╰────────────────────────────────┴──────────────────────┴────────┴──────╯
Local API Machines Metrics:
╭──────────────────────────────────────────────────┬────────────┬────────┬──────╮
│ Machine │ Route │ Method │ Hits │
├──────────────────────────────────────────────────┼────────────┼────────┼──────┤
│ <your_machine_id_will_be_here> │ /v1/alerts │ GET │ 2 │
╰──────────────────────────────────────────────────┴────────────┴────────┴──────╯
Parser Metrics:
╭─────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers │ Hits │ Parsed │ Unparsed │
├─────────────────────────────────┼──────┼────────┼──────────┤
│ child-crowdsecurity/sshd-logs │ 41 │ 4 │ 37 │
│ child-crowdsecurity/syslog-logs │ 35 │ 35 │ - │
│ crowdsecurity/dateparse-enrich │ 4 │ 4 │ - │
│ crowdsecurity/sshd-logs │ 5 │ 4 │ 1 │
│ crowdsecurity/syslog-logs │ 35 │ 35 │ - │
╰─────────────────────────────────┴──────┴────────┴──────────╯
Scenario Metrics:
╭─────────────────────────────────────┬───────────────┬───────────┬──────────────┬────────┬─────────╮
│ Scenario │ Current Count │ Overflows │ Instantiated │ Poured │ Expired │
├─────────────────────────────────────┼───────────────┼───────────┼──────────────┼────────┼─────────┤
│ crowdsecurity/ssh-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
│ crowdsecurity/ssh-slow-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-slow-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
╰─────────────────────────────────────┴───────────────┴───────────┴──────────────┴────────┴─────────╯
```
A saída acima pode ser assustadora, mas é uma boa maneira de verificar se o Mecanismo de Segurança está lendo logs e o Componente de Remediação está bloqueando endereços IP. Então, uma rápida análise de cada seção:
- **Métricas de Aquisição**: Esta seção mostra os logs que o Mecanismo de Segurança está lendo e analisando. Se você vir logs na coluna `Lines unparsed`, significa que o Mecanismo de Segurança não está conseguindo analisar os logs. Isso pode ser devido a uma configuração incorreta ou os logs não estão no formato esperado.
- **Decisões da API Local**: Esta seção mostra as decisões que o Mecanismo de Segurança tem no banco de dados. Se você vir logs na coluna `Count`, significa que o Mecanismo de Segurança detectou atividade maliciosa e bloqueou o endereço IP.
- Origem: De onde veio a decisão. Neste caso, é da API Central (CAPI).
- **Métricas da API Local**: Esta seção mostra o número de acessos à API Local. Esta é a API que o Mecanismo de Segurança usa para se comunicar com o Componente de Remediação.
- **Métricas dos Bouncers da API Local**: Esta seção mostra o número de acessos à API Local pelo Componente de Remediação.
- **Métricas de Máquinas da API Local**: Esta seção mostra o número de acessos à API Local pelo Mecanismo de Segurança (se você executar vários Mecanismos de Segurança em uma configuração centralizada, poderá ver vários IDs aqui).
- **Métricas de Parsers**: Esta seção mostra os parsers que estão sendo usados pelo Mecanismo de Segurança. Se você vir logs na coluna `Unparsed`, significa que o Mecanismo de Segurança não está conseguindo analisar os logs. Isso pode ser devido a uma configuração incorreta ou os logs não estão no formato esperado.
- **Métricas de Cenários**: Esta seção mostra os cenários que estão sendo usados pelo Mecanismo de Segurança. Se você vir logs na coluna `Current Count`, significa que o Mecanismo de Segurança detectou atividade maliciosa e está rastreando o endereço IP.
#### Desbanir um IP
Para desbanir um IP, use este comando:``` bash
cscli decisions delete --ip [IP]
```
`[IP]` é o endereço IP que deseja desbanir. Por exemplo, para desbanir `192.168.1.100` do SSH você faria:``` bash
cscli decisions delete --ip 192.168.1.100
```
## A Auditoria
### Monitoramento de Integridade de Arquivos/Pastas com AIDE (WIP)
#### Porquê
WIP
#### Como Funciona
WIP
#### Objetivos
WIP
#### Referências
- https://aide.github.io/
- https://www.hiroom2.com/2017/06/09/debian-8-file-integrity-check-with-aide/
- https://blog.rapid7.com/2017/06/30/how-to-install-and-configure-aide-on-ubuntu-linux/
- https://www.stephenrlang.com/2016/03/using-aide-for-file-integrity-monitoring-fim-on-ubuntu/
- https://www.howtoforge.com/how-to-configure-the-aide-advanced-intrusion-detection-environment-file-integrity-scanner-for-your-website
- https://www.tecmint.com/check-integrity-of-file-and-directory-using-aide-in-linux/
- https://www.cyberciti.biz/faq/debian-ubuntu-linux-software-integrity-checking-with-aide/
- https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/83
#### Passos
1. Instalar o AIDE.
Em sistemas baseados em Debian:
``` bash
sudo apt install aide aide-common
```
1. Fazer um backup do ficheiro de padrões do AIDE:
``` bash
sudo cp -p /etc/default/aide /etc/default/aide-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Revisar `/etc/default/aide` e definir os padrões do AIDE conforme os seus requisitos. Se quiser que o AIDE seja executado diariamente e lhe envie um e-mail, certifique-se de definir `CRON_DAILY_RUN` como `yes`.
1. Fazer um backup dos ficheiros de configuração do AIDE:
``` bash
sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Em sistemas baseados em Debian:
- Os ficheiros de configuração do AIDE estão em `/etc/aide/aide.conf.d/`.
- Deverá ler a documentação do AIDE e os ficheiros de configuração para os definir conforme os seus requisitos.
- Se quiser novas definições, por exemplo para monitorizar uma nova pasta, deverá adicioná-las a `/etc/aide/aide.conf` ou `/etc/aide/aide.conf.d/`.
- Faça um backup dos ficheiros de configuração originais: `sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")`.
1. Criar uma nova base de dados e instalá-la.
Em sistemas baseados em Debian:
``` bash
sudo aideinit
```
> ```
> Running aide --init...
> Start timestamp: 2019-04-01 21:23:37 -0400 (AIDE 0.16)
> AIDE initialized database at /var/lib/aide/aide.db.new
> Verbose level: 6
>
> Number of entries: 25973
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db.new
> RMD160 : moyQ1YskQQbidX+Lusv3g2wf1gQ=
> TIGER : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
> SHA256 : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
> g16VTPpIfYQ=
> SHA512 : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
> rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
> tV+jt3ELvwFzGefq4ZBNMg==
> CRC32 : /cusZw==
> HAVAL : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
> CPGQSW4tl14=
> GOST : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
> aMv7Oby604A=
>
>
> End timestamp: 2019-04-01 21:24:45 -0400 (run time: 1m 8s)
> ```
1. Testar se tudo funciona sem alterações.
Em sistemas baseados em Debian:
``` bash
sudo aide.wrapper --check
```
> ```
> Start timestamp: 2019-04-01 21:24:45 -0400 (AIDE 0.16)
> AIDE found NO differences between database and filesystem. Looks okay!!
> Verbose level: 6
>
> Number of entries: 25973
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db
> RMD160 : moyQ1YskQQbidX+Lusv3g2wf1gQ=
> TIGER : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
> SHA256 : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
> g16VTPpIfYQ=
> SHA512 : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
> rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
> tV+jt3ELvwFzGefq4ZBNMg==
> CRC32 : /cusZw==
> HAVAL : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
> CPGQSW4tl14=
> GOST : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
> aMv7Oby604A=
>
>
> End timestamp: 2019-04-01 21:26:03 -0400 (run time: 1m 18s)
> ```
1. Testar se tudo funciona após fazer algumas alterações.
Em sistemas baseados em Debian:
``` bash
sudo touch /etc/test.sh
sudo touch /root/test.sh
sudo aide.wrapper --check
sudo rm /etc/test.sh
sudo rm /root/test.sh
sudo aideinit -y -f
```
> ```
> Start timestamp: 2019-04-01 21:37:37 -0400 (AIDE 0.16)
> AIDE found differences between database and filesystem!!
> Verbose level: 6
>
> Summary:
> Total number of entries: 25972
> Added entries: 2
> Removed entries: 0
> Changed entries: 1
>
> ---------------------------------------------------
> Added entries:
> ---------------------------------------------------
>
> f++++++++++++++++: /etc/test.sh
> f++++++++++++++++: /root/test.sh
>
> ---------------------------------------------------
> Changed entries:
> ---------------------------------------------------
>
> d =.... mc.. .. .: /root
>
> ---------------------------------------------------
> Detailed information about changes:
> ---------------------------------------------------
>
> Directory: /root
> Mtime : 2019-04-01 21:35:07 -0400 | 2019-04-01 21:37:36 -0400
> Ctime : 2019-04-01 21:35:07 -0400 | 2019-04-01 21:37:36 -0400
>
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db
> RMD160 : qF9WmKaf2PptjKnhcr9z4ueCPTY=
> TIGER : zMo7MvvYJcq1hzvTQLPMW7ALeFiyEqv+
> SHA256 : LSLLVjjV6r8vlSxlbAbbEsPcQUB48SgP
> pdVqEn6ZNbQ=
> SHA512 : Qc4U7+ZAWCcitapGhJ1IrXCLGCf1IKZl
> 02KYL1gaZ0Fm4dc7xLqjiquWDMSEbwzW
> oz49NCquqGz5jpMIUy7UxA==
> CRC32 : z8ChEA==
> HAVAL : YapzS+/cdDwLj3kHJEq8fufLp3DPKZDg
> U12KCSkrO7Y=
> GOST : 74sLV4HkTig+GJhokvxZQm7CJD/NR0mG
> 6jV7zdt5AXQ=
>
>
> End timestamp: 2019-04-01 21:38:50 -0400 (run time: 1m 13s)
> ```
1. É isso. Se definir `CRON_DAILY_RUN` como `yes` em `/etc/default/aide`, o cron executará `/etc/cron.daily/aide` todos os dias e enviar-lhe-á a saída por e-mail.
#### Atualizar a Base de Dados
Sempre que fizer alterações a ficheiros/pastas que o AIDE monitoriza, precisará de atualizar a base de dados para capturar essas alterações. Para o fazer em sistemas baseados em Debian:``` bash
sudo aideinit -y -f
```
([Table of Contents](#table-of-contents))
### Verificação Antivírus com ClamAV (WIP)
#### Porquê
WIP
#### Como Funciona
- ClamAV é um scanner de vírus
- ClamAV-Freshclam é um serviço que mantém as definições de vírus atualizadas
- ClamAV-Daemon mantém o processo `clamd` em execução para tornar a verificação mais rápida
#### Objetivos
WIP
#### Notas
- Estas instruções **não** lhe dizem como ativar o serviço ClamAV daemon para garantir que o `clamd` está sempre em execução. O `clamd` é apenas se estiver a executar um servidor de correio e não fornece monitorização em tempo real dos ficheiros. Em vez disso, deve digitalizar ficheiros manualmente ou de forma programada.
#### Referências
- https://www.clamav.net/documents/installation-on-debian-and-ubuntu-linux-distributions
- https://wiki.debian.org/ClamAV
- https://www.osradar.com/install-clamav-debian-9-ubuntu-18/
- https://www.lisenet.com/2014/automate-clamav-to-perform-daily-system-scan-and-send-email-notifications-on-linux/
- https://www.howtoforge.com/tutorial/configure-clamav-to-scan-and-notify-virus-and-malware/
- https://serverfault.com/questions/741299/is-there-a-way-to-keep-clamav-updated-on-debian-8
- https://askubuntu.com/questions/250290/how-do-i-scan-for-viruses-with-clamav
- https://ngothang.com/how-to-install-clamav-and-configure-daily-scanning-on-centos/
#### Passos
1. Instalar o ClamAV.
Em sistemas baseados em Debian:
``` bash
sudo apt install clamav clamav-freshclam clamav-daemon
```
1. Faça uma cópia de segurança do ficheiro de configuração do `clamav-freshclam` `/etc/clamav/freshclam.conf`:
``` bash
sudo cp --archive /etc/clamav/freshclam.conf /etc/clamav/freshclam.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. As predefinições do `clamav-freshclam` provavelmente são suficientes, mas se quiser alterá-las, pode editar o ficheiro `/etc/clamav/freshclam.conf` ou usar o `dpkg-reconfigure`:
``` bash
sudo dpkg-reconfigure clamav-freshclam
```
**Nota**: As predefinições atualizam as definições 24 vezes por dia. Para alterar o intervalo, verifique a definição `Checks` em `/etc/clamav/freshclam.conf` ou use `dpkg-reconfigure`.
1. Inicie o serviço `clamav-freshclam`:
``` bash
sudo service clamav-freshclam start
```
1. Pode verificar se o `clamav-freshclam` está em execução:
``` bash
sudo service clamav-freshclam status
```
> ```
> ● clamav-freshclam.service - ClamAV virus database updater
> Loaded: loaded (/lib/systemd/system/clamav-freshclam.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-03-16 22:57:07 EDT; 2min 13s ago
> Docs: man:freshclam(1)
> man:freshclam.conf(5)
> https://www.clamav.net/documents
> Main PID: 1288 (freshclam)
> CGroup: /system.slice/clamav-freshclam.service
> └─1288 /usr/bin/freshclam -d --foreground=true
>
> Mar 16 22:57:08 host freshclam[1288]: Sat Mar 16 22:57:08 2019 -> ^Local version: 0.100.2 Recommended version: 0.101.1
> Mar 16 22:57:08 host freshclam[1288]: Sat Mar 16 22:57:08 2019 -> DON'T PANIC! Read https://www.clamav.net/documents/upgrading-clamav
> Mar 16 22:57:15 host freshclam[1288]: Sat Mar 16 22:57:15 2019 -> Downloading main.cvd [100%]
> Mar 16 22:57:38 host freshclam[1288]: Sat Mar 16 22:57:38 2019 -> main.cvd updated (version: 58, sigs: 4566249, f-level: 60, builder: sigmgr)
> Mar 16 22:57:40 host freshclam[1288]: Sat Mar 16 22:57:40 2019 -> Downloading daily.cvd [100%]
> Mar 16 22:58:13 host freshclam[1288]: Sat Mar 16 22:58:13 2019 -> daily.cvd updated (version: 25390, sigs: 1520006, f-level: 63, builder: raynman)
> Mar 16 22:58:14 host freshclam[1288]: Sat Mar 16 22:58:14 2019 -> Downloading bytecode.cvd [100%]
> Mar 16 22:58:16 host freshclam[1288]: Sat Mar 16 22:58:16 2019 -> bytecode.cvd updated (version: 328, sigs: 94, f-level: 63, builder: neo)
> Mar 16 22:58:24 host freshclam[1288]: Sat Mar 16 22:58:24 2019 -> Database updated (6086349 signatures) from db.local.clamav.net (IP: 104.16.219.84)
> Mar 16 22:58:24 host freshclam[1288]: Sat Mar 16 22:58:24 2019 -> ^Clamd was NOT notified: Can't connect to clamd through /var/run/clamav/clamd.ctl: No such file or directory
> ```
**Nota**: Não se preocupe com essa linha `Local version`. Consulte https://serverfault.com/questions/741299/is-there-a-way-to-keep-clamav-updated-on-debian-8 para mais detalhes.
1. Faça uma cópia de segurança do ficheiro de configuração do `clamav-daemon` `/etc/clamav/clamd.conf`:
``` bash
sudo cp --archive /etc/clamav/clamd.conf /etc/clamav/clamd.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Pode alterar as definições do `clamav-daemon` editando o ficheiro `/etc/clamav/clamd.conf` ou usando `dpkg-reconfigure`:
``` bash
sudo dpkg-reconfigure clamav-daemon
```
#### Digitalizar Ficheiros/Pastas
- Para digitalizar ficheiros/pastas, use o programa `clamscan`.
- O `clamscan` é executado como o utilizador que o executa, por isso precisa de permissões de leitura para os ficheiros/pastas que está a digitalizar.
- Usar `clamscan` como `root` é perigoso porque, se um ficheiro for de facto um vírus, existe o risco de poder usar os privilégios de root.
- Para digitalizar um ficheiro: `clamscan /caminho/para/ficheiro`.
- Para digitalizar um diretório: `clamscan -r /caminho/para/pasta`.
- Pode usar a opção `-i` para mostrar apenas ficheiros infetados.
- Consulte as páginas `man` do `clamscan` para outras opções/opções.
([Table of Contents](#table-of-contents))
### Deteção de Rootkits com Rkhunter (WIP)
#### Porquê
WIP
#### Como Funciona
WIP
#### Objetivos
WIP
#### Referências
- http://rkhunter.sourceforge.net/
- https://www.cyberciti.biz/faq/howto-check-linux-rootkist-with-detectors-software/
- https://www.tecmint.com/install-rootkit-hunter-scan-for-rootkits-backdoors-in-linux/
#### Passos
1. Instalar o Rkhunter.
Em sistemas baseados em Debian:
``` bash
sudo apt install rkhunter
```
1. Faça uma cópia de segurança do ficheiro de predefinições do rkhunter:
``` bash
sudo cp -p /etc/default/rkhunter /etc/default/rkhunter-COPY-$(date +"%Y%m%d%H%M%S")
```
1. O ficheiro de configuração do rkhunter é `/etc/rkhunter.conf`. Em vez de fazer alterações a este, crie e use o ficheiro `/etc/rkhunter.conf.local`:
``` bash
sudo cp -p /etc/rkhunter.conf /etc/rkhunter.conf.local
```
1. Percorra o ficheiro de configuração `/etc/rkhunter.conf.local` e defina de acordo com os seus requisitos. As minhas recomendações:
|Definição|Nota|
|--|--|
|`UPDATE_MIRRORS=1`||
|`MIRRORS_MODE=0`||
|`MAIL-ON-WARNING=root`||
|`COPY_LOG_ON_ERROR=1`|para guardar uma cópia do registo se houver um erro|
|`PKGMGR=...`|defina para o valor apropriado conforme a documentação|
|`PHALANX2_DIRTEST=1`|leia a documentação para saber porquê|
|`WEB_CMD=""`|isto é para resolver um problema com o pacote Debian que desativa a capacidade do rkhunter de se auto-atualizar.|
|`USE_LOCKING=1`|para evitar problemas com o rkhunter a ser executado várias vezes|
|`SHOW_SUMMARY_WARNINGS_NUMBER=1`|para ver o número real de avisos encontrados|
ssh-copy-idssh-copy-id user@server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub" The authenticity of host 'host (192.168.1.96)' can't be established. ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys user@host's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'user@host'" and check to make sure that only the key(s) you wanted were added.
ssh-keygen -l -f ~/.ssh/id_rsa########################################################################################################
# início das configurações de https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 em 2019-01-01
########################################################################################################
# Algoritmos HostKey suportados por ordem de preferência.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
# LogLevel VERBOSE regista a impressão digital da chave do usuário no login. Necessário para ter uma trilha de auditoria clara de qual chave foi usada para fazer login.
LogLevel VERBOSE
# Usar mecanismos de sandbox do kernel quando possível em processos não privilegiados
# Systrace no OpenBSD, Seccomp no Linux, seatbelt no MacOSX/Darwin, rlimit em outros lugares.
# Nota: Esta configuração está obsoleta no OpenSSH 7.5 (https://www.openssh.com/txt/release-7.5)
# UsePrivilegeSeparation sandbox
########################################################################################################
# fim das configurações de https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 em 2019-01-01
########################################################################################################
# não permitir que usuários definam variáveis de ambiente
PermitUserEnvironment no
# Registar acesso a nível de ficheiros sftp (leitura/escrita/etc.) que de outra forma não seriam facilmente registados.
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO
# desativar encaminhamento X11, pois X11 é muito inseguro
# você realmente não deveria estar executando X em um servidor de qualquer forma
X11Forwarding no
# desativar encaminhamento de portas
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
# não permitir login se a conta tiver uma senha vazia
PermitEmptyPasswords no
# ignorar .rhosts e .shosts
IgnoreRhosts yes
# verificar se o nome do host corresponde ao IP
UseDNS yes
Compression no
# TCP keepalive é falsificável (executa fora do canal criptografado)
# Use ClientAlive em vez disso (executa dentro do canal criptografado)
TCPKeepAlive no
AllowAgentForwarding no
PermitRootLogin no
# não permitir .rhosts ou /etc/hosts.equiv
HostbasedAuthentication no
# OpenSSH 9.1 e posteriores
# Impõe um tamanho mínimo de chave RSA de 3072 bits
# https://www.keylength.com/en/compare/
# RequiredRSASize 3072
# https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/115
HashKnownHosts yes
Em seguida, encontre e edite ou adicione estas configurações e defina os valores de acordo com seus requisitos:
| Configuração | Valores Válidos | Exemplo | Descrição | Notas |
|---|---|---|---|---|
| AllowGroups | nome do grupo UNIX local | AllowGroups sshusers | grupo ao qual permitir acesso SSH | |
| ClientAliveCountMax | número | ClientAliveCountMax 3 | número máximo de mensagens de cliente vivo enviadas sem resposta | |
| ClientAliveInterval | número de segundos | ClientAliveInterval 15 | tempo limite em segundos antes de uma solicitação de resposta | |
| ListenAddress | lista separada por espaços de endereços locais |
| endereços locais nos quais sshd deve escutar | Veja Issue #1 para detalhes importantes. |
| LoginGraceTime | número de segundos | LoginGraceTime 30 | tempo em segundos antes do login expirar | |
| MaxAuthTries | número | MaxAuthTries 2 | número máximo permitido de tentativas de login | |
| MaxSessions | número | MaxSessions 2 | número máximo de sessões abertas | |
| MaxStartups | número | MaxStartups 2 | número máximo de sessões de login | |
| PasswordAuthentication | yes ou no | PasswordAuthentication no | se o login com senha é permitido | |
| Port | qualquer número de porta aberta/disponível | Port 22 | porta na qual sshd deve escutar |
Consulte man sshd_config para mais detalhes sobre o significado dessas configurações.
Certifique-se de que não haja configurações duplicadas que se contradigam. O comando abaixo não deve ter nenhuma saída.
awk 'NF && $1!~/^(#|HostKey)/{print $1}' /etc/ssh/sshd_config | sort | uniq -c | grep -v ' 1 '
Reinicie o ssh:
sudo service sshd restart
Você pode verificar se as configurações funcionaram com sshd -T e verificar a saída:
sudo sshd -T
port 22 addressfamily any listenaddress [::]:22 listenaddress 0.0.0.0:22 usepam yes logingracetime 30 x11displayoffset 10 maxauthtries 2 maxsessions 2 clientaliveinterval 15 clientalivecountmax 3 streamlocalbindmask 0177 permitrootlogin no ignorerhosts yes ignoreuserknownhosts no hostbasedauthentication no ... subsystem sftp internal-sftp -f AUTHPRIV -l INFO maxstartups 2:30:2 permittunnel no ipqos lowdelay throughput rekeylimit 0 0 permitopen any
Repare que isto não é executado como root.
Selecione a opção predefinida (y na maioria dos casos) para todas as perguntas que fizer e lembre-se de guardar os códigos de emergência de reserva.
Faça uma cópia de segurança do ficheiro de configuração PAM do SSH /etc/pam.d/sshd:
sudo cp --archive /etc/pam.d/sshd /etc/pam.d/sshd-COPY-$(date +"%Y%m%d%H%M%S")
Agora precisamos de o ativar como método de autenticação para SSH adicionando esta linha ao /etc/pam.d/sshd:
auth required pam_google_authenticator.so nullok
Nota: Consulte aqui o que significa nullok.
echo -e "\nauth required pam_google_authenticator.so nullok # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/pam.d/sshd
Indique ao SSH para o utilizar adicionando ou editando esta linha no /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
sudo sed -i -r -e "s/^(challengeresponseauthentication .*)$/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/I" /etc/ssh/sshd_config
echo -e "\nChallengeResponseAuthentication yes # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ssh/sshd_config
Reinicie o ssh:
sudo service sshd restart
Reinicie o serviço para aplicar as alterações:
sudo systemctl restart systemd-timesyncd
Verifique o estado da sincronização:
timedatectl timesync-status
Server: 108.61.56.35 (pool.ntp.org) Poll interval: 32s (min: 32s; max: 34min 8s) Leap: normal Version: 4 Stratum: 2 Reference: C342F10A Precision: 1us (2^0) Root distance: 24.054ms (max: 5s) Offset: +2.156ms Delay: 48.567ms Jitter: 1.452ms Packet count: 3
Exemplo de /etc/ntp.conf:
driftfile /var/lib/ntp/ntp.drift statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited restrict 127.0.0.1 restrict ::1 restrict source notrap nomodify noquery pool pool.ntp.org iburst # added by user on 2019-03-09 @ 10:23:35
Reinicie o ntp:
sudo service ntp restart
Verifique o estado do serviço ntp:
sudo systemctl status ntp
● ntp.service - LSB: Start NTP daemon Loaded: loaded (/etc/init.d/ntp; generated; vendor preset: enabled) Active: active (running) since Sat 2019-03-09 15:19:46 EST; 4s ago Docs: man:systemd-sysv-generator(8) Process: 1016 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS) Process: 1028 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS) Tasks: 2 (limit: 4915) CGroup: /system.slice/ntp.service └─1038 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:113 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 0 v6wildcard [::]:123 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 1 v4wildcard 0.0.0.0:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 2 lo 127.0.0.1:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 3 enp0s3 10.10.20.96:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 4 lo [::1]:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 5 enp0s3 [fe80::a00:27ff:feb6:ed8e%2]:123 Mar 09 15:19:46 host ntpd[1038]: Listening on routing socket on fd #22 for interface updates Mar 09 15:19:47 host ntpd[1038]: Soliciting pool server 108.61.56.35 Mar 09 15:19:48 host ntpd[1038]: Soliciting pool server 69.89.207.199 Mar 09 15:19:49 host ntpd[1038]: Soliciting pool server 45.79.111.114
Verifique o estado do ntp:
sudo ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== pool.ntp.org .POOL. 16 p - 64 0 0.000 0.000 0.000 *lithium.constan 198.30.92.2 2 u - 64 1 19.900 4.894 3.951 ntp2.wiktel.com 212.215.1.157 2 u 2 64 1 48.061 -0.431 0.104
ucredit=-1 = deve ter pelo menos uma letra maiúsculalcredit=-1 = deve ter pelo menos uma letra minúsculaocredit=-1 = deve ter pelo menos um caractere não alfanuméricodifok=3 = pelo menos 3 caracteres da nova senha não podem estar na senha antigamaxrepeat=3 = permitir no máximo 3 caracteres repetidosgecoschec = não permitir senhas com o nome da contasudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2 # comentado por $(whoami) em $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec # adicionado por $(whoami) em $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
Notas:
/usr/lib/apt/apt.systemd.daily para detalhes sobre as opções APT::PeriodicUnattended-UpgradeExecute uma simulação do unattended-upgrades para garantir que seu arquivo de configuração está correto:
sudo unattended-upgrade -d --dry-run
Se tudo estiver correto, você pode deixar ele executar quando agendado ou forçar uma execução com unattended-upgrade -d.
Configure o apt-listchanges conforme sua preferência:
sudo dpkg-reconfigure apt-listchanges
Para o apticron, as configurações padrão já são suficientes, mas você pode verificá-las em /etc/apticron/apticron.conf se quiser alterá-las. Por exemplo, minha configuração fica assim:
EMAIL="root" NOTIFY_NO_UPDATES="1"