Package: capirca
capircaAboutThe basicsAnatomy of a policy fileHeadersTermsTokensKeywordsRequiredOptionalIncludesExampleTerm Keywords By GeneratorTerm ExamplesExample Policy FileGetting StartedInstallationFrom SourcePackage ManagerBasic UsagePython PackageRunning with DockerMiscellaneousAboutCapirca is designed to utilize common definitions of networks, services and
high-level policy files to facilitate the development and manipulation of
network access control lists (ACLs) for various platforms. It was developed by
Google for internal use, and is now open source.Capirca consist ofcapircaPython package and thecapircatool.The typical usage workflow consists of the following steps:Createobject definitionscontaining "network" and "service" definitionsCreate aaccess control policydefining the desired state of access
control and referencing theobject definitionstogether with desired
firewall platformsGenerate ACL configurations by runningcapircacommand referencing the
access control policy and the object definitions. The command triggers ageneratorfor each of the firewall platforms.The basicsAt a high-level capirca rationalizes objects (networks, services) against a
security definition (.pol file) to generate a specific device configuration file
via a platform specificACL generator. Before getting started some objects
must exist, the below table summarizes where objects are stored:pathdescription/def/NETWORK.neta list ofnetwork objectsdefinitions/def/SERVICES.svca list ofservice objectsdefinitionsEach network or service definition file has a very simple structure. A token is
defined, e.g.GUEST_NET, followed by an equal sign, then followed by a
definition, e.g.10.10.10.0/24, and optional description field, e.g.# guest network range.GUEST_NET = 10.10.10.0/24      # guest network rangeThe tool populates theaccess control policyfrom.polfiles in a
particular directory, e.g.policies/. The tool searches
recursively for.polfiles and add them to the policy, .e.g.polfiles are
located inpolicies/pol.Additionally, the.polfiles MAY reference other policy definition files
located outside of the directory by usingincludedirective. Please seeIncludessection for documentation.Network ObjectsThe files with.netextension contain the definitions of network objects, e.g.
IP networks and hosts. The following definition createsINTERNALandRFC1918network objects in the object definitions, whetherINTERNALreferences the IP
ranges of RFC 1918 defined in theRFC1918.RFC1918 = 10.0.0.0/8      # non-public
          172.16.0.0/12   # non-public
          192.168.0.0/16  # non-public

INTERNAL = RFC1918Back to TopService ObjectsThe files with.svcextension contain the definitions of service objects, e.g.
ports and protocols.DNS = 53/tcp  # transfers
      53/udp  # queriesBack to TopObject NestingThe nesting of tokens is permitted only when both tokens are of the same type.
The referencing of a "network" object by "service" object is not allowed, and
vice versa.The examples of nesting of the network and service object follow.HTTP = 80/tcp               # common web
HTTPS = 443/tcp             # SSL web
HTTP_8080 = 8080/tcp        #  web on non-standard port
WEB_SERVICES = HTTP HTTP_8080 HTTPS  # all our web services
DB_SERVICES = 3306/tcp      # allow db access
              HTTPS         # and SSL access
NYC_NETWORK = 200.1.1.0/24  # New York office
ATL_NETWORK = 200.2.1.0/24  # Atlanta office
DEN_NETWORK = 200.5.1.0/24  # Denver office
REMOTE_OFFICES = NYC_NETWORK
                 ATL_NETWORK
                 DEN_NETWORKThe network objects may reference both IPv4 and IPv6 addresses at the same time.LOOPBACK = 127.0.0.1/32          # loopback in IPv4
           ::1/128               # loopback in IPv6
LINKLOCAL = FE80::/10            # IPv6 link local address
NYC_NETWORK = 172.16.1.0/24      # NYC IPv4
              2620:0:10A1::/48   # NYC IPv6Back to TopAnatomy of a policy fileA policy file (/policies/pol/something.pol) has the security policy written
