hashicorp保险库中声明性设置pki的命令行实用程序

pkictl的Python项目详细描述


pkictl

LicensePythonVersionDockerCoverage StatusCircleCI

pkictl是一个cli工具,用于在hashicorp保险库中声明性地配置和设置pki机密。根证书和中间证书颁发机构(CA)及其关联的角色和策略可以从yaml文件中定义和创建。它简化了使用保险库自动提供内部pki的过程,并努力实现等幂性。

pkictl的灵感来自kubectl

工作原理

pkictl使用保险库http api挂载根和中间ca的PKI secrets engines。中间ca可以由根ca或其他中间ca签名。角色和策略可以在中间ca的yaml文件中定义。

Key/Value secrets engine还用于存储配置为导出的中间ca的私钥(即spec.type: exported)。

安装

pkictl可以通过pip安装:

$ pip install pkictl

兼容性

pkictl已经针对0.10.x、0.11.x和1.0.x版本的保险库进行了测试。

用法

$ pkictl --help

declaratively configure PKI secrets in Hashicorp Vault

optional arguments:
-h, --help     show this help message and exit
-d, --debug    enable debug output
-v, --version  show program's version number and exit

subcommands:

    init         Initializes the Hashicorp Vault server
    apply        Creates PKI secrets from a YAML file

先决条件

如果您不熟悉保险库的pki机密,请阅读本指南:Build Your Own Certificate Authority (CA)

pkictl需要未密封的hashicorp保险存储服务器和具有以下权限的身份验证令牌:

  • 安装pki和kv secrets引擎
  • 读写PKI机密
  • 编写KV机密

初始化保险库服务器

初始化新的保险存储服务器并将其解封:

$ pkictl init -u https://localhost:8200

保险库服务器将使用5个密钥共享和3个密钥阈值进行初始化。

  • 根令牌保存在.vault-token
  • 主密钥共享保存在vault.log

以这种方式初始化和解封保险存储服务器只是为了便于开发/测试,因此强烈建议不要使用这种方式。

声明性设置pki机密

yaml清单文件用于定义根和中间ca、密钥/值引擎、角色和策略。

创建manifest file

---
kind: RootCA
metadata:
  name: demo-root-ca
  description: pkictl demo Root CA
spec:
  key_type: ec
  key_bits: 384
  ttl: 17532h
  exclude_cn_from_sans: true
  subject:
    common_name: Demo Root CA
    organization: pkictl
    ou: README Demo
    country: US
    locality: San Francisco
    province: California
---
kind: IntermediateCA
metadata:
  name: demo-intermediate-ca
  description: pkictl demo Intermediate CA
  issuer: demo-root-ca
  kv_backend: demo-kv-engine
spec:
  type: exported
  key_type: rsa
  key_bits: 4096
  ttl: 8766h
  subject:
    common_name: Demo Intermediate CA
    organization: pkictl
    ou: README Demo
    country: US
    locality: San Francisco
    province: California
  roles:
  - name: server
    config:
      max_ttl: 8766h
      ttl: 8766h
      allow_subdomains: true
      allowed_domains:
        - demo.pkictl.com
      client_flag: false
      server_flag: true
  - name: client
    config:
      max_ttl: 336h
      ttl: 336h
      allow_any_name: true
      client_flag: true
      server_flag: false
  policies:
  - name: demo-intermediate-ca-pkey
    policy: |
      path "demo-kv-engine" {
        capabilities = ["list"]
      }
      path "demo-kv-engine/demo-intermediate-ca" {
        capabilities = ["read"]
      }
  - name: demo-intermediate-ca-server
    policy: |
      path "demo-intermediate-ca/issue/server" {
        capabilities = ["read", "update"]
      }
      path "demo-intermediate-ca/sign/server" {
        capabilities = ["read", "update"]
      }
  - name: demo-intermediate-ca-client
    policy: |
      path "demo-intermediate-ca/issue/client" {
        capabilities = ["read", "update"]
      }
      path "demo-intermediate-ca/sign/client" {
        capabilities = ["read", "update"]
      }
---
kind: KV
metadata:
  name: demo-kv-engine
  description: pkictl demo KV v1 engine
spec:
  options:
    version: 1

