O sistema operacional Ubuntu Linux vem sendo cada vez mais utilizado, devido em parte a sua facilidade de uso, a sua estabilidade e a sua segurança. Mas não há nada que esteja bom que não possa melhorar, apesar da sua instalação padrão fornecer um nível satisfatório de segurança, nada melhor que aplicar alguns ajustes para melhor um pouco.
O objetivo deste artigo é apresentar um conjunto básico de procedimentos de hardening a serem aplicados logo apos a instalação do Ubuntu Linux em uma máquina. Este artigo foi construído utilizando várias fontes da internet, algumas serão citadas no final, mas várias foram perdidas a medida que este procedimento evoluía até a versão atual.
Atualizando o arquivo sources.list
Ao finalizarmos a instalação do sistema e do daemon do SSH, podemos continuar o processo a partir de um terminal remoto. Uma vez realizada a conexão, através do ssh, com a máquina que acabamos de instalar podemos iniciar sua configuraçao pelo ajuste do aquivo sources.list.
Passo 1: Guardar a versão original do sources.list
sudo mkdir /opt/backup sudo mv /etc/apt/sources.list /opt/backup
Passo 2: Criar o novo arquivo sources.list
Antes de criar o novo arquivo precisamos determinar qual a versao do ubuntu que esta instalada
lsb_release -a
O comando acima deve gerar uma saida semelhante a:
No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.3 LTS Release: 16.04 Codename: xenial
Podemos observar que o “Codenome” da versão do Ubuntu que esta instalada na maquina e “xenial“. Com esta informação, podemos montar o nosso arquivo. Para criar o arquivo podemos utilizar o comando abaixo:
sudo nano /etc/apt/sources.list
Dependo da versão do Ubuntu que estivermos utilizando o conteúdo do arquivo será ligeiramente diferente, mas basta copiar as linhas abaixo substituindo CODENAME pelo codnome obtido anteriormente, como por exemplo xenial.
# Mirror - C3SL - UFPR deb http://ubuntu.c3sl.ufpr.br/ubuntu/ CODENAME main restricted universe multiverse deb http://ubuntu.c3sl.ufpr.br/ubuntu/ CODENAME-security main restricted universe multiverse deb http://ubuntu.c3sl.ufpr.br/ubuntu/ CODENAME-updates main restricted universe multiverse deb http://mirror.lncc.br/ubuntu CODENAME-proposed main restricted universe multiverse deb http://ubuntu.c3sl.ufpr.br/ubuntu/ CODENAME-backports main restricted universe multiverse
O processo abaixo descreve como remover o arquivo original e criar um que utiliza, ou melhor, aponta para os pacotes hospedados no mirror do LNCC.
# Mirror LNCC deb http://mirror.lncc.br/ubuntu CODENAME main restricted universe multiverse deb http://mirror.lncc.br/ubuntu CODENAME-security main restricted universe multiverse deb http://mirror.lncc.br/ubuntu CODENAME-updates main restricted universe multiverse deb http://mirror.lncc.br/ubuntu CODENAME-proposed main restricted universe multiverse deb http://mirror.lncc.br/ubuntu CODENAME-backports main restricted universe multiverse
Depois de adicionar as linhas, salve as modificações e feche o arquivo.
Atualizando os pacotes
Com o novo arquivo sources.list, podemos executar a atualização dos pacotes instalados.
sudo apt update sudo apt full-upgrade sudo apt dist-upgrade sudo apt autoremove
Em seguida podemos instalar alguns aplicativos uteis:
sudo apt-get install git mutt iptables-persistent fping mtr htop nano
Depois, podemos instalar outros pacotes relacionados ao Kernel do sistema; estes serão úteis na detecção e manutenção de alguns hardwares.
sudo apt-get install linux-firmware
Criando as contas administrativas
Com os principais pacotes instalados, podemos criar as contas e os grupos utilizados na administração do sistema, inicialmente serão criados os grupos abaixo:
- sudo – permitirá o acesso ao sudo
- ssh – grupo com privilégio para acessar o host por meio do ssh
- admin – grupo com privilégio para gerenciar alguns serviços e acessar pastas compartilhadas pela equipe de técnicos que administra o host.
Para criar os grupos podemos utilizar:
sudo groupadd sudo sudo groupadd ssh sudo groupadd admin
Em seguida podemos criar os usuários e liberar o acesso administrativo; o processo consiste em executar os comandos abaixom substiruindo “USER” pelo login do usuário a ser criado
sudo adduser USER sudo adduser USER ssh sudo adduser USER sudo sudo adduser USER admin
Limitando acesso ao ”’su”’
Para limitar o acesso ao comando “su” aos membros do grupo admin, devemos ajustar as permissões do “/bin/su”
sudo dpkg-statoverride --update --add root admin 4750 /bin/su
Configurando o processo de resolução de nomes
Ajustando o arquivo /etc/host.conf
Arquivo “/etc/host.conf” é o principal responsável por determinar como o host deve executar o processo de resolução de nomes; devemos ajusta-lo de forma que seu conteúdo fique semelhante à:
order bind,hosts multi on nospoof on spoofalert on
O multi on retornará todos os endereços IP resolvidos, ao invés do primeiro, o parâmetro nospoof on ativa a resolução reversa do nome da biblioteca resolv (para checar se o endereço pertence realmente à aquele nome) e o spoofalert on registra falhas desta operação no syslog.
Ajustando o Sysctl
O sysctl é utilizado para modificar os parâmetros do kernel em tempo de execução, o seu funcionamento está subordinado ao “procfs“, o qual disponibiliza o diretório “/proc/sys/“, que contem os parâmetros que podem ser lidos e escritos pelo sysctl.
O arquivo de configuração desta ferramenta é o “/etc/sysctl.conf“, desta forma precisamos edita-lo para adicionar as linhas abaixo após as ultimas existentes.
##------------------------------------------- # Ajustes de Seguranca ##------------------------------------------- # BOOLEAN Values: # a) 0 (zero) - disabled / no / false # b) Non zero - enabled / yes / true ##------------------------------------------- # Controls whether core dumps will append the PID to the core filename # Useful for debugging multi-threaded applications kernel.core_uses_pid = 1 #Enable ExecShield protection kernel.exec-shield = 1 kernel.randomize_va_space = 1 # increase system file descriptor limit fs.file-max = 65535 #Allow for more PIDs kernel.pid_max = 65536 ########## IPv4 networking start ############## # TCP and memory optimization # increase TCP max buffer size setable using setsockopt() #net.ipv4.tcp_rmem = 4096 87380 8388608 #net.ipv4.tcp_wmem = 4096 87380 8388608 # increase Linux auto tuning TCP buffer limits #net.core.rmem_max = 8388608 #net.core.wmem_max = 8388608 #net.core.netdev_max_backlog = 5000 #net.ipv4.tcp_window_scaling = 1 #Increase system IP port limits net.ipv4.ip_local_port_range = 2000 65000 # Controls IP packet forwarding net.ipv4.ip_forward = 0 # IP Spoofing protection net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # Ignore ICMP broadcast requests net.ipv4.icmp_echo_ignore_broadcasts = 1 # Disable source packet routing net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # Block SYN attacks net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 5 # Accept Redirects? No, this is not router net.ipv4.conf.all.secure_redirects = 0 # Ignore ICMP redirects net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 # Send redirects, if router, but this is just server # Ignore send redirects net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Log Martians (http://en.wikipedia.org/wiki/Martian_packet) net.ipv4.conf.all.log_martians = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 # Log packets with impossible addresses to kernel log? yes net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 # Ignore all ICMP ECHO and TIMESTAMP requests sent to it via broadcast/multicast net.ipv4.icmp_echo_ignore_broadcasts = 1 # Prevent against the common 'syn flood attack' net.ipv4.tcp_syncookies = 1 # Enable source validation by reversed path, as specified in RFC1812 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 ########## IPv6 networking start ############## # Disable IPv6 support net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 # Number of Router Solicitations to send until assuming no routers are present. # This is host and not router net.ipv6.conf.default.router_solicitations = 0 # Accept Router Preference in RA? net.ipv6.conf.default.accept_ra_rtr_pref = 0 # Learn Prefix Information in Router Advertisement net.ipv6.conf.default.accept_ra_pinfo = 0 # Setting controls whether the system will accept Hop Limit settings from a router advertisement net.ipv6.conf.default.accept_ra_defrtr = 0 #router advertisements can cause the system to assign a global unicast address to an interface net.ipv6.conf.default.autoconf = 0 #how many neighbor solicitations to send out per address? net.ipv6.conf.default.dad_transmits = 0 # How many global unicast IPv6 addresses can be assigned to each interface? net.ipv6.conf.default.max_addresses = 1
Depois de salvar o arquivo, devemos utilizar o comando abaixo para que o sistema leia as novas configurações
sudo sysctl -p
Configurando o servidor de SSH
Teoricamente o daemon do SSH deveria ter sido instalado junto com o sistema, mas caso ele ainda não esteja instalado, podemos utilizar o comando abaixo:
sudo apt install openssh-server
Depois de instalado, para configurar o serviço devemos editar o arquivo “/etc/ssh/sshd_config”
sudo nano /etc/ssh/sshd_config
Para evitar alguns ataques direcionados a porta padrão do SSH (22/TCP), vamos alterar a porta utilizada. Desta forma, a primeiro passo será comentar a linha abaixo:
Port 22
E acrescentar as seguintes linha no final do arquivo
## ---------------------------------------------------------------------- # Ajustes basicos ## ---------------------------------------------------------------------- # Arquivo: /etc/ssh/sshd_config ## ---------------------------------------------------------------------- Port 65222 PermitRootLogin no AllowTcpForwarding no #AllowGroups ssh AllowGroups admin users MaxStartups 5 MaxAuthTries 3 DebianBanner no PrintMotd yes PrintLastLog yes Banner /etc/issue.net UseDNS no
Para limitar as maquinas que poderão estabelecer uma conexão com o daemon devemos editar o arquivo /etc/hosts.allow
sudo nano /etc/hosts.allow
E adicionar as linhas:
## ---------------------------------------------------------------------- # Arquivo: /etc/hosts.allow ## ---------------------------------------------------------------------- sshd:192.0.2.
Para evitar que os dois arquivos de configuração sejam editados, por engano, vamos ajustar as suas permissões e protege-los.
sudo chmod 640 /etc/ssh/sshd_config sudo chattr +i /etc/ssh/sshd_config sudo chmod 644 /etc/hosts.allow sudo chattr +i /etc/hosts.allow
Quando os arquivo tiverem de ser editados, antes de tentar edita-los lembre-se de executar os comandos abaixo:
sudo chattr -i /etc/ssh/sshd_config sudo chattr -i /etc/hosts.allow
E depois de salvar as modificações volte a proteger os arquivos
sudo chattr +i /etc/ssh/sshd_config sudo chattr +i /etc/hosts.allow
Agora devemos reiniciar o daemon do ssh
sudo service ssh restart
E verificar se ele está ativo
sudo lsof -i:65222
Se nossa configuração funcionou o comando acima deve gerar uma saída informado que o serviço está escutando na porta 65222. Para finalizarmos o processo vamos realizar o mesmo teste na porta 22
sudo lsof -i:22
Neste caso o comando não deve retornar nenhuma informação, ou seja, a porta não está ativa.
Configurando o NTP Client
O protocolo/serviço NTP é uma das principais forma de mantermos o horário (marca do tempo) sincronizado, este protocolo baseia-se um uma estrutura hierárquica de fornecimento de hora, onde um servidor pode fornecer a marca de tempo para outra máquina que por sua vez compartilha esta informação com outras.
Nosso objetivo é instalar e configurar a versão cliente deste serviço, ou seja precisamos instalar alguns pacotes e em seguida configura-los. Para realizar a instalação do NTP podemos usar:
sudo apt install ntp ntpdate
Depois de instalado, devemos ajustar as configurações no NTP, que por padrão, estão contidas no arquivo ”/etc/ntp.conf”. Inicialmente precisamos comentar as linhas, ou seja adicionar o caracter “#” no início de cada uma das linhas abaixo:
Em maquinas baseadas em Debian
server 0.debian.pool.ntp.org iburst server 1.debian.pool.ntp.org iburst server 2.debian.pool.ntp.org iburst server 3.debian.pool.ntp.org iburst restrict -4 default kod notrap nomodify nopeer noquery restrict -6 default kod notrap nomodify nopeer noquery
Em maquinas baseadas no Ubuntu
pool 0.ubuntu.pool.ntp.org iburst pool 1.ubuntu.pool.ntp.org iburst pool 2.ubuntu.pool.ntp.org iburst pool 3.ubuntu.pool.ntp.org iburst pool ntp.ubuntu.com restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited
Dependendo da versão do sistema as linhas podem ser um pouco diferentes, mas a ideia é comentar todas as linhas que começam com “server“, com “pool” e as duas “restrict”
No Brasil os principais servidores de NTP são:
a.st1.ntp.br 200.160.7.186 2001:12ff:0:7::186 b.st1.ntp.br 201.49.148.135 c.st1.ntp.br 200.186.125.195 d.st1.ntp.br 200.20.186.76 a.ntp.br 200.160.0.8 2001:12ff::8 b.ntp.br 200.189.40.8 c.ntp.br 200.192.232.8 gps.ntp.br 200.160.7.193 2001:12ff:0:7::193
Para utilizar estes servidores devemos adicionar as seguintes linhas no final do arquivo de configuração do ntp
##------------------------------------------------ # Ajuste de seguranca ##------------------------------------------------ restrict -4 ignore restrict -6 ignore server 200.160.7.186 server 201.49.148.135 server 200.186.125.195 server 200.20.186.76 server 200.160.0.8 server 200.189.40.8 server 200.192.232.8 server 200.160.7.193
Antes de reiniciar o serviço do NTP, podemos realizar uma sincronização manual utilizando o comando:
sudo ntpdate -u 200.160.7.186
Em seguida podemos reiniciar o serviço do ntp
sudo service ntp restart
Para verificar o Status da sincronização podemos utilizar:
sudo ntpq -p
O qual deve gerar uma saida semelhante a:
remote refid st t when poll reach delay offset jitter ============================================================================== +ntp1.lncc.br 200.160.7.197 2 u 54 64 377 0.497 6.208 13.077 *ntp2.lncc.br 140.27.121.190 2 u 58 64 377 0.431 5.407 13.261
Instalando e configurando o Postfix
O próximo passo consiste na instalação do postfix, que será utilizado no envio das mensagens sobre o funcionamento e incidentes relacionados ao sistema. Para instala-lo execute o comando:
sudo apt install postfix ssl-cert
Durante a instalação, selecione Site da Internet e pressione Enter; verifique se o nome informado é o FQDN da máquina, se for pressione Enter, senão corrija-o e pressione Enter para prosseguir.
Com o postfix instalado, podemos configurá-lo de forma a enviar e-mails e aceitar conexões oriundas apenas da interface de loopback. Para isto precisamos editar o arquivo /etc/postfix/main.cf
sudo nano /etc/postfix/main.cf
Comentar a linha abaixo:
#inet_interfaces = all
E adicionar, no final do arquivo, as seguintes linha
## ---------------------------------------------------------------------- # Bind: IP e Porta ## ---------------------------------------------------------------------- inet_interfaces = 127.0.0.1 # Disable VRFY and/or EXPN on your Mailserver disable_vrfy_command=yes
Em seguida devemos reiniciar o daemon do postfix
sudo service postfix restart
E finalmente, podemos verificar se o serviço foi recarregado
sudo lsof -i:25
Depois que configuramos o postfix podemos, realizar um ultimo ajuste; o sistema Linux, pode informar sobre a ocorrência de vários eventos, estes avisos geralmente são enviados para contas específicas, para redirecionar a maioria destes avisos para a conta do root e dela para um outro e-mail devemos editar o arquivo “/etc/aliases”
sudo nano /etc/aliases
As linhas abaixo representam algumas das configurações que podemos utilizar. No exemplo abaixo, as mesagens encaminhadas para a conta de root serão enviada para o endereço user@gmail.com
postmaster: root mailer-daemon: postmaster nobody: root hostmaster: root usenet: root news: root webmaster: root www: root ftp: root abuse: root noc: root security: root root: user@gmail.com
Para aplicar as modificações, devemos executar o comando:
sudo newaliases
Podemos testar se as mensagens encaminhadas para a conta de root serão enviada para o endereço externo simplesmente enviando uma mensagem para o usuários root. Para isto, vamos precisar do aplicativo “mail“, cuja instalação pode ser realizada utilizando-se o comando:
sudo apt install mailutils
Finalmente, para enviar a mensagem podemos utilizar:
NOME_HOST=`hostname -f` echo "Testando o envio de mensagens a partir do host $NOME_HOST" | mail -s "Mensagem de teste (${NOME_HOST})" root
Desativando a rotação dos logs sobre as tentativas de acesso
O Ubuntu e vários outros sistemas Linux, geralmente, rotacionam mensalmente os logs relacionados as tentativas de acesso ao sistema, para inibir o “rotate” destes logs devemos editar o arquivo “/etc/logrotate.conf” e comentar as linhas abaixo:
#/var/log/wtmp { # missingok # monthly # create 0664 root utmp # rotate 1 #} #/var/log/btmp { # missingok # monthly # create 0660 root utmp # rotate 1 #}
Com isto da próxima vez que o comando logrotate for executado os arquivos “/var/log/wtmp” e “/var/log/btmp” não serão rotacionados