CAPA
Um dentro do outro
Atualmente, virtualização é a palavra da vez. Porém, do ponto de vista da segurança, existem alguns aspectos importantes a considerar.
por Thorsten Scherf
Num primeiro momento, alguns administradores de sistemas podem se assustar com o esforço necessário para garantir a segurança de sistemas virtualizados.
O mais curioso é que todos os for- necedores desse tipo de tecnologia usam o argumento da segurança em favor da sua adoção. Afinal, com o uso de máquinas virtuais é muito simples estabelecer uma separação entre os diversos serviços.
Se antes eram necessários dois computadores para separar o servidor web e o banco de dados, a virtuali- zação permite tudo isso com apenas
uma máquina física, que por sua vez serve de base para quantas máquinas virtuais o administrador desejar – e o hardware permitir. Entretanto, como em tudo na vida, é nos pe- quenos detalhes que se escondem os maiores problemas: há mais questões envolvidas na virtualização do que se supunha em primeira instância.
Este artigo fornece um panorama geral dos diferentes aspectos de se- gurança envolvidos na implementa- ção e na manutenção de ambientes virtualizados.
Na maioria das distribuições Li- nux, o acesso ao hypervisor – ou seja,
o programa responsável pela virtua- lização propriamente dita – utiliza como base a biblioteca Libvirt [1], que cria uma camada entre o siste- ma de virtualização e o espaço de usuário. Com isso, o usuário con- segue manipular qualquer um dos sistemas de virtualização por meio de ferramentas de administração pa- dronizadas. Além de fornecer suporte ao Xen e ao KVM/QEMU, a Libvirt ainda suporta o LXC, o OpenVZ, o UML e o VirtualBox.
Por sua vez, as ferramentas virt- manager, virt-install e virsh permitem ao administrador gerenciar, instalar e monitorar máquinas virtuais, in- dependentemente da tecnologia de virtualização utilizada.
Ferramentas de gerenciamento
Com as ferramentas virt-manager e virt-install, é muito simples criar e administrar máquinas virtuais. Na configuração padrão, elas se conec- tam ao hypervisor da mesma máquina em que foram iniciadas. Entretanto, também é possível estabelecer uma conexão com um hypervisor remoto.
Quem não quiser que os dados de acesso e de usuário sejam transmi- tidos pela rede em texto puro pode fazê-lo por meio de uma conexão Figura 1 Com o virt-manager, o administrador tem à mão diferentes formas
de se autenticar em um hypervisor remoto.
segura: as opções são SSH, TLS/
SSL com certificados X.509 e Ker- beros. No exemplo deste artigo, os dados serão enviados através de um túnel SSH seguro (figura 1). Para isso, é necessário que exista um par de chaves SSH na máquina onde o virt-manager estiver sendo executado:
ssh-keygen -t das
ssh-copy-id -i ~/.ssh/id_dsa.pub root@exemplo.remoto.com
Em seguida, é necessário ter certe- za de que tanto o servidor SSH quanto o da Libvirt estejam ativos. Com o comando virt-manager, pode-se ver a conexão segura recém estabeleci- da para acessar o hypervisor remoto por meio da Libvirt e gerenciar as máquinas virtuais existentes na má- quina remota – além de criar novas.
Também é possível criar instâncias de máquinas virtuais pelo comando virt-install. A listagem 1 exibe um exemplo de instalação de máquina virtual em um computador remoto.
Rede virtual
Nesse exemplo, a máquina virtual recém criada usa uma rede chama- da default, uma rede virtual que faz parte da configuração padrão da Libvirt. Com a ferramenta virsh, pode-se mostrar como essa rede está configurada (listagem 2).
Assim, um endereço IP da rede 192.168.122.0/24 é alocado para a máquina virtual. O serviço res- ponsável por isso é o dnsmasq. Por meio do dispositivo de rede virbr0 do sistema real, a máquina virtual pode se comunicar com o mundo externo via source NAT (SNAT).
Para tráfego de fora para dentro da rede é necessário definir as regras de NAT adequadas (destination NAT ou DNAT).
As regras de SNAT são criadas por padrão pela Libvirt, conforme mostra o comando iptables -t nat -L POSTROUTING:
Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 192.168.122.0/24
!192.168.122.0/24
Às vezes, entretanto, a comunica- ção com redes externas não é dese- jável. Por exemplo, por que o banco de dados deveria estar aberto a soli- citações do mundo externo? Em vez disso, seria mais adequado instalar duas placas de rede no servidor de Internet. A primeira se comunicaria com redes externas via NAT e a se- gunda faria parte de uma rede virtual própria, que incluiria o próprio ser-
vidor de banco de dados. Para essa rede virtual, não há qualquer tipo de NAT. Para isso, é necessário pri- meiramente configurar a nova rede (listagem 3). Em seguida, o virsh faz com que o arquivo de configu- ração assim produzido seja incluído na configuração da Libvirt e ative a rede (listagem 4).
Isolamento total
Na sequência, é possível alocar uma segunda placa de rede ao servidor de Internet e conectá-lo a essa rede.
Durante o processo de implementa- ção do servidor de banco de dados,
Listagem 1: Novas VMs com o virt-install
01 virt-install \ 02 --hvm
03 --connect qemu+ssh://root@remote.example.com/system 04 --name demo \
05 --ram 512 \
06 --disk path=/var/lib/libvirt/images/demo.img,size=10 \ 07 --network network:default \
08 --vnc \
09 --location ftp://local.example.com/pub/fedora/f11/
10 --extra-args ks=ftp://local.example.com/pub/ks/fedora.cfgv
Listagem 2: O virsch mostra as configurações da VM
01 $ virsh net-dumpxml default 02 <network>
03 <name>default</name>
04 <uuid>478de122-05dc-4d12-b7f0-52349b59f8ef</uuid>
05 <forward mode=’nat’/>
06 <bridge name=’virbr0’ stp=’on’ forwardDelay=’0’ />
07 <ip address=’192.168.122.1’ netmask=’255.255.255.0’>
08 <dhcp>
09 <range start=’192.168.122.2’ end=’192.168.122.254’ />
10 </dhcp>
11 </ip>
12 </network>
Listagem 3: Rede privada da VM
01 $ cat > /tmp/private-net <<EOF 02 <network>
03 <name>private-net</name>
04 <uuid>478d1122-05dc-4d12-b7f0-5234911911ef</uuid>
05 <ip address=’192.168.130.1’ netmask=’255.255.255.0’>
06 <dhcp>
07 <range start=’192.168.130.2’ end=’192.168.130.254’ />
08 </dhcp>
09 </ip>
10 </network>
11 EOF
o administrador pode usar essa nova rede já na instalação. Dessa forma, é até possível que o servidor de In- ternet se comunique com o mundo externo, apesar de a comunicação do servidor de banco de dados estar limitada apenas aos computadores conectados à rede privada.
Como fica a configuração caso o administrador não deseje usar uma rede virtual, mas queira integrar os computadores a uma rede já existen-
te? Neste caso, ele pode configurar uma bridge, que é incluída na con- figuração da Libvirt. Na maioria dos casos, os pacotes de rede das diferentes máquinas virtuais devem permanecer separados – especialmente quando as máquinas funcionam de maneira totalmente independente.
Imagine então como fica uma instalação dessas em um provedor de Internet. Nesse caso, provavelmente nenhum cliente vai querer que al-
gum outro seja capaz de monitorar o seu tráfego de rede. Uma das solu- ções possíveis seria o uso de VLANs (LANs virtuais) com máquinas vir- tuais conectadas a elas, conforme a necessidade. Para fazer isso, basta conectar o dispositivo da VLAN à bridge correspondente.
No próximo exemplo, temos dois sistemas de clientes que devem ser mantidos separados. Um deles está conectado a uma VLAN com o ró- tulo 100, ao passo que a outra VLAN usa o rótulo 200. Nos dois casos é ne- cessário primeiramente realizarmos a configuração das placas de rede (listagem 5). Em seguida, o admi- nistrador precisa criar os dispositivos de bridge necessários (listagem 6).
Após reiniciarmos as redes, as novas bridges deverão estar disponíveis. O comando brctl serve para confirmar essa disponibilidade (listagem 7).
Caso o administrador instale ago- ra uma máquina virtual e deseje conectá-la à VLAN 100, ele pode fazê-lo com o comando virt-install --network bridge:br100. Alternativa- mente, o virt-manager oferece ao usuário as novas bridges por meio de uma interface gráfica com um menu pull-down.
Alta disponibilidade
Uma configuração segura também é à prova de falhas de hardware. Como esse é um tema bastante abrangen- te, vamos fornecer aqui apenas dois exemplos. Na configuração mencio- nada acima, é possível concatenar as duas interfaces de rede em um dispositivo de bonding. Conforme o modo de bonding escolhido, os paco- tes serão enviados de forma paralela ou intercalada pelas duas placas de rede. Para uma configuração como essa, é preciso primeiramente alocar um dispositivo de bonding para as duas placas:
$ cat > /etc/sysconfig/network- scripts/ifcfg-eth0 <<EOF
Listagem 5: Configuração de VLAN
01 $ cat > /etc/sysconfig/network-scripts/ifcfg-eth0.100 <<EOF 02 DEVICE=eth0.100
03 ONBOOT=yes 04 BRIDGE=br100 05 VLAN=yes 06 EOF
0708 $ cat > /etc/sysconfig/network-scripts/ifcfg-eth0.200 <<EOF 09 DEVICE=eth0.200
10 ONBOOT=yes 11 BRIDGE=br200 12 VLAN=yes 13 EOF
Listagem 6: Dispositivos de bridge
01 $ cat > /etc/sysconfig/network-scripts/ifcfg-br100 <<EOF 02 DEVICE=br100
03 BOOTPROTO=static 04 IPADDR=192.168.100.1 05 NETMASK=255.255.255.0 06 ONBOOT=yes
07 TYPE=Bridge
01 $ cat > /etc/sysconfig/network-scripts/ifcfg-br200 <<EOF 02 DEVICE=br200
03 BOOTPROTO=static 04 IPADDR=192.168.200.1 05 NETMASK=255.255.255.0 06 ONBOOT=yes
07 TYPE=Bridge
Listagem 4: Ativação da rede
01 $ virsh net-define /tmp/private-net
02 Network private-net defined from /tmp/private-net 0304 $ virsh net-start private-net
05 Network private-net started 0607 [root@tiffy ~]# virsh net-list 08 Name State Autostart 09 --- 10 default active yes 11 private-net active no
DEVICE=eth0 ONBOOT=yes MASTER=bond0 SLAVE=yes BOOTPROTO=none
Para a segunda placa de rede – eth1 –, essa configuração tem a mesma
“cara”. A configuração do dispositivo de bonding fica como segue:
$ cat > /etc/sysconfig/network- scripts/ifcfg-bond0 <<EOF DEVICE=bond0
BOOTPROTO=none ONBOOT=yes TYPE=Ethernet
BONDING_OPTS=”mode=1 miimon=100”
EOF
Nas opções de bonding, escolhe- mos o modo 1 (balance-RR), na qual os pacotes trafegam alternadamente por ambas as placas de rede. Com a opção miimon=100, o driver do disposi- tivo de bonding é instruído a testar a cada 100 ms se as placas ainda estão conectadas à rede. Caso uma das pla- cas perca o link, o driver “percebe”
isso quase imediatamente e para de enviar pacotes por aquele dispositivo de rede. No arquivo /etc/modprobe.
conf, o administrador pode determi- nar que o dispositivo virtual bond0 deverá utilizar o driver de bonding com a diretiva alias bond0 bonding.
O dispositivo de bonding pode ser utilizado simplesmente como uma interface de rede comum, o que sig- nifica que podemos alocar normal- mente um endereço IP a ele, bem como associá-lo a diferentes VLANs.
O que vale para a rede também vale para outros componentes, como a infraestrutura de armazanamen- to. Independentemente de essa infraestrutura utilizar um arquivo de imagem ou um dispositivo de blocos para armazenar as máquinas virtuais, sua disponibilidade deveria ser garantida, de modo a evitar para- das no serviço em caso de panes de
hardware. O modo mais simples de fazer isso é utilizar sistemas RAID, de preferência em uma configura- ção multipath, caso os dispositivos de blocos se localizem numa SAN (storage area network).
O resto deste artigo descreve um método de baixo custo baseado no protocolo iSCSI, no qual o servidor iSCSI disponibiliza na rede um dis- positivo RAID1 via software. Antes da instalação de uma nova máquina virtual, o administrador pode conec- tar o dispositivo iSCSI à rede. Para a comunicação via protocolo iSCSI
é recomendável utilizar uma rede separada, à qual as placas de rede deverão novamente ser unidas em dispositivos de bonding. A configu- ração do servidor iSCSI no modo RAID1 e a sua disponibilização são mostradas na listagem 8.
O último comando tgtadm mos- trado na listagem 8 permite o acesso ao dispositivo iSCSI para uma única máquina ou rede determinada – tam- bém é prudente restringir o acesso à rede iSCSI. As ferramentas de ge- renciamento de dispositivos iSCSI podem ser encontradas na maioria
Listagem 8: iSCSI
01 # mdadm -C /dev/md0 -l 1 -n 2 /dev/sdb /dev/sdc 02 # chkconfig tgtd on; service tgtd start
03 # tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2009-05.com.example:storage.iscsi.disk1
04 # tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/md0
05 # tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
Listagem 9: Informações de dispositivos iSCSI
01 $ tgtadm --lld iscsi --op show --mode target
02 Target 1: iqn.2009-05.com.example:storage.iscsi.disk1 03 System information:
04 Driver: iscsi 05 Status: running 06 I_T nexus information:
07 LUN information:
08 LUN: 0
09 Type: controller 10 SCSI ID: deadbeaf1:0 11 SCSI SN: beaf10 12 Size: 0
13 Backing store: No backing store 14 LUN: 1
15 Type: disk
16 SCSI ID: deadbeaf1:1 17 SCSI SN: beaf11 18 Size: 100G
19 Backing store: /dev/md0 20 Account information:
21 ACL information:
22 ALL
Listagem 7: Comando brctl
01 $ brctl show
02 bridge name bridge id STP enabled interfaces 03 br100 8000.000e0cb30440 no eth0.100
04 br200 8000.000e0cb30450 no eth0.200
das distribuições Linux, nos pacotes iscsitarget e scsi-target-utils. Uma vez que o dispositivo iSCSI esteja funcionando, pode-se listar algumas de suas informações (listagem 9). O administrador pode então conectar o dispositivo iSCSI à máquina real.
Para isso, é necessário usar o pacote iscsi-initiator-utils. O acesso ao dis- positivo é feito com os comandos mostrados na listagem 10.
Se tudo estiver funcionando cor- retamente, o comando fdisk na má- quina real deve mostrar não apenas o disco rígido local, mas também o dispositivo iSCSI exportado como /dev/sda na lista de dispositivos dis- poníveis. Caso o disco rígido local seja SCSI ou SATA, o nome do dis- positivo /dev/sda já deverá ter sido alocado para ele, e o dispositivo iSCSI receberá automaticamente o nome do próximo dispositivo livre (provavelmente /dev/sdb).
Ao instalar novas máquinas vir- tuais, elas poderão utilizar esse dis- positivo iSCSI como infraestrutura de armazenamento. Isso ocorre por meio da opção --disk path=/dev/sdX do virt-install. Da mesma maneira, o virt-manager permite que um novo
dispositivo de blocos seja alocado a uma máquina virtual. Graças ao espelhamento do RAID escolhido no servidor iSCSI, o sistema está protegido contra panes de hardware.
Problemas com o hypervisor
De nada serve a melhor das configu- rações se o hypervisor contiver erros.
Se este for o caso, dependendo das circunstâncias, uma máquina virtual pode acabar acessando recursos de uma outra. No pior dos casos, um processo executado em uma máquina virtual poderia ganhar acesso ao siste- ma real e, com isso, acessar também todas as outras máquinas virtuais.
Isso não é nenhuma teoria da cons- piração, como mostraram artigos de vários especialistas nos últimos meses [2]. Com o propósito de limitar ao máximo as consequências de falhas do hypervisor, alguns desenvolvedo- res incluíram, em março de 2009, um dispositivo de segurança no fra- mework da Libvirt (figura 3). Esse dispositivo de segurança baseia-se em uma política de acesso conhecida como Controle de Acesso Obrigatório
(Mandatory Access Control, ou MAC – veja o artigo “Pequeno por fora, se- guro por dentro” à página 40 desta edição). Isso significa que um sistema de controle central determina com precisão as permissões de acesso de uma determinada máquina virtual a cada recurso.
A decisão de liberar ou impedir o acesso é independente do usuário que executa a máquina. Essa esco- lha depende de “rótulos” atribuídos às máquinas virtuais e também dos recursos disponíveis – se essa técnica parece familiar, é porque o sistema MAC da libvirt será o SELinux.
De modo geral, seria possível utili- zar qualquer outro tipo de sistema MAC – tal como o Smack (confira o artigo “Pequeno por fora, seguro por dentro”) –, mas, no estágio atu- al de desenvolvimento do sistema, apenas o SE Linux está disponível para essa função.
Um ponto importante entre os ob- jetivos do projeto foi aprender com os erros das primeiras implementa- ções do SE Linux, tornando toda a sua configuração mais amigável. E de fato esse objetivo foi alcançado:
a configuração do sistema é total- mente feita em segundo plano, de forma transparente para o usuário.
Esses avanços apareceram primeira- mente no Fedora 11 [3] sob o nome de SVirt [4].
Durante a instalação de uma nova máquina, automaticamente são alocadas à infraestrutura de ar- mazenamento duas categorias alea- tórias de MCS do SE Linux (MCS é o acrônimo para Multi Category Security [5]): neste exemplo, c230 e c794. Diferentemente do MCS clás- sico, não há qualquer mapeamento entre essas categorias e um rótulo
Listagem 11: Comando virsh dominfo fedora
01 $ virsh dominfo fedora 02 Id: 18 03 Name: fedora
04 UUID: be8b4a9a-492a-db25-7aed-f831d-cec9127 05 OS Type: hvm
06 State: running 07 CPU(s): 4 08 CPU time: 4591.8s 09 Max memory: 2014400 kB 10 Used memory: 2014208 kB 11 Autostart: disable 12 Security model: selinux 13 Security DOI: 0
14 Security label: system_u:system_r:svirt_t:s0:c230,c794 (permissive)
Listagem 10: Uso do iSCSI
01 # chkconfig iscsi on; service iscsi start
02 # iscsiadm -m discovery -t st -p iscsi.example.com iqn.2009-05.com.example:storage.iscsi.disk1 03 # iscsiadm -m node -T iqn.2009-05.com.example:storage.iscsi.disk1 -p iscsi.example.com -l
tradicional. Com a definição de duas categorias por máquina virtual tam- bém é possível executar mais de mil máquinas virtuais por máquina real usando o SVirt:
ls -lZ /var/lib/libvirt/images/
-rw––-. root root
system_u:object_r:svirt_
image_t:s0:c230,c794 fedora.img -rw––-. root root
system_u:object_r:svirt_
image_t:s0:c325,c811 rhel5.img A partir deste momento, somente processos que pertençam à mesma categoria do recurso em questão (a infraestrutura de armazenamento, no caso) terão permissão para acessá-lo.
Na configuração das máquinas vir- tuais são listadas as categorias MCS acessíveis às quais essa máquina vir- tual tem acesso (listagem 11).
Durante a inicialização da má- quina virtual, o serviço Libvirt cuida para que ela seja alocada na catego- ria correta:
ps -AZ|grep qemu
system_u:system_r:svirt_t:s0:c230, c794 17235 ? 00:00:01 qemu-kvm
Conforme configurado, a má- quina virtual tem acesso somente ao arquivo de imagem fedora.img. Um acesso ao arquivo rhel5.img seria negado com uma mensagem AVC- Deny – supondo-se, naturalmente, que a máquina real esteja configu- rada com o SE Linux em modo de efetivação (enforcing mode).
Na versão atual do SVirt, somente objetos de arquivo e máquinas vir- tuais ganham rótulos. Com isso, o controle de acesso rigoroso ocorre somente entre máquinas virtuais, processos e as infraestruturas de armazenamento correspondentes.
No futuro, outros recursos também deverão ser suportados, como obje- tos de rede. A partir de então será possível, por exemplo, permitir o
acesso somente a determinadas por- tas de rede de uma máquina virtual.
O suporte ao acesso transparente a dispositivos PCI e USB também tem prioridade na lista dos desen- volvedores do SVirt – que, como podemos ver, está em ritmo frené- tico de desenvolvimento.
Conclusão
O uso de máquinas virtuais traz uma lista quase interminável de vanta- gens. Além do custo economizado com energia e espaço no data center,
com a configuração correta – no ge- ral – o administrador não precisa se preocupar com a segurança das má- quinas virtuais. É importante ter em mente, entretanto, que a segurança de um ou vários sistemas, sejam eles reais ou virtualizados, não é um pro- cesso fechado. Vale a regra de ouro:
estar informado e atualizado com as últimas correções de segurança que, inevitavelmente, terão que ser instaladas, em vez de acreditar cega- mente nas afirmações do fabricante da tecnologia utilizada. n
Mais informações
[1] Página do projeto Libvirt: http://libvirt.org/
[2] Joanna Rutkowska, “0wning Xen in Vegas”: http://
theinvisiblethings.blogspot.com/2008/07/0wning-xen-in-vegas.html [3] Projeto Fedora: http://fedoraproject.org/
[4] SVirt: http://selinuxproject.org/page/SVirt/
[5] Multi-Category-Security:
http://fedoraproject.org/wiki/SELinux/MCS/
Gostou do artigo?
Queremos ouvir sua opinião. Fale conosco em cartas@linuxmagazine.com.br
Este artigo no nosso site:
http://lnm.com.br/article/2972
Drivers
Hypervisor Hypervisors
Xen KVM OpenVZ
LXC UML
I-SCSI NFS Lógico
FS
Segurança SE Linux
etc.
Virsh Virt-Manager
API Armazenamento
Armazenamento Disco
Anfitrião
Hóspede Hóspede Hóspede
Figura 2 A versão mais recente da Libvirt oferece um módulo de segurança próprio.