Bug #160

Shutdown Hooks for isolating networks

Added by Ruben S. Montero over 9 years ago. Updated over 9 years ago.

Status:ClosedStart date:10/07/2009
Priority:NormalDue date:
Assignee:Javi Fontan% Done:

0%

Category:Core & System
Target version:Release 1.4
Resolution:fixed Pull request:
Affected Versions:

Description

The KVM scripts can not undo the firewall rules as the tap interface is not available once the VM is deleted. The tap can be stored when the VM is created, or it may be obtained by the current rules given that we have the MAC address of the interface.

Associated revisions

Revision 2aea6c33
Added by Jaime Melis over 9 years ago

Modified ebtables scripts to use FORWARD rules (#160)

git-svn-id: http://svn.opennebula.org/one/trunk@895 3034c82b-c49b-4eb3-8279-a7acafdc01c0

Revision 033a20eb
Added by Jaime Melis over 9 years ago

Modified ebtables-xen script to use FORWARD rules (#160)

git-svn-id: http://svn.opennebula.org/one/trunk@898 3034c82b-c49b-4eb3-8279-a7acafdc01c0

Revision 8d4cfaf1
Added by Jaime Melis almost 2 years ago

Merge pull request #160 from atodorov-storpool/tmCephOnSharedFs

tm/ceph {pre,post}migrate do nothing if not SYSTEM DS

History

#1 Updated by Ruben S. Montero over 9 years ago

Also check that the isolation is really taking place.

A message from Shi Jin:

After some debugging, I think in order to restrict a VM to a

particular MAC address, we need to work on the FORWARD chain.
Therefore I added the following to the ebtables-kvm script:
forward_rule1="FORWARD -s ! #{iface_mac}/FF:FF:FF:FF:FF:FF -i #{tap} -j DROP"
forward_rule2="FORWARD -d ! #{iface_mac}/FF:FF:FF:FF:FF:FF -o #{tap} -j DROP"
And call them in start (similar in stop)
activate(forward_rule1)
activate(forward_rule2)

This has been working for me. If I tried to change the MAC address

within the VM I will lose connection.

I guess similarly I can work out rules on FORWARD to prevent users

from changing the VM IP address as well.

#2 Updated by Ruben S. Montero over 9 years ago

  • Assignee changed from Jaime Melis to Javi Fontan

#3 Updated by Javi Fontan over 9 years ago

  • Status changed from New to Assigned

#4 Updated by Javi Fontan over 9 years ago

Added a new script 'ebtables-flush' that deletes all ebtables rules not used. Commit r889

#5 Updated by Shi Jin over 9 years ago

Javi Fontan wrote:

Added a new script 'ebtables-flush' that deletes all ebtables rules not used. Commit r889

Hi Javi,

I tried your script. It removes all ebtables, including those are still in use.
I am running KVM as the hypervisor. I think the issue is that the rules operate on vnet1, vnet2,... instead of br0, br1, br2. Therefore,
[[if !interfaces.include?(rule[:interface])]]
is always true. Maybe this works for Xen but it does not for my KVM case.
How do you think?
Thanks.

#6 Updated by Shi Jin over 9 years ago

I've modify the script to work with my KVM based OpenNebula system. The code is

#!/usr/bin/env ruby

require 'rexml/document'

def deactivate(rule)
    system "sudo ebtables -D #{rule}" 
end

def interfaces_for_VM(vm,interfaces)
    nets=`virsh dumpxml #{vm}`
    doc=REXML::Document.new(nets).root
    doc.elements.each('/domain/devices/interface') {|net|
        tap=net.elements['target'].attributes['dev']
        interfaces.push(tap)
        }
end

def get_vm_list
    vmList=`virsh list`
    vms=vmList.split("\n")[2..-1].collect{|l| l.split.first}
    vms
end

def get_interfaces
     interfaces=[]
     vmList=get_vm_list
     vmList.each do |vm|
        interfaces_for_VM(vm,interfaces)
     end
    interfaces     
end

RULE_TYPES={
    'INPUT' => /-i ([\w\.\-]+) /,
    'OUTPUT' => /-o ([\w\.\-]+) /
}

def get_rules
    rules=Hash.new
    RULE_TYPES.each do |name, reg|
        r=Array.new
        ebtables_exit=`sudo ebtables -L #{name}`
        rules[name]=ebtables_exit.split("\n")[3..-1].collect do |l|
            line=l.strip
            m=line.match(reg)
            if m
                interface=m[1]
                {
                    :interface  => interface, 
                    :rule       => line
                }
            else
                nil
            end
        end.compact
    end

    rules
end

interfaces=get_interfaces

all_rules=get_rules

all_rules.each do |chain, rules|
    rules.each do |rule|
        if !interfaces.include?(rule[:interface])
            deactivate("#{chain} #{rule[:rule]}") 
        end
    end
end

#7 Updated by Ruben S. Montero over 9 years ago

There was a couple of bugs in the rules for the ebtables. As Shi Jin suggested previously, the target rule should be FORWARD. Let say that a VM has virtual NIC (vnet3) attached to the bridge for the private networks. The rules should be:

# Accept all packets traversing the forward rule 
ebtables -P FORWARD ACCEPT

# Filter those packets with a MAC not included in the virtual net
# This rules applies to packets being forwarded from the bridge to vnet3
ebtables -A FORWARD -s ! 00:03:c0:a8:c8:00/ff:ff:ff:ff:ff:00 -o vnet3 -j DROP

# Filter those packets with a MAC different from that assigned by OpenNebula
# This rules applies to packets being forwarded from vnet3 to the bridge
ebtables -A FORWARD -s ! 00:03:c0:a8:c8:0d -i vnet3 -j DROP

Also we do not really see the need to filter packets based on the IP. The user is responsible of setting the IPs in her own private network. However this could be very useful if someone wants to provide basic firewalling capabilities for the public IPs, like Amazon EC2 for the VMs...

#8 Updated by Jaime Melis over 9 years ago

  • Status changed from Assigned to Closed
  • Resolution set to fixed

Modified scripts according to Ruben Montero's comment. Tested and it works. Closing ticket.

Also available in: Atom PDF