Ubuntu – Procedimentos de segurança (hardening) pós instalação

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