Skip to content

Commit

Permalink
PAN: extract security rule categories (#8111)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfraint committed Mar 8, 2022
1 parent c2cb44b commit 633806b
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ srs_application

srs_category
:
CATEGORY
null_rest_of_line
CATEGORY variable_list
;

srs_description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.NAT_RULE_TO_ZONE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.REDIST_RULE_REDIST_PROFILE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_APPLICATION;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_CATEGORY;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_DESTINATION;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_FROM_ZONE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_SELF_REF;
Expand Down Expand Up @@ -2841,6 +2842,18 @@ public void enterSrs_definition(Srs_definitionContext ctx) {
referenceStructure(SECURITY_RULE, uniqueName, SECURITY_RULE_SELF_REF, getLine(ctx.name.start));
}

@Override
public void exitSrs_category(PaloAltoParser.Srs_categoryContext ctx) {
for (Variable_list_itemContext var : variables(ctx.variable_list())) {
String name = getText(var);
_currentSecurityRule.addCategory(name);
// Use constructed object name so same-named refs across vsys are unique
String uniqueName = computeObjectName(_currentVsys, name);
referenceStructure(
CUSTOM_URL_CATEGORY, uniqueName, SECURITY_RULE_CATEGORY, getLine(var.start));
}
}

@Override
public void exitSrs_definition(Srs_definitionContext ctx) {
_currentSecurityRule = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.batfish.representation.palo_alto;

import javax.annotation.Nonnull;

/** Represents a reference to a custom-url-category. */
public final class CustomUrlCategoryReference implements Reference {

@Override
public <T, U> T accept(ReferenceVisitor<T, U> visitor, U arg) {
return visitor.visitCustomUrlCategoryReference(this, arg);
}

public CustomUrlCategoryReference(String name) {
_name = name;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CustomUrlCategoryReference)) {
return false;
}
return _name.equals(((CustomUrlCategoryReference) o).getName());
}

@Override
public int hashCode() {
return _name.hashCode();
}

/** Return the name of the referenced Category */
@Override
@Nonnull
public String getName() {
return _name;
}

@Nonnull private final String _name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1738,7 +1738,7 @@ private List<AclLineMatchExpr> matchServicesForApplications(
.collect(ImmutableList.toImmutableList());
}

private static final ReferenceInVsys REFERENCE_IN_VSYS = new ReferenceInVsys();
@VisibleForTesting static final ReferenceInVsys REFERENCE_IN_VSYS = new ReferenceInVsys();

/** Visitor that determines if a {@link Reference} exists in the specified {@link Vsys}. */
public static class ReferenceInVsys implements ReferenceVisitor<Boolean, Vsys> {
Expand All @@ -1755,6 +1755,12 @@ public Boolean visitApplicationOrApplicationGroupReference(
return vsys.getApplications().containsKey(reference.getName())
|| vsys.getApplicationGroups().containsKey(reference.getName());
}

@Override
public Boolean visitCustomUrlCategoryReference(
CustomUrlCategoryReference reference, Vsys vsys) {
return vsys.getCustomUrlCategories().containsKey(reference.getName());
}
}

/**
Expand Down Expand Up @@ -3358,6 +3364,11 @@ private Configuration toVendorIndependentConfiguration() throws VendorConversion
PaloAltoStructureType.APPLICATION,
ImmutableList.of(PaloAltoStructureType.APPLICATION),
PaloAltoStructureUsage.APPLICATION_OVERRIDE_RULE_APPLICATION);
// Custom URL Categories
markAbstractStructureFromUnknownNamespace(
PaloAltoStructureType.CUSTOM_URL_CATEGORY,
ImmutableList.of(PaloAltoStructureType.CUSTOM_URL_CATEGORY),
PaloAltoStructureUsage.SECURITY_RULE_CATEGORY);

return _c;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum PaloAltoStructureUsage implements StructureUsage {
NAT_RULE_TO_ZONE("rulebase nat rules to"),
REDIST_RULE_REDIST_PROFILE("redist-rule redist-profile"),
SECURITY_RULE_APPLICATION("rulebase security rules application"),
SECURITY_RULE_CATEGORY("rulebase security rules category"),
SECURITY_RULE_DESTINATION("rulebase security rules destination"),
SECURITY_RULE_FROM_ZONE("rulebase security rules from"),
SECURITY_RULE_SOURCE("rulebase security rules source"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ default T visit(Reference reference, U arg) {

T visitApplicationOrApplicationGroupReference(
ApplicationOrApplicationGroupReference reference, U arg);

T visitCustomUrlCategoryReference(CustomUrlCategoryReference reference, U arg);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.batfish.representation.palo_alto;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import java.io.Serializable;
import java.util.HashSet;
Expand Down Expand Up @@ -27,6 +28,9 @@ public enum RuleType {
@Nonnull private final String _name;
// Action of the rule
@Nonnull private LineAction _action;

@Nonnull private Set<CustomUrlCategoryReference> _category;

// Owning Vsys of this rule
@Nonnull private final Vsys _vsys;

Expand Down Expand Up @@ -59,6 +63,7 @@ public enum RuleType {
public SecurityRule(String name, Vsys vsys) {
_action = LineAction.DENY;
_applications = new TreeSet<>();
_category = ImmutableSet.of();
_destination = new LinkedList<>();
_negateDestination = false;
_disabled = false;
Expand Down Expand Up @@ -86,11 +91,28 @@ public void addApplication(String application) {
_applications.add(new ApplicationOrApplicationGroupReference(application));
}

public void addCategory(String category) {
CustomUrlCategoryReference ref = new CustomUrlCategoryReference(category);
if (_category.contains(ref)) {
return;
}
_category =
ImmutableSet.<CustomUrlCategoryReference>builderWithExpectedSize(_category.size() + 1)
.addAll(_category)
.add(ref)
.build();
}

@Nonnull
public SortedSet<ApplicationOrApplicationGroupReference> getApplications() {
return ImmutableSortedSet.copyOf(_applications);
}

@Nonnull
public Set<CustomUrlCategoryReference> getCategory() {
return _category;
}

@Nullable
public String getDescription() {
return _description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import static org.batfish.representation.palo_alto.PaloAltoStructureType.ZONE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.IMPORT_INTERFACE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_APPLICATION;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.SECURITY_RULE_CATEGORY;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.STATIC_ROUTE_INTERFACE;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.TEMPLATE_STACK_TEMPLATES;
import static org.batfish.representation.palo_alto.PaloAltoStructureUsage.VIRTUAL_ROUTER_INTERFACE;
Expand Down Expand Up @@ -230,6 +231,7 @@
import org.batfish.representation.palo_alto.AddressPrefix;
import org.batfish.representation.palo_alto.AdminDistances;
import org.batfish.representation.palo_alto.Application;
import org.batfish.representation.palo_alto.ApplicationOrApplicationGroupReference;
import org.batfish.representation.palo_alto.ApplicationOverrideRule;
import org.batfish.representation.palo_alto.BgpConnectionOptions;
import org.batfish.representation.palo_alto.BgpPeer;
Expand All @@ -240,6 +242,7 @@
import org.batfish.representation.palo_alto.CryptoProfile;
import org.batfish.representation.palo_alto.CryptoProfile.Type;
import org.batfish.representation.palo_alto.CustomUrlCategory;
import org.batfish.representation.palo_alto.CustomUrlCategoryReference;
import org.batfish.representation.palo_alto.DeviceGroup;
import org.batfish.representation.palo_alto.EbgpPeerGroupType;
import org.batfish.representation.palo_alto.EbgpPeerGroupType.ExportNexthopMode;
Expand Down Expand Up @@ -2831,7 +2834,13 @@ public void testProfilesReference() throws IOException {
assertThat(ccae, hasDefinedStructure(filename, CUSTOM_URL_CATEGORY, category1Name));
assertThat(ccae, hasDefinedStructure(filename, CUSTOM_URL_CATEGORY, category2Name));

// TODO references and undefined references once refs are added
// Structure references are tracked
assertThat(ccae, hasNumReferrers(filename, CUSTOM_URL_CATEGORY, category1Name, 1));
assertThat(ccae, hasNumReferrers(filename, CUSTOM_URL_CATEGORY, category2Name, 0));
assertThat(
ccae,
hasUndefinedReference(
filename, CUSTOM_URL_CATEGORY, "CAT_UNDEFINED", SECURITY_RULE_CATEGORY));
}

@Test
Expand Down Expand Up @@ -3949,6 +3958,44 @@ public void testVirtualRouterEcmp() {
parsePaloAltoConfig(hostname);
}

@Test
public void testRulebaseExtraction() {
String hostname = "rulebase-extraction";
PaloAltoConfiguration c = parsePaloAltoConfig(hostname);
Map<String, SecurityRule> rules =
c.getVirtualSystems().get(DEFAULT_VSYS_NAME).getRulebase().getSecurityRules();
RuleEndpoint addr1 = new RuleEndpoint(REFERENCE, "ADDR1");
RuleEndpoint addr2 = new RuleEndpoint(REFERENCE, "ADDR2");
RuleEndpoint addr3 = new RuleEndpoint(REFERENCE, "ADDR3");
CustomUrlCategoryReference cat1 = new CustomUrlCategoryReference("CAT1");
CustomUrlCategoryReference cat2 = new CustomUrlCategoryReference("CAT2");
ApplicationOrApplicationGroupReference ssh = new ApplicationOrApplicationGroupReference("ssh");
ApplicationOrApplicationGroupReference ssl = new ApplicationOrApplicationGroupReference("ssl");

assertThat(rules.keySet(), contains("RULE1", "RULE2"));
SecurityRule rule1 = rules.get("RULE1");
SecurityRule rule2 = rules.get("RULE2");

assertNotNull(rule1);
assertThat(rule1.getAction(), equalTo(LineAction.DENY));
assertThat(rule1.getDescription(), equalTo("descr"));
assertThat(rule1.getFrom(), containsInAnyOrder("z1", "z2"));
assertThat(rule1.getTo(), containsInAnyOrder("z1", "z3"));
assertThat(rule1.getSource(), containsInAnyOrder(addr1, addr2));
assertThat(rule1.getDestination(), containsInAnyOrder(addr1, addr3));
assertTrue(rule1.getNegateDestination());
assertTrue(rule1.getNegateSource());
assertThat(rule1.getCategory(), containsInAnyOrder(cat1, cat2));
assertThat(rule1.getApplications(), containsInAnyOrder(ssh, ssl));

// Check default values
assertNotNull(rule2);
assertThat(rule2.getAction(), equalTo(LineAction.PERMIT));
assertFalse(rule2.getNegateSource());
assertFalse(rule2.getNegateDestination());
assertThat(rule2.getCategory(), emptyIterable());
}

@Test
public void testSecurityRuleMove() {
String hostname = "move-rulebase-security";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import static org.batfish.datamodel.matchers.IpAccessListMatchers.accepts;
import static org.batfish.datamodel.matchers.IpAccessListMatchers.rejects;
import static org.batfish.datamodel.matchers.IpAccessListMatchers.rejectsByDefault;
import static org.batfish.representation.palo_alto.PaloAltoConfiguration.DEFAULT_VSYS_NAME;
import static org.batfish.representation.palo_alto.PaloAltoConfiguration.REFERENCE_IN_VSYS;
import static org.batfish.representation.palo_alto.PaloAltoConfiguration.checkIntrazoneValidityAndWarn;
import static org.batfish.representation.palo_alto.PaloAltoConfiguration.computeObjectName;
import static org.batfish.representation.palo_alto.PaloAltoConfiguration.deviceBindingAndIdCompatible;
Expand Down Expand Up @@ -724,6 +726,52 @@ public void testDeviceBindingAndIdCompatible() {
// TODO test PRIMARY once that is better supported
}

@Test
public void testReferenceInVsys() {
String objName = "objName";
// Service or service-group
{
ServiceOrServiceGroupReference ref = new ServiceOrServiceGroupReference(objName);
Vsys vsys = new Vsys(DEFAULT_VSYS_NAME);
assertFalse(REFERENCE_IN_VSYS.visit(ref, vsys));

vsys = new Vsys(DEFAULT_VSYS_NAME);
vsys.getServices().put(objName, new Service("service"));
assertTrue(REFERENCE_IN_VSYS.visit(ref, vsys));

vsys = new Vsys(DEFAULT_VSYS_NAME);
vsys.getServiceGroups().put(objName, new ServiceGroup("serviceGroup"));
assertTrue(REFERENCE_IN_VSYS.visit(ref, vsys));
}

// Application or application-group
{
ApplicationOrApplicationGroupReference ref =
new ApplicationOrApplicationGroupReference(objName);
Vsys vsys = new Vsys(DEFAULT_VSYS_NAME);
assertFalse(REFERENCE_IN_VSYS.visit(ref, vsys));

vsys = new Vsys(DEFAULT_VSYS_NAME);
vsys.getApplications().put(objName, Application.builder("app").build());
assertTrue(REFERENCE_IN_VSYS.visit(ref, vsys));

vsys = new Vsys(DEFAULT_VSYS_NAME);
vsys.getApplicationGroups().put(objName, new ApplicationGroup("appGroup"));
assertTrue(REFERENCE_IN_VSYS.visit(ref, vsys));
}

// Custom-url-category
{
CustomUrlCategoryReference ref = new CustomUrlCategoryReference(objName);
Vsys vsys = new Vsys(DEFAULT_VSYS_NAME);
assertFalse(REFERENCE_IN_VSYS.visit(ref, vsys));

vsys = new Vsys(DEFAULT_VSYS_NAME);
vsys.getCustomUrlCategories().put(objName, new CustomUrlCategory("category"));
assertTrue(REFERENCE_IN_VSYS.visit(ref, vsys));
}
}

@Test
public void testUnexpectedUnboundedCustomUrlWildcard() {
// Unexpected and unbounded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,12 @@ set deviceconfig system hostname profiles-reference

set profiles custom-url-category CAT1 description description1
set profiles custom-url-category CAT2 description description2

set rulebase security rules RULE1 from any
set rulebase security rules RULE1 to any
set rulebase security rules RULE1 source any
set rulebase security rules RULE1 destination any
set rulebase security rules RULE1 service any
set rulebase security rules RULE1 category [ CAT1 CAT_UNDEFINED ]
set rulebase security rules RULE1 application any
set rulebase security rules RULE1 action deny
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
set deviceconfig system hostname rulebase
set network interface ethernet ethernet1/1 layer3 ip 1.1.1.1/24
set network interface ethernet ethernet1/2 layer3 ip 1.1.2.1/24
set network interface ethernet ethernet1/3 layer3 ip 1.1.3.1/24
set zone z1 network layer3 ethernet1/1
set zone z2 network layer3 ethernet1/2
set zone z3 network layer3 ethernet1/2

set address ADDR1 ip-netmask 10.1.1.1/24
set address ADDR2 ip-netmask 10.2.1.1/24
set address ADDR3 ip-netmask 10.2.1.1/24

set service SERVICE1 protocol tcp port 999
set service SERVICE2 protocol tcp port 9999

set profiles custom-url-category CAT1 list github.com
set profiles custom-url-category CAT2 list example.com

# All supported fields populated
set rulebase security rules RULE1 from [ z1 z2 ]
set rulebase security rules RULE1 to [ z1 z3 ]
set rulebase security rules RULE1 source [ ADDR1 ADDR2]
set rulebase security rules RULE1 negate-source yes
set rulebase security rules RULE1 destination [ ADDR1 ADDR3 ]
set rulebase security rules RULE1 negate-destination yes
set rulebase security rules RULE1 service [ SERVICE1 SERVICE2 ]
set rulebase security rules RULE1 category [ CAT1 CAT2 ]
set rulebase security rules RULE1 application [ ssh ssl ]
set rulebase security rules RULE1 action deny
set rulebase security rules RULE1 description descr
# No-op's - these items already exist
set rulebase security rules RULE1 from z2
set rulebase security rules RULE1 to z3
# TODO uncomment these when they are also no-op's
#set rulebase security rules RULE1 source ADDR2
#set rulebase security rules RULE1 destination ADDR3
set rulebase security rules RULE1 service SERVICE2
set rulebase security rules RULE1 category CAT2
set rulebase security rules RULE1 application ssl

# Only required fields are populated
set rulebase security rules RULE2 from any
set rulebase security rules RULE2 to any
set rulebase security rules RULE2 source any
set rulebase security rules RULE2 destination any
set rulebase security rules RULE2 service any
set rulebase security rules RULE2 application any
set rulebase security rules RULE2 action allow

0 comments on commit 633806b

Please sign in to comment.