Ubuntu/Debian: Como instalar Nginx / Postfix / Dovecot a usar LibreSSL

LibreSSLVamos supor que tens um servidor Ubuntu ou Debian, a usar um ou mais entre o Nginx, Postfix e Dovecot, e queres “linká-los” ao LibreSSL em vez do OpenSSL default do sistema. (As razões podem ser várias: talvez porque a distro que usas ainda só inclui o OpenSSL 1.0.x, que é antigo (“estável”, do ponto de vista conservador) e não suporta cifras modernas como a ChaCha20, ou porque confias mais nos developers do OpenBSD (que fazem o LibreSSL) do que nos do OpenSSL, ou — e não há nada de errado com isso, é assim que se evolui — apenas pela piada da coisa. Podias também usar o OpenSSL 1.1.x, a ser abordado num post futuro.)

Segue-se, então, uma forma relativamente simples de o fazer, que não muda o OpenSSL default do sistema (o que não seria boa ideia, a não ser que recompilasses tudo, e estivesses disposto a ter muito trabalho):

Instalar dependências:

apt-get install build-essential
apt-get build-dep openssl nginx dovecot postfix

Instalar o LibreSSL:

  • faz o download da última versão do código fonte portável1 em www.libressl.org
  • compila e instala, fazendo:
./configure --prefix=/usr/local/libressl --with-openssldir=/usr/local/libressl && make && make install

Instala o Nginx:

rm -rf /usr/local/src/nginx-libressl
mkdir /usr/local/src/nginx-libressl
cd /usr/local/src/nginx-libressl
apt-get source nginx # ignora o erro de permissões no fim
  • edita o ficheiro nginx-<versão>/debian/rules:  adiciona
-I/usr/local/libressl/include

à linha que começa por “debian_cflags:=“, e:

-L/usr/local/libressl/lib

à linha que começa por “debian_ldflags:“. De seguida, entra na directoria nginx-<versão> e compila os pacotes com o comando:

debuild -uc -us -b
  • Instala os pacotes recém-criados na directoria anterior com o comando “dpkg -i <pacotes>” (sugestão: faz “dpkg -l | grep nginx” para ver que pacotes já tinhas instalados; tipicamente queres substituir esses pelas versões acabadas de compilar);
  • E, por último:
apt-mark hold nginx* # para impedir que actualizações do Ubuntu / Debian substituam as versões compiladas

Feito! Podes agora usar o Guia de TLS da Mozilla para adicionar suporte a cifras modernas à tua configuração de Nginx, e a Ferramenta de teste de servidores TLS da SSLLabs para verificar se estão correctamente configuradas.

Instalar o Postfix:

O processo é igual ao Nginx (substituindo “nginx” por “postfix” em cada comando / nome de directoria, obviamente), excepto que as alterações ao ficheiro debian/rules são as seguintes:

  • encontra  a linha com -DHAS_SSL, adiciona -I/usr/include/libressl/include/openssl à frenre;
  • encontra AUXLIBS += , acrescenta -L/usr/local/libressl/lib à frente;
  • encontra a linha com dh_shlibdeps -a, adiciona –dpkg-shlibdeps-params=–ignore-missing-info no fim;
  • não esquecer o apt-mark hold postfix* após a instalação dos novos pacotes.

Instalar o Dovecot:

Mais uma vez, adapta as instruções para o Nginx, uando “dovecot” em vez de “nginx” em cada sítio, excepto que as alterações ao debian/rules devem ser:

  • após a linha:
export DEB_BUILD_MAINT_OPTIONS=hardening=+all

adiciona:

export SSL_CFLAGS=-I/usr/local/libressl/include
export SSL_LIBS=-L/usr/local/libressl/lib -lssl -lcrypto
  • após a secção:
override_dh_makeshlibs:
# Do not add an ldconfig trigger; none of the dovecot shared libraries
# are public.
        dh_makeshlibs -n

acrescenta:

override_dh_shlibdeps:
        dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info

