bug 10617: Added Egress rules to Security groups.

Description :
   API's:
     -  Two new api's authorizeSecurityGroupEgress,revokeSecurityGroupEgressCmd are added. These two API's are similer to ingress rule API's.
           - authorizeSecurityGroupEgress :Authorizes a particular egress rule for this security group . Usageof API is very similer to that of authorizeSecurityGroupIngress except that instead of source cidr  there will be destination cidr. By default like ingress, all the outgoing flows are blocked.
           - revokeSecurityGroupEgress : It is similer to revokeSecurityGroupIngress api, It removes the egress rule.
     -  listSecurityGroup API's response changed. It include's egress list apart from the existing ingress rules in the output of the API.

   Hypervisors :
      - It is implemented in Xen and KVM.

   Pending Tasks :  Blocking using destination security groups.

   Previous commits: c9fda641673df7701f44963ef27e1d488f121219 , 24e4e44b8f0712a37147a3777833de3f9e24829e
This commit is contained in:
Naredula Janardhana Reddy 2011-08-30 15:55:51 +05:30
parent 279d21ee92
commit 854f81962f
5 changed files with 44 additions and 19 deletions

View File

@ -929,7 +929,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} else if (cmd instanceof CopyVolumeCommand) {
return execute((CopyVolumeCommand)cmd);
} else {
s_logger.warn("Unsupported command ");
s_logger.warn("Unsupported command :"+cmd.toString());
return Answer.createUnsupportedCommandAnswer(cmd);
}
} catch (final IllegalArgumentException e) {
@ -1622,7 +1622,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.stringifyRules(), vif, brname);
if (!result) {
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
s_logger.warn("Failed to program Ingress network rules for vm " + cmd.getVmName());
return new SecurityIngressRuleAnswer(cmd, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length);
@ -1650,7 +1650,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.stringifyRules(), vif, brname);
if (!result) {
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
s_logger.warn("Failed to program Egress network rules for vm " + cmd.getVmName());
return new SecurityEgressRuleAnswer(cmd, false, "programming network rules failed");
} else {
s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", numrules=" + cmd.getRuleSet().length);
@ -3516,7 +3516,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.add("--vmid", vmId);
cmd.add("--vmip", guestIP);
/* type of the rule : ingress or egress */
cmd.add("--type", type);
cmd.add("--ruletype", type);
cmd.add("--sig", sig);
cmd.add("--seq", seq);
cmd.add("--vmmac", mac);

View File

@ -481,6 +481,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((CheckSshCommand)cmd);
} else if (clazz == SecurityIngressRulesCmd.class) {
return execute((SecurityIngressRulesCmd) cmd);
} else if (clazz == SecurityEgressRulesCmd.class) {
return execute((SecurityEgressRulesCmd) cmd);
} else if (clazz == OvsCreateGreTunnelCommand.class) {
return execute((OvsCreateGreTunnelCommand)cmd);
} else if (clazz == OvsSetTagAndFlowCommand.class) {

View File

@ -82,6 +82,7 @@ def ipset(ipsetname, proto, start, end, ips):
def destroy_network_rules_for_vm(vm_name, vif=None):
vmchain = vm_name
vmchain_egress = vm_name + "-egress"
vmchain_default = None
delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
@ -111,7 +112,19 @@ def destroy_network_rules_for_vm(vm_name, vif=None):
execute("iptables -X " + vmchain)
except:
logging.debug("Ignoring failure to delete chain " + vmchain)
try:
execute("iptables -F " + vmchain_egress)
except:
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)
if vif is not None:
try:
dnats = execute("iptables -t nat -S | grep " + vif + " | sed 's/-A/-D/'").split("\n")
@ -246,6 +259,7 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname):
domID = getvmId(vm_name)
delete_rules_for_vm_in_bridge_firewall_chain(vmName)
vmchain = vm_name
vmchain_egress = vm_name +"-egress"
vmchain_default = '-'.join(vmchain.split('-')[:-1]) + "-def"
destroy_ebtables_rules(vmName, vif)
@ -254,7 +268,12 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname):
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:
@ -270,7 +289,7 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname):
#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 + " --source " + vm_ip + " -j ACCEPT")
execute("iptables -A " + vmchain_default + " -m physdev --physdev-is-bridged --physdev-in " + vif + " --source " + vm_ip + " -j " + vmchain_egress)
execute("iptables -A " + vmchain_default + " -j " + vmchain)
execute("iptables -A " + vmchain + " -j DROP")
except:
@ -552,12 +571,17 @@ def remove_rule_log_for_vm(vmName):
return result
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname):
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname,ruletype):
try:
vmName = vm_name
domId = getvmId(vmName)
vmchain = vm_name
if ruletype == 'egress':
vmchain = vm_name + "-egress"
else:
vmchain = vm_name
changes = []
changes = check_rule_log_for_vm(vmName, vm_id, vm_ip, domId, signature, seqno)
@ -704,6 +728,7 @@ if __name__ == '__main__':
parser.add_option("--vmid", dest="vmID")
parser.add_option("--vmmac", dest="vmMAC")
parser.add_option("--vif", dest="vif")
parser.add_option("--ruletype", dest="ruletype")
parser.add_option("--sig", dest="sig")
parser.add_option("--seq", dest="seq")
parser.add_option("--rules", dest="rules")
@ -724,7 +749,7 @@ if __name__ == '__main__':
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, option.vif, option.brname)
add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname,option.ruletype)
elif cmd == "cleanup_rules":
cleanup_rules()
elif cmd == "post_default_network_rules":

View File

@ -175,11 +175,6 @@ public class SecurityGroupResultObject {
currentGroup = groupResult;
}
SecurityGroupRulesVO dummyIngressobj=new SecurityGroupRulesVO();
SecurityGroupEgressRulesVO dummyEgressobj=new SecurityGroupEgressRulesVO() ;
String str=dummyIngressobj.getClass().getName();
String s1=netGroupRule.getClass().getSimpleName();
if (netGroupRule.getRuleId() != null && netGroupRule.getClass().getSimpleName().indexOf("SecurityGroupRulesVO") != -1) {
// there's at least one ingress rule for this network group, add the ingress rule data
@ -246,6 +241,9 @@ String s1=netGroupRule.getClass().getSimpleName();
if (!ingressDataList.isEmpty()) {
currentGroup.setIngressRules(ingressDataList);
}
if (!egressDataList.isEmpty()) {
currentGroup.setEgressRules(egressDataList);
}
resultObjects.add(currentGroup);
}
}

View File

@ -988,10 +988,10 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
Account caller = UserContext.current().getCaller();
Long id = cmd.getId();
IngressRuleVO rule = _ingressRuleDao.findById(id);
EgressRuleVO rule = _egressRuleDao.findById(id);
if (rule == null) {
s_logger.debug("Unable to find ingress rule with id " + id);
throw new InvalidParameterValueException("Unable to find ingress rule with id " + id);
s_logger.debug("Unable to find egress rule with id " + id);
throw new InvalidParameterValueException("Unable to find egress rule with id " + id);
}
// Check permissions
@ -1010,8 +1010,8 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG
return false;
}
_ingressRuleDao.remove(id);
s_logger.debug("revokeSecurityGroupIngress succeeded for ingress rule id: " + id);
_egressRuleDao.remove(id);
s_logger.debug("revokeSecurityGroupEgress succeeded for ingress rule id: " + id);
final Set<Long> affectedVms = new HashSet<Long>();
affectedVms.addAll(_securityGroupVMMapDao.listVmIdsBySecurityGroup(groupHandle.getId()));