Como atribuir vários endereços IP públicos para 2 convidados KVM

4

Sou novo em todo este tópico e tento há dias descobrir como atribuir vários endereços IP públicos a convidados KVM através de um host KVM. Eu encontrei muitos exemplos de como obter essa configuração com 1 IP público em execução.

Aqui está minha configuração: O servidor tem apenas um NIC / MAC e executa 2 KVM-Guests com o apache (e outras coisas). Ambos os ambientes convidados são o servidor Ubuntu 11.10 e devem ser executados em VMs separadas. Os 5 endereços IP públicos são usados para lidar com certificados SSL e outras coisas. A primeira VM deve usar 3 dos 5 endereços / certificados. A segunda VM obtém o restante. O material do apache está configurado corretamente.

Eu tentei várias maneiras diferentes através do iptables para rotear o tráfego da NIC dos hosts para as NICs convidadas. Apesar do fato de que um caminho era o certo, mas apenas o mal implementado, deixo os detalhes não revelados para deixá-lo despreparado. A pergunta é: qual é a maneira ideal de fazer isso?

As seguintes condições devem ser atendidas:

  • O Apache deve obter o endereço IP original do visitante
  • O Apache precisa saber qual endereço de IP público foi ultilizado para usar o SSL-vhost correto
  • O tráfego não deve ser roteado por meio de um proxy (reverso) no host, pois há outros dois serviços não http, em outros convidados da VM, que devem estar acessíveis a partir do público. E: Apenas sshd deve ouvir diretamente no host - nada mais
  • Cada VM deve poder acessar a internet diretamente.
  • A rede no datacenter é baseada em MAC. Como eu descobri, a única maneira de se comunicar com a internet é através da eth0 e seu endereço MAC.

Se eu descartasse todo o material de virtualização, isso seria perfeitamente fácil, já que o apache obtém o pedido diretamente de um endereço IP específico.

Estou aberto para qualquer solução de trabalho.

    
por Ron 22.03.2012 / 13:32

3 respostas

5

Use uma ponte na sua interface WAN dom0 (por exemplo, KVM Host). Isso requer a instalação do bridge-utils package. Como esta é a distro baseada no Debian, você pode configurá-la em /etc/network/interfaces :

iface eth0 inet manual

auto br_wan
iface br_wan inet dhcp
    # Assuming DHCP to get address, otherwise migrate all WAN connection options here
    #address 192.168.122.0
    bridge_ports eth0 tap_guest1
    bridge_stp      off
    bridge_maxwait  0
    bridge_fd       0
    pre-up ip tuntap add dev tap_guest1 user guest1 mode tap
    # This command is required if your ISP allocates static IPs depending on MAC address
    # You shouldn't use this but might be handy some time
    #pre-up sysctl -q -w net/ipv4/conf/tap_guest1/proxy_arp=1
    post-down ip tuntap del tap_guest1 mode tap

Os comandos de pré-configuração configuram a interface TAP para conectar seu convidado KVM a uma ponte. Note que esta configuração permite executar o kvm a partir do guest1 não privilegiado do usuário. Observe que a configuração de net.ipv4.ip_forward = 1 com sysctl também pode ser útil.

Eu usei o comando ip tuntap do pacote iproute2 . Ainda não está documentado no pacote Debian, mas em breve estará disponível na página de manual do upstream. Como este pacote está instalado em todos os servidores baseados no Debian, você não precisará instalar uml-utilities ou openvpn package para criar apenas essas interfaces.

Essa abordagem não tem muita elegância para gerenciar muitas interfaces de toque, porque você precisará criar linhas semelhantes de pré e pós-down para a interface tap_guest1 . Isso pode ser corrigido escrevendo scripts adicionais em /etc/network/pre-up.d e /etc/network/post-down.d . Também é um problema se você deseja reconfigurar a interface br_wan com scripts ifdown / ifup enquanto os convidados do KVM ainda estão em execução - você precisará remover todas as interfaces, exceto eth0 da configuração de pontes e desconectá-las manualmente (don esqueça de anexá-los novamente após a reconfiguração da ponte) ou encerre todas as instâncias do KVM em execução em uma ponte.

Outra maneira, talvez mais limpa, é escrever um script ifup customizado para o próprio KVM e usá-lo na opção script para seu NIC. Você pode obter um exemplo em /etc/qemu-ifup . Veja a página de manual do kvm para detalhes.

Então você pode rodar sua caixa KVM assim:

kvm -net nic,model=virtio,macaddr=12:34:56:78:9a:bc \
    -net tap,ifname=tap_guest1,script=no,downscript=no \
    -boot c -nographic -display none -daemonize \
    guest1-drive.qcow2

A configuração de vários endereços IP em uma interface para o convidado KVM pode ser feita manualmente com o comando

ip address add aaa.bbb.ccc.101/24 dev eth0