using capirca specific meta-language and format. There are specific sections
(e.g: header) that tell capirca how to generate the output configuration of the
security policy.HeadersThe header section defines:targetfirewall platforms (which ACL generator to use)passesadditional argumentsto the generator responsible for that
platform.A single header may have many targets within a section. It will result in
multiple outputs being generated for that policy.TermsThetermsections defines the access control rules within an ACL, it contains
keywords followed by an object (service or network) and policy decision ("action" keyword).The term section specifies the network flow metadata for ACL matching.AddressesPortsProtocolsAction (allow/deny)Inside aterma mandatory keyword will be found followed by an object token
for rule evaluation.TokensTokens are the names of services and networks loaded from the object
definitions. Example:token_namedefinition"HTTPS"443"NYC_NETWORK"192.168.0.0/24Keywordskeyworddescriptionrequiredmust be supported by all output policy generatorsoptionalavailable in a subset of the generators and are intended to:          : provide additional flexibility when developing policies for that ::          : specific target platform                                         :Requiredactionacceptdenyrejectnextreject-with-tcp-rstcommenta text comment enclosed in double-quotes. Comments may span multiple
lines if desired.destination-addressone or more destination address tokens.destination-excludeexclude one or more address tokens from the specified
destination-address.destination-portone or more service definition tokens.icmp-typespecific icmp-type code to match (IPv4/IPv6 types vary).IPv4:echo-replyunreachablesource-quenchredirectalternate-addressecho-requestrouter-advertisementrouter-solicitationtime-exceededparameter-problemtimestamp-requesttimestamp-replyinformation-requestinformation-replymask-requestmask-replyconversion-errormobile-redirectIPv6:destination-unreachablepacket-too-bigtime-exceededparameter-problemecho-requestecho-replymulticast-listener-querymulticast-listener-reportmulticast-listener-donerouter-solicitrouter-advertisementneighbor-solicitneighbor-advertisementredirect-messagerouter-renumberingicmp-node-information-queryicmp-node-information-responseinverse-neighbor-discovery-solicitationinverse-neighbor-discovery-advertisementversion-2-multicast-listener-reporthome-agent-address-discovery-requesthome-agent-address-discovery-replymobile-prefix-solicitationmobile-prefix-advertisementcertification-path-solicitationcertification-path-advertisementmulticast-router-advertisementmulticast-router-solicitationmulticast-router-terminationoptionconnection options.establishedonly permit established connections; implements tcp-established
flag if protocol is tcp only, otherwise adds 1024-65535 to
required destination-ports.tcp-establishedonly permit established tcp connections, usually checked based
on TCP flag settings. If protocol UDP is included in term, only
adds 1024-65535 to required destination-ports.samplenot supported by all generators. Samples traffic for netflow.intialcurrently only supported by juniper generator. Appends
tcp-initial to the term.rstcurrently only supported by juniper generator. Appends
"tcp-flags rst" to the term.first-fragmentcurrently only supported by juniper generator. Appends
'first-fragment' to the term.protocolnetwork protocols this term will match, such as tcp, udp, icmp, or a
numeric value.protocol-exceptnetwork protocols that should be excluded from the protocol
specification. This is rarely used.source-addressone or more source address tokens.source-excludeexclude one or more address tokens from the specified source-address.source-portone or more service definition tokens.verbatimthis specifies that the text enclosed within quotes should be rendered
into the output without interpretation or modification. This is
sometimes used as a temporary workaround while new required features are
being added.OptionalWARNING: These terms may or may not function properly on all generators. Always
refer to the generator specific documentation and code base.addressone or more network address tokens matches either source or destination.counter(Juniper only) enable filter-based generic routing encapsulation (GRE)
tunneling using the specified tunnel template.destination-prefix(Juniper only) specify destination-prefix matching (e.g. source-prefix`
configured-neighbors-only).ether-type(Juniper only) specify matching ether-type(e.g. ether-type` arp).fragement-offset(Juniper only) specify a fragment offset of a fragmented packet.logging(Juniper, speedway/iptables) specify that this packet should be logged
via syslog.loss-priority(Juniper only) specify loss priority.packet-length(Juniper only) specify packet length.policer(Juniper only) specify which policer to apply to matching packets.precedence(Juniper only) specify precendence.qos(Juniper only) apply quality of service classification to matching
packets (e.g. qos` af4).routing-instance(iptables, speedway only) specify specific interface a term should apply
to (e.g. source-interface` eth3).source-prefix(Juniper only) specify source-prefix matching (e.g. source-prefix,
configured-neighbors-only).traffic-type(Juniper only) specify traffic-type.IncludesPolicy files support the use of#includestatements. An include may be used to
avoid duplication of commonly used text, such as a group of terms that permit or
block specific types of traffic.An include directive will result in the contents of the included file being
injected into the current policy file in the exact location of the#includedirective. An example include:#include 'includes/untrusted-networks-blocking.inc'NOTE: Includes are only read from the subdirectories of your base_directory,
all other directories will error out.The.incfile extension and theincludes/folder is not required but it is
recommended to be used as a best practice and for easier readability.ExampleWARNING: Not all generators have the same configuration options or feature set.header {
  target:: paloalto from-zone internal to-zone external
}

