vault

[!NOTE|label:references]

environment

install

  • macos

    $ brew tap hashicorp/tap
    $ brew install hashicorp/tap/vault
  • ubunut/debian

    $ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    $ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    $ sudo apt update && sudo apt install vault
  • centos/rhel

    $ sudo yum install -y yum-utils
    $ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
    $ sudo yum -y install vault

compltion

$ vault -autocomplete-install

status

$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    5
Threshold       3
Version         1.9.0
Build Date      n/a
Storage Type    file
Cluster Name    vault-cluster-ea2f5821
Cluster ID      e034c5c3-53c6-2d38-2adf-e9bbd57ad87c
HA Enabled      false

get info

auth

  • list role type

    $ vault auth list
    Path        Type       Accessor                 Description                Version
    ----        ----       --------                 -----------                -------
    approle/    approle    auth_approle_375212fa    n/a                        n/a
    ldap/       ldap       auth_ldap_8fc0eb82       n/a                        n/a
    token/      token      auth_token_f61ed5a6      token based credentials    n/a
  • list roles

    $ vault list auth/approle/role
    Keys
    ----
    jenkins
    jenkins-role
  • read role

    $ vault read auth/approle/role/jenkins
    Key                        Value
    ---                        -----
    bind_secret_id             true
    local_secret_ids           false
    secret_id_bound_cidrs      <nil>
    secret_id_num_uses         0
    secret_id_ttl              0s
    token_bound_cidrs          []
    token_explicit_max_ttl     0s
    token_max_ttl              4h
    token_no_default_policy    false
    token_num_uses             0
    token_period               0s
    token_policies             [service-ssh]
    token_ttl                  1h
    token_type                 default

security

  • get token

    $ vault auth list
    Path        Type       Accessor                 Description                Version
    ----        ----       --------                 -----------                -------
    approle/    approle    auth_approle_375212fa    n/a                        n/a
    ldap/       ldap       auth_ldap_8fc0eb82       n/a                        n/a
    token/      token      auth_token_f61ed5a6      token based credentials    n/a
    
    $ vault token lookup
    Key                 Value
    ---                 -----
    accessor            Wf********************5y
    creation_time       1640161759
    creation_ttl        0s
    display_name        root
    entity_id           n/a
    expire_time         <nil>
    explicit_max_ttl    0s
    id                  s.s**********************K
    meta                <nil>
    num_uses            0
    orphan              true
    path                auth/token/root
    policies            [root]
    ttl                 0s
    type                service

list

  • list all path

    $ vault secrets list [ -detailed ]
    Path                       Type         Accessor              Description
    ----                       ----         --------              -----------
    devops/                    kv           kv_374198a0           for devops
  • list keys

    $ vault kv list devops/service-account/
    Keys
    ----
    read-only
    read-write
    read-write-delete
  • get contents

    $ vault kv get devops/service-account/read-only
    =============== Secret Path ===============
    devops/data/service-account/read-only
    
    ======= Metadata =======
    Key                Value
    ---                -----
    created_time       2023-03-06T15:52:45.827580966Z
    custom_metadata    <nil>
    deletion_time      n/a
    destroyed          false
    version            5
    
    ============ Data ============
    Key                      Value
    ---                      -----
    cn                       read-only
    dn                       CN=read-only,OU=Service-Accounts,DC=example,DC=com
    password                 ********
    sAMAccountName           read-only
    username                 read-only

approle

[!NOTE|label:references:]

via CLI

  • pre-setup

    $ export VAULT_ADDR='https://vault.domain.com'
    $ export VAULT_TOKEN='s.s**********************K'
    
    # VAULT_TOKEN=$(vault print token)
  • setup

    $ vault write auth/approle/role/devops \
                  token_num_uses=0 \
                  secret_id_num_uses=0 \
                  policies="devops"
    Success! Data written to: auth/approle/role/devops
    
    $ vault read auth/approle/role/devops
    Key                        Value
    ---                        -----
    bind_secret_id             true
    local_secret_ids           false
    policies                   [devops]
    secret_id_bound_cidrs      <nil>
    secret_id_num_uses         0
    secret_id_ttl              0s
    token_bound_cidrs          []
    token_explicit_max_ttl     0s
    token_max_ttl              0s
    token_no_default_policy    false
    token_num_uses             0
    token_period               0s
    token_policies             [devops]
    token_ttl                  0s
    token_type                 default

