security group is per bridge

This commit is contained in:
Edison Su 2011-02-25 18:32:05 -05:00
parent 98ac48e8c2
commit 52a1b2decb
11 changed files with 132 additions and 65 deletions

View File

@ -1402,12 +1402,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private Answer execute(SecurityIngressRulesCmd cmd) {
String vif = null;
String brname = null;
try {
Connect conn = LibvirtConnection.getConnection();
List<InterfaceDef> nics = getInterfaces(conn, cmd.getVmName());
vif = nics.get(0).getBrName();
vif = nics.get(0).getDevName();
brname = nics.get(0).getBrName();
} catch (LibvirtException e) {
return new SecurityIngressRuleAnswer(cmd, false, e.toString());
}
boolean result = add_network_rules(cmd.getVmName(),
@ -1415,7 +1417,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.getGuestIp(),cmd.getSignature(),
Long.toString(cmd.getSeqNum()),
cmd.getGuestMac(),
cmd.stringifyRules(), vif);
cmd.stringifyRules(), vif, brname);
if (!result) {
s_logger.warn("Failed to program network rules for vm " + cmd.getVmName());
@ -2053,9 +2055,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.debug("starting " + vmName + ": " + vm.toString());
startDomain(conn, vmName, vm.toString());
if (vmSpec.getType() != VirtualMachine.Type.User) {
default_network_rules_for_systemvm(vmName);
}
NicTO[] nics = vmSpec.getNics();
for (NicTO nic : nics) {
if (nic.isSecurityGroupEnabled()) {
if (vmSpec.getType() != VirtualMachine.Type.User) {
default_network_rules_for_systemvm(conn, vmName);
} else {
default_network_rules(conn, vmName, nic, vmSpec.getId());
}
}
}
// Attach each data volume to the VM, if there is a deferred attached disk
for (DiskDef disk : vm.getDevices().getDisks()) {
@ -3129,6 +3139,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
if (!_can_bridge_firewall) {
return false;
}
Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
cmd.add("destroy_network_rules_for_vm");
cmd.add("--vmname");
@ -3140,16 +3151,28 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return true;
}
private boolean default_network_rules(String vmName, long vmId, String rules) {
private boolean default_network_rules(Connect conn, String vmName, NicTO nic, Long vmId) {
if (!_can_bridge_firewall) {
return false;
}
List<InterfaceDef> intfs = getInterfaces(conn, vmName);
if (intfs.size() < nic.getDeviceId()) {
return false;
}
InterfaceDef intf = intfs.get(nic.getDeviceId());
String brname = intf.getBrName();
String vif = intf.getDevName();
Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
cmd.add("default_network_rules");
cmd.add("--vmname", vmName);
cmd.add("--rules", rules);
cmd.add("--vmid", Long.toString(vmId));
cmd.add("--vmid", vmId.toString());
cmd.add("--vmip", nic.getIp());
cmd.add("--vmmac", nic.getMac());
cmd.add("--vif", vif);
cmd.add("--brname", brname);
String result = cmd.execute();
if (result != null) {
return false;
@ -3157,14 +3180,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return true;
}
private boolean default_network_rules_for_systemvm(String vmName) {
private boolean default_network_rules_for_systemvm(Connect conn, String vmName) {
if (!_can_bridge_firewall) {
return false;
}
List<InterfaceDef> intfs = getInterfaces(conn, vmName);
if (intfs.size() < 1) {
return false;
}
/*FIX ME: */
InterfaceDef intf = intfs.get(intfs.size() - 1);
String brname = intf.getBrName();
Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
cmd.add("default_network_rules_systemvm");
cmd.add("--vmname");
cmd.add(vmName);
cmd.add("--vmname", vmName);
cmd.add("--brname", brname);
String result = cmd.execute();
if (result != null) {
return false;
@ -3172,10 +3203,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return true;
}
private boolean add_network_rules(String vmName, String vmId, String guestIP, String sig, String seq, String mac, String rules, String vif) {
private boolean add_network_rules(String vmName, String vmId, String guestIP, String sig, String seq, String mac, String rules, String vif, String brname) {
if (!_can_bridge_firewall) {
return false;
}
String newRules = rules.replace(" ", ";");
Script cmd = new Script(_securityGroupPath, _timeout, s_logger);
cmd.add("add_network_rules");
@ -3186,6 +3218,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
cmd.add("--seq", seq);
cmd.add("--vmmac", mac);
cmd.add("--vif", vif);
cmd.add("--brname", brname);
if (rules != null)
cmd.add("--rules", newRules);
String result = cmd.execute();
@ -3302,8 +3335,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
private Answer execute(NetworkRulesSystemVmCommand cmd) {
boolean success = false;
success = default_network_rules_for_systemvm(cmd.getVmName());
Connect conn;
try {
conn = LibvirtConnection.getConnection();
success = default_network_rules_for_systemvm(conn, cmd.getVmName());
} catch (LibvirtException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Answer(cmd, success, "");
}

View File

@ -37,6 +37,7 @@ public class NetworkTO {
protected TrafficType type;
protected URI broadcastUri;
protected URI isolationUri;
protected boolean isSecurityGroupEnabled;
public NetworkTO() {
}
@ -84,7 +85,11 @@ public class NetworkTO {
public void setType(TrafficType type) {
this.type = type;
}
public void setSecurityGroupEnabled(boolean enabled) {
this.isSecurityGroupEnabled = enabled;
}
/**
* This constructor is usually for hosts where the other information are not important.
*
@ -160,4 +165,9 @@ public class NetworkTO {
public void setIsolationuri(URI isolationUri) {
this.isolationUri = isolationUri;
}
public boolean isSecurityGroupEnabled() {
return this.isSecurityGroupEnabled;
}
}

View File

@ -9,6 +9,7 @@ public class NicTO extends NetworkTO {
Integer networkRateMulticastMbps;
boolean defaultNic;
public NicTO() {
super();
}

View File

@ -34,6 +34,7 @@ public class NicProfile {
String dns1;
String dns2;
int networkRate;
boolean isSecurityGroupEnabled;
public String getDns1() {
return dns1;
@ -238,6 +239,14 @@ public class NicProfile {
this.reservationId = reservationId;
}
public boolean isSecurityGroupEnabled() {
return this.isSecurityGroupEnabled;
}
public void setSecurityGroupEnabled(boolean enabled) {
this.isSecurityGroupEnabled = enabled;
}
public void deallocate() {
this.gateway = null;
this.mode = null;

View File

@ -54,34 +54,13 @@ def can_bridge_firewall(privnic):
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 not os.path.exists('/var/run/cloud'):
os.makedirs('/var/run/cloud')
cleanup_rules_for_dead_vms()
cleanup_rules()
return result
return True
'''
def ipset(ipsetname, proto, start, end, ips):
try:
@ -195,10 +174,14 @@ def default_ebtables_rules(vm_name, vm_ip, vm_mac, vif):
return 'false'
def default_network_rules_systemvm(vm_name):
def default_network_rules_systemvm(vm_name, brname):
if not addFWFramework(brname):
return False
vifs = getVifs(vm_name)
domid = getvmId(vm_name)
vmchain = vm_name
brfw = "BRIDGE-FIREWALL-" + brname
delete_rules_for_vm_in_bridge_firewall_chain(vm_name)
@ -210,8 +193,8 @@ def default_network_rules_systemvm(vm_name):
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)
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain)
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain)
except:
logging.debug("Failed to program default rules")
return 'false'
@ -223,8 +206,12 @@ def default_network_rules_systemvm(vm_name):
return 'true'
def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif):
def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif, brname):
if not addFWFramework(brname):
return False
vmName = vm_name
brfw = "BRIDGE-FIREWALL-" + brname
domID = getvmId(vm_name)
delete_rules_for_vm_in_bridge_firewall_chain(vmName)
vmchain = vm_name
@ -243,8 +230,8 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_mac, vif):
execute("iptables -F " + vmchain_default)
try:
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default)
execute("iptables -A BRIDGE-FIREWALL -m physdev --physdev-is-bridged --physdev-in " + vif + " -j " + vmchain_default)
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + vif + " -j " + vmchain_default)
execute("iptables -A " + brfw + " -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")
@ -272,7 +259,7 @@ def delete_rules_for_vm_in_bridge_firewall_chain(vmName):
vmchain = vm_name
delcmd = "iptables -S BRIDGE-FIREWALL | grep " + vmchain + " | sed 's/-A/-D/'"
delcmd = "iptables -S | grep " + vmchain + " | grep physdev-is-bridged | sed 's/-A/-D/'"
delcmds = execute(delcmd).split('\n')
delcmds.pop()
for cmd in delcmds:
@ -419,7 +406,7 @@ def remove_rule_log_for_vm(vmName):
return result
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif):
def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif, brname):
try:
vmName = vm_name
domId = getvmId(vmName)
@ -437,7 +424,7 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif
return 'true'
if changes[0] or changes[2]:
default_network_rules(vmName, vm_id, vm_ip, vmMac, vif)
default_network_rules(vmName, vm_id, vm_ip, vmMac, vif, brname)
lines = rules.split(';')[:-1]
@ -513,6 +500,32 @@ def getvmId(vmName):
cmd = "virsh list |grep " + vmName + " | awk '{print $1}'"
return bash("-c", cmd).stdout.strip()
def addFWFramework(brname):
brfw = "BRIDGE-FIREWALL-" + brname
try:
execute("iptables -L " + brfw)
except:
execute("iptables -N " + brfw)
try:
refs = execute("iptables -n -L " + brfw + " |grep " + brfw + " | cut -d \( -f2 | awk '{print $1}'").strip()
if refs == "0":
execute("iptables -A FORWARD -i " + brname + " -m physdev --physdev-is-bridged -j " + brfw)
execute("iptables -A FORWARD -o " + brname + " -m physdev --physdev-is-bridged -j " + brfw)
phydev = execute("brctl show |grep " + brname + " | awk '{print $4}'").strip()
execute("iptables -A " + brfw + " -m physdev --physdev-is-bridged --physdev-out " + phydev + " -j ACCEPT")
execute("iptables -A " + brfw + " -m state --state RELATED,ESTABLISHED -j ACCEPT")
execute("iptables -A FORWARD -i " + brname + " -j DROP")
execute("iptables -A FORWARD -o " + brname + " -j DROP")
return True
except:
try:
execute("iptables -F " + brfw)
except:
return False
return False
if __name__ == '__main__':
logging.basicConfig(filename="/var/log/cloud/security_group.log", format="%(asctime)s - %(message)s", level=logging.DEBUG)
parser = OptionParser()
@ -524,20 +537,20 @@ if __name__ == '__main__':
parser.add_option("--sig", dest="sig")
parser.add_option("--seq", dest="seq")
parser.add_option("--rules", dest="rules")
parser.add_option("--phynic", dest="phynic")
parser.add_option("--brname", dest="brname")
(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.vmID, option.vmIP, option.vmMAC, option.vif)
default_network_rules(option.vmName, option.vmID, option.vmIP, option.vmMAC, option.vif, option.brname)
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)
default_network_rules_systemvm(option.vmName, option.brname)
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)
add_network_rules(option.vmName, option.vmID, option.vmIP, option.sig, option.seq, option.vmMAC, option.rules, option.vif, option.brname)
elif cmd == "cleanup_rules":
cleanup_rules()

View File

@ -152,7 +152,6 @@ public enum Config {
SecStorageAllowedInternalDownloadSites("Advanced", ManagementServer.class, String.class, "secstorage.allowed.internal.sites", null, "Comma separated list of cidrs internal to the datacenter that can host template download servers", null),
SecStorageEncryptCopy("Advanced", ManagementServer.class, Boolean.class, "secstorage.encrypt.copy", "false", "Use SSL method used to encrypt copy traffic between zones", "true,false"),
SecStorageSecureCopyCert("Advanced", ManagementServer.class, String.class, "secstorage.ssl.cert.domain", "realhostip.com", "SSL certificate used to encrypt copy traffic between zones", null),
DirectAttachSecurityGroupsEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.security.groups.enabled", "false", "Ec2-style distributed firewall for direct-attach VMs", "true,false"),
DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"),
DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null),
CheckPodCIDRs("Advanced", ManagementServer.class, String.class, "check.pod.cidrs", "true", "If true, different pods must belong to different CIDR subnets.", "true,false"),

View File

@ -1135,10 +1135,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
//Create deafult networks
createDefaultNetworks(zone.getId(), isSecurityGroupEnabled);
if (isSecurityGroupEnabled) {
_configDao.update(Config.DirectAttachSecurityGroupsEnabled.key(), "true");
}
txn.commit();
return zone;
} catch (Exception ex) {

View File

@ -49,6 +49,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setBroadcastUri(profile.getBroadCastUri());
to.setIsolationuri(profile.getIsolationUri());
to.setNetworkRateMbps(profile.getNetworkRate());
to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
return to;
}

View File

@ -1172,6 +1172,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
element.prepare(network, profile, vmProfile, dest, context);
}
profile.setSecurityGroupEnabled(network.isSecurityGroupEnabled());
concierge.updateNicProfile(profile, network);
vmProfile.addNic(profile);
}

View File

@ -172,6 +172,11 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
}
getIp(nic, dc, vm, network);
/*It's public ip, don't release it*/
if (network.isSecurityGroupEnabled() && nic.getIp4Address() != null) {
nic.setStrategy(ReservationStrategy.Create);
}
return nic;
}

View File

@ -84,14 +84,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
VlanType type = VlanType.VirtualNetwork;
Long networkId = null;
if (network.isSecurityGroupEnabled()) {
type = VlanType.DirectAttached;
networkId = network.getId();
}
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), type, networkId);
PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null);
nic.setIp4Address(ip.getAddress().toString());
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());