term ping-gdns{
  source-address:: INTERNAL
  destination-address:: GOOGLE_DNS
  protocol:: icmp
  action:: accept
}The above example tells capirca to use paloalto.py to generate a platform
specific configuration for Palo Alto.The security policy is written within the term section using the meta-language:name/description: ping-gdnssource: any INTERNAL network (check /def/NETWORK.net definition of
'INTERNAL')destination: service object named GOOGLE_DNSprotocol: icmpaction: acceptThe above ACL controls traffic in one direction only (outbound towards the
service) and there should be another header and term to control the traffic in
the opposite direction. Unless the target generator features the ability to
automatically create bi-directional configuration from a single ACL term. Always
check the documentation of the generator or validate the output generated to
validate final configuration and policy interpretation.Term Keywords By GeneratorThe following list contains links to the documentation of the individual policy
generators:arista: Aristaaruba: Arubabrocade: Brocadecisco: Ciscociscoasa: Cisco ASAcisconx: Cisco NXciscoxr: Cisco XRcloudarmor: cloudarmorgce: GCEgcp_hfipset: ipsetiptables: iptablesjuniper: Juniperjuniperevo: Juniper EVOjunipermsmpc: Juniperjunipersrx: Juniper SRXk8s: Kubernetes NetworkPolicynftables: nftablesnsxv: NSXpacketfilter: PacketFilterpaloaltofw: Palo Alto PANOSpcap: PcapFiltersonic: SONiC ACLs in config_db.json formatspeedway: Speedwaysrxlo: Stateless Juniper ACLwindows_advfirewall: Windows
Advanced FirewallBack to TopTerm ExamplesThe following are examples of how to construct a term, and assumes that naming
definition tokens used have been defined in the definitions files.Block incoming bogons and spoofed trafficterm block-bogons {
  source-address:: BOGONS RFC1918
  source-address:: COMPANY_INTERNAL
  action:: deny
}Permit Public to Web Serversterm permit-to-web-servers {
  destination-address:: WEB_SERVERS
  destination-port:: HTTP
  protocol:: tcp
  action:: accept
}Permit Replies to DNS Servers From Primariesterm permit-dns-tcp-replies {
  source-address:: DNS_PRIMARIES
  destination-address:: DNS_SECONDARIES
  source-address:: DNS
  protocol:: tcp
  option:: tcp-established
  action:: accept
}Permit All Corporate Networks, Except New York, to FTP ServerThis will "subtract" theCORP_NYC_NETBLOCKfrom theCORP_NETBLOCKStoken.
For example, assumeCORP_NETBLOCKSincludes200.0.0.0/20, andCORP_NYC_NETBLOCKis defined as200.2.0.0/24. Thesource-excludewill
remove the NYC netblock from the permitted source addresses. If the excluded
address is not contained with the source address, nothing is changed.term allow-inbound-ftp-from-corp {
  source-address:: CORP_NETBLOCKS
  source-exclude:: CORP_NYC_NETBLOCK
  destination-port:: FTP
  protocol:: tcp
  action:: accept
}Back to TopExample Policy FileBelow is an example policy file for a Juniper target platform. It contains two
filters, each with a handful of terms. This examples assumes that the network
and service naming definition tokens have been defined.header {
  comment:: "edge input filter for sample network."
  target:: juniper edge-inbound
}
term discard-spoofs {
  source-address:: RFC1918
  action:: deny
}
term permit-ipsec-access {
  source-address:: REMOTE_OFFICES
  destination-address:: VPN_HUB
  protocol:: 50
  action:: accept
}
term permit-ike-access {
  source-address:: REMOTE_OFFICES
  destination-address:: VPN_HUB
  protocol:: udp
  destination-port:: IKE
  action:: accept
}
term permit-public-web-access {
  destination-address:: WEB_SERVERS
  destination-port:: HTTP HTTPS HTTP_8080
  protocol:: tcp
  action:: accept
}
term permit-tcp-replies {
  option:: tcp-established
  action:: accept
}
term default-deny {
  action:: deny
}