# enable auth method
$ curl \
      --header "X-Vault-Token: ..." \
      --request POST \
      --data '{"type": "approle"}' \
      http://127.0.0.1:8200/v1/sys/auth/approle

# create approle with policy
$ curl \
      --header "X-Vault-Token: ..." \
      --request POST \
      --data '{"policies": "dev-policy,test-policy"}' \
      http://127.0.0.1:8200/v1/auth/approle/role/my-role

# check identifier of role
$ curl \
      --header "X-Vault-Token: ..." \
      http://127.0.0.1:8200/v1/auth/approle/role/my-role/role-id
{
  "data": {
    "role_id": "988a9dfd-ea69-4a53-6cb6-9d6b86474bba"
  }
}

# create new security
$ curl \
      --header "X-Vault-Token: ..." \
      --request POST \
       http://127.0.0.1:8200/v1/auth/approle/role/my-role/secret-id
{
  "data": {
    "secret_id_accessor": "45946873-1d96-a9d4-678c-9229f74386a5",
    "secret_id": "37b74931-c4cd-d49a-9246-ccc62d682a25",
    "secret_id_ttl": 600,
    "secret_id_num_uses": 40
  }
}

get secret_id and role_id

# read for role-id
$ vault read auth/approle/role/devops/role-id
Key        Value
---        -----
role_id    1*******-****-****-****-***********5

$ vault write -f auth/approle/role/srv-ssd-fw-devops/secret-id
Key                   Value
---                   -----
secret_id             3*******-****-****-****-***********3
secret_id_accessor    9*******-****-****-****-***********b
secret_id_ttl         0

# list for secret_id
$ vault list auth/approle/role/devops/secret-id
Keys
-----
9*******-****-****-****-***********b

operator

tokens

[!NOTE|label:references:]

TOKEN TYPEVAULT 1.9.X +VAULT 1.10 -

Service tokens

s.<random>

hvs.<random>

Batch tokens

b.<random>

hvb.<random>

Recovery tokens

r.<random>

hvr.<random>

[!TIP]

  • initial root token with no expiration

    $ vault operator init
  • generate root token with share holders ( with unseal key )

    [!NOTE|label:references:]

    $ vault operator generate-root
    • example:

      • generate an otp code for the final token

        $ vault operator generate-root -generate-otp
      • start a root token generation:

        $ vault operator generate-root -init
      • enter an unseal key to progress root token generation:

        $ vault operator generate-root
  • check status

    $ vault operator generate-root -status
    Nonce         n/a
    Started       false
    Progress      0/3
    Complete      false
    OTP Length    26

