Upgrade 2.0

Transcrição

Upgrade 2.0
Coluna do Kurt
COLUNA
Upgrade 2.0
Atualizações constantes de segurança podem deixálo em paz, mas a inconveniência do processo de
baixar-instalar-reiniciar pode ser dolorosa. Veja como
manter o sistema atualizado sem precisar pará-lo.
E
xistem poucas coisas mais incômodas do que
testar algo e ver que um software teve sua versão
alterada inesperadamente. Por isso, eu desativo
as atualizações automáticas na minha máquina de testes com um Fedora 11. Porém, recentemente, quando
executei yum update, levei um pequeno choque: apesar
de já ter atualizado a máquina recentemente, ainda
havia 250 MB para baixar e instalar. Que bom que eu
tenho banda larga – se ainda usasse acesso discado, eu
estaria no mato sem cachorro.
exemplo, o binário httpd incluído no pacote do Apache
no Fedora 11 é um executável de 322 KB; contudo, o
bsdiff da atualização mais recente ocupa meros 8 KB.
Infelizmente, o bsdiff nem sempre funciona bem –
uma única alteração a uma chamada de função ou uma
nova função no início do binário pode resultar em dois
arquivos binários suficientemente diferentes para fazer
o patch grande demais (por exemplo, a comparação de
dois arquivos recentes do kernel do Fedora 11, cada um
com 1,8 MB, resulta num patch com 1,8 MB).
Menor é melhor
Melhor forma
Quem se importa se eu preciso baixar 100 MB toda
semana e eventualmente reiniciar o sistema para mantê-lo atualizado? Se as atualizações forem pequenas o
suficiente para não afetar a banda usada (no caso de
sistemas sem fio, isso significa mais duração da bateria),
é muito mais provável que você consiga automatizar as
atualizações e manter todos seguros. Além disso, com os
dispositivos embarcados tornando-se mais e mais complicados (executando Java, servidores web, de email e
assim por diante), há uma chance ainda maior de que
tudo isso precise de atualizações de segurança.
No caso de pacotes como RPM e DEB, uma solução
simples é não encostar nos arquivos que não tenham
sido alterados. Por exemplo, no Fedora 11, o pacote open­
office.org-core ocupa 92 MB, mas entre a versão original
e a primeira atualização desse arquivo há aproximadamente 30,3 MB de arquivos idênticos (imagens, arquivos
XML etc.), além do overhead de incluir esses arquivos
no RPM (informações de diretórios, hashes dos arquivos etc.). Mas mesmo isso ainda não é muito vantajoso.
Como deixar as atualizações realmente pequenas?
Ferramentas de diff binário como o bsdiff [1] podem ser
usadas para comparar dois arquivos executáveis e criar
um arquivo com as diferenças, que pode ser usado para
atualizar o binário antigo com esse pequeno diff. Por
18
O novo navegador web Google Chrome inclui uma função de atualização automática chamada Courgette [2],
que sem dúvida será incluída no sistema operacional da
empresa (uma plataforma leve sobre Linux com o navegador Chrome por cima). O Courgette basicamente
faz o mesmo que o bsdiff, mas com um pouco mais de
inteligência. Em vez de simplesmente comparar dois executáveis brutos no formato binário, o Courgette converte
os binários para um assembly primitivo e faz o diff nesse
nível. Ao subir um nível, o Courgette consegue comparar
as tabelas de símbolos dos executáveis com uma chance
muito maior de encontrar trechos semelhantes, o que
evidentemente resulta num patch menor. O Google
alega aproximadamente 90% de redução no tamanho
dos patches em comparação com o uso do bsdiff sozinho.
Embora resolva o problema do tamanho, essa solução
ainda tem o problema pegajoso de lidar com atualizações do kernel que exigem uma reinicialização. Apesar
de o kernel poder reiniciar rapidamente, alguns serviços
como o VMware e vários bancos de dados podem levar
alguns minutos para subir novamente. No caso de um
banco de dados, ele pode até levar horas para o cache
local ser devidamente populado.
Outros serviços, como VoIP, podem precisar permanecer em uso 24 horas por dia, sete dias por semana,
http://www.linuxmagazine.com.br
Insegurança | COLUNA
sem possibilidade de desligamento. Felizmente, esse
problema levou à criação do Ksplice [3]. O Ksplice é
relativamente simples na teoria. Ele cria um código
substituto (obtido na comparação com a atualização),
resolve símbolos do código substituto e em seguida verifica a segurança do patch (por exemplo, determinando se as funções substituídas não sofreram in-lining em
outros locais e se precisam de atualização nesses locais).
Depois, o Ksplice insere instruções jump (JMP) no
kernel original para apontar para o novo código, e – voilà – temos um kernel atualizado sem precisar reiniciar.
O interessante do Ksplice é que ele também pode ser
aplicado aos serviços que são executados no espaço do
usuário, o que poderia resultar, fatalmente, em sistemas capazes de ser atualizados sem desligar ou sequer
reiniciar serviços. Se você ficou com vontade de experimentar o Ksplice, ele está disponível para o Ubuntu
a partir do repositório no seu site [4].
Papel dos fornecedores
Por outro lado, por que os fornecedores não entregam
um arquivo completo e outro parcial com a atualização? Parte do problema é o overhead: como manter os
pacotes para todas as possíveis atualizações? Um arquivo
para cada atualização de versão (1.0 para a 1.1, outro da
1.1 para a 1.2, ou outro da 1.0 para a 1.2) ou apenas para
as principais mudanças de versão? A boa notícia é que
certas tecnologias relacionadas a atualizações, como a
geolocalização, estão sendo levadas em conta, e suspeito
que, conforme as ferramentas como Courgette e Ksplice
forem amadurecendo, veremos fornecedores abraçando-as.
O que fazer
Se você tem uma única máquina, não há muito a fazer
para reduzir o tamanho das atualizações. Se você tiver
duas ou mais máquinas (com o mesmo software), há
vários truques fáceis para diminuir o número de downloads e também o tempo gasto em cada atualização. A
maioria dos softwares de atualização baixa os pacotes
via HTTP, o que significa que é possível usar um proxy
web para tratar as requisições e fazer cache dos dados.
Obviamente, isso requer alterações significativas à configuração padrão, permitindo arquivos de até 100 MB
e com um cache bem grande, com vários gigabytes. A
vantagem disso é que é possível instalar um servidor
proxy transparente como o Squid [5] e evitar modificar
a configuração dos sistemas.
Outra estratégia eficaz é montar o diretório de atualizações num servidor central. Com um sistema baseado
em RPM, é preciso garantir que somente o diretório que
contém os pacotes seja compartilhado (isto é, /var/cache/
yum/updates/packages/). Se você compartilhar o diretório
Linux Magazine #59 | Outubro de 2009
/var/cache/yum/updates/, por exemplo, os diversos siste-
mas podem ficar chateados por compartilhar arquivos
como filelists.xml.gz.sqlite, pois estes não foram
feitos para acessos concorrentes de múltiplos sistemas.
No meu servidor principal, eu simplesmente ativo o
NFS com um /etc/exports com o seguinte conteúdo:
/var/cache/yum/base/packages *(rw,no_root_squash)
/var/cache/yum/updates/packages #(rw,no_root_squash)
Mas espere um minuto: qualquer um pode montar
esses diretórios e gravar neles como root?
O RPM oferece segurança de ponta a ponta na forma
de pacotes assinados. Então, se você ativar as verificações por GPG (gpgcheck=1) no arquivo yum.conf, você
descobrirá rapidamente se alguém alterou um pacote.
A vantagem de permitir que qualquer um escreva nesse
diretório central é que se um cliente iniciar uma atualização e baixar os pacotes, elas ficarão disponíveis para
todas as outras máquinas, incluindo o servidor.
E com isso finalmente simplificamos as instalações.
Em vez de instalar o sistema operacional e depois aplicar as atualizações, pode-se criar mídias de instalação
personalizadas com as atualizações já incluídas. Em instalações baseadas em RPM e Anaconda, pode-se alcançar isso com o comando createrepo [6] para criar novos
arquivos (normalmente contido no diretório repodata
do CD ou DVD de instalação). Simplesmente copie a
imagem .iso de instalação, copie os novos pacotes para
ela (e livre-se das velhas, pois você provavelmente vai
precisar desse espaço), execute createrepo e grave um
CD ou DVD novo para ter mídias de instalação com
pacotes atualizados. n
Mais informações
[1]Utilitários binários diff/patch:
http://www.daemonology.net/bsdiff/
[2]Courgette: http://dev.chromium.org/developers/
design-documents/software-updates-courgette
[3]Ksplice: http://www.ksplice.com/
[4]Pacote Ksplice do Ubuntu:
http://packages.ubuntu.com/jaunty/ksplice
[5]Squid: http://www.squid-cache.org/
[6]createrepo: http://createrepo.baseurl.org/
Kurt Seifried é consultor de segurança da informação especializado
em redes e Linux desde 1996. Ele frequentemente se pergunta como
a tecnologia funciona em grande escala mas costuma falhar em
pequena escala.
19