header {
  comment:: "edge output filter for sample network."
  target:: juniper edge-outbound
}
term drop-internal-sourced-outbound {
  destination-address:: INTERNAL
  destination-address:: RESERVED
  action:: deny
}
term reject-internal {
  source-address:: INTERNAL
  action:: reject
}
term default-accept {
  action:: accept
}Back to TopGetting StartedInstallationFrom SourceIfsetuptoolsPython package is not installed on your system, install it: For
example, the following commands installs the package withaptpackage manager.sudoapt-getinstallpython3-pippython3-setuptoolsNext, to installcapircafrom source, clone thecapircarepository and run
its installer:gitclonehttps://github.com/google/capirca.gitcdcapirca/
python3setup.pyinstall--userTypically, when provided--userargument, the installer creates the following
files, where3.8is Python version and2.0.0is the version ofcapirca:~/.local/bin/capirca~/.local/lib/python3.8/site-packages/capirca-2.0.0-py3.8.eggIf necessary, remove build files:rm-rfbuildcapirca.egg-infodistNext, testcapircaby generating sample output filters for Cisco, Juniper,
iptables, and other firewall platforms.~/.local/bin/capircaThe generation of sample output while in thecapirca's source code directory
does not require command line parameters, becausecapircainherits default
settings from the following configuration (seecapirca/utils/config.py).{'base_directory':'./policies','definitions_directory':'./def','policy_file':None,'output_directory':'./filters','optimize':False,'recursive':True,'debug':False,'verbose':False,'ignore_directories':['DEPRECATED','def'],'max_renderers':10,'shade_check':False,'exp_info':2}Although thepolicy_fileisNone, the tool processes all policies located inbase_directory, i.e../policies. The tool loads network and service
definitions fromdefinitions_directory. The tool output generated ACLs to the
root of the source directory becauseoutput_directoryis./filters.Back to TopPackage ManagerCurrently, the PyPI is out of date. Nevertheless, a user can install an older
version ofcapircawithpip:pipinstallcapirca--userBack to TopBasic UsageThere are a number of command-line arguments that can be used withcapirca.$ ~/.local/bin/capirca --helpfull

       USAGE: capirca [flags]
flags:

absl.app:
  -?,--[no]help: show this help
    (default: 'false')
  --[no]helpfull: show full help
    (default: 'false')
  --[no]helpshort: show this help
    (default: 'false')
  --[no]helpxml: like --helpfull, but generates XML output
    (default: 'false')
  --[no]only_check_args: Set to true to validate args and exit.
    (default: 'false')
  --[no]pdb: Alias for --pdb_post_mortem.
    (default: 'false')
  --[no]pdb_post_mortem: Set to true to handle uncaught exceptions with PDB post mortem.
    (default: 'false')
  --profile_file: Dump profile information to a file (for python -m pstats). Implies --run_with_profiling.
  --[no]run_with_pdb: Set to true for PDB debug mode
    (default: 'false')
  --[no]run_with_profiling: Set to true for profiling the script. Execution will be slower, and the output format might change over time.
    (default: 'false')
  --[no]use_cprofile_for_profiling: Use cProfile instead of the profile module for profiling. This has no effect unless --run_with_profiling
    is set.
    (default: 'true')