$ vault operator init
Unseal Key 1: p******************************************Y
Unseal Key 2: /******************************************y
Unseal Key 3: j******************************************I
Unseal Key 4: V******************************************K
Unseal Key 5: l******************************************M

Initial Root Token: s.s**********************K
  • check status

    $ vault operator key-status
    Key Term            1
    Install Time        22 Dec 21 08:29 UTC
    Encryption Count    211817
  • generate new unseal key

    $ vault operator rekey
  • seal/unseal

    $ vault operator seal
    $ vault operator unseal

ssh

[!NOTE|label:references:]

client key sign

  • mount ssh secret engine

    $ vault secrets enable -path=devops-ssh ssh
  • configure vault with a ca

    $ vault write devops-ssh/config/ca generate_signing_key=true
    # or with private/public key pairs
    $ vault write devops-ssh/config/ca \
            private_key="..." \
            public_key="..."
    
  • add CA to all servers

    # download pem
    $ curl -o /etc/ssh/trusted-user-ca-keys.pem http://vault.sample.com:8200/v1/ssh-client-signer/public_key
    # or
    $ vault read -field=public_key devops-ssh/config/ca > /etc/ssh/trusted-user-ca-keys.pem
    
    # modify sshd_config to `TrustedUserCAKeys`
    $ sudo vim /etc/ssh/sshd_config
    ...
    TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
    
    # restart sshd
    $ sudo systemctl daemon-reload
    $ sudo systemctl restart sshd.service
  • create role

    $ vault write devops-ssh/roles/my-role -<<"EOH"
    {
      "algorithm_signer": "rsa-sha2-256",
      "allow_user_certificates": true,
      "allowed_users": "*",
      "allowed_extensions": "permit-pty,permit-port-forwarding",
      "default_extensions": {
        "permit-pty": ""
      },
      "key_type": "ca",
      "default_user": "ubuntu",
      "ttl": "30m0s"
    }
    EOH

  • create ssh-key paire

    $ ssh-keygen -t ed25519 -C "user@example.com"
  • sign the public key

    $ vault write ssh-client-signer/sign/my-role \
        public_key=@$HOME/.ssh/id_ed25519.pub
    
    Key             Value
    ---             -----
    serial_number   c73f26d2340276aa
    signed_key      ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1...
    
    # or customerize
    $ vault write ssh-client-signer/sign/my-role -<<"EOH"
    {
      "public_key": "ssh-rsa AAA...",
      "valid_principals": "my-user",
      "key_id": "custom-prefix",
      "extensions": {
        "permit-pty": "",
        "permit-port-forwarding": ""
      }
    }
    EOH
  • saved the signed keys

    $ vault write -field=signed_key ssh-client-signer/sign/my-role \
        public_key=@$HOME/.ssh/id_ed25519.pub > signed-cert.pub
    
    # verify
    $ ssh-keygen -Lf ~/.ssh/signed-cert.pub
    
    # ssh
    $ ssh -i signed-cert.pub -i ~/.ssh/id_ed25519 username@10.0.23.5

host key sign

  • mount ssh security

    $ vault secrets enable -path=devops-ssh-hosts ssh
    Successfully mounted 'ssh' at 'devops-ssh-hosts'!
  • configure CA

    $ vault write devops-ssh-hosts/config/ca generate_signing_key=true
    Key             Value
    ---             -----
    public_key      ssh-rsa AAAAB3NzaC1yc2EA...
    
    # or with key pairs
    $ vault write devops-ssh-hosts/config/ca \
            private_key="..." \
            public_key="..."
  • extend host key certificate ttls

    $ vault secrets tune -max-lease-ttl=87600h devops-ssh-hosts
  • create role

    $ vault write devops-ssh-hosts/roles/hostrole \
        key_type=ca \
        algorithm_signer=rsa-sha2-256 \
        ttl=87600h \
        allow_host_certificates=true \
        allowed_domains="localdomain,example.com" \
        allow_subdomains=true
  • sign ssh public key

    $ vault write devops-ssh-hosts/sign/hostrole \
        cert_type=host \
        public_key=@/etc/ssh/ssh_host_ed25519_key.pub
    Key             Value
    ---             -----
    serial_number   3746eb17371540d9
    signed_key      ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1y...
  • signed certificate as HostCertificate

    $ vault write -field=signed_key devops-ssh-hosts/sign/hostrole \
        cert_type=host \
        public_key=@/etc/ssh/ssh_host_ed25519_key.pub > /etc/ssh/ssh_host_ed25519_key-cert.pub
    
    $ chmod 0640 /etc/ssh/ssh_host_ed25519_key-cert.pub
    
    # modify sshd_config
    $ sudo vim /etc/ssh/sshd_config
    ...
    # For client keys
    TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
    ...
    # For host keys
    HostKey /etc/ssh/ssh_host_ed25519_key
    HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
    
    $ sudo systemctl daemon-reload
    $ sudo systemctl restasrt sshd.service

verify

  • retrieve the host signing ca public key

    $ curl http://127.0.0.1:8200/v1/devops-ssh-hosts/public_key
    
    # or
    $ vault read -field=public_key devops-ssh-hosts/config/ca
  • add into ~/.ssh/authorized_keys

    $ cat >> ~/.ssh/known_hosts << EOF
    @cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAA...
    EOF

  • set verbose log level

    $ sudo vim /etc/ssh/sshd_config
    ...
    LogLevel VERBOSE
    
    $ sudo systemctl daemon-reload
    $ sudo systemctl restart sshd.services
  • check in /var/log/auth.log

    $ tail -f /var/log/auth.log | grep --line-buffered "sshd"

usage

API

[!NOTE|label:references:]

$ curl \
      -H "X-Vault-Token: f3b09679-3001-009d-2b80-9c306ab81aa6" \
      -H "X-Vault-Namespace: ns1/ns2/" \
      -X GET \
      http://127.0.0.1:8200/v1/secret/foo

# or
$ curl \
      -H "X-Vault-Token: f3b09679-3001-009d-2b80-9c306ab81aa6" \
      -X GET \
      http://127.0.0.1:8200/v1/ns1/ns2/secret/foo

CLI

[!NOTE|label:references:]

$ vault write -output-curl-string  auth/userpass/users/bob password="long-password"
curl -X PUT -H "X-Vault-Request: true" -H "X-Vault-Token: $(vault print token)" -d '{"password":"long-password"}' http://127.0.0.1:8200/v1/auth/userpass/users/bob
  • print policy requirements

    $ vault kv put -output-policy kv/secret value=itsasecret
    path "kv/data/secret" {
      capabilities = ["create", "update"]
    }

 $ vault path-help devops
   ...

     ^.*$

     ^config$
         Configures settings for the KV store

     ^data/(?P<path>.*)$
         Write, Patch, Read, and Delete data in the Key-Value Store.

     ^delete/(?P<path>.*)$
         Marks one or more versions as deleted in the KV store.

     ^destroy/(?P<path>.*)$
         Permanently removes one or more versions in the KV store

     ^metadata/(?P<path>.*)$
         Configures settings for the KV store

     ^undelete/(?P<path>.*)$
         Undeletes one or more versions from the KV store.
  • and more

    $ vault path-help sys/mounts
    Request:        mounts
    Matching Route: ^mounts$
    
    ## DESCRIPTION
    This path responds to the following HTTP methods.
    
        GET /
            Lists all the mounted secret backends.
    
        GET /<mount point>
            Get information about the mount at the specified path.
    
        POST /<mount point>
            Mount a new secret backend to the mount point in the URL.
    
        POST /<mount point>/tune
            Tune configuration parameters for the given mount point.
    
        DELETE /<mount point>
            Unmount the specified mount point.

$ echo -n '{"value":"itsasecret"}' | vault kv put secret/password -

# or
$ echo -n "itsasecret" | vault kv put secret/password value=-

$ vault kv put secret/password @data.json

# or
$ vault kv put secret/password value=@data.txt

basic usage

$ export VAULT_ADDR='http://127.0.0.1:8200'
$ export VAULT_TOKEN=root

# enable azure
$ vault auth enable azure

# write config
$ vault write auth/azure/config \
              tenant_id="${TENANT_ID}" \
              client_id="${CLIENT_ID}" \
              client_secret="${CLIENT_SECRET}" \
              resource="https://management.azure.com/"

# write role
$ vault write auth/azure/role/rotation-role \
              bound_subscription_ids="${SUBSCRIPTION_ID}" \
              bound_resource_groups="${RESOURCE_GROUP_NAME}"

# login
$ vault write auth/azure/login \
              role="rotation-role" \
              jwt="${ACCESS_TOKEN_JWT}" \
              subscription_id="${SUBSCRIPTION_ID}" \
              resource_group_name="${RESOURCE_GROUP_NAME}" \
              vm_name="${VM_NAME}"
  • result

    Key                               Value
    ---                               -----
    token                             hvs.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    token_accessor                    XXXXXXXXXXXXXXXXXXXXXX
    token_duration                    768h
    token_renewable                   true
    token_policies                    ["default"]
    identity_policies                 []
    policies                          ["default"]
    token_meta_vm_name                vault-azure-tests-vm
    token_meta_resource_group_name    vault_azure_tests_XXXXXXXX
    token_meta_role                   rotation-role
    token_meta_subscription_id        XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX

Last updated