Skip to content

Instantly share code, notes, and snippets.

@ludwig
Forked from jjenkins70/README.md
Created March 10, 2024 11:02
Show Gist options
  • Save ludwig/c78fbf19778e39cd3797942d6a9fd0e7 to your computer and use it in GitHub Desktop.
Save ludwig/c78fbf19778e39cd3797942d6a9fd0e7 to your computer and use it in GitHub Desktop.

Revisions

  1. Jeremiah created this gist Jan 23, 2020.
    141 changes: 141 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,141 @@
    # Simple Vault TLS Certificate validation & testing
    Set of scripts to deploy locally, vault and configure TLS server and user certificates for testing TLS AUTH.

    credit to @reard3n (https://github.com/reard3n) and @v6 (https://github.com/v6) for the gist this grew from

    # Notes
    This was tested using Vagrant and Ubuntu

    # Getting Setup
    - On the OS of your choice copy VaultCASetup.sh script locally and update any variables that would be specific to your environment and/or
    version of Vault you want to test against.
    - Copy vaultCAuser.sh scripts locally, also updating any variables that you want to change and run. This creates a separate user cert, signed by the initial "server" certificate created
    in step 1.

    # Start Vault
    ## Run the following on the command line
    `nohup vault server -dev -config=vault.hcl > vault_verbose.log &`

    # set up the vault CLI
    `export VAULT_ADDR="https://vault.testdomain.local:8500"`

    # Save root token
    `TOKEN=$(grep "Root Token" vault_verbose.log | cut -c 12-)`

    now you can run `vault login $TOKEN` to login as root

    # Using the Certificate Authentication Methods
    ## enable certificate authentication and upload the CA cert to vault

    Enable the TLS Certificates Auth Method

    `vault auth enable cert`

    Create the "web" user certificate - simulates giving specific access to only a web app
    ```
    vault write auth/cert/certs/web display_name=webcert policies=default,web [email protected] ttl=3600
    ```

    Create the "app" user certificate - simulates giving specific access to only an application
    ```
    vault write auth/cert/certs/app display_name=appcert policies=default,app [email protected] ttl=3600
    ```

    # Create Vault policies
    You can either download and run create_policies.sh or copy below to create the unique policies.

    Web Policy:

    ```
    vault policy write web -<<EOF
    path "secret/web" {
    capabilities = ["read", "create", "update"]
    }
    path "secret/data/web" {
    capabilities = ["read", "create", "update"]
    }
    EOF
    ```

    App Policy:

    ```
    vault policy write app -<<EOF
    path "secret/app" {
    capabilities = ["read", "create", "update"]
    }
    path "secret/data/app" {
    capabilities = ["read", "create", "update"]
    }
    EOF
    ```

    Confirm the policy is stored:

    `vault policy read web`

    `vault policy read app`

    output would be similar to :
    ```
    vault policy read web
    path "secret/web" {
    capabilities = ["read", "create", "update"]
    }
    path "secret/data/web" {
    capabilities = ["read", "create", "update"]
    }
    ```

    # Test and Validate
    Create some secrets:

    `vault kv put secret/web password=webPassword`

    `vault kv put secret/app password=appPassword`

    ## Web Auth
    attempt a login using the user certificate we created above (Web)
    ```
    vault login -ca-cert=certAuth.pem -method=cert -client-cert=user.crt -client-key=user.key name=web
    ```

    Investigate your token properties:
    `vault token lookup`

    Try to read the web secret:
    `vault kv get secret/web`

    Try to update the web secret:
    `vault kv put secret/web password=updateWebPassword`

    Try to read the app secret:
    `vault kv get secret/app` (note - this should error)

    Try to update the app secret:
    `vault kv put secret/app testing=thisShouldFail`

    ## App Auth
    attempt a login using the user certificate we created above (App)
    ```
    vault login -ca-cert=certAuth.pem -method=cert -client-cert=user_app.crt -client-key=user_app.key name=app
    ```

    Investigate your token properties:
    `vault token lookup`

    Try to read the web secret:
    `vault kv get secret/web` (note - this should error)

    Try to update the web secret:
    `vault kv put secret/web password=thisShouldFail`

    Try to read the app secret:
    `vault kv get secret/app`

    Try to update the app secret:
    `vault kv put secret/app password=`

    ```
    vault login -ca-cert=certAuth.pem -method=cert -client-cert=user_app.crt -client-key=user_app.key name=app
    ```
    27 changes: 27 additions & 0 deletions create_policies.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    function create_policies {
    cat << EOF > web.hcl
    path "secret/web" {
    capabilities = ["read", "create", "update"]
    }
    path "secret/data/web" {
    capabilities = ["read", "create", "update"]
    }
    EOF
    cat << EOF > app.hcl
    path "secret/app" {
    capabilities = ["read", "create", "update"]
    }
    path "secret/data/app" {
    capabilities = ["read", "create", "update"]
    }
    EOF
    }

    function write_policy {
    vault policy write web web.hcl
    vault policy write app app.hcl
    }

    #MAIN
    create_policies
    write_policy
    127 changes: 127 additions & 0 deletions vaultCASetup.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    #!/bin/bash
    # Variables
    #
    VAULTFQDN=vault.testdomain.local
    USERNAME=jjenkins
    # check releases.hashicorp.com/vault/ for the OS version you need. MAC = darwin_amd64, Linux=linux_amd64, WINDOWS = windows_amd64
    OSVER=linux_amd64

    # Use below when +ent is top of the releases page
    VAULTLATESTDIR=https://releases.hashicorp.com/vault/1.3.1/
    VAULTLATESTBIN=vault_1.3.1

    function download_vault {
    # Pull latest version for the OS defined in OSVER
    #This doesn't work when +ent is the top of the list
    #####
    #VAULTLATESTDIR=`curl -s https://releases.hashicorp.com/vault/ | grep href | grep -v - | grep -v "\.\." | head -n1 | awk -F"\"" '{print $2}'`
    #VAULTLATESTBIN=`curl -s https://releases.hashicorp.com/vault/ | grep href | grep -v - | grep -v "\.\." | head -n1 | awk -F">" '{print $2}' | awk -F"<" '{print $1}'`
    #echo "Latest version directory is $VAULTLATESTDIR"
    #echo "Latest version binary is $VAULTLATESTBIN"
    #FULLURL="https://releases.hashicorp.com${VAULTLATESTDIR}${VAULTLATESTBIN}_${OSVER}.zip"
    #####

    ###
    ### Use below with hard coded download path
    ###
    FULLURL="${VAULTLATESTDIR}${VAULTLATESTBIN}_${OSVER}.zip"
    echo "Fetching Vault from $FULLURL"
    curl ${FULLURL} > ${VAULTLATESTBIN}_${OSVER}.zip
    sudo unzip -o ${VAULTLATESTBIN}_${OSVER}.zip -d /usr/local/bin
    }

    function create_ca_config {
    # dump the contents of the Certificate Authority config file into a conf
    cat << EOF > caconf.certAuth.conf
    [ req ]
    # Options for the req tool (man req).
    default_bits = 4096
    distinguished_name = req_distinguished_name
    string_mask = utf8only
    # SHA-1 is deprecated, please use SHA-2 or greater instead.
    default_md = sha384
    # Extension to add when the -x509 option is used.
    x509_extensions = v3_ca
    [ req_distinguished_name ]
    countryName = Country Name (2 letter code)
    stateOrProvinceName = State or Province Name
    localityName = Locality Name
    0.organizationName = Organization Name
    organizationalUnitName = Organizational Unit Name
    commonName = Common Name
    emailAddress = Email Address
    # Optionally, specify some defaults.
    countryName_default = US
    stateOrProvinceName_default = CA
    localityName_default = San Francisco
    0.organizationName_default = HashiCorpTesting
    organizationalUnitName_default = Testing
    emailAddress_default = [email protected]
    [ v3_ca ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    EOF

    # make a CA cert key and then a csr, then sign the csr
    openssl genrsa -out certAuth.key 2048
    openssl req -x509 -new -nodes -key certAuth.key -sha256 -days 2014 -out certAuth.pem -config caconf.certAuth.conf -extensions v3_ca -subj "/CN=JJGenericCA"

    # VAULT INSTANCE CERT - generate a key and CSR
    openssl req -new -newkey rsa:2048 -nodes -keyout vault.key -out vault.csr -subj "/CN=$VAULTFQDN"

    cat << EOF > caconf.vault.conf
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = $VAULTFQDN
    EOF
    # sign the vault server CSR with the CA we created above
    openssl x509 -req -in vault.csr -CA certAuth.pem -CAkey certAuth.key -CAcreateserial -out vault.crt -days 365 -sha256 -extfile caconf.vault.conf

    # USER IDENTIFICATION CERT - generate a key and CSR
    openssl req -new -newkey rsa:2048 -nodes -keyout user.key -out user.csr -subj "/CN=$USERNAME"

    cat << EOF > caconf.user.conf
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = $USERNAME
    EOF

    # sign the vault server CSR with the CA we created above
    openssl x509 -req -in user.csr -CA certAuth.pem -CAkey certAuth.key -CAcreateserial -out user.crt -days 365 -sha256 -extfile caconf.user.conf
    }

    function vault_config {
    cat << EOF > vault.hcl
    listener "tcp" {
    address = "0.0.0.0:8500"
    tls_disable = false
    tls_cert_file = "vault.crt"
    tls_key_file = "vault.key"
    tls_client_ca_file = "certAuth.pem"
    tls_require_and_verify_client_cert = false
    }
    EOF
    # Set /etc/hosts
    sudo sh -c 'echo "127.0.0.1 vault.testdomain.local" >> /etc/hosts'

    # Add CA to OS trusted root -- for Ubuntu
    sudo mkdir /usr/local/share/ca-certificates/vault/
    sudo cp vault.crt /usr/local/share/ca-certificates/vault/vault.crt
    sudo update-ca-certificates
    }

    ###
    #Main
    ###
    download_vault
    create_ca_config
    vault_config
    28 changes: 28 additions & 0 deletions vaultCAuser.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    #!/bin/bash
    # Variables
    #
    VAULTFQDN=vault.testdomain.local
    USERNAME=jjenkinsUser

    function create_ca_config {

    # USER IDENTIFICATION CERT - generate a key and CSR
    openssl req -new -newkey rsa:2048 -nodes -keyout user_app.key -out user_app.csr -subj "/CN=$USERNAME"

    cat << EOF > caconf.user_app.conf
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = $USERNAME
    EOF

    # sign the vault server CSR with the CA we created above
    openssl x509 -req -in user_app.csr -CA certAuth.pem -CAkey certAuth.key -CAcreateserial -out user_app.crt -days 365 -sha256 -extfile caconf.user_app.conf
    }


    # MAIN
    create_ca_config