absl.logging:
  --[no]alsologtostderr: also log to stderr?
    (default: 'false')
  --log_dir: directory to write logfiles into
    (default: '')
  --logger_levels: Specify log level of loggers. The format is a CSV list of `name:level`. Where `name` is the logger name used with
    `logging.getLogger()`, and `level` is a level name  (INFO, DEBUG, etc). e.g. `myapp.foo:INFO,other.logger:DEBUG`
    (default: '')
  --[no]logtostderr: Should only log to stderr?
    (default: 'false')
  --[no]showprefixforinfo: If False, do not prepend prefix to info messages when it's logged to stderr, --verbosity is set to INFO level,
    and python logging is used.
    (default: 'true')
  --stderrthreshold: log messages at this level, or more severe, to stderr in addition to the logfile.  Possible values are 'debug', 'info',
    'warning', 'error', and 'fatal'.  Obsoletes --alsologtostderr. Using --alsologtostderr cancels the effect of this flag. Please also note
    that this flag is subject to --verbosity and requires logfile not be stderr.
    (default: 'fatal')
  -v,--verbosity: Logging verbosity level. Messages logged at this level or lower will be included. Set to 1 for debug logging. If the flag
    was not set or supplied, the value will be changed from the default of -1 (warning) to 0 (info) after flags are parsed.
    (default: '-1')
    (an integer)

capirca.capirca:
  --base_directory: The base directory to look for acls; typically where you'd find ./corp and ./prod
    (default: './policies')
  --config_file: A yaml file with the configuration options for capirca;
    repeat this option to specify a list of values
  --[no]debug: Debug messages
    (default: 'false')
  --definitions_directory: Directory where the definitions can be found.
    (default: './def')
  --exp_info: Print a info message when a term is set to expire in that many weeks.
    (default: '2')
    (an integer)
  --ignore_directories: Don't descend into directories that look like this string
    (default: 'DEPRECATED,def')
    (a comma separated list)
  --max_renderers: Max number of rendering processes to use.
    (default: '10')
    (an integer)
  -o,--[no]optimize: Turn on optimization.
    (default: 'False')
  --output_directory: Directory to output the rendered acls.
    (default: './filters')
  --policy_file: Individual policy file to generate.
  --[no]recursive: Descend recursively from the base directory rendering acls
    (default: 'true')
  --[no]shade_check: Raise an error when a term is completely shaded by a prior term.
    (default: 'false')
  --[no]verbose: Verbose messages
    (default: 'false')

absl.flags:
  --flagfile: Insert flag definitions from the given file into the command line.
    (default: '')
  --undefok: comma-separated list of flag names that it is okay to specify on the command line even if the program does not define a flag
    with that name.  IMPORTANT: flags in this list that have arguments MUST use the --flag=value format.
    (default: '')Notably, the--config_file PATHargument allows passing one or more yaml
configuration files. These files will be prioritized from left to right, i.e.
any duplicate configurations will be overriden, not merged.The command line arguments take precendence over any settings passed via the
configuration files.The defaultcapircaconfigurations in a YAML format follows:---base_directory:./policiesdefinitions_directory:./defoutput_directory:./optimize:falserecursive:truedebug:falseverbose:falseignore_directories:-DEPRECATED-defmax_renderers:10shade_check:trueexp_info:2Back to TopPython PackageThecapircatool usescapircaPython package.Therefore, there is a way to accesscapircaprogrammatically.policies/sample_paloalto.poldef/SERVICES.svcdef/NETWORK.netProvided you have the following files in your directory, the following code
snippets create anamingdefinitions object, policy object, and render
generator filter output.NOTE: Paste the code snippets one line at a time.First, start Python interpreter:$ python3
Python 3.8.7 (default, Dec 22 2020, 10:37:26)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>Next, importnaminglibrary and createnamingobject from definitions files
in./defdirectory.frompprintimportpprintfromcapirca.libimportnamingdefs=naming.Naming('./def')pprint(defs)<capirca.lib.naming.Namingobjectat0x7f8421b57280>Thedefsobject follows:<capirca.lib.naming.Naming object at 0x7f8421b57280>TheNamingobject has various methods. TheGetServiceNamesmethod returns
the service name tokens.>>> dir(defs)
['GetIpParents', 'GetNet', 'GetNetAddr', 'GetNetChildren', 'GetServiceNames',
 <...intentionally omitted ..>
'unseen_networks', 'unseen_services']
>>>