以上示例将创建:

  • 基于ecdsa的{a12}ca,ttl为2年
  • 基于rsa的Intermediateca,其ttl为1年,由根ca签名
  • 名为serverRole允许中间ca为demo.pkictl.com上的任何子域颁发或签署tls服务器证书
  • 一个名为clientRole允许中间ca颁发或签署tls客户端证书
  • 映射到server角色的Policy
  • 映射到client角色的Policy
  • 存储中间ca的导出私钥的Key/Value引擎
  • 允许从kv引擎检索导出的私钥的Policy

从yaml清单文件创建pki机密:

$ pkictl apply -u https://localhost:8200 -f manifest.yaml

[*] pkictl - the Vault server has been initialized and is not sealed
[*] pkictl - Enabled KV backend: demo-kv-engine
[*] pkictl - Enabled PKI backend: demo-root-ca
[*] pkictl - Generated Root CA: demo-root-ca
[*] pkictl - Enabled PKI backend: demo-intermediate-ca
[*] pkictl - Created intermediate CA: demo-intermediate-ca
[*] pkictl - Signed intermediate CA 'demo-intermediate-ca' with issuing CA: demo-root-ca
[*] pkictl - Set signed certificate for intermediate CA: demo-intermediate-ca
[*] pkictl - Configured URLs for CA: demo-intermediate-ca
[*] pkictl - Set CRL configuration for CA: demo-intermediate-ca
[*] pkictl - Stored private key for 'demo-intermediate-ca' in KV backend: demo-kv-engine
[*] pkictl - Configured role 'server' for intermediate CA: demo-intermediate-ca
[*] pkictl - Configured role 'client' for intermediate CA: demo-intermediate-ca
[*] pkictl - Configured policy 'demo-intermediate-ca-pkey' for intermediate CA: demo-intermediate-ca
[*] pkictl - Configured policy 'demo-intermediate-ca-server' for intermediate CA: demo-intermediate-ca
[*] pkictl - Configured policy 'demo-intermediate-ca-client' for intermediate CA: demo-intermediate-ca

获取附加到demo-intermediate-ca-server策略的保管库令牌:

$ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-client -ttl=1h -format json | jq -r .auth.client_token)

使用此令牌从中间CA获取web.demo.pkictl.com的TLS服务器证书和私钥:

$ vault write demo-intermediate-ca/issue/server common_name=web.demo.pkictl.com ttl=2160h

或者,您可以在本地生成证书签名请求(CSR)和私钥,并让中间CA对CSR进行签名:

$ openssl req -batch -nodes -sha256 -new -newkey rsa:2048 \
  -keyout web.demo.pkictl.com.key -out web.demo.pkictl.com.csr -subj '/CN=web.demo.pkictl.com/'

$ vault write demo-intermediate-ca/sign/server csr=@web.demo.pkictl.com.csr ttl=2160h

保险库将返回已签名的TLS服务器证书和完整链(根和中间CA的证书)。

获取附加到demo-intermediate-ca-client策略的保管库令牌:

$ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-client -ttl=1h -format json | jq -r .auth.client_token)

使用此令牌可从中间CA获取TLS客户端证书和私钥:

$ vault write demo-intermediate-ca/issue/client common_name="example@demo.pkictl.com" ttl=24h

spec.type: exported以来,此ca的私钥已保存在kv引擎demo-kv-engine中。需要附加到demo-intermediate-ca-pkey策略的保险存储令牌才能检索它:

$ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-pkey -ttl=1m -format json | jq -r .auth.client_token)
$ vault kv get -version=1 demo-kv-engine/demo-intermediate-ca

文件

有关文档和其他示例,请参见docs目录。

测试

nose2用于测试。测试位于pkictl/tests

运行单元测试:

$ make test

端到端测试需要本地运行的保险库。要构建和运行保险库容器:

$ make build-vault-container
$ make run-vault-container

运行端到端测试:

$ make e2e-test

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何使用JNA创建同一库的多个实例?   java在将Graphql查询作为JSON字符串传递时收到意外的令牌错误   OAuth2 oltu的java问题   java桌面应用程序使用的好的嵌入式数据库是什么?   java Firebase数据库高级查询选项   java正在使磁盘上的EhCache元素过期   java 安卓还原处于backstack中的片段的实例状态   XMemcached中的java异步集   java TimescaleDB是否使用与Postgresql完全相同的JDBC驱动程序?   java从网站c读取信息#   检查java Android中的字符串是否只包含数字和空格   c#如何向web服务发送特殊字符?   grails无法调用需要java的方法。lang.类参数?   java我在组合框中调用的方法不会运行所有代码,它只运行部分代码   java发送带有标头的HTTP GET请求