mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			551 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			551 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/python
 | 
						|
import cloud_utils
 | 
						|
from cloud_utils import Command
 | 
						|
import logging
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import xml.dom.minidom
 | 
						|
from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
 | 
						|
iptables = Command("iptables")
 | 
						|
bash = Command("/bin/bash")
 | 
						|
virsh = Command("virsh")
 | 
						|
ebtablessave = Command("ebtables-save")
 | 
						|
ebtables = Command("ebtables")
 | 
						|
augtool = Command("augtool")
 | 
						|
def execute(cmd):
 | 
						|
    logging.debug(cmd)
 | 
						|
    return bash("-c", cmd).stdout
 | 
						|
def can_bridge_firewall(privnic):
 | 
						|
    try:
 | 
						|
        execute("which iptables")
 | 
						|
    except:
 | 
						|
        print "no iptables on your host machine"
 | 
						|
        exit(1)
 | 
						|
 | 
						|
    try:
 | 
						|
        execute("which ebtables")
 | 
						|
    except:
 | 
						|
        print "no ebtables on your host machine"
 | 
						|
        exit(2)
 | 
						|
 | 
						|
    try:
 | 
						|
        alreadySetup = augtool.match("/files/etc/sysctl.conf/net.bridge.bridge-nf-call-arptables", "1").stdout.strip()
 | 
						|
        if len(alreadySetup) == 0:
 | 
						|
            script = """
 | 
						|
                        set /files/etc/sysctl.conf/net.bridge.bridge-nf-call-arptables 1
 | 
						|
                        save"""
 | 
						|
            augtool < script
 | 
						|
 | 
						|
        alreadySetup = augtool.match("/files/etc/sysctl.conf/net.bridge.bridge-nf-call-iptables", "1").stdout.strip()
 | 
						|
        if len(alreadySetup) == 0:
 | 
						|
            script = """
 | 
						|
                        set /files/etc/sysctl.conf/net.bridge.bridge-nf-call-iptables 1
 | 
						|
                        save"""
 | 
						|
            augtool < script
 | 
						|
 | 
						|
        alreadySetup = augtool.match("/files/etc/sysctl.conf/net.bridge.bridge-nf-call-ip6tables", "1").stdout.strip()
 | 
						|
        if len(alreadySetup) == 0:
 | 
						|
            script = """
 | 
						|
                        set /files/etc/sysctl.conf/net.bridge.bridge-nf-call-ip6tables 1
 | 
						|
                        save"""
 | 
						|
            augtool < script
 | 
						|
        execute("sysctl -p /etc/sysctl.conf")
 | 
						|
    except:
 | 
						|
        print "failed to turn on bridge netfilter"
 | 
						|
        exit(3)
 | 
						|
 | 
						|
    try:
 | 
						|
        execute("iptables -N BRIDGE-FIREWALL")
 | 
						|
        execute("iptables -N BRIDGE-FIREWALL")
 | 
						|
        execute("iptables -I BRIDGE-FIREWALL -m state --state RELATED,ESTABLISHED -j ACCEPT")
 | 
						|
        execute("iptables -D FORWARD -j RH-Firewall-1-INPUT")
 | 
						|
    except:
 | 
						|
        logging.exception('Chain BRIDGE-FIREWALL already exists: ')
 | 
						|
 | 
						|
    result = 0
 | 
						|
    try:
 | 
						|
        execute("iptables -n -L FORWARD | grep BRIDGE-FIREWALL")
 | 
						|
    except:
 | 
						|
        try:
 | 
						|
            execute("iptables -I FORWARD -m physdev --physdev-is-bridged -j BRIDGE-FIREWALL")
 | 
						|
            execute("iptables -A FORWARD -m physdev --physdev-is-bridged --physdev-out " +  privnic + " -j ACCEPT")
 | 
						|
            execute("iptables -A FORWARD -j DROP")
 | 
						|
        except:
 | 
						|
            result = 1
 | 
						|
 | 
						|
    
 | 
						|
    if result == 1:
 | 
						|
        print "br firewall is not supported"
 | 
						|
    if not os.path.exists('/var/run/cloud'):
 | 
						|
        os.makedirs('/var/run/cloud')
 | 
						|
 
 | 
						|
    cleanup_rules_for_dead_vms()
 | 
						|
    cleanup_rules()
 | 
						|
    
 | 
						|
    return result
 | 
						|
