diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 10610f0a9b1..044747a2991 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -6,9 +6,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -48,13 +48,13 @@ def can_bridge_firewall(privnic): print "no ebtables on your host machine" sys.exit(2) - + if not os.path.exists('/var/run/cloud'): os.makedirs('/var/run/cloud') - + cleanup_rules_for_dead_vms() cleanup_rules() - + return True ''' def ipset(ipsetname, proto, start, end, ips): @@ -66,16 +66,16 @@ def ipset(ipsetname, proto, start, end, ips): result = True ipsettmp = ''.join(''.join(ipsetname.split('-')).split('_')) + str(int(time.time()) % 1000) - try: - check_call(['ipset', '-N', ipsettmp, 'iptreemap']) + 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]) + check_call(['ipset', '-W', ipsettmp, ipsetname]) + check_call(['ipset', '-X', ipsettmp]) except: logging.debug("Failed to program ipset " + ipsetname) result = False @@ -87,52 +87,52 @@ def destroy_network_rules_for_vm(vm_name, vif=None): vmchain = vm_name vmchain_egress = egress_chain_name(vm_name) vmchain_default = None - + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) if vm_name.startswith('i-') or vm_name.startswith('r-'): - vmchain_default = '-'.join(vm_name.split('-')[:-1]) + "-def" + vmchain_default = '-'.join(vm_name.split('-')[:-1]) + "-def" destroy_ebtables_rules(vmchain, vif) - + try: - if vmchain_default != None: + if vmchain_default != None: execute("iptables -F " + vmchain_default) except: - logging.debug("Ignoring failure to delete chain " + vmchain_default) - + logging.debug("Ignoring failure to delete chain " + vmchain_default) + try: - if vmchain_default != None: + if vmchain_default != None: execute("iptables -X " + vmchain_default) except: - logging.debug("Ignoring failure to delete chain " + vmchain_default) + logging.debug("Ignoring failure to delete chain " + vmchain_default) try: execute("iptables -F " + vmchain) except: - logging.debug("Ignoring failure to delete chain " + vmchain) - + logging.debug("Ignoring failure to delete chain " + vmchain) + try: execute("iptables -X " + vmchain) except: - logging.debug("Ignoring failure to delete chain " + vmchain) - + logging.debug("Ignoring failure to delete chain " + vmchain) + try: execute("iptables -F " + vmchain_egress) except: - logging.debug("Ignoring failure to delete chain " + vmchain_egress) - + logging.debug("Ignoring failure to delete chain " + vmchain_egress) + try: execute("iptables -X " + vmchain_egress) except: - logging.debug("Ignoring failure to delete chain " + vmchain_egress) + logging.debug("Ignoring failure to delete chain " + vmchain_egress) try: execute("ipset -F " + vm_name) execute("ipset -X " + vm_name) except: logging.debug("Ignoring failure to delete ipset " + vmchain) - + if vif is not None: try: dnats = execute("iptables -t nat -S | grep " + vif + " | sed 's/-A/-D/'").split("\n") @@ -140,7 +140,7 @@ def destroy_network_rules_for_vm(vm_name, vif=None): try: execute("iptables -t nat " + dnat) except: - logging.debug("Igoring failure to delete dnat: " + dnat) + logging.debug("Igoring failure to delete dnat: " + dnat) except: pass remove_rule_log_for_vm(vm_name) @@ -148,7 +148,7 @@ def destroy_network_rules_for_vm(vm_name, vif=None): if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]: return 'true' - + return 'true' def destroy_ebtables_rules(vm_name, vif): @@ -174,73 +174,73 @@ def destroy_ebtables_rules(vm_name, vif): for cmd in delcmds: try: - execute("ebtables -t nat " + cmd) + 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", vm_name+"-in-ips", vm_name+"-out-ips"] for chain in chains: try: - execute("ebtables -t nat -F " + chain) - execute("ebtables -t nat -X " + chain) + 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) + logging.debug("Ignoring failure to delete ebtables chain for vm " + vm_name) def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif): vmchain_in = vm_name + "-in" vmchain_out = vm_name + "-out" vmchain_in_ips = vm_name + "-in-ips" vmchain_out_ips = vm_name + "-out-ips" - + for chain in [vmchain_in, vmchain_out, vmchain_in_ips, vmchain_out_ips]: try: execute("ebtables -t nat -N " + chain) except: - execute("ebtables -t nat -F " + chain) + 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) + # -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) - execute("ebtables -t nat -A " + vmchain_in_ips + " -j DROP") - execute("ebtables -t nat -A " + vmchain_out_ips + " -j DROP") + execute("ebtables -t nat -A " + vmchain_in_ips + " -j DROP") + execute("ebtables -t nat -A " + vmchain_out_ips + " -j DROP") except: logging.debug("Failed to program default rules") return 'false' - + try: - execute("ebtables -t nat -A " + vmchain_in + " -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 + " -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") if vm_ip is not None: - execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j " + vmchain_in_ips) - execute("ebtables -t nat -I " + vmchain_in_ips + " -p ARP --arp-ip-src " + vm_ip + " -j RETURN") - 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") + execute("ebtables -t nat -A " + vmchain_in + " -p ARP -j " + vmchain_in_ips) + execute("ebtables -t nat -I " + vmchain_in_ips + " -p ARP --arp-ip-src " + vm_ip + " -j RETURN") + 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-op Reply --arp-mac-dst ! " + vm_mac + " -j DROP") if vm_ip is not None: execute("ebtables -t nat -A " + vmchain_out + " -p ARP -j " + vmchain_out_ips ) - execute("ebtables -t nat -I " + vmchain_out_ips + " -p ARP --arp-ip-dst " + vm_ip + " -j RETURN") - 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") + execute("ebtables -t nat -I " + vmchain_out_ips + " -p ARP --arp-ip-dst " + vm_ip + " -j RETURN") + 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' - - + return 'false' + + def default_network_rules_systemvm(vm_name, localbrname): bridges = getBridges(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: @@ -249,20 +249,20 @@ def default_network_rules_systemvm(vm_name, localbrname): for bridge in bridges: if bridge != localbrname: if not addFWFramework(bridge): - return False + return False brfw = "BF-" + bridge vifs = getVifsForBridge(vm_name, bridge) for vif in vifs: try: - execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) - execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain) + execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) + execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain) execute("iptables -A " + vmchain + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j RETURN") 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' @@ -305,7 +305,7 @@ def create_ipset_forvm (ipsetname): logging.debug("Creating ipset chain .... " + ipsetname) execute("ipset -F " + ipsetname) execute("ipset -X " + ipsetname) - execute("ipset -N " + ipsetname + " iphash") + execute("ipset -N " + ipsetname + " iphash") except: logging.debug("ipset chain not exists creating.... " + ipsetname) execute("ipset -N " + ipsetname + " iphash") @@ -317,7 +317,7 @@ def add_to_ipset(ipsetname, ips, action): for ip in ips: try: logging.debug("vm ip " + ip) - execute("ipset " + action + " " + ipsetname + " " + ip) + execute("ipset " + action + " " + ipsetname + " " + ip) except: logging.debug("vm ip alreday in ip set " + ip) continue @@ -345,36 +345,36 @@ def ebtables_rules_vmip (vmname, ips, action): for ip in ips: logging.debug("ip = "+ip) try: - execute("ebtables -t nat -I " + vmchain_inips + " -p ARP --arp-ip-src " + ip + " -j RETURN") - execute("ebtables -t nat -I " + vmchain_outips + " -p ARP --arp-ip-dst " + ip + " -j RETURN") + execute("ebtables -t nat -I " + vmchain_inips + " -p ARP --arp-ip-src " + ip + " -j RETURN") + execute("ebtables -t nat -I " + vmchain_outips + " -p ARP --arp-ip-dst " + ip + " -j RETURN") except: - logging.debug("Failed to program ebtables rules for secondary ip "+ ip) + logging.debug("Failed to program ebtables rules for secondary ip "+ ip) continue def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, sec_ips): if not addFWFramework(brname): - return False + return False vmName = vm_name brfw = "BF-" + brname domID = getvmId(vm_name) delete_rules_for_vm_in_bridge_firewall_chain(vmName) vmchain = vm_name - vmchain_egress = egress_chain_name(vm_name) + vmchain_egress = egress_chain_name(vm_name) vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def" - + destroy_ebtables_rules(vmName, vif) try: execute("iptables -N " + vmchain) except: execute("iptables -F " + vmchain) - + try: execute("iptables -N " + vmchain_egress) except: execute("iptables -F " + vmchain_egress) - + try: execute("iptables -N " + vmchain_default) except: @@ -406,59 +406,59 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, sec_ips): logging.debug("Failed to log default network rules, ignoring") try: - execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default) - execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default) - execute("iptables -A " + vmchain_default + " -m state --state RELATED,ESTABLISHED -j ACCEPT") + execute("iptables -A " + brfw + "-OUT" + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default) + execute("iptables -A " + brfw + "-IN" + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default) + execute("iptables -A " + vmchain_default + " -m state --state RELATED,ESTABLISHED -j ACCEPT") #allow dhcp execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -p udp --dport 67 --sport 68 -j ACCEPT") execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -p udp --dport 68 --sport 67 -j ACCEPT") #don't let vm spoof its ip address if vm_ip is not None: - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p udp --dport 53 -j RETURN ") - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -j " + vmchain_egress) - execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -p udp --dport 53 -j RETURN ") + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -m set --set " + vmipsetName + " src -j " + vmchain_egress) + execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain) execute("iptables -A " + vmchain + " -j DROP") except: logging.debug("Failed to program default rules for vm " + vm_name) return 'false' - + default_ebtables_rules(vmchain, vm_ip, vm_mac, vif) #default ebtables rules for vm secondary ips ebtables_rules_vmip(vm_name, ips, "-I") - + if vm_ip is not None: 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 post_default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname, dhcpSvr, hostIp, hostMacAddr): vmchain_default = '-'.join(vm_name.split('-')[:-1]) + "-def" vmchain_in = vm_name + "-in" vmchain_out = vm_name + "-out" domID = getvmId(vm_name) try: - execute("iptables -I " + vmchain_default + " 4 -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT") + execute("iptables -I " + vmchain_default + " 4 -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j ACCEPT") except: pass try: execute("iptables -t nat -A PREROUTING -p tcp -m physdev --physdev-in " + vif + " -m tcp --dport 80 -d " + dhcpSvr + " -j DNAT --to-destination " + hostIp + ":80") except: pass - + try: execute("ebtables -t nat -I " + vmchain_in + " -p IPv4 --ip-protocol tcp --ip-destination-port 80 --ip-dst " + dhcpSvr + " -j dnat --to-destination " + hostMacAddr) except: pass - + try: - execute("ebtables -t nat -I " + vmchain_in + " 4 -p ARP --arp-ip-src ! " + vm_ip + " -j DROP") + execute("ebtables -t nat -I " + vmchain_in + " 4 -p ARP --arp-ip-src ! " + vm_ip + " -j DROP") except: pass try: - execute("ebtables -t nat -I " + vmchain_out + " 2 -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP") + execute("ebtables -t nat -I " + vmchain_out + " 2 -p ARP --arp-ip-dst ! " + vm_ip + " -j DROP") except: pass if write_rule_log_for_vm(vm_name, vm_id, vm_ip, domID, '_initial_', '-1') == False: @@ -467,10 +467,10 @@ 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]) + "-def" - + vmchain = vm_name - - delcmd = "iptables-save | grep BF | grep " + vmchain + " | grep physdev-is-bridged | sed 's/-A/-D/'" + + delcmd = "iptables-save | grep BF | grep " + vmchain + " | grep physdev-is-bridged | sed 's/-A/-D/'" delcmds = execute(delcmd).split('\n') delcmds.pop() for cmd in delcmds: @@ -482,14 +482,14 @@ def delete_rules_for_vm_in_bridge_firewall_chain(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 + 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): @@ -497,14 +497,14 @@ def get_rule_log_for_vm(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 check_domid_changed(vmName): @@ -512,37 +512,37 @@ def check_domid_changed(vmName): try: curr_domid = getvmId(vmName) if (curr_domid is None) or (not curr_domid.isdigit()): - curr_domid = '-1' + curr_domid = '-1' except: pass - + logfilename = "/var/run/cloud/" + vmName +".log" if not os.path.exists(logfilename): return ['-1', curr_domid] - + lines = (line.rstrip() for line in open(logfilename)) - + [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = ['_', '-1', '_', '-1', '_', '-1'] for line in lines: [_vmName,_vmID,_vmIP,old_domid,_signature,_seqno] = line.split(',') break - + return [curr_domid, old_domid] def network_rules_for_rebooted_vm(vmName): vm_name = vmName [curr_domid, old_domid] = check_domid_changed(vm_name) - + if curr_domid == old_domid: return True - + if old_domid == '-1': return True - + if curr_domid == '-1': return True - - logging.debug("Found a rebooted VM -- reprogramming rules for " + vm_name) - + + logging.debug("Found a rebooted VM -- reprogramming rules for " + vm_name) + delete_rules_for_vm_in_bridge_firewall_chain(vm_name) brName = execute("iptables-save |grep physdev-is-bridged |grep FORWARD |grep BF |grep '\-o' |awk '{print $9}' | head -1").strip() @@ -552,10 +552,10 @@ def network_rules_for_rebooted_vm(vmName): brName = re.sub("^BF-", "", brName) if 1 in [ vm_name.startswith(c) for c in ['r-', 's-', 'v-'] ]: - + default_network_rules_systemvm(vm_name, brName) return True - + vmchain = vm_name vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def" @@ -567,8 +567,8 @@ def network_rules_for_rebooted_vm(vmName): #change antispoof rule in vmchain try: - delcmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev | sed 's/-A/-D/'" - inscmd = "iptables-save |grep '\-A " + vmchain_default + "' | grep physdev | sed -r 's/vnet[0-9]+/ " + vifs[0] + "/' | sed 's/-A/-I/'" + delcmd = "iptables-save | grep '\-A " + vmchain_default + "' | grep physdev | sed 's/-A/-D/'" + inscmd = "iptables-save |grep '\-A " + vmchain_default + "' | grep physdev | sed -r 's/vnet[0-9]+/ " + vifs[0] + "/' | sed 's/-A/-I/'" ipts = [] for cmd in [delcmd, inscmd]: logging.debug(cmd) @@ -577,7 +577,7 @@ def network_rules_for_rebooted_vm(vmName): for c in cmds: ipt = "iptables " + c ipts.append(ipt) - + for ipt in ipts: try: execute(ipt) @@ -592,7 +592,7 @@ def network_rules_for_rebooted_vm(vmName): def get_rule_logs_for_vms(): cmd = "virsh list|awk '/running/ {print $2}'" vms = bash("-c", cmd).stdout.split("\n") - + result = [] try: for name in vms: @@ -605,11 +605,11 @@ def get_rule_logs_for_vms(): 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 + return True def cleanup_rules(): @@ -620,7 +620,7 @@ def cleanup_rules(): for chain in chains: if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]: vm_name = chain - + cmd = "virsh list |awk '/" + vm_name + "/ {print $3}'" try: result = execute(cmd).strip() @@ -634,13 +634,13 @@ def cleanup_rules(): if not (result == "running" or result == "paused"): logging.debug("vm " + vm_name + " is not running or paused, cleaning up iptable rules") cleanup.append(vm_name) - + chainscmd = "ebtables-save |grep :i |awk '{print $1}' |sed -e 's/\-in//g' |sed -e 's/\-out//g' |sed -e 's/^://g'" chains = execute(chainscmd).split('\n') for chain in chains: if 1 in [ chain.startswith(c) for c in ['r-', 'i-', 's-', 'v-'] ]: vm_name = chain - + cmd = "virsh list |awk '/" + vm_name + "/ {print $3}'" try: result = execute(cmd).strip() @@ -657,8 +657,8 @@ def cleanup_rules(): for vmname in cleanup: destroy_network_rules_for_vm(vmname) - - logging.debug("Cleaned up rules for " + str(len(cleanup)) + " chains") + + logging.debug("Cleaned up rules for " + str(len(cleanup)) + " chains") except: logging.debug("Failed to cleanup rules !") @@ -667,11 +667,11 @@ def check_rule_log_for_vm(vmName, vmId, vmIP, domID, signature, seqno): 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) + logging.debug("failed to open " + logfilename) return [True, True, True, True, True, True] [_vmName,_vmID,_vmIP,_domID,_signature,_seqno] = ['_', '-1', '_', '-1', '_', '-1'] @@ -683,7 +683,7 @@ def check_rule_log_for_vm(vmName, vmId, vmIP, domID, signature, seqno): logging.debug("Failed to parse log file for vm " + vm_name) remove_rule_log_for_vm(vm_name) return [True, True, True, True, True, True] - + 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): @@ -699,9 +699,9 @@ def write_rule_log_for_vm(vmName, vmID, vmIP, domID, signature, seqno): except: logging.debug("Failed to write to rule log file " + logfilename) result = False - + logf.close() - + return result def remove_rule_log_for_vm(vmName): @@ -714,7 +714,7 @@ def remove_rule_log_for_vm(vmName): except: logging.debug("Failed to delete rule log file " + logfilename) result = False - + return result def egress_chain_name(vm_name): @@ -724,17 +724,17 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif try: vmName = vm_name domId = getvmId(vmName) - - - + + + changes = [] 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[0] or changes[1] or changes[2] or changes[3]: default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname, sec_ips) @@ -743,18 +743,18 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif else: lines = rules.split(';')[:-1] - logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name) + logging.debug(" programming network rules for IP: " + vm_ip + " vmname=" + vm_name) try: vmchain = vm_name execute("iptables -F " + vmchain) egress_vmchain = egress_chain_name(vm_name) execute("iptables -F " + egress_vmchain) - except: - logging.debug("Error flushing iptables rules for " + vmchain + ". Presuming firewall rules deleted, re-initializing." ) + except: + logging.debug("Error flushing iptables rules for " + vmchain + ". Presuming firewall rules deleted, re-initializing." ) default_network_rules(vm_name, vm_id, vm_ip, vmMac, vif, brname) egressrule = 0 for line in lines: - + tokens = line.split(':') if len(tokens) != 5: continue @@ -775,12 +775,12 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif vmchain = vm_name action = "ACCEPT" direction = "-s" - if '0.0.0.0/0' in ips: + 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 ips: if protocol == 'all': for ip in ips: execute("iptables -I " + vmchain + " -m state --state NEW " + direction + " " + ip + " -j "+action) @@ -792,32 +792,32 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif if start == "-1": range = "any" for ip in ips: - execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " " + direction + " " + ip + " -j "+ action) - + execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " " + direction + " " + ip + " -j "+ action) + if allow_any and protocol != 'all': if protocol != 'icmp': - execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -j "+ action) + execute("iptables -I " + vmchain + " -p " + protocol + " -m " + protocol + " --dport " + range + " -m state --state NEW -j "+ action) else: range = start + "/" + end if start == "-1": range = "any" execute("iptables -I " + vmchain + " -p icmp --icmp-type " + range + " -j "+action) - + egress_vmchain = egress_chain_name(vm_name) if egressrule == 0 : - iptables = "iptables -A " + egress_vmchain + " -j RETURN" + iptables = "iptables -A " + egress_vmchain + " -j RETURN" execute(iptables) else: - iptables = "iptables -A " + egress_vmchain + " -j DROP" + iptables = "iptables -A " + egress_vmchain + " -j DROP" execute(iptables) vmchain = vm_name - iptables = "iptables -A " + vmchain + " -j DROP" - 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: exceptionText = traceback.format_exc() @@ -826,15 +826,15 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif def getVifs(vmName): vifs = [] try: - xmlfile = virsh("dumpxml", vmName).stdout + xmlfile = virsh("dumpxml", vmName).stdout except: - return vifs + return vifs dom = xml.dom.minidom.parseString(xmlfile) for network in dom.getElementsByTagName("interface"): target = network.getElementsByTagName('target')[0] nicdev = target.getAttribute("dev").strip() - vifs.append(nicdev) + vifs.append(nicdev) return vifs def getVifsForBridge(vmName, brname): @@ -871,7 +871,7 @@ def getBridges(vmName): def getvmId(vmName): cmd = "virsh list |awk '/" + vmName + "/ {print $1}'" return bash("-c", cmd).stdout.strip() - + def addFWFramework(brname): try: cfo = configFileOps("/etc/sysctl.conf") @@ -904,7 +904,7 @@ def addFWFramework(brname): execute("iptables -N " + brfwin) try: - refs = execute("iptables -n -L " + brfw + " |grep " + brfw + " | cut -d \( -f2 | awk '{print $1}'").strip() + refs = execute("iptables -n -L " + brfw + " |grep " + brfw + " | cut -d \( -f2 | awk '{print $1}'").strip() if refs == "0": execute("iptables -I FORWARD -i " + brname + " -j DROP") execute("iptables -I FORWARD -o " + brname + " -j DROP") @@ -915,8 +915,8 @@ def addFWFramework(brname): execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-in -j " + brfwin) execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-is-out -j " + brfwout) execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT") - - + + return True except: try: @@ -924,7 +924,7 @@ def addFWFramework(brname): except: return False return False - + if __name__ == '__main__': logging.basicConfig(filename="/var/log/cloudstack/agent/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG) parser = OptionParser() @@ -953,7 +953,7 @@ if __name__ == '__main__': elif cmd == "default_network_rules": default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname, option.nicSecIps) elif cmd == "destroy_network_rules_for_vm": - destroy_network_rules_for_vm(option.vmName, option.vif) + destroy_network_rules_for_vm(option.vmName, option.vif) elif cmd == "default_network_rules_systemvm": default_network_rules_systemvm(option.vmName, option.localbrname) elif cmd == "get_rule_logs_for_vms":