>>> pprint(defs.GetServiceNames())
['WHOIS',
 'SSH',
 <...intentionally omitted ..>
 'TRACEROUTE']
>>>Then, importpolicylibrary, read in the policy configuration data from./policies/sample_paloalto.pol, and create a policy object.fromcapirca.libimportpolicyconf=open('./policies/sample_paloalto.pol').read()pol=policy.ParsePolicy(conf,defs,optimize=True)The policy object follows:>>> pprint(pol)
Policy: {Target[paloalto], Comments [], Apply groups: [], except: []:[ name: ping-gdns
  source_address: [IPv4('10.0.0.0/8'), IPv4('172.16.0.0/12'), IPv4('192.168.0.0/16')]
  destination_address: [IPv4('8.8.4.4/32'), IPv4('8.8.8.8/32'), IPv6('2001:4860:4860::8844/128'), IPv6('2001:4860:4860::8888/128')]
  protocol: ['icmp']
  action: ['accept'],  name: dns-gdns
  source_address: [IPv4('10.0.0.0/8'), IPv4('172.16.0.0/12'), IPv4('192.168.0.0/16')]
  destination_address: [IPv4('8.8.4.4/32'), IPv4('8.8.8.8/32'), IPv6('2001:4860:4860::8844/128'), IPv6('2001:4860:4860::8888/128')]
  protocol: ['tcp']
  destination_port: [(53, 53)]
  action: ['accept'],  name: allow-web-outbound
  source_address: [IPv4('10.0.0.0/8'), IPv4('172.16.0.0/12'), IPv4('192.168.0.0/16')]
  protocol: ['tcp']
  destination_port: [(80, 80), (443, 443)]
  action: ['accept']], Target[paloalto], Comments [], Apply groups: [], except: []:[ name: allow-icmp
  protocol: ['icmp']
  action: ['accept'],  name: allow-only-pan-app
  action: ['accept']
  pan_application: ['http'],  name: allow-web-inbound
  destination_address: [IPv4('200.1.1.1/32'), IPv4('200.1.1.2/32')]
  protocol: ['tcp']
  destination_port: [(80, 80), (443, 443)]
  action: ['accept']
  pan_application: ['ssl', 'http']]}
>>>Next, import a generator library (herepaloaltofwfor Palo Alto firewalls) and
output a policy in the desired format.fromcapirca.libimportpaloaltofwforheaderinpol.headers:if'paloalto'inheader.platforms:jcl=Trueifjcl:output=paloaltofw.PaloAltoFW(pol,1)print(output)The following code initiates Palo Alto firewall ACL model with the default
expiration of 1 week.paloaltofw.PaloAltoFW(pol, 1)Back to TopRunning with DockerIf your use case is to just use the CLI and you don't want to go through the
process of installingcapirca, you can use the dockerized version of the tool.When usingdocker, mount your working directory to the/datadirectory of
the container and pass command-line arguments in the following way.dockerrun-v"${PWD}:/data"docker.pkg.github.com/google/capirca/capirca:latest
dockerrun-v"${PWD}:/data"docker.pkg.github.com/google/capirca/capirca:latest--helpfull
dockerrun-v"${PWD}:/data"docker.pkg.github.com/google/capirca/capirca:latest--config_file/data/path/to/configBack to TopMiscellaneousSecurity considerationsThe Capirca threat model assumes some control and verification of policy
definitions (in .pol files). This is either through human user verification,
or that policies are generated by upstream systems that enforce correctness.It is recommended that the ACL generated by Capirca is always tested for
correctness before being applied to production. Not all generators support every
feature, configuration option or term keywords. When something is unsupported,
Capirca will error out. But due to the sensitive nature of network ACLs, it is
always recommended to test any new generator being used, or new policies being
generated.Additional documentationaclcheck librarypolicy reader librarypolicy librarynaming librarycapirca design docExternal links, resources and references:Brief Overview (4 slides):Nanog49; Enterprise QoSCapirca Slack at NetworkToCodeBack to Top