'''
 | 
						|
def ipset(ipsetname, proto, start, end, ips):
 | 
						|
    try:
 | 
						|
        check_call(['ipset', '-N', ipsetname, 'iptreemap'])
 | 
						|
    except:
 | 
						|
        logging.debug("ipset chain already exists" + ipsetname)
 | 
						|
 | 
						|
    result = True
 | 
						|
    ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000)
 | 
						|
 | 
						|
    try: 
 | 
						|
        check_call(['ipset', '-N', ipsettmp, 'iptreemap']) 
 | 
						|
        for ip in ips:
 | 
						|
            try:
 | 
						|
                check_call(['ipset', '-A', ipsettmp, ip])
 | 
						|
            except CommandException, cex:
 | 
						|
                if cex.reason.rfind('already in set') == -1:
 | 
						|
                   raise
 | 
						|
        check_call(['ipset', '-W', ipsettmp, ipsetname]) 
 | 
						|
        check_call(['ipset', '-X', ipsettmp]) 
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to program ipset " + ipsetname)
 | 
						|
        result = False
 | 
						|
 | 
						|
    return result
 | 
						|
'''
 | 
						|
 | 
						|
def destroy_network_rules_for_vm(vm_name):
 | 
						|
    vmchain = vm_name
 | 
						|
    
 | 
						|
    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
 | 
						|
    if vm_name.startswith('i-') or vm_name.startswith('r-'):
 | 
						|
        vmchain =  '-'.join(vm_name.split('-')[:-1])
 | 
						|
        vmchain_default =  '-'.join(vm_name.split('-')[:-1]) + "-def"
 | 
						|
 | 
						|
    destroy_ebtables_rules(vmchain)
 | 
						|
    
 | 
						|
    try:
 | 
						|
        execute("iptables -F " + vmchain_default)
 | 
						|
        execute("iptables -X " + vmchain_default)
 | 
						|
    except:
 | 
						|
        logging.exception("Ignoring failure to delete  chain " + vmchain_default)
 | 
						|
    
 | 
						|
    try:
 | 
						|
        execute("iptables -F " + vmchain)
 | 
						|
        execute("iptables -X " + vmchain)
 | 
						|
    except:
 | 
						|
        logging.debug("Ignoring failure to delete  chain " + vmchain)
 | 
						|
    
 | 
						|
    remove_rule_log_for_vm(vm_name)
 | 
						|
    
 | 
						|
    if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]:
 | 
						|
        return 'true'
 | 
						|
    
 | 
						|
    return 'true'
 | 
						|
 | 
						|
def destroy_ebtables_rules(vm_name):
 | 
						|
    delcmd = "ebtables-save | grep ROUTING | grep " +  vm_name + " | sed 's/-A/-D/'"
 | 
						|
    delcmds = execute(delcmd).split('\n')
 | 
						|
    delcmds.pop()
 | 
						|
    for cmd in delcmds:
 | 
						|
        try:
 | 
						|
            execute("ebtables -t nat " +  cmd)
 | 
						|
        except:
 | 
						|
            logging.debug("Ignoring failure to delete ebtables rules for vm " + vm_name)
 | 
						|
    chains = [vm_name+"-in", vm_name+"-out"]
 | 
						|
    for chain in chains:
 | 
						|
        try:
 | 
						|
            execute("ebtables -t nat -F " +  chain)
 | 
						|
            execute("ebtables -t nat -X " +  chain)
 | 
						|
        except:
 | 
						|
            logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_name)   
 | 
						|
 | 
						|