NOTA: a indentação na segunda linha tem de ser um tab; não utilizes espaços.

Uma vez mais, não esquecer o “apt-mark hold dovecot*” após a instalação.

Como verificar se as tuas novas instalações do Nginx, Postfix e/ou Dovecot estão a usar o LibreSSL em vez do OpenSSL default do sistema? Poderias usar o comando ldd para ver para que libraries de SSL/TLS os binários estão “linkados”, mas a melhor forma é provavelmente usar uma ferramenta como o sslscan, que permite ver que cifras os serviços de HTTPS, SMTP, IMAP, etc. suportam (incluindo através do STARTTLS). Se vires nessa lista a cifra ChaCha20, está tudo bem. A não ser, claro, quando eventualmente o Debian e o Ubuntu passarem a usar o OpenSSL 1.1.x por default (ainda não o fizeram, à data deste post), caso esse em que a cifra já estará lá à partida; nesse caso o melhor é mesmo usar o ldd.

Para voltar às versões “normais” destes serviços, basta fazer apt-mark unhold nginx* (por exemplo).

Adicionei também /usr/local/libressl/bin ao início da minha variável de ambiente PATH, de forma a que os binários do LibreSSL sejam usados por default (ex. para gerar chaves, CSRs, etc.), se bem que isto não é necessário para o Nginx, etc. funcionarem.

Hoje Aprendi Que: Grupos em Unix/Linux podem ter passwords

(Bem-vindo/a a uma nova secção no Zurgl-PT: Hoje Aprendi Que. Como o nome sugere, a ideia é partilhar coisas relacionadas com Linux que acabei de aprender (se bem que, tratando-se este post de uma tradução da versão em Inglês deste blog, o “acabei de” já tem uns meses, mas eventualmente este blog “apanhará” o outro), mesmo usando Linux há mais de 20 anos. Algumas dessas coisas podem ser relativamente básicas (como é o caso do que se segue) e até ser de conhecimento geral; mesmo assim, a “piada da coisa” é que fui capaz de trabalhar como um sysadmin Linux por duas décadas, além de administrar servidores pessoais há quase tanto tempo, e até usá-lo como desktop ocasionalmente, e consegui fazê-lo até agora sem necessitar de aprender isto.)

Sabias que grupos em Linux/Unix (não me refiro a utilizadores) podem também ter passwords? Por default não as têm, mas o comando groupadd tem uma opção “-p” (que requer uma password já encriptada, pelo que é necessário encriptá-la primeiro e depois fazer “pipe” dela para o comando). Existe também um comando gpasswd.

Supostamente, a ideia de passwords de grupo é permitir que utilizadores se consigam eles próprios juntar a um grupo protegido por password com o comando newgrp, desde que saibam/introduzam a password correcta. Se o grupo não tiver password, então só alguém com acesso de root é que consegue adicionar um utilizador ao mesmo.

(O comando newgrp também permite que o utilizador altere o seu grupo primário para o resto da sua sessão, desde que esse seja um dos seus grupos secundários.)

Linux: Como criar um Volume Group com todos os discos acabados de adicionar

Vamos supor que acabaste de adicionar um ou mais discos a um sistema Linux (físico ou virtual), e que queres criar um volume group chamado “vgdata” composto por todos eles — ou adicioná-los a esse VG caso ele já exista.

Pela piada da coisa, vamos também supor que queres fazer isto para vários sistemas ao mesmo tempo, e que há bastante heterogeneidade entre eles — uns podem já ter o VG “vgdata” e outros não, e uns podem ter tido apenas um disco adicionado, quando outros tiveram vários. Como scriptar isto?

#!/bin/bash

# cria partições LVM de tamanho máximo em todas as drives sem partições; cria também PVs para elas
for i in b c d e f g h i j k l m n o p q r s t u v w x y z; do sfdisk -s /dev/sd$i >/dev/null 2>&1 && ( sfdisk -s /dev/sd${i}1 >/dev/null 2>&1 || ( parted /dev/sd$i mklabel msdos && parted -a optimal /dev/sd$i mkpart primary ext4 "0%" "100%" && parted -s /dev/sd$i set 1 lvm on && pvcreate /dev/sd${i}1 ) ) ; done

