Update README with CA instructions

Add CA issuer instructions for vault-ca
This commit is contained in:
ducoterra
2021-05-21 11:50:34 -04:00
parent a4117db3e7
commit cd91da981e
7 changed files with 195 additions and 9 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
cert-manager/
certs/

161
README.md
View File

@@ -12,7 +12,7 @@ brew install jq
## Install (Standalone) ## Install (Standalone)
```bash ```bash
kubectl apply -f certificate.yaml kubectl apply -f k8s/certificate.yaml
helm repo add hashicorp https://helm.releases.hashicorp.com helm repo add hashicorp https://helm.releases.hashicorp.com
helm search repo hashicorp/vault helm search repo hashicorp/vault
@@ -26,7 +26,7 @@ kubectl exec -ti vault-0 -- vault operator unseal
## Install (Cluster) ## Install (Cluster)
```bash ```bash
kubectl apply -f certificate.yaml kubectl apply -f k8s/certificate.yaml
helm repo add hashicorp https://helm.releases.hashicorp.com helm repo add hashicorp https://helm.releases.hashicorp.com
helm search repo hashicorp/vault helm search repo hashicorp/vault
@@ -43,7 +43,7 @@ kubectl exec -ti vault-2 -- vault operator raft join http://vault-0.vault-intern
kubectl exec -ti vault-2 -- vault operator unseal kubectl exec -ti vault-2 -- vault operator unseal
``` ```
## Add policy ## Add/Update policy
```bash ```bash
vault policy write ducoterra policies/ducoterra.hcl vault policy write ducoterra policies/ducoterra.hcl
@@ -121,7 +121,7 @@ rm /home/vault/.vault-token
Set your kube config to the namespace you want to use vault with Set your kube config to the namespace you want to use vault with
```bash ```bash
kubectl apply -f service-account-internal-app.yaml kubectl apply -f k8s/service-account-internal-app.yaml
``` ```
Add secrets to your pod Add secrets to your pod
@@ -163,10 +163,10 @@ vault write auth/jwt/role/myproject-production - <<EOF
"user_claim": "user_email", "user_claim": "user_email",
"bound_claims_type": "glob", "bound_claims_type": "glob",
"bound_claims": { "bound_claims": {
"project_id": "22", "project_id": "127",
"ref_protected": "true", "ref_protected": "false",
"ref_type": "branch", "ref_type": "branch",
"ref": "auto-deploy-*" "ref": "main"
} }
} }
EOF EOF
@@ -196,3 +196,150 @@ read_secrets:
# Use the secret # Use the secret
- echo $PASSWORD - echo $PASSWORD
``` ```
## Certificate Management
<https://learn.hashicorp.com/tutorials/vault/pki-engine>
<https://learn.hashicorp.com/tutorials/vault/kubernetes-cert-manager>
### Create a CA
```bash
vault secrets enable -path=pki_dnet pki
vault secrets tune -max-lease-ttl=87600h pki_dnet
vault write pki_dnet/root/generate/internal \
common_name=vault.ducoterra.net \
ttl=87600h
vault write pki_dnet/config/urls \
issuing_certificates="https://vault.ducoterra.net/v1/pki_dnet/ca" \
crl_distribution_points="https://vault.ducoterra.net/v1/pki_dnet/crl"
```
### Create an intermediate CA
```bash
vault secrets enable -path=pki_dnet_int pki
vault secrets tune -max-lease-ttl=43800h pki_dnet_int
vault write -format=json pki_dnet_int/intermediate/generate/internal \
common_name="vault.ducoterra.net Intermediate Authority" \
| jq -r '.data.csr' > certs/pki_dnet_intermediate.csr
vault write -format=json pki_dnet/root/sign-intermediate \
csr=@certs/pki_dnet_intermediate.csr format=pem_bundle ttl=43800h \
| jq -r '.data.certificate' > certs/pki_dnet_intermediate.cert.pem
vault write pki_dnet_int/intermediate/set-signed certificate=@certs/pki_dnet_intermediate.cert.pem
vault write pki_dnet_int/config/urls \
issuing_certificates="https://vault.ducoterra.net/v1/pki_dnet_int/ca" \
crl_distribution_points="https://vault.ducoterra.net/v1/pki_dnet_int/crl"
vault write pki_dnet_int/roles/dnet \
allowed_domains=dnet \
allow_subdomains=true max_ttl=43800h
vault write pki_dnet_int/roles/pi_hole \
allowed_domains=hole \
allow_subdomains=true max_ttl=43800h
```
Navigate to <https://vault.ducoterra.net/v1/pki_dnet_int/ca> and download the CA. Import to your devices.
### Issue a certificate
```bash
# Use -format=json to dump a json file
vault write pki_dnet_int/issue/dnet \
common_name=freenas.dnet > certs/freenas.dnet.cert
vault write pki_dnet_int/issue/pi_hole \
common_name=pi.hole > certs/pi.hole.cert
```
### Revoke a certificate
```bash
vault write pki_dnet_int/revoke serial_number=<serial_number>
vault write pki_dnet_int/tidy tidy_cert_store=true tidy_revoked_certs=true
```
### Use with cert-manager
```bash
vault policy write pki_dnet - <<EOF
path "pki_dnet_int*" { capabilities = ["read", "list"] }
path "pki_dnet_int/roles/*" { capabilities = ["create", "update"] }
path "pki_dnet_int/sign/*" { capabilities = ["create", "update"] }
path "pki_dnet_int/issue/*" { capabilities = ["create"] }
EOF
vault write auth/kubernetes/role/issuer \
bound_service_account_names=issuer \
bound_service_account_namespaces=cert-manager \
policies=pki_dnet \
ttl=20m
kubectl -n cert-manager create serviceaccount issuer
ISSUER_SECRET_REF=$(kubectl -n cert-manager get serviceaccount issuer -o json | jq -r ".secrets[].name")
cat > cert-manager/vault-issuer.yaml <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: vault-issuer
spec:
vault:
server: https://vault.ducoterra.net
path: pki_dnet_int/sign/dnet
auth:
kubernetes:
mountPath: /v1/auth/kubernetes
role: issuer
secretRef:
name: $ISSUER_SECRET_REF
key: token
EOF
```
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.org/client-max-body-size: "0"
name: {{ .Release.Name }}
spec:
rules:
- host: test.dnet
http:
paths:
- backend:
service:
name: {{ .Release.Name }}
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- test-dnet
secretName: test-dnet-cert
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: test-dnet
spec:
secretName: test-dnet-cert
issuerRef:
name: vault-issuer
kind: ClusterIssuer
commonName: test.dnet
dnsNames:
- test.dnet
```

26
pi-values.yaml Normal file
View File

@@ -0,0 +1,26 @@
global:
enabled: true
server:
standalone:
enabled: true
config: |
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "file" {
path = "/vault/data"
}
dataStorage:
enabled: true
size: 32Gi
storageClass: null
accessMode: ReadWriteOnce
ui:
serviceType: LoadBalancer

View File

@@ -9,3 +9,11 @@ path "totp/code/*" {
path "secret/*" { path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list"] capabilities = ["create", "read", "update", "delete", "list"]
} }
path "pki_dnet/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "pki_dnet_int/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}

View File

@@ -18,8 +18,11 @@ for vault in vaults:
threading.Thread( threading.Thread(
target = subprocess.run, target = subprocess.run,
args = ( args = (
["kubectl", "exec", "-ti", vault, "--", "vault", "operator", "unseal", vault_secrets.get("unseal_keys_b64")[key]],)) ["kubectl", "--context", "k3os-alpha.dnet-admin-vault",
for key in range(int(vault_secrets.get("unseal_threshold"))) "exec", "-ti", vault, "--",
"vault", "operator", "unseal",
vault_secrets.get("unseal_keys_b64")[key]],))
for key in range(int(vault_secrets.get("unseal_threshold")))
] ]
for thread in procs: for thread in procs: