CLOUDSTACK-779 Egress firewall rules support for Juniper SRX

This commit is contained in:
Jayapal 2013-04-10 18:04:02 +05:30 committed by Sheng Yang
parent ee0a91d111
commit a4a059c043
7 changed files with 328 additions and 80 deletions

View File

@ -23,6 +23,7 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.State; import com.cloud.network.rules.FirewallRule.State;
import com.cloud.network.rules.FirewallRule.TrafficType;
import com.cloud.utils.net.NetUtils; import com.cloud.utils.net.NetUtils;
/** /**
@ -109,6 +110,11 @@ public class FirewallRuleTO implements InternalIdentity {
this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode()); this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
} }
public FirewallRuleTO(FirewallRule rule, String guestVlanTag, FirewallRule.TrafficType trafficType) {
this(rule.getId(), guestVlanTag, null, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(), rule.getSourceCidrList(), rule.getIcmpType(), rule.getIcmpCode());
this.trafficType = trafficType;
}
public FirewallRule.TrafficType getTrafficType(){ public FirewallRule.TrafficType getTrafficType(){
return trafficType; return trafficType;
} }

View File

@ -274,7 +274,7 @@ PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, Junip
firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
firewallCapabilities.put(Capability.MultipleIps, "true"); firewallCapabilities.put(Capability.MultipleIps, "true");
firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress"); firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
capabilities.put(Service.Firewall, firewallCapabilities); capabilities.put(Service.Firewall, firewallCapabilities);
// Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work // Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work

View File

@ -303,7 +303,7 @@ public class JuniperSrxResource implements ServerResource {
} }
private enum Protocol { private enum Protocol {
tcp, udp, icmp, any; tcp, udp, icmp, all, any;
} }
private enum RuleMatchCondition { private enum RuleMatchCondition {
@ -320,7 +320,8 @@ public class JuniperSrxResource implements ServerResource {
private enum SecurityPolicyType { private enum SecurityPolicyType {
STATIC_NAT("staticnat"), STATIC_NAT("staticnat"),
DESTINATION_NAT("destnat"), DESTINATION_NAT("destnat"),
VPN("vpn"); VPN("vpn"),
SECURITYPOLICY_EGRESS("egress");
private String identifier; private String identifier;
@ -776,6 +777,43 @@ public class JuniperSrxResource implements ServerResource {
s_logger.debug(msg); s_logger.debug(msg);
} }
private Map<String, ArrayList<FirewallRuleTO>> getActiveFirewallEgressRules(FirewallRuleTO[] allRules) {
Map<String, ArrayList<FirewallRuleTO>> activeRules = new HashMap<String, ArrayList<FirewallRuleTO>>();
for (FirewallRuleTO rule : allRules) {
String guestVlan;
guestVlan = rule.getSrcVlanTag();
ArrayList<FirewallRuleTO> activeRulesForNetwork = activeRules.get(guestVlan);
if (activeRulesForNetwork == null) {
activeRulesForNetwork = new ArrayList<FirewallRuleTO>();
}
if (!rule.revoked() || rule.isAlreadyAdded()) {
activeRulesForNetwork.add(rule);
}
activeRules.put(guestVlan, activeRulesForNetwork);
}
return activeRules;
}
private List<String> extractCidrs(List<FirewallRuleTO> rules) throws ExecutionException {
List<String> allCidrs = new ArrayList<String>();
List<String> cidrs = new ArrayList<String>();
for (FirewallRuleTO rule : rules) {
cidrs = (rule.getSourceCidrList());
for (String cidr: cidrs) {
if (!allCidrs.contains(cidr)) {
allCidrs.add(cidr);
}
}
}
return allCidrs;
}
/* security policies */ /* security policies */
private synchronized Answer execute(SetFirewallRulesCommand cmd) { private synchronized Answer execute(SetFirewallRulesCommand cmd) {
@ -787,24 +825,39 @@ public class JuniperSrxResource implements ServerResource {
FirewallRuleTO[] rules = cmd.getRules(); FirewallRuleTO[] rules = cmd.getRules();
try { try {
openConfiguration(); openConfiguration();
if (rules[0].getTrafficType() == FirewallRule.TrafficType.Egress) {
Map<String, ArrayList<FirewallRuleTO>> activeRules = getActiveFirewallEgressRules(rules);
Set<String> guestVlans = activeRules.keySet();
List<String> cidrs = new ArrayList();
for (FirewallRuleTO rule : rules) { for (String guestVlan : guestVlans) {
int startPort = 0, endPort = 0; List<FirewallRuleTO> activeRulesForGuestNw = activeRules.get(guestVlan);
if (rule.getSrcPortRange() != null) {
startPort = rule.getSrcPortRange()[0]; removeEgressSecurityPolicyAndApplications(SecurityPolicyType.SECURITYPOLICY_EGRESS, guestVlan, extractCidrs(activeRulesForGuestNw));
endPort = rule.getSrcPortRange()[1]; if (activeRulesForGuestNw.size() > 0) {
addEgressSecurityPolicyAndApplications(SecurityPolicyType.SECURITYPOLICY_EGRESS, guestVlan, extractApplications(activeRulesForGuestNw), extractCidrs(activeRulesForGuestNw));
}
} }
FirewallFilterTerm term = new FirewallFilterTerm(genIpIdentifier(rule.getSrcIp()) + "-" + String.valueOf(rule.getId()), rule.getSourceCidrList(), commitConfiguration();
rule.getSrcIp(), rule.getProtocol(), startPort, endPort, } else {
rule.getIcmpType(), rule.getIcmpCode(), genIpIdentifier(rule.getSrcIp()) + _usageFilterIPInput.getCounterIdentifier()); for (FirewallRuleTO rule : rules) {
if (!rule.revoked()) { int startPort = 0, endPort = 0;
manageFirewallFilter(SrxCommand.ADD, term, _publicZoneInputFilterName); if (rule.getSrcPortRange() != null) {
} else { startPort = rule.getSrcPortRange()[0];
manageFirewallFilter(SrxCommand.DELETE, term, _publicZoneInputFilterName); endPort = rule.getSrcPortRange()[1];
FirewallFilterTerm term = new FirewallFilterTerm(genIpIdentifier(rule.getSrcIp()) + "-" + String.valueOf(rule.getId()), rule.getSourceCidrList(),
rule.getSrcIp(), rule.getProtocol(), startPort, endPort,
rule.getIcmpType(), rule.getIcmpCode(), genIpIdentifier(rule.getSrcIp()) + _usageFilterIPInput.getCounterIdentifier());
if (!rule.revoked()) {
manageFirewallFilter(SrxCommand.ADD, term, _publicZoneInputFilterName);
} else {
manageFirewallFilter(SrxCommand.DELETE, term, _publicZoneInputFilterName);
}
}
commitConfiguration();
} }
} }
commitConfiguration();
return new Answer(cmd); return new Answer(cmd);
} catch (ExecutionException e) { } catch (ExecutionException e) {
s_logger.error(e); s_logger.error(e);
@ -992,7 +1045,7 @@ public class JuniperSrxResource implements ServerResource {
// Delete all security policies // Delete all security policies
for (String securityPolicyName : getVpnObjectNames(SrxXml.SECURITY_POLICY_GETALL, accountId)) { for (String securityPolicyName : getVpnObjectNames(SrxXml.SECURITY_POLICY_GETALL, accountId)) {
manageSecurityPolicy(SecurityPolicyType.VPN, SrxCommand.DELETE, accountId, null, null, null, securityPolicyName); manageSecurityPolicy(SecurityPolicyType.VPN, SrxCommand.DELETE, accountId, null, null, null, null, securityPolicyName);
} }
// Delete all address book entries // Delete all address book entries
@ -1064,7 +1117,7 @@ public class JuniperSrxResource implements ServerResource {
manageAddressBookEntry(srxCmd, _privateZone , guestNetworkCidr, ipsecVpnName); manageAddressBookEntry(srxCmd, _privateZone , guestNetworkCidr, ipsecVpnName);
// Security policy // Security policy
manageSecurityPolicy(SecurityPolicyType.VPN, srxCmd, null, null, guestNetworkCidr, null, ipsecVpnName); manageSecurityPolicy(SecurityPolicyType.VPN, srxCmd, null, null, guestNetworkCidr, null, null, ipsecVpnName);
} }
commitConfiguration(); commitConfiguration();
@ -2455,38 +2508,44 @@ public class JuniperSrxResource implements ServerResource {
* Applications * Applications
*/ */
private String genApplicationName(Protocol protocol, int startPort, int endPort) { private String genApplicationName(SecurityPolicyType type, Protocol protocol, int startPort, int endPort) {
if (protocol.equals(Protocol.any)) { if (protocol.equals(Protocol.any)) {
return Protocol.any.toString(); return Protocol.any.toString();
} else { } else {
return genObjectName(protocol.toString(), String.valueOf(startPort), String.valueOf(endPort)); if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
return genObjectName(type.getIdentifier(), protocol.toString(), String.valueOf(startPort), String.valueOf(endPort));
} else {
return genObjectName(protocol.toString(), String.valueOf(startPort), String.valueOf(endPort));
}
} }
} }
private Object[] parseApplicationName(String applicationName) throws ExecutionException { private Object[] parseApplicationName(SecurityPolicyType type, String applicationName) throws ExecutionException {
String errorMsg = "Invalid application: " + applicationName; String errorMsg = "Invalid application: " + applicationName;
String[] applicationComponents = applicationName.split("-"); String[] applicationComponents = applicationName.split("-");
Protocol protocol; Protocol protocol;
Integer startPort; Integer startPort;
Integer endPort; Integer endPort;
int offset = 0;
try { try {
protocol = getProtocol(applicationComponents[0]); offset = type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS) ? 1 : 0;
startPort = Integer.parseInt(applicationComponents[1]); protocol = getProtocol(applicationComponents[offset + 0]);
endPort = Integer.parseInt(applicationComponents[2]); startPort = Integer.parseInt(applicationComponents[offset + 1]);
} catch (Exception e) { endPort = Integer.parseInt(applicationComponents[offset + 2]);
} catch (Exception e) {
throw new ExecutionException(errorMsg); throw new ExecutionException(errorMsg);
} }
return new Object[]{protocol, startPort, endPort}; return new Object[]{protocol, startPort, endPort};
} }
private boolean manageApplication(SrxCommand command, Protocol protocol, int startPort, int endPort) throws ExecutionException { private boolean manageApplication(SecurityPolicyType type, SrxCommand command, Protocol protocol, int startPort, int endPort) throws ExecutionException {
if (protocol.equals(Protocol.any)) { if (protocol.equals(Protocol.any)) {
return true; return true;
} }
String applicationName = genApplicationName(protocol, startPort, endPort); String applicationName = genApplicationName(type, protocol, startPort, endPort);
String xml; String xml;
switch (command) { switch (command) {
@ -2498,23 +2557,28 @@ public class JuniperSrxResource implements ServerResource {
return sendRequestAndCheckResponse(command, xml, "name", applicationName); return sendRequestAndCheckResponse(command, xml, "name", applicationName);
case ADD: case ADD:
if (manageApplication(SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) { if (manageApplication(type, SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
return true; return true;
} }
String icmpOrDestPort;
xml = SrxXml.APPLICATION_ADD.getXml(); xml = SrxXml.APPLICATION_ADD.getXml();
xml = replaceXmlValue(xml, "name", applicationName); xml = replaceXmlValue(xml, "name", applicationName);
xml = replaceXmlValue(xml, "protocol", protocol.toString()); xml = replaceXmlValue(xml, "protocol", protocol.toString());
if (protocol.toString() == Protocol.icmp.toString()) {
String destPort; icmpOrDestPort = "<icmp-type>" + startPort + "</icmp-type>";
if (startPort == endPort) { icmpOrDestPort += "<icmp-code>" + endPort + "</icmp-code>";
destPort = String.valueOf(startPort);
} else { } else {
destPort = startPort + "-" + endPort; String destPort;
if (startPort == endPort) {
destPort = String.valueOf(startPort);
} else {
destPort = startPort + "-" + endPort;
}
icmpOrDestPort = "<destination-port>" + destPort + "</destination-port>";
} }
xml = replaceXmlValue(xml, "dest-port", destPort); xml = replaceXmlValue(xml, "dest-port-icmp", icmpOrDestPort);
if (!sendRequestAndCheckResponse(command, xml)) { if (!sendRequestAndCheckResponse(command, xml)) {
throw new ExecutionException("Failed to add application " + applicationName); throw new ExecutionException("Failed to add application " + applicationName);
} else { } else {
@ -2522,7 +2586,7 @@ public class JuniperSrxResource implements ServerResource {
} }
case DELETE: case DELETE:
if (!manageApplication(SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) { if (!manageApplication(type, SrxCommand.CHECK_IF_EXISTS, protocol, startPort, endPort)) {
return true; return true;
} }
@ -2543,13 +2607,13 @@ public class JuniperSrxResource implements ServerResource {
} }
private List<String> getUnusedApplications(List<String> applications) throws ExecutionException { private List<String> getUnusedApplications(List<String> applications, String fromZone, String toZone) throws ExecutionException {
List<String> unusedApplications = new ArrayList<String>(); List<String> unusedApplications = new ArrayList<String>();
// Check if any of the applications are unused by existing security policies // Check if any of the applications are unused by existing security policies
String xml = SrxXml.SECURITY_POLICY_GETALL.getXml(); String xml = SrxXml.SECURITY_POLICY_GETALL.getXml();
xml = replaceXmlValue(xml, "from-zone", _publicZone); xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", _privateZone); xml = replaceXmlValue(xml, "to-zone", toZone);
String allPolicies = sendRequest(xml); String allPolicies = sendRequest(xml);
for (String application : applications) { for (String application : applications) {
@ -2560,10 +2624,7 @@ public class JuniperSrxResource implements ServerResource {
return unusedApplications; return unusedApplications;
} }
private List<String> getApplicationsForSecurityPolicy(SecurityPolicyType type, String privateIp, String fromZone, String toZone) throws ExecutionException {
private List<String> getApplicationsForSecurityPolicy(SecurityPolicyType type, String privateIp) throws ExecutionException {
String fromZone = _publicZone;
String toZone = _privateZone;
String policyName = genSecurityPolicyName(type, null, null, fromZone, toZone, privateIp); String policyName = genSecurityPolicyName(type, null, null, fromZone, toZone, privateIp);
String xml = SrxXml.SECURITY_POLICY_GETONE.getXml(); String xml = SrxXml.SECURITY_POLICY_GETONE.getXml();
xml = setDelete(xml, false); xml = setDelete(xml, false);
@ -2591,8 +2652,31 @@ public class JuniperSrxResource implements ServerResource {
for (FirewallRuleTO rule : rules) { for (FirewallRuleTO rule : rules) {
Object[] application = new Object[3]; Object[] application = new Object[3];
application[0] = getProtocol(rule.getProtocol()); application[0] = getProtocol(rule.getProtocol());
application[1] = rule.getSrcPortRange()[0]; if (application[0] == Protocol.icmp) {
application[2] = rule.getSrcPortRange()[1]; if (rule.getIcmpType() == -1) {
application[1] = 255;
} else {
application[1] = rule.getIcmpType();
}
if (rule.getIcmpCode() == -1) {
application[2] = 255;
} else {
application[2] = rule.getIcmpCode();
}
} else if (application[0] == Protocol.tcp || application[0] == Protocol.udp) {
if (rule.getSrcPortRange() != null) {
application[1] = rule.getSrcPortRange()[0];
application[2] = rule.getSrcPortRange()[1];
} else {
application[1] = 0;
application[2] = 65535;
}
} else if (application[0] == Protocol.all) {
application[1] = 0;
application[2] = 65535;
}
applications.add(application); applications.add(application);
} }
@ -2611,16 +2695,20 @@ public class JuniperSrxResource implements ServerResource {
} }
} }
private boolean manageSecurityPolicy(SecurityPolicyType type, SrxCommand command, Long accountId, String username, String privateIp, List<String> applicationNames, String ipsecVpnName) throws ExecutionException { private boolean manageSecurityPolicy(SecurityPolicyType type, SrxCommand command, Long accountId, String username, String privateIp, List<String> applicationNames, List<String> cidrs, String ipsecVpnName) throws ExecutionException {
String fromZone = _publicZone; String fromZone = _publicZone;
String toZone = _privateZone; String toZone = _privateZone;
String securityPolicyName; String securityPolicyName;
String addressBookEntryName; String addressBookEntryName = null;
if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) { if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) {
securityPolicyName = ipsecVpnName; securityPolicyName = ipsecVpnName;
addressBookEntryName = ipsecVpnName; addressBookEntryName = ipsecVpnName;
} else if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
fromZone = _privateZone;
toZone = _publicZone;
securityPolicyName = genSecurityPolicyName(type, accountId, username, fromZone, toZone, privateIp);
} else { } else {
securityPolicyName = genSecurityPolicyName(type, accountId, username, fromZone, toZone, privateIp); securityPolicyName = genSecurityPolicyName(type, accountId, username, fromZone, toZone, privateIp);
addressBookEntryName = genAddressBookEntryName(privateIp); addressBookEntryName = genAddressBookEntryName(privateIp);
@ -2661,17 +2749,38 @@ public class JuniperSrxResource implements ServerResource {
return false; return false;
case ADD: case ADD:
if (!manageAddressBookEntry(SrxCommand.CHECK_IF_EXISTS, toZone, privateIp, ipsecVpnName)) { if (!type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
throw new ExecutionException("No address book entry for policy: " + securityPolicyName); if (!manageAddressBookEntry(SrxCommand.CHECK_IF_EXISTS, toZone, privateIp, addressBookEntryName)) {
throw new ExecutionException("No address book entry for policy: " + securityPolicyName);
}
}
String srcAddrs = "";
String dstAddrs = "";
xml = SrxXml.SECURITY_POLICY_ADD.getXml();
xml = replaceXmlValue(xml, "policy-name", securityPolicyName);
if (type.equals(SecurityPolicyType.SECURITYPOLICY_EGRESS)) {
xml = replaceXmlValue(xml, "from-zone", _privateZone);
xml = replaceXmlValue(xml, "to-zone", _publicZone);
if (cidrs == null) {
srcAddrs = "<source-address>any</source-address>";
} else {
for (String cidr : cidrs) {
srcAddrs += "<source-address>" + genAddressBookEntryName(cidr) + "</source-address>";
}
}
xml = replaceXmlValue(xml, "src-address", srcAddrs);
dstAddrs = "<destination-address>any</destination-address>";
xml = replaceXmlValue(xml, "dst-address", dstAddrs);
} else {
xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", toZone);
srcAddrs = "<source-address>any</source-address>";
xml = replaceXmlValue(xml, "src-address", srcAddrs);
dstAddrs = "<destination-address>" + addressBookEntryName + "</destination-address>";
xml = replaceXmlValue(xml, "dst-address", dstAddrs);
} }
xml = SrxXml.SECURITY_POLICY_ADD.getXml();
xml = replaceXmlValue(xml, "from-zone", fromZone);
xml = replaceXmlValue(xml, "to-zone", toZone);
xml = replaceXmlValue(xml, "policy-name", securityPolicyName);
xml = replaceXmlValue(xml, "src-address", "any");
xml = replaceXmlValue(xml, "dest-address", addressBookEntryName);
if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) { if (type.equals(SecurityPolicyType.VPN) && ipsecVpnName != null) {
xml = replaceXmlValue(xml, "tunnel", "<tunnel><ipsec-vpn>" + ipsecVpnName + "</ipsec-vpn></tunnel>"); xml = replaceXmlValue(xml, "tunnel", "<tunnel><ipsec-vpn>" + ipsecVpnName + "</ipsec-vpn></tunnel>");
} else { } else {
@ -2679,7 +2788,7 @@ public class JuniperSrxResource implements ServerResource {
} }
String applications; String applications;
if (applicationNames == null) { if (applicationNames == null || applicationNames.size() == 0) {
applications = "<application>any</application>"; applications = "<application>any</application>";
} else { } else {
applications = ""; applications = "";
@ -2697,11 +2806,11 @@ public class JuniperSrxResource implements ServerResource {
} }
case DELETE: case DELETE:
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, applicationNames, ipsecVpnName)) { if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, applicationNames, cidrs, ipsecVpnName)) {
return true; return true;
} }
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, applicationNames, ipsecVpnName)) { if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, applicationNames, cidrs, ipsecVpnName)) {
return true; return true;
} }
@ -2757,42 +2866,42 @@ public class JuniperSrxResource implements ServerResource {
int startPort = application[1] != null ? ((Integer) application[1]) : -1; int startPort = application[1] != null ? ((Integer) application[1]) : -1;
int endPort = application[2] != null ? ((Integer) application[2]) : -1; int endPort = application[2] != null ? ((Integer) application[2]) : -1;
String applicationName = genApplicationName(protocol, startPort, endPort); String applicationName = genApplicationName(type, protocol, startPort, endPort);
if (!applicationNames.contains(applicationName)) { if (!applicationNames.contains(applicationName)) {
applicationNames.add(applicationName); applicationNames.add(applicationName);
} }
manageApplication(SrxCommand.ADD, protocol, startPort, endPort); manageApplication(type, SrxCommand.ADD, protocol, startPort, endPort);
} }
// Add a new security policy // Add a new security policy
manageSecurityPolicy(type, SrxCommand.ADD, null, null, privateIp, applicationNames, null); manageSecurityPolicy(type, SrxCommand.ADD, null, null, privateIp, applicationNames, null, null);
return true; return true;
} }
private boolean removeSecurityPolicyAndApplications(SecurityPolicyType type, String privateIp) throws ExecutionException { private boolean removeSecurityPolicyAndApplications(SecurityPolicyType type, String privateIp) throws ExecutionException {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, null, null)) { if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, privateIp, null,null, null)) {
return true; return true;
} }
if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, null, null)) { if (manageSecurityPolicy(type, SrxCommand.CHECK_IF_IN_USE, null, null, privateIp, null, null, null)) {
return true; return true;
} }
// Get a list of applications for this security policy // Get a list of applications for this security policy
List<String> applications = getApplicationsForSecurityPolicy(type, privateIp); List<String> applications = getApplicationsForSecurityPolicy(type, privateIp, _publicZone, _privateZone);
// Remove the security policy // Remove the security policy
manageSecurityPolicy(type, SrxCommand.DELETE, null, null, privateIp, null, null); manageSecurityPolicy(type, SrxCommand.DELETE, null, null, privateIp, null, null, null);
// Remove any applications for the removed security policy that are no longer in use // Remove any applications for the removed security policy that are no longer in use
List<String> unusedApplications = getUnusedApplications(applications); List<String> unusedApplications = getUnusedApplications(applications, _publicZone, _privateZone);
for (String application : unusedApplications) { for (String application : unusedApplications) {
Object[] applicationComponents; Object[] applicationComponents;
try { try {
applicationComponents = parseApplicationName(application); applicationComponents = parseApplicationName(type, application);
} catch (ExecutionException e) { } catch (ExecutionException e) {
s_logger.error("Found an invalid application: " + application + ". Not attempting to clean up."); s_logger.error("Found an invalid application: " + application + ". Not attempting to clean up.");
continue; continue;
@ -2800,13 +2909,78 @@ public class JuniperSrxResource implements ServerResource {
Protocol protocol = (Protocol) applicationComponents[0]; Protocol protocol = (Protocol) applicationComponents[0];
Integer startPort = (Integer) applicationComponents[1]; Integer startPort = (Integer) applicationComponents[1];
Integer endPort = (Integer) applicationComponents[2]; Integer endPort = (Integer) applicationComponents[2];
manageApplication(SrxCommand.DELETE, protocol, startPort, endPort); manageApplication(type, SrxCommand.DELETE, protocol, startPort, endPort);
} }
return true; return true;
} }
private boolean removeEgressSecurityPolicyAndApplications(SecurityPolicyType type, String guestVlan, List <String> cidrs) throws ExecutionException {
if (!manageSecurityPolicy(type, SrxCommand.CHECK_IF_EXISTS, null, null, guestVlan, null, cidrs, null)) {
return true;
}
// Get a list of applications for this security policy
List<String> applications;
applications = getApplicationsForSecurityPolicy(type, guestVlan, _privateZone, _publicZone);
// Remove the security policy even if it is in use
manageSecurityPolicy(type, SrxCommand.DELETE, null, null, guestVlan, null, cidrs, null);
// Remove any applications for the removed security policy that are no longer in use
List<String> unusedApplications;
unusedApplications = getUnusedApplications(applications, _privateZone, _publicZone);
for (String application : unusedApplications) {
Object[] applicationComponents;
try {
applicationComponents = parseApplicationName(type, application);
} catch (ExecutionException e) {
s_logger.error("Found an invalid application: " + application + ". Not attempting to clean up.");
continue;
}
Protocol protocol = (Protocol) applicationComponents[0];
Integer startPort = (Integer) applicationComponents[1];
Integer endPort = (Integer) applicationComponents[2];
manageApplication(type, SrxCommand.DELETE, protocol, startPort, endPort);
}
for (String cidr: cidrs) {
manageAddressBookEntry(SrxCommand.DELETE, _publicZone, cidr, null);
}
return true;
}
private boolean addEgressSecurityPolicyAndApplications(SecurityPolicyType type, String guestVlan, List<Object[]> applications, List <String> cidrs) throws ExecutionException {
// Add all necessary applications
List<String> applicationNames = new ArrayList<String>();
for (Object[] application : applications) {
Protocol protocol = (Protocol) application[0];
if (!protocol.equals(Protocol.all)) {
int startPort = application[1] != null ? ((Integer) application[1]) : 0;
int endPort = application[2] != null ? ((Integer) application[2]) : 65535;
String applicationName = genApplicationName(type, protocol, startPort, endPort);
if (!applicationNames.contains(applicationName)) {
applicationNames.add(applicationName);
}
manageApplication(type, SrxCommand.ADD, protocol, startPort, endPort);
}
}
for (String cidr: cidrs) {
manageAddressBookEntry(SrxCommand.ADD, _privateZone, cidr, null);
}
// Add a new security policy
manageSecurityPolicy(type, SrxCommand.ADD, null, null, guestVlan, applicationNames, cidrs, null);
s_logger.debug("Added Egress firewall rule for guest network " + guestVlan);
return true;
}
/* /*
* Filter terms * Filter terms
*/ */

View File

@ -23,7 +23,7 @@ under the License.
<application> <application>
<name>%name%</name> <name>%name%</name>
<protocol>%protocol%</protocol> <protocol>%protocol%</protocol>
<destination-port>%dest-port%</destination-port> %dest-port-icmp%
</application> </application>
</applications> </applications>
</configuration> </configuration>

View File

@ -27,8 +27,8 @@ under the License.
<policy> <policy>
<name>%policy-name%</name> <name>%policy-name%</name>
<match> <match>
<source-address>%src-address%</source-address> %src-address%
<destination-address>%dest-address%</destination-address> %dst-address%
%applications% %applications%
</match> </match>
<then> <then>

View File

@ -1,3 +1,4 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
@ -541,8 +542,15 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl
if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) { if (rule.getSourceCidrList() == null && (rule.getPurpose() == Purpose.Firewall || rule.getPurpose() == Purpose.NetworkACL)) {
_fwRulesDao.loadSourceCidrs((FirewallRuleVO)rule); _fwRulesDao.loadSourceCidrs((FirewallRuleVO)rule);
} }
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId()); FirewallRuleTO ruleTO;
FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr()); if (rule.getPurpose() == Purpose.Firewall && rule.getTrafficType() == FirewallRule.TrafficType.Egress) {
String guestVlanTag = network.getBroadcastUri().getHost();
String guestCidr = network.getCidr();
ruleTO = new FirewallRuleTO(rule, guestVlanTag, rule.getTrafficType());
} else {
IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr());
}
rulesTO.add(ruleTO); rulesTO.add(ruleTO);
} }