# se o VG "vgdata" existe, estende-o com todos os PVs não usados...
vgs | grep -q vgdata && pvs --no-headings -o pv_name -S vg_name="" | sed 's/^ *//g' | xargs vgextend vgdata

# ... caso contrário, cria-o com esses mesmos PVs
vgs | grep -q vgdata || pvs --no-headings -o pv_name -S vg_name="" | sed 's/^ *//g' | xargs vgcreate vgdata

Como sempre, podes usar o sistema de automatização da tua empresa para correr isto numa lista de servidores, ou usar o pssh, ou um ciclo “for” em bash, ou…

Linux: Como encontrar utilizadores com acesso total de sudo (numa lista de máquinas)

(Nota: há, de certeza, formas bem melhores de fazer isto — está à vontade para sugerir algumas nos comentários. Isto é apenas um script que escrevi há tempos, quando um colega de trabalho perguntou se haveria uma forma de fazer isto para os servidores que administramos.)

A situação: administras 1000 ou mais servidores, e tu a tua equipa são os únicos que supostamente devem poder fazer “sudo su” para root (ao invés de apenas correr comandos específicos, em geral relacionados com aplicações administradas por outras equipas, o que normalmente não é um problema). No entanto, às vezes é conveniente fornecer temporariamente acesso total de root a um utilizador ou grupo de utilizadores, por exemplo para fazer a instalação inicial das aplicações, mas depois esse acesso é retirado quando a máquina passa a produção.

O problema: é fácil esquecermo-nos disso, e dessa forma o acesso temporário torna-se permanente (sim, há outras formas de contornar isso, como o uso de uma sintaxe específica para esses acessos que inclui um comentário no fim da linha, em combinação com um comando configurado no daemon de “at” para retirar o acesso no fim do período temporário, mas para já vamos pôr isso de parte). Não seria útil a capacidade de passar por um grupo de máquinas, possivelmente até todo o parque Linux da empresa, e detectar esses acessos de sudo “esquecidos”?

Continuar a ler “Linux: Como encontrar utilizadores com acesso total de sudo (numa lista de máquinas)”

Red Hat / CentOS: Como listar RPMs instalados no ano X

Auditor paranóico 2“Preciso de uma lista de todos os RPMs instalados este ano nestes servidores!”

Tu: “OK, deixa ver…”

Numa máquina específica:

for i in `rpm -qa`; do rpm -qi $i | grep Install | grep -q 2018 && echo $i; done

(Substituindo “2018” pelo ano desejado, obviamente.)

Para fazer em vários servidores, podes usar uma combinação de ciclo “for” em bash e ssh, ou o pssh, ou alguma ferramenta de automatização da tua empresa, ou…

Como actualizar o Red Hat Enterprise Linux (RHEL) ou o CentOS sem mudar de “minor version”

Se és um administrador de sistemas Linux, ou mesmo um “mero” utilizador, e utilizas ou já utilizaste sistemas tipo Red Hat, provavelmente já reparaste que ao fazer “yum update” o sistema frequentemente muda de versão (ex. 6.7 para 6.9). Para ser exacto, o comando actualiza o sistema para a última “minor version” (o número depois do ponto) da “major version” (o número antes do ponto) actualmente instalada.

Talvez já tenhas perguntado a ti mesmo se não é possível fazer uma actualização ao sistema que “pare” antes de mudar a versão. Mais frequentemente, terão sido outros a pedir-te isso: um chefe medroso, ou uma equipa aplicacional que dê importância a questões tipo “o fabricante diz que só suporta até à versão 7.1, não podemos passar disso”.