def default_ebtables_rules(vm_name, vif, vm_ip, vm_mac):
 | 
						|
    vmchain_in = vm_name + "-in"
 | 
						|
    vmchain_out = vm_name + "-out"
 | 
						|
    
 | 
						|
    for chain in [vmchain_in, vmchain_out]:
 | 
						|
        try:
 | 
						|
            execute("ebtables -t nat -N " + chain)
 | 
						|
        except:
 | 
						|
            execute("ebtables -t nat -F " + chain) 
 | 
						|
 | 
						|
    try:
 | 
						|
        # -s ! 52:54:0:56:44:32 -j DROP 
 | 
						|
        execute("ebtables -t nat -A PREROUTING -i " + vif + " -j " +  vmchain_in)
 | 
						|
        execute("ebtables -t nat -A POSTROUTING -o " + vif + " -j " + vmchain_out)
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to program default rules")
 | 
						|
        return 'false'
 | 
						|
    
 | 
						|
    try:
 | 
						|
        execute("ebtables -t nat -A " +  vmchain_in + " -i " + vif + " -s ! " +  vm_mac + " -j DROP")
 | 
						|
        execute("ebtables -t nat -A " +  vmchain_in + " -p ARP -s ! " + vm_mac + " -j DROP")
 | 
						|
        execute("ebtables -t nat -A " +  vmchain_in + " -p ARP --arp-mac-src ! " + vm_mac + " -j DROP")
 | 
						|
        execute("ebtables -t nat -A " + vmchain_in +  " -p ARP --arp-ip-src ! " + vm_ip + " -j DROP") 
 | 
						|
        execute("ebtables -t nat -A " + vmchain_in + " -p ARP --arp-op Request -j ACCEPT")   
 | 
						|
        execute("ebtables -t nat -A " + vmchain_in  + " -p ARP --arp-op Reply -j ACCEPT")    
 | 
						|
        execute("ebtables -t nat -A " + vmchain_in + " -p ARP  -j DROP")    
 | 
						|
    except:
 | 
						|
        logging.exception("Failed to program default ebtables IN rules")
 | 
						|
        return 'false'
 | 
						|
   
 | 
						|
    try:
 | 
						|
        execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply --arp-mac-dst ! " +  vm_mac + " -j DROP")
 | 
						|
        execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP") 
 | 
						|
        execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Request -j ACCEPT")   
 | 
						|
        execute("ebtables -t nat -A " + vmchain_out + " -p ARP --arp-op Reply -j ACCEPT")    
 | 
						|
        execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j DROP")    
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to program default ebtables OUT rules")
 | 
						|
        return 'false' 
 | 
						|
    
 | 
						|
            
 | 
						|
def default_network_rules_systemvm(vm_name):
 | 
						|
    vifs = getVifs(vm_name)
 | 
						|
    domid = getvmId(vm_name)
 | 
						|
    vmchain = vm_name
 | 
						|
 
 | 
						|
    delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
 | 
						|
  
 | 
						|
    try:
 | 
						|
        execute("iptables -N " + vmchain)
 | 
						|
    except:
 | 
						|
        execute("iptables -F " + vmchain)
 | 
						|
 | 
						|
  
 | 
						|
    for vif in vifs:
 | 
						|
        try:
 | 
						|
            execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-out " + vif +  " -j " + vmchain)
 | 
						|
            execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " +  vmchain)
 | 
						|
        except:
 | 
						|
            logging.debug("Failed to program default rules")
 | 
						|
            return 'false'
 | 
						|
 | 
						|
    execute("iptables -A " + vmchain + " -j ACCEPT")
 | 
						|
    
 | 
						|
    if write_rule_log_for_vm(vm_name, '-1', '_ignore_', domid, '_initial_', '-1') == False:
 | 
						|
        logging.debug("Failed to log default network rules for systemvm, ignoring")
 | 
						|
    return 'true'
 | 
						|
 | 
						|
 | 
						|
