Capirca
项目描述
capirca
关于
Capirca旨在利用网络、服务的高级策略文件定义,以促进各种平台网络访问控制列表(ACLs)的开发和管理。它由Google开发用于内部使用,现在是开源的。
Capirca由capirca
Python包和capirca
工具组成。
典型的使用工作流程包括以下步骤
- 创建包含“网络”和“服务”定义的对象定义
- 创建一个访问控制策略,定义所需的访问控制状态,并引用对象定义以及所需的防火墙平台
- 通过运行
capirca
命令,根据访问控制策略和对象定义生成ACL配置。该命令会针对每个防火墙平台触发一个生成器。
基础
从高层次来看,capirca通过安全定义(.pol文件)对对象(网络、服务)进行合理化,通过特定平台的ACL生成器生成特定的设备配置文件。在开始之前,必须存在一些对象,以下表格总结了对象存储的位置
路径 | 描述 |
---|---|
/def/NETWORK.net | 网络对象定义列表 |
/def/SERVICES.svc | 服务对象定义列表 |
每个网络或服务定义文件具有一个非常简单的结构。定义一个令牌,例如GUEST_NET
,然后是等号,然后是定义,例如10.10.10.0/24
,以及可选的描述字段,例如# guest network range
。
GUEST_NET = 10.10.10.0/24 # guest network range
该工具从特定目录中的.pol
文件填充访问控制策略,例如a/
。该工具递归地搜索.pol
文件并将它们添加到策略中,例如.pol
文件位于a/policies/pol
。
此外,.pol
文件可以使用include
指令引用目录之外的其他策略定义文件。请参阅包含部分以获取文档。
网络对象
扩展名为.net
的文件包含网络对象的定义,例如IP网络和主机。以下定义在对象定义中创建INTERNAL
和RFC1918
网络对象,其中INTERNAL
引用在RFC1918
中定义的RFC 1918 IP范围。
RFC1918 = 10.0.0.0/8 # non-public
172.16.0.0/12 # non-public
192.168.0.0/16 # non-public
INTERNAL = RFC1918
服务对象
扩展名为.svc
的文件包含服务对象的定义,例如端口和协议。
DNS = 53/tcp # transfers
53/udp # queries
对象嵌套
仅当两个令牌都是同一类型时才允许令牌嵌套。不允许“网络”对象由“服务”对象引用,反之亦然。
以下是一些网络对象和服务对象嵌套的示例。
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_NETWORK
网络对象可以同时引用IPv4和IPv6地址。
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 IPv6
策略文件的结构
策略文件(/policies/pol/something.pol)使用capirca特定的元语言和格式编写安全策略。有一些特定部分(例如:标题)告诉capirca如何生成安全策略的输出配置。
标题
标题部分定义
- 目标防火墙平台(使用哪个ACL生成器)
- 将附加参数传递给负责该平台的生成器。
单个标题可以在部分内具有多个目标。它将为该策略生成多个输出。
术语
术语部分定义ACL中的访问控制规则,它包含关键字后面跟着对象(服务或网络)和政策决策(“操作”关键字)。
术语部分指定ACL匹配的网络流元数据。
- 地址
- 端口
- 协议
- 操作(允许/拒绝)
在term
中,将找到一个强制关键字,后跟用于规则评估的对象令牌。
标记
令牌是加载自对象定义的服务和网络名称。例如
令牌名称 | 定义 |
---|---|
"HTTPS" | 443 |
"NYC_NETWORK" | 192.168.0.0/24 |
关键词
关键字 | 描述 |
---|---|
必需 | 必须支持所有输出策略生成器 |
可选 | 在生成器子集中可用,并旨在 |
: : 在开发针对特定目标平台的策略时提供额外的灵活性 | |
: : 针对特定目标平台 |
必需
- 操作
- 接受
- 拒绝
- 拒绝
- 下一个
- 以TCP RST拒绝
- 注释
- 双引号中的文本注释。如果需要,注释可以跨越多行。
- 目标地址
- 一个或多个目标地址令牌。
- 目标排除
- 从指定的目标地址排除一个或多个地址令牌。
- 目标端口
- 一个或多个服务定义令牌。
- icmp类型
- 要匹配的特定icmp类型代码(IPv4/IPv6类型不同)。
- IPv4
- 回显应答
- 不可到达
- 源抑制
- 重定向
- 备用地址
- 回显请求
- 路由器公告
- 路由器请求
- 超时
- 参数问题
- 时间请求
- 时间应答
- 信息请求
- 信息应答
- 掩码请求
- 掩码应答
- 转换错误
- 移动重定向
- IPv6
- 目标不可到达
- 数据包过大
- 超时
- 参数问题
- 回显请求
- 回显应答
- 多播监听器查询
- 多播监听器报告
- 多播监听器完成
- 路由器请求
- 路由器公告
- 邻居请求
- 邻居公告
- 重定向消息
- 路由器重编号
- icmp节点信息查询
- icmp节点信息响应
- 逆向邻居发现请求
- 逆向邻居发现公告
- 版本2多播监听器报告
- 家庭代理地址发现请求
- 家庭代理地址发现应答
- 移动前缀请求
- 移动前缀公告
- 证书路径请求
- 证书路径公告
- 多播路由器公告
- 多播路由器请求
- 多播路由器终止
- 要匹配的特定icmp类型代码(IPv4/IPv6类型不同)。
- 选项
- 连接选项。
- 已建立
- 仅允许已建立的连接;如果协议仅为TCP,则实现tcp-established标志,否则将1024-65535添加到所需的目标端口。
- tcp-established
- 仅允许已建立的TCP连接,通常基于TCP标志设置进行检查。如果术语中包含UDP,则仅将1024-65535添加到所需的目标端口。
- 示例
- 并非所有生成器都支持。为netflow采样流量。
- 初始
- 目前仅由juniper生成器支持。将tcp-initial附加到术语中。
- rst
- 目前仅由juniper生成器支持。将"tcp-flags rst"附加到术语中。
- 第一个分段
- 目前仅由juniper生成器支持。将'first-fragment'附加到术语中。
- 已建立
- 连接选项。
- 协议
- 本术语将匹配的网络协议,例如tcp、udp、icmp或数字值。
- 协议除外
- 应从协议规范中排除的网络协议。这很少使用。
- 源地址
- 一个或多个源地址令牌。
- 源排除
- 从指定的源地址排除一个或多个地址令牌。
- 源端口
- 一个或多个服务定义令牌。
- 原义
- 这指定了引号内的文本应直接渲染到输出中,不进行解释或修改。这有时用作在添加新功能时的一种临时解决方案。
可选
警告:这些术语可能在所有生成器上无法正常工作。请始终参考特定生成器的文档和代码库。
- 地址
- 一个或多个网络地址令牌匹配源或目标。
- 计数器
- (仅限Juniper)启用基于过滤器的通用路由封装(GRE)隧道使用指定的隧道模板。
- 目标前缀
- (仅限Juniper)指定目标前缀匹配(例如,source-prefix` configured-neighbors-only)。
- 以太类型
- (仅限Juniper)指定匹配以太类型(例如,ether-type` arp)。
- 分段偏移量
- (仅限Juniper)指定分段数据包的分段偏移量。
- 记录
- (Juniper,speedway/iptables)指定此数据包应通过syslog进行记录。
- 丢失优先级
- (仅限Juniper)指定丢失优先级。
- 数据包长度
- (仅限Juniper)指定数据包长度。
- 流量 shaping
- (仅限Juniper)指定将应用于匹配数据包的流量 shaping。
- 优先级
- (仅限Juniper)指定优先级。
- QoS
- (仅限Juniper)将服务质量分类应用于匹配数据包(例如,qos` af4)。
- 路由实例
- (iptables,speedway仅限)指定术语应应用于特定接口(例如,source-interface` eth3)。
- 源前缀
- (仅限Juniper)指定源前缀匹配(例如,source-prefix,configured-neighbors-only)。
- 流量类型
- (仅限Juniper)指定流量类型。
包含
策略文件支持使用#include
语句。可以使用包含语句避免重复使用常用文本,例如允许或阻止特定类型流量的术语组。
包含指令会将包含文件的正文注入到当前策略文件的#include
指令的确切位置。以下是一个包含示例:
#include 'includes/untrusted-networks-blocking.inc'
注意:仅从base_directory的子目录中读取包含文件,其他目录将出错。
建议使用.inc
文件扩展名和includes/
文件夹,尽管这不是必需的,但作为最佳实践和便于阅读的建议。
示例
警告:并非所有生成器都具有相同的配置选项或功能集。
header {
target:: paloalto from-zone internal to-zone external
}
term ping-gdns{
source-address:: INTERNAL
destination-address:: GOOGLE_DNS
protocol:: icmp
action:: accept
}
上述示例告诉capirca使用paloalto.py生成针对Palo Alto的平台特定配置。
安全策略是在术语部分使用元语言编写的。
- 名称/描述:ping-gdns
- 源:任何内部网络(检查/def/NETWORK.net中对'INTERNAL'的定义)
- 目的:名为GOOGLE_DNS的服务对象
- 协议:icmp
- 动作:接受
上述ACL仅控制一个方向的流量(向服务的外出流量),并且应该有另一个标题和术语来控制相反方向的流量。除非目标生成器具有从单个ACL术语自动创建双向配置的功能。始终检查生成器的文档或验证生成的输出以验证最终配置和策略解释。
由生成器生成的术语关键词
以下列表包含对个别策略生成器文档的链接
arista
: Aristaaruba
: Arubabrocade
: Brocadecisco
: Ciscociscoasa
: Cisco ASAcisconx
: Cisco NXciscoxr
: Cisco XRcloudarmor
: cloudarmorgce
: GCEgcp_hf
ipset
: 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 Firewall
术语示例
以下是如何构建术语的示例,并假设已定义命名定义令牌。
- 阻止进入的bogons和伪造流量
term block-bogons {
source-address:: BOGONS RFC1918
source-address:: COMPANY_INTERNAL
action:: deny
}
- 允许公共服务器访问Web服务器
term permit-to-web-servers {
destination-address:: WEB_SERVERS
destination-port:: HTTP
protocol:: tcp
action:: accept
}
- 允许从主服务器回复DNS服务器
term permit-dns-tcp-replies {
source-address:: DNS_PRIMARIES
destination-address:: DNS_SECONDARIES
source-address:: DNS
protocol:: tcp
option:: tcp-established
action:: accept
}
- 允许所有公司网络(除了纽约)访问FTP服务器
这将从CORP_NETBLOCKS
令牌中“减去”CORP_NYC_NETBLOCK
。例如,假设CORP_NETBLOCKS
包含200.0.0.0/20
,而CORP_NYC_NETBLOCK
被定义为200.2.0.0/24
。source-exclude将从允许的源地址中删除纽约网络块。如果排除的地址不包含在源地址中,则不会进行任何更改。
term allow-inbound-ftp-from-corp {
source-address:: CORP_NETBLOCKS
source-exclude:: CORP_NYC_NETBLOCK
destination-port:: FTP
protocol:: tcp
action:: accept
}
示例策略文件
以下是一个 Juniper 目标平台的示例策略文件。它包含两个过滤器,每个过滤器包含一些术语。本示例假设网络和服务命名定义令牌已经被定义。
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
}
入门指南
安装
从源代码
如果您的系统上未安装 setuptools
Python 包,请安装它:例如,以下命令使用 apt
软件包管理器安装该包。
sudo apt-get install python3-pip python3-setuptools
接下来,从源代码安装 capirca
,克隆 capirca
仓库并运行其安装程序
git clone https://github.com/google/capirca.git
cd capirca/
python3 setup.py install --user
通常,当提供 --user
参数时,安装程序会创建以下文件,其中 3.8
是 Python 版本,而 2.0.0
是 capirca
的版本
~/.local/bin/capirca
~/.local/lib/python3.8/site-packages/capirca-2.0.0-py3.8.egg
如有必要,请删除构建文件
rm -rf build capirca.egg-info dist
接下来,通过生成用于 Cisco、Juniper、iptables 和其他防火墙平台的示例输出过滤器来测试 capirca
~/.local/bin/capirca
在 capirca
的源代码目录中生成示例输出时,不需要命令行参数,因为 capirca
从以下配置中继承了默认设置(请参阅 capirca/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
}
尽管 policy_file
是 None
,但该工具处理位于 base_directory
中的所有策略,即 ./policies
。工具从 definitions_directory
加载网络和服务定义。工具将生成的 ACL 输出到源目录的根目录,因为 output_directory
是 ./filters
。
包管理器
目前,PyPI 已过时。尽管如此,用户可以使用 pip
安装 capirca
的旧版本。
pip install capirca --user
基本用法
可以使用 capirca
的许多命令行参数。
$ ~/.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: '')
值得注意的是,--config_file PATH
参数允许传递一个或多个 yaml 配置文件。这些文件将按照从左到右的顺序进行优先级排序,即任何重复的配置将覆盖而不是合并。
命令行参数优先于通过配置文件传递的任何设置。
以下是以 YAML 格式默认的 capirca
配置
---
base_directory: ./policies
definitions_directory: ./def
output_directory: ./
optimize: false
recursive: true
debug: false
verbose: false
ignore_directories:
- DEPRECATED
- def
max_renderers: 10
shade_check: true
exp_info: 2
Python包
capirca
工具使用 capirca
Python 包。
因此,有方法可以通过编程方式访问 capirca
。
policies/sample_paloalto.pol
def/SERVICES.svc
def/NETWORK.net
假设您的目录中有以下文件,以下代码片段创建了一个 naming
定义对象、策略对象,并生成渲染生成器过滤器输出。
注意:逐行粘贴代码片段。
首先,启动 Python 解释器
$ 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.
>>>
接下来,导入 naming
库,并从 ./def
目录中的定义文件创建 naming
对象。
from pprint import pprint
from capirca.lib import naming
defs = naming.Naming('./def')
pprint(defs)
<capirca.lib.naming.Naming object at 0x7f8421b57280>
以下是对 defs
对象的描述
<capirca.lib.naming.Naming object at 0x7f8421b57280>
Naming
对象具有各种方法。其中,GetServiceNames
方法返回服务名称令牌。
>>> dir(defs)
['GetIpParents', 'GetNet', 'GetNetAddr', 'GetNetChildren', 'GetServiceNames',
<...intentionally omitted ..>
'unseen_networks', 'unseen_services']
>>>
>>> pprint(defs.GetServiceNames())
['WHOIS',
'SSH',
<...intentionally omitted ..>
'TRACEROUTE']
>>>
然后,导入 policy
库,从 ./policies/sample_paloalto.pol
读取策略配置数据,并创建策略对象。
from capirca.lib import policy
conf = open('./policies/sample_paloalto.pol').read()
pol = policy.ParsePolicy(conf, defs, optimize=True)
以下是对策略对象的描述
>>> 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']]}
>>>
接下来,导入一个生成器库(此处为 Palo Alto 防火墙的 paloaltofw
),以所需格式输出策略。
from capirca.lib import paloaltofw
for header in pol.headers:
if 'paloalto' in header.platforms:
jcl = True
if jcl:
output = paloaltofw.PaloAltoFW(pol, 1)
print(output)
以下代码以默认过期时间为 1 周初始化 Palo Alto 防火墙 ACL 模型。
paloaltofw.PaloAltoFW(pol, 1)
使用Docker运行
如果您的用例仅使用 CLI 并且您不想安装 capirca
,则可以使用该工具的 docker 版本。
使用 docker
时,将您的工作目录挂载到容器的 /data
目录,并按以下方式传递命令行参数。
docker run -v "${PWD}:/data" docker.pkg.github.com/google/capirca/capirca:latest
docker run -v "${PWD}:/data" docker.pkg.github.com/google/capirca/capirca:latest --helpfull
docker run -v "${PWD}:/data" docker.pkg.github.com/google/capirca/capirca:latest --config_file /data/path/to/config
其他
安全考虑
Capirca 威胁模型假定对策略定义(在 .pol 文件中)进行了一些控制和验证。这可能是通过人工用户验证,或者是通过上游系统生成策略以强制正确性。
建议在将Capirca生成的ACL应用于生产之前,始终对其进行正确性测试。并非所有生成器都支持每个功能、配置选项或术语关键词。当不支持某个功能时,Capirca将报错。但由于网络ACL的敏感性,始终建议测试任何正在使用的新生成器或生成的新策略。
附加文档
外部链接、资源和参考
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
capirca-2.0.9.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 48e33e5d06f3a877ff49fe7f3bea94757f8e421d3e2112a7bdc2d02c257ac987 |
|
MD5 | 43c2ad9156be459cb141d4a65c427195 |
|
BLAKE2b-256 | 6a212f7a20f2da1f7785f2236fdb4f000e79b5f4cb65eacd09c191700f3c9702 |
capirca-2.0.9-py3-none-any.whl的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | cf333ac9315f0d61890710f412f6b113950095ff71580530887b48b267fe2a6f |
|
MD5 | 87c61ad55d8d5b4822e163ddf3c9f792 |
|
BLAKE2b-256 | af2cbf9cdfe6653c0bf93c12fae81c6c3b3e89297609f8766a800f889f34f62d |