Antes de continuar, tenho de dizer que não há em geral nenhuma razão técnica para fazer isto (com algumas excepções mencionadas por um comentador na versão original deste artigo), e espero que tenhas chegado aqui porque um chefe, gestor de projecto ou developer o exigiu, e não trabalhas (“ainda”, espero 🙂 ) num sítio onde possas dizer “não, isso é estúpido, não o vou fazer“, ou simplesmente por curiosidade científica.

As “minor versions” do Red Hat (ou CentOS) não são realmente “versões” no significado habitual da palavra, em que são incluídas novas versões de aplicações, libraries, etc., com possíveis questões de compatibilidade. Ao invés disso (com algumas excepções em geral relacionadas com o uso como desktop, como por exemplo web browsers), a Red Hat tem o cuidado de  resolver problemas de segurança e outros bugs. Se olhares para as versões dos pacotes, quer estejas num Red Hat 6.0 ou 6.9, elas mantêm-se sempre, só aumentando o “número Red Hat” (ex. file-5.11-21.el7). Devido a isto, não se põem questões de compatibilidade; podem apenas haver questões de “suporte oficial”, o que em geral é sinónimo de “testámos o nosso produto com esta versão, e não queremos ter trabalho de o testar com outras.”

Desculpem o desabafo. 🙂 Portanto, sendo tu um sysadmin competente, vou assumir que te estão a obrigar a fazer isto. Eis como:

Com o Satellite:

Para ver que versões estão disponíveis:

subscription-manager release --list

Exemplo:

# subscription-manager release --list
+-------------------------------------------+
 Available Releases
+-------------------------------------------+
5.11
5Server
6.2
6.7
6.8
6.9
6Server
7.0
7.1
7.2
7.3
7Server

Para “trancar” o sistema numa versão (ex. 7.1):

subscription-manager release --set=7.1

E para “destrancar”:

subscription-manager release --unset

(ou talvez –set=7Server)

Sem o Satellite:

Para uma única actualização, adiciona –releasever=x.y ao teu comando “yum”; por exemplo:

yum --releasever=7.1 update

Para tornar isso permanente, adiciona:

distroverpkg=x.y

à secção [main] do teu ficheiro /etc/yum.conf.

Nota: pelo menos no caso do CentOS, desde a versão 7 que as versões não são apenas “x.y”, mas incluem um terceiro número, aparentemente o ano e data do lançamento. Browsando em http://vault.centos.org/centos/ , por exemplo, vê-se que estão disponíveis estas versões:

[DIR] 6.7/ 21-Jan-2016 13:22 - 
[DIR] 6.8/ 24-May-2016 17:36 - 
[DIR] 6.9/ 10-Apr-2017 12:48 - 
[DIR] 6/ 10-Apr-2017 12:48 - 
[DIR] 7.0.1406/ 07-Apr-2015 14:36 - 
[DIR] 7.1.1503/ 13-Nov-2015 13:01 - 
[DIR] 7.2.1511/ 18-May-2016 16:48 - 
[DIR] 7.3.1611/ 20-Feb-2017 22:23 - 
[DIR] 7/ 20-Feb-2017 22:23 -

E, sim, é necessário especificar o terceiro número no teu comando/ficheiro de configuração.

Podes também ter de activar as várias entradas no teu ficheiro /etc/yum.repos.d/CentOS-Vault.repo file (altera a opção enabled=0 para 1).

Fontes: 1

Bem vindo/a ao Zurgl-PT!

Para mais detalhes sobre o blog, ver a página Sobre o Zurgl-PT. 🙂

De resto, a ideia é ir traduzindo para Português (Europeu, a minha língua nativa) os posts (em Inglês) do Zurgl, idealmente mais rapidamente do que escrevo lá posts novos, de forma a eventualmente os dois blogs estarem “lado a lado”, e cada post novo num ter imediatamente o correspondente no outro (provavelmente escreverei primeiro em Inglês; por alguma estranha razão gosto mais de traduzir no sentido EN->PT do que o inverso).

Qualquer questão, está à vontade para me contactar, ou escrever um comentário.