def default_network_rules(vm_name, vm_ip, vm_id, vm_mac):
 | 
						|
    print vm_name 
 | 
						|
    print vm_ip 
 | 
						|
    print vm_mac
 | 
						|
    vmName = vm_name 
 | 
						|
    domID = getvmId(vm_name)
 | 
						|
    delete_rules_for_vm_in_bridge_firewall_chain(vmName)
 | 
						|
    vmchain = vm_name
 | 
						|
    vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def"
 | 
						|
    
 | 
						|
    destroy_ebtables_rules(vmName)
 | 
						|
    
 | 
						|
    vifs = getVifs(vmName)
 | 
						|
 | 
						|
    try:
 | 
						|
        execute("iptables -N " + vmchain)
 | 
						|
    except:
 | 
						|
        execute("iptables -F " + vmchain)
 | 
						|
        
 | 
						|
    try:
 | 
						|
        execute("iptables -N " + vmchain_default)
 | 
						|
    except:
 | 
						|
        execute("iptables -F " + vmchain_default)
 | 
						|
 | 
						|
    try:
 | 
						|
        for v in vifs:
 | 
						|
            execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-out " + v + " -j " +  vmchain_default)
 | 
						|
            execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-in " +  v + " -j " + vmchain_default)
 | 
						|
        execute("iptables -A  " + vmchain_default + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
 | 
						|
        #allow dhcp
 | 
						|
        for v in vifs:
 | 
						|
            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + v + " -p udp --dport 67 --sport 68 -j ACCEPT")
 | 
						|
            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + v + " -p udp --dport 68 --sport 67  -j ACCEPT")
 | 
						|
 | 
						|
        #don't let vm spoof its ip address
 | 
						|
        for v in vifs:
 | 
						|
            execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + v  + " --source " +  vm_ip +  " -j RETURN")
 | 
						|
        execute("iptables -A " + vmchain_default + " -j " +  vmchain)
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to program default rules for vm " + vm_name)
 | 
						|
        return 'false'
 | 
						|
    
 | 
						|
    for v in vifs:
 | 
						|
    	default_ebtables_rules(vmchain, v, vm_ip, vm_mac)
 | 
						|
    
 | 
						|
    if write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1') == False:
 | 
						|
        logging.debug("Failed to log default network rules, ignoring")
 | 
						|
        
 | 
						|
    logging.debug("Programmed default rules for vm " + vm_name)
 | 
						|
    return 'true'
 | 
						|
    
 | 
						|
def delete_rules_for_vm_in_bridge_firewall_chain(vmName):
 | 
						|
    vm_name = vmName
 | 
						|
    if vm_name.startswith('i-') or vm_name.startswith('r-'):
 | 
						|
        vm_name =  '-'.join(vm_name.split('-')[:-1])
 | 
						|
    
 | 
						|
    vmchain = vm_name
 | 
						|
    
 | 
						|
    delcmd = "iptables -S BRIDGE-FIREWALL | grep " +  vmchain + " | sed 's/-A/-D/'"
 | 
						|
    delcmds = execute(delcmd).split('\n')
 | 
						|
    delcmds.pop()
 | 
						|
    for cmd in delcmds:
 | 
						|
        try:
 | 
						|
            execute("iptables " + cmd)
 | 
						|
        except:
 | 
						|
              logging.exception("Ignoring failure to delete rules for vm " + vmName)
 | 
						|
 | 
						|