Ou permanentemente em /etc/network/interfaces assim:

auto eth0 eth0:1
iface eth0 inet static
    address aaa.bbb.ccc.100
    network aaa.bbb.ccc.0
    netmask 255.255.255.0
    broadcast aaa.bbb.ccc.255
    gateway aaa.bbb.ccc.1

iface eth0:1 inet static
    address aaa.bbb.ccc.101
    network aaa.bbb.ccc.0
    netmask 255.255.255.0
    broadcast aaa.bbb.ccc.255
    gateway aaa.bbb.ccc.1

Observe que, se o seu datacenter / provedor não espera que você revele caixas adicionais na mesma rede, ele pode não configurá-las e elas não estarão disponíveis. Neste caso você pode querer criar bridge interna e usar o iptables para encaminhar pacotes entre sua interface WAN e esta ponte usando DNAT e SNAT. Supondo que sua rede de bridge virtual local seja 10.0.0.0/8, seu guest1 é 10.0.0.2, você precisará disso:

iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.100 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.101 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2
...
iptables -t nat -A POSTROUTING -p tcp --dst 10.0.0.2 -j SNAT --to-source aaa.bbb.ccc.100

Observe que você precisará de tantos comandos DNAT quanto os IPs externos por convidado KVM, mas apenas uma regra SNAT para fornecer acesso à Internet. Além disso, você pode permitir somente o tráfego HTTP / HTTPS / SSH, permitindo apenas as portas desejadas. Se você omitir a instrução --dport , todas as portas serão encaminhadas. Seu convidado KVM deve ter configurações de rede estática com o host KVM como gateway padrão, a menos que você esteja disposto a hospedar o servidor DHCP.

    
por 22.03.2012 / 21:43
2

Você usa uma ponte em vez de encaminhar pacotes com iptables. Depois que você iniciou o guest, basta configurar o IP para as NICs (se você tiver mais de 1 NIC virtual) em seu guest.

Consulte esta documentação .

    
por 22.03.2012 / 14:20
2

@jollyroger: Muito obrigado pelo seu guia abrangente. Infelizmente, no meu caso, não funcionou. Mas o seu guia me ajudou a entender melhor a funcionalidade do Linux-networking / bridging junto com o KVM.

Então, reverti tudo e obtive ajuda da minha empresa de hospedagem diretamente. O cenário foi tão fácil quanto usar virt-manager e virsh para adicionar uma configuração de rede personalizada. Aqui está a solução, que finalmente funcionou para mim:

Eu tenho uma sub-rede / 29 (+ outro IP diferente para ssh no host). A rede no centro de dados é comutada com base em mac, portanto todo o tráfego deve passar por um gateway local (até onde eu entendi). Meu provedor é Hetzner, na Alemanha. Eu usei o link para calcular todas as configurações necessárias para um xml de configuração de rede:

<network>
        <name>{some systemwide unique name. e.g.: subnet1}</name>
        <uuid>{> call uuidgen from shell to generate a uuid}</uuid>
        <forward dev="{interface e.g.: eth0}" mode="route" />
        <bridge name="{name of a _new_ virtual interface e.g.: virbr2}" stp="off" forwardDelay="0" />
        <ip address="{subnet-calc: Host Address Range Start Address}" netmask="subnet-calc: Subnet Mask">
                <dhcp>
                        <range start="{subnet-calc: Host Address Range Start Address+1}" end="{subnet-calc: Host Address Range End Address}" />
                </dhcp>
        </ip>
</network>

Salvei esse xml-data em algo como /tmp/subnet1.xml e apliquei essa nova rede virtual usando:

sudo virsh net-define /tmp/subnet1.xml

Eu uso o virt-manager 0.9.0 (sobre x11-forwarding via putty no meu windows-machine) para criar e editar todas as VMs. Então, minhas duas VMs públicas recebem essa nova rede virtual. Em cada VM, criei uma nova interface de rede virtual por ip público. Eu notei qual endereço MAC eu usei para qual ip público. Portanto, se eu quiser mover um endereço IP público para outra VM, não é nada mais do que excluir a NIC virtual na VM A e criá-la na VM B usando o mesmo endereço MAC.

Outra coisa, se você tentar reproduzir este cenário: Antes de iniciar a (s) VM (s), certifique-se de que a rede virtual "subnet1" (s.a.) esteja ativa. Na janela principal do virt-manager, vá para Editar > Detalhes da conexão e pule para a guia Redes virtuais . Se a rede "subnet1" estiver cinza, apenas marque e clique no botão play.

Agora inicie a VM e digite ifconfig . No meu caso, tudo funcionou diretamente.

Se eu perdi alguma coisa neste relatório, é só pedir. Se alguém tiver uma solução melhor, sinta-se à vontade para adicioná-la aqui.

    
por 23.03.2012 / 13:54