View File

@ -65,6 +65,7 @@ public class Upgrade410to420 implements DbUpgrade {
updateSystemVmTemplates(conn); updateSystemVmTemplates(conn);
updateCluster_details(conn); updateCluster_details(conn);
updatePrimaryStore(conn); updatePrimaryStore(conn);
addEgressFwRulesForSRXGuestNw(conn);
} }
private void updateSystemVmTemplates(Connection conn) { private void updateSystemVmTemplates(Connection conn) {
@ -305,4 +306,63 @@ public class Upgrade410to420 implements DbUpgrade {
} }
} }
} }
private void addEgressFwRulesForSRXGuestNw(Connection conn) {
PreparedStatement pstmt = null;
ResultSet rs = null;
ResultSet rsId = null;
ResultSet rsNw = null;
try {
pstmt = conn.prepareStatement("select network_id FROM `cloud`.`ntwk_service_map` where service='Firewall' and provider='JuniperSRX' ");
rs = pstmt.executeQuery();
while (rs.next()) {
long netId = rs.getLong(1);
//checking for Isolated OR Virtual
pstmt = conn.prepareStatement("select account_id, domain_id FROM `cloud`.`networks` where (guest_type='Isolated' OR guest_type='Virtual') and traffic_type='Guest' and vpc_id is NULL and (state='implemented' OR state='Shutdown') and id=? ");
pstmt.setLong(1, netId);
s_logger.debug("Getting account_id, domain_id from networks table: " + pstmt);
rsNw = pstmt.executeQuery();
if(rsNw.next()) {
long accountId = rsNw.getLong(1);
long domainId = rsNw.getLong(2);
//Add new rule for the existing networks
s_logger.debug("Adding default egress firewall rule for network " + netId);
pstmt = conn.prepareStatement("INSERT INTO firewall_rules (uuid, state, protocol, purpose, account_id, domain_id, network_id, xid, created, traffic_type) VALUES (?, 'Active', 'all', 'Firewall', ?, ?, ?, ?, now(), 'Egress')");
pstmt.setString(1, UUID.randomUUID().toString());
pstmt.setLong(2, accountId);
pstmt.setLong(3, domainId);
pstmt.setLong(4, netId);
pstmt.setString(5, UUID.randomUUID().toString());
s_logger.debug("Inserting default egress firewall rule " + pstmt);
pstmt.executeUpdate();
pstmt = conn.prepareStatement("select id from firewall_rules where protocol='all' and network_id=?");
pstmt.setLong(1, netId);
rsId = pstmt.executeQuery();
long firewallRuleId;
if(rsId.next()) {
firewallRuleId = rsId.getLong(1);
pstmt = conn.prepareStatement("insert into firewall_rules_cidrs (firewall_rule_id,source_cidr) values (?, '0.0.0.0/0')");
pstmt.setLong(1, firewallRuleId);
s_logger.debug("Inserting rule for cidr 0.0.0.0/0 for the new Firewall rule id=" + firewallRuleId + " with statement " + pstmt);
pstmt.executeUpdate();
}
}
}
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to set egress firewall rules ", e);
} finally {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
}
}
}
} }