def rewrite_rule_log_for_vm(vm_name, new_domid):
 | 
						|
    logfilename = "/var/run/cloud/" + vm_name +".log"
 | 
						|
    if not os.path.exists(logfilename):
 | 
						|
        return 
 | 
						|
    lines = (line.rstrip() for line in open(logfilename))
 | 
						|
    
 | 
						|
    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = ['_', '-1', '_', '-1', '_', '-1']
 | 
						|
    for line in lines:
 | 
						|
        [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
 | 
						|
        break
 | 
						|
    
 | 
						|
    write_rule_log_for_vm(_vmName, _vmID, '0.0.0.0', new_domid, _signature, '-1')
 | 
						|
 | 
						|
def get_rule_log_for_vm(vmName):
 | 
						|
    vm_name = vmName;
 | 
						|
    logfilename = "/var/run/cloud/" + vm_name +".log"
 | 
						|
    if not os.path.exists(logfilename):
 | 
						|
        return ''
 | 
						|
    
 | 
						|
    lines = (line.rstrip() for line in open(logfilename))
 | 
						|
    
 | 
						|
    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = ['_', '-1', '_', '-1', '_', '-1']
 | 
						|
    for line in lines:
 | 
						|
        [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
 | 
						|
        break
 | 
						|
    
 | 
						|
    return ','.join([_vmName, _vmID, _vmIP, _domID, _signature, _seqno])
 | 
						|
 | 
						|
def get_rule_logs_for_vms():
 | 
						|
    cmd = "virsh list|grep running |awk '{print $2}'"
 | 
						|
    vms = bash("-c", cmd).stdout.split("\n")
 | 
						|
    
 | 
						|
    result = []
 | 
						|
    try:
 | 
						|
        for name in vms:
 | 
						|
            name = name.rstrip()
 | 
						|
            if 1 not in [ name.startswith(c) for c in ['r-', 's-', 'v-', 'i-'] ]:
 | 
						|
                continue
 | 
						|
            #network_rules_for_rebooted_vm(session, name)
 | 
						|
            if name.startswith('i-'):
 | 
						|
                log = get_rule_log_for_vm(name)
 | 
						|
                result.append(log)
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to get rule logs, better luck next time!")
 | 
						|
        
 | 
						|
    print ";".join(result)
 | 
						|
 | 
						|
def cleanup_rules_for_dead_vms():
 | 
						|
    return True 
 | 
						|
 | 
						|
 | 
						|
def cleanup_rules():
 | 
						|
  try:
 | 
						|
 | 
						|
    chainscmd = "iptables-save | grep '^:' | grep -v '.*-def' | awk '{print $1}' | cut -d':' -f2"
 | 
						|
    chains = execute(chainscmd).split('\n')
 | 
						|
    cleaned = 0
 | 
						|
    cleanup = []
 | 
						|
    for chain in chains:
 | 
						|
        if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]:
 | 
						|
            vm_name = chain
 | 
						|
                
 | 
						|
            cmd = "virsh list |grep " + vm_name 
 | 
						|
            try:
 | 
						|
                result = execute(cmd)
 | 
						|
            except:
 | 
						|
                result = None
 | 
						|
 | 
						|
            if result == None or len(result) == 0:
 | 
						|
                logging.debug("chain " + chain + " does not correspond to a vm, cleaning up")
 | 
						|
                cleanup.append(vm_name)
 | 
						|
                continue
 | 
						|
            if result.find("running") == -1:
 | 
						|
                logging.debug("vm " + vm_name + " is not running, cleaning up")
 | 
						|
                cleanup.append(vm_name)
 | 
						|
                
 | 
						|
    for vmname in cleanup:
 | 
						|
        destroy_network_rules_for_vm(vmname)
 | 
						|
                    
 | 
						|
    logging.debug("Cleaned up rules for " + str(len(cleanup)) + " chains")                
 | 
						|
  except:
 | 
						|
    logging.debug("Failed to cleanup rules !")
 | 
						|
 | 
						|
def check_rule_log_for_vm(vmName, vmId, vmIP, domID, signature, seqno):
 | 
						|
    vm_name = vmName;
 | 
						|
    logfilename = "/var/run/cloud/" + vm_name +".log"
 | 
						|
    if not os.path.exists(logfilename):
 | 
						|
        return [True, True, True, True, True, True]
 | 
						|
        
 | 
						|
    try:
 | 
						|
        lines = (line.rstrip() for line in open(logfilename))
 | 
						|
    except:
 | 
						|
        logging.debug("failed to open " + logfilename) 
 | 
						|
        return False
 | 
						|
 | 
						|
    [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = ['_', '-1', '_', '-1', '_', '-1']
 | 
						|
    try:
 | 
						|
        for line in lines:
 | 
						|
            [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = line.split(',')
 | 
						|
            break
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to parse log file for vm " + vm_name)
 | 
						|
        remove_rule_log_for_vm(vm_name)
 | 
						|
        return False
 | 
						|
    
 | 
						|
    return [(vm_name != _vmName), (vmId != _vmID), (vmIP != _vmIP), (domID != _domID), (signature != _signature),(seqno != _seqno)]
 | 
						|
 | 
						|
def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno):
 | 
						|
    vm_name = vmName
 | 
						|
    logfilename = "/var/run/cloud/" + vm_name +".log"
 | 
						|
    logging.debug("Writing log to " + logfilename)
 | 
						|
    logf = open(logfilename, 'w')
 | 
						|
    output = ','.join([vmName, vmID, vmIP, domID, signature, seqno])
 | 
						|
    result = True
 | 
						|
    try:
 | 
						|
        logf.write(output)
 | 
						|
        logf.write('\n')
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to write to rule log file " + logfilename)
 | 
						|
        result = False
 | 
						|
        
 | 
						|
    logf.close()
 | 
						|
    
 | 
						|
    return result
 | 
						|
 | 
						|
def remove_rule_log_for_vm(vmName):
 | 
						|
    vm_name = vmName
 | 
						|
    logfilename = "/var/run/cloud/" + vm_name +".log"
 | 
						|
 | 
						|
    result = True
 | 
						|
    try:
 | 
						|
        os.remove(logfilename)
 | 
						|
    except:
 | 
						|
        logging.debug("Failed to delete rule log file " + logfilename)
 | 
						|
        result = False
 | 
						|
    
 | 
						|
    return result
 | 
						|
 | 
						|
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules):
 | 
						|
  try:
 | 
						|
    vmName = vm_name
 | 
						|
    domId = getvmId(vmName)
 | 
						|
    vm_name =  '-'.join(vm_name.split('-')[:-1])
 | 
						|
    vmchain = vm_name
 | 
						|
    
 | 
						|
    changes = check_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno)
 | 
						|
    
 | 
						|
    if not 1 in changes:
 | 
						|
        logging.debug("Rules already programmed for vm " + vm_name)
 | 
						|
        return 'true'
 | 
						|
    
 | 
						|
    if changes[1] or changes[2] or changes[3]:
 | 
						|
        logging.debug("Change detected in vmId or vmIp or domId, resetting default rules")
 | 
						|
        default_network_rules(vmName, vm_ip, vm_id, vmMac)
 | 
						|
        
 | 
						|
    lines = rules.split(';')
 | 
						|
 | 
						|
    print lines
 | 
						|
    logging.debug("    programming network rules for  IP: " + vm_ip + " vmname=" + vm_name)
 | 
						|
    #iptables('-F', vmchain)
 | 
						|
    print lines
 | 
						|
    
 | 
						|
    for line in lines:
 | 
						|
        tokens = line.split(':')
 | 
						|
        if len(tokens) != 4:
 | 
						|
          continue
 | 
						|
        protocol = tokens[0]
 | 
						|
        start = tokens[1]
 | 
						|
        end = tokens[2]
 | 
						|
        cidrs = tokens.pop();
 | 
						|
        ips = cidrs.split(",")
 | 
						|
        ips.pop()
 | 
						|
        allow_any = False
 | 
						|
        if  '0.0.0.0/0' in ips:
 | 
						|
            i = ips.index('0.0.0.0/0')
 | 
						|
            del ips[i]
 | 
						|
            allow_any = True
 | 
						|
        range = start + ":" + end
 | 
						|
        if ips:    
 | 
						|
            if protocol == 'all':
 | 
						|
                for ip in ips:
 | 
						|
                    iptables = "iptables -I " + vmchain + " -m state --state NEW -m iprange --src-range " + ip + " -j ACCEPT"
 | 
						|
            elif protocol != 'icmp':
 | 
						|
                for ip in ips:
 | 
						|
                    iptables = "iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -m iprange --src-range " + ip + " -j ACCEPT"
 | 
						|
            else:
 | 
						|
                range = start + "/" + end
 | 
						|
                if start == "-1":
 | 
						|
                    range = "any"
 | 
						|
                    for ip in ips:
 | 
						|
                        iptables = "iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -m iprange --src-range " + ip + " -j ACCEPT"
 | 
						|
            execute(iptables)
 | 
						|
        
 | 
						|
        if allow_any and protocol != 'all':
 | 
						|
            if protocol != 'icmp':
 | 
						|
                iptables = "iptables -I " + vmchain + " -p " + protocol + " -m " +  protocol + " --dport " + range + " -m state --state NEW -j ACCEPT"
 | 
						|
            else:
 | 
						|
                range = start + "/" + end
 | 
						|
                if start == "-1":
 | 
						|
                    range = "any"
 | 
						|
                    iptables = "iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -j ACCEPT"
 | 
						|
            execute(iptables)
 | 
						|
 | 
						|
    iptables =  "iptables -A " + vmchain + " -j DROP"       
 | 
						|
    execute(iptables)
 | 
						|
 | 
						|
    if write_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno) == False:
 | 
						|
        return 'false'
 | 
						|
    
 | 
						|
    return 'true'
 | 
						|
  except:
 | 
						|
    logging.debug("Failed to network rule !: " + sys.exc_type)
 | 
						|
 | 
						|
def getVifs(vmName):
 | 
						|
    vifs = []
 | 
						|
    try:
 | 
						|
        xmlfile = virsh("dumpxml", vmName).stdout 
 | 
						|
    except:
 | 
						|
        return vifs    
 | 
						|
 | 
						|
    dom = xml.dom.minidom.parseString(xmlfile)
 | 
						|
    vifs = []
 | 
						|
    for network in dom.getElementsByTagName("interface"):
 | 
						|
        target = network.getElementsByTagName('target')[0]
 | 
						|
        nicdev = target.getAttribute("dev").strip()
 | 
						|
        vifs.append(nicdev) 
 | 
						|
    return vifs
 | 
						|
def getvmId(vmName):
 | 
						|
    cmd = "virsh list |grep " + vmName + " | awk '{print $1}'"
 | 
						|
    return bash("-c", cmd).stdout.strip()
 | 
						|
    
 | 
						|
if __name__ == '__main__':
 | 
						|
    logging.basicConfig(filename="/var/log/cloud/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG)
 | 
						|
    parser = OptionParser()
 | 
						|
    parser.add_option("--vmname", dest="vmName")
 | 
						|
    parser.add_option("--vmip", dest="vmIP")
 | 
						|
    parser.add_option("--vmid", dest="vmID")
 | 
						|
    parser.add_option("--vmmac", dest="vmMAC")
 | 
						|
    parser.add_option("--vif", dest="vif")
 | 
						|
    parser.add_option("--sig", dest="sig")
 | 
						|
    parser.add_option("--seq", dest="seq")
 | 
						|
    parser.add_option("--rules", dest="rules")
 | 
						|
    (option, args) = parser.parse_args()
 | 
						|
    cmd = args[0]
 | 
						|
    if cmd == "can_bridge_firewall":
 | 
						|
        can_bridge_firewall(args[1])
 | 
						|
    elif cmd == "default_network_rules":
 | 
						|
        default_network_rules(option.vmName, option.vmIP, option.vmID, option.vmMAC)
 | 
						|
    elif cmd == "destroy_network_rules_for_vm":
 | 
						|
        destroy_network_rules_for_vm(option.vmName) 
 | 
						|
    elif cmd == "default_network_rules_systemvm":
 | 
						|
        default_network_rules_systemvm(option.vmName)
 | 
						|
    elif cmd == "get_rule_logs_for_vms":
 | 
						|
        get_rule_logs_for_vms()
 | 
						|
    elif cmd == "add_network_rules":
 | 
						|
        add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules)
 |