上一篇文章我们使用cert-manager的ACME功能从自己的Vault生成了数字证书,其实cert-manager也能直接与Vault的非ACME API交互。
过程很简单,cert-manager在Vault那里验证身份,通过后就可以提交证书请求,有权限的话就拿到证书。
身份验证与权限
Vault支持多种身份验证方式
先改下安全凭据的默认有效期:
1
2
vault login # 用root的token登录,照我第一篇文章那样搞的日常管理员用户没权限读下面的路径
vault read sys/auth/approle/tune
可以看到当前的也是默认的设置:
1
2
3
4
5
6
7
Key Value
--- -----
default_lease_ttl 768h
description n/a
force_no_cache false
max_lease_ttl 768h
token_type default-service
喜欢的话可以把它改长点:
1
vault auth tune -default-lease-ttl= 8760h -max-lease-ttl= 8760h approle/
㊟ 确保/etc/vault.d/
这里没有 文件定义了上面的时间。
⚠️ 本系列文章都不适合于生产环境,这些只是过家家的。
验证方式默认都是关闭的:我们手动打开AppRole类型的验证方式
1
vault auth enable approle
然后可以创建一个服务账号:
1
2
3
4
5
6
7
vault write auth/approle/role/certmanager-approle \
token_type = batch \
# secret_id_ttl=720h \ # 从这行开始我都注释掉的,过家家无所谓什么过期时间,默认是0——永不过期
token_ttl = 720h \
token_max_ttl = 720h \
secret_id_num_uses = 20 \ #使用次数
secret_id_bound_cidrs = "" # 使用反向代理服务器或负载均衡器的填写对端地址,比如“127.0.0.1/32”
可以查看它的信息:
1
vault read auth/approle/role/certmanager-approle
可以改,比如:
1
vault write auth/approle/role/certmanager-approle secret_id_bound_cidrs = "192.168.0.0/16, 127.0.0.1/32"
获取role ID,四舍五入约等于用户名:
1
2
3
4
vault read auth/approle/role/certmanager-approle/role-id
Key Value
--- -----
role_id 24d0b1fc-de60-cd1e-b69c-e53be481c864
创建一条ACL,这决定了关联的服务账号能不能搞证书,能在哪里搞:
1
2
3
4
5
6
vault policy write cert-manager - <<EOF
path "ca*" { capabilities = ["read", "list"] }
path "ca-int-x1/roles/cert-test" { capabilities = ["create", "update"] }
path "ca-int-x1/sign/cert-test" { capabilities = ["create", "update"] }
path "ca-int-x1/issue/cert-test" { capabilities = ["create"] }
EOF
将策略与服务账号关联:
1
vault write auth/approle/role/certmanager-approle policies = cert-manager
给它生成secure ID,四舍五入相当于密码:
1
2
3
4
5
vault write -f auth/approle/role/certmanager-approle/secret-id
Key Value
--- -----
secret_id 51434556-11ed-1447-157f-5ad363a38727
secret_id_accessor 8c666f20-a127-7464-a08b-783e1bd3574e
㊟ 只显示一次,坏掉了忘记了等等情况就要再生成一个。
看看密码过期时间:
1
vault write auth/approle/role/certmanager-approle/secret-id/lookup secret_id = '<secret_id>'
编个码:
1
2
echo -n '<secret-id>' | openssl base64
ZTRkY2IzMzYtMzQzYy0wYmZiLThlYzMtY2ViMmE4ZDk0NjVl # 记下来
我们那个发证书的角色我手贱乱改过,先看看信息:
1
vault read ca-int-x1/roles/cert-test
有什么地方不满意的话可以改,比如:
1
2
3
4
vault write ca-int-x1/roles/cert-test \
key_type=any \
allowed_domains=miyunda.com,.local \
allow_subdomains=true
Kubernetes 这边
这回与上次不同,这次实验不再需要搞什么DNS劫持什么IP转发了,因为不再有ACME挑战,而是有权限就能给。让我们到minikube机器上:
1
2
3
minikube stop
minikube delete
minikube start
Secret
“密码”存这里:
1
2
3
4
mkdir ~/hellonerd-certmanager-approle && cd ~/hellonerd-certmanager-approle
nano secret.yaml
kubectl create -f secret.yaml
secret/certmanager-vault-approle created
1
2
3
4
5
6
7
8
9
# secret.yaml
piVersion : v1
kind : Secret
type : Opaque
metadata :
name : certmanager-vault-approle
namespace : default # 这行的内容和楼下的文件要一致
data :
secretId : "<secret_id>"
Issuer
还得把Vault的信息给它,让它知道去哪能得到证书:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# issuer.yaml
apiVersion : cert-manager.io/v1
kind : Issuer
metadata :
name : vault-dev-approle
namespace : default
spec :
vault :
path : ca-int-x1/sign/cert-test
server : https://vault-dev.miyunda.com
# caBundle: <base64 encoded caBundle PEM file> # Vault使用自签名CA提供服务的话得把CA证书放在这里
auth :
appRole :
path : approle
roleId : "<rold_id>"
secretRef :
name : certmanager-vault-approle
key : secretId
1
2
3
nano issuer.yaml
kubectl create -f issuer.yaml
certificate.cert-manager.io/foo-miyunda-com created
建好之后可以看看状态:
1
2
3
kubectl get issuer
NAME READY AGE
vault-dev-approle True 3s
不行的话可以看看:
1
kubectk describe issuer <issuer名字> # -n <namespace>
打印的信息会报告哪里有问题。
证书
从Vault获取证书:
1
2
nano mycert.yaml
kubectl create -f mycert.yaml
这文件很多地方不用填写的,我就是为了举例子弄成这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# mycert.yaml
apiVersion : cert-manager.io/v1
kind : Certificate
metadata :
name : foo-miyunda-com
namespace : default
annotations :
cert-manager.io/issuer : "vault-dev-approle"
spec :
secretName : foo-miyunda-com
subject :
organizations :
- "Miyunda & Co Inc"
countries :
- Haidian # ???
- Xuanwu # ???
localities :
- Beijing
organizationalUnits :
- "Marketing"
provinces :
- Asia
commonName : foo.miyunda.com
dnsNames :
- bar.miyunda.com
- foo.bar.miyunda.com
issuerRef :
name : vault-dev-approle
kind : Issuer
group : cert-manager.io
privateKey :
# Vault那边叫“EC”
algorithm : ECDSA
duration : 2160h
# 默认是三个月有效期,提前一个月续期
renewBefore : 360h
isCA : false
usages :
- server auth
- client auth
看看状态:
1
2
3
kubectl get certificate foo-miyunda-com
NAME READY SECRET AGE
foo-miyunda-com True foo-miyunda-com 2s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
kubectl describe certificate foo-miyunda-com # -n <namespace>
Name : foo-miyunda-com
Namespace : default
Labels : <none>
Annotations: cert-manager.io/issuer : vault-dev-approle
API Version : cert-manager.io/v1
Kind : Certificate
Metadata :
Creation Timestamp : 2024-09-15T14:13:51Z
Generation : 1
Resource Version : 187301
UID : c74f8a18-bdde-4c90-ba55-fa89c98d3351
Spec :
Common Name : foo.miyunda.com
Dns Names :
bar.miyunda.com
foo.bar.miyunda.com
Duration : 2160h
Is CA : false
Issuer Ref :
Group : cert-manager.io
Kind : Issuer
Name : vault-dev-approle
Private Key :
Algorithm : ECDSA
Renew Before : 360h
Secret Name : foo-miyunda-com
Subject :
Countries :
Haidian
Xuanwu
Localities :
Beijing
Organizational Units :
Marketing
Organizations :
Miyunda & Co Inc
Provinces :
Asia
Usages :
server auth
client auth
Status :
Conditions :
Last Transition Time : 2024-09-15T14:13:51Z
Message : Certificate is up to date and has not expired
Observed Generation : 1
Reason : Ready
Status : True
Type : Ready
Not After : 2024-12-12T14:27:12Z
Not Before : 2024-09-13T14:26:42Z
Renewal Time : 2024-11-27T14:27:12Z
Events : <none>
kubectl describe certificate hellonerd-example-tls-approle
Name : hellonerd-example-tls-approle
Namespace : default
Labels : <none>
Annotations : <none>
API Version : cert-manager.io/v1
Kind : Certificate
Metadata :
Creation Timestamp : 2024-09-15T14:12:37Z
Generation : 1
Owner References :
API Version : networking.k8s.io/v1
Block Owner Deletion : true
Controller : true
Kind : Ingress
Name : kuard
UID : c273e1c4-68ca-48bf-bb86-775ed5e86d40
Resource Version : 187229
UID : 85bc79a6-bff5-469b-bee6-18568e45e14a
Spec :
Common Name : hellonerd.miyunda.com
Dns Names :
hellonerd.miyunda.com
Duration : 2160h0m0s
Issuer Ref :
Group : cert-manager.io
Kind : Issuer
Name : vault-dev-approle
Private Key :
Algorithm : ECDSA
Rotation Policy : Always
Size : 384
Renew Before : 720h0m0s
Secret Name : hellonerd-example-tls-approle
Subject :
Countries :
CN
Localities :
Beijing
Organizational Units :
Marketing
Organizations :
Miyunda & Co Inc
Provinces :
Haidian
Xuanwu
Usages :
key agreement
digital signature
server auth
Status :
Conditions :
Last Transition Time : 2024-09-15T14:12:37Z
Message : Certificate is up to date and has not expired
Observed Generation : 1
Reason : Ready
Status : True
Type : Ready
Not After : 2024-12-14T13:31:50Z
Not Before : 2024-09-15T13:31:20Z
Renewal Time : 2024-11-14T13:31:50Z
Events : <none>
然后在随便什么资源里面引用这个证书就好了。
Ingress
也可以搞成纯自动的,自动申请安装续期等等。
先把上一篇文章那个DNS私有解析去掉——用不上了:
1
2
sudo sed -i '/hellonerd/d' /etc/hosts
nslookup hellonerd.miyunda.com
准备一个文件,同上面的例子一样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# ingress.yaml
apiVersion : networking.k8s.io/v1
kind : Ingress
metadata :
name : kuard
annotations :
cert-manager.io/issuer : "vault-dev-approle" #必填
cert-manager.io/common-name : "hellonerd.miyunda.com" #必填
cert-manager.io/subject-organizations : "Miyunda & Co Inc"
cert-manager.io/subject-organizationalunits : "Marketing"
cert-manager.io/subject-countries : "CN"
cert-manager.io/subject-provinces : "Haidian,Xuanwu"
cert-manager.io/subject-localities : "Beijing"
cert-manager.io/private-key-algorithm : "ECDSA" #默认是RSA
cert-manager.io/private-key-size : "384" # 选了ECDSA那么默认是256
cert-manager.io/duration : "2160h" # 默认就是这个
cert-manager.io/renew-before : "720h" # 同上
cert-manager.io/usages : "key agreement, digital signature, server auth" # 同上
cert-manager.io/private-key-rotation-policy : "Always" # 默认是永不改
spec :
ingressClassName : nginx
tls :
- hosts :
- hellonerd.miyunda.com
secretName : hellonerd-example-tls-approle
rules :
- host : hellonerd.miyunda.com
http :
paths :
- path : /
pathType : Prefix
backend :
service :
name : kuard
port :
number : 80
创建:
1
kubectl create -f ingress.yaml
可以看看它的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
kubectl describe certificate hellonerd-example-tls-approle -n <namespace>
Name : hellonerd-example-tls-approle
Namespace : default
Labels : <none>
Annotations : <none>
API Version : cert-manager.io/v1
Kind : Certificate
Metadata :
Creation Timestamp : 2024-09-15T14:12:37Z
Generation : 1
Owner References :
API Version : networking.k8s.io/v1
Block Owner Deletion : true
Controller : true
Kind : Ingress
Name : kuard
UID : c273e1c4-68ca-48bf-bb86-775ed5e86d40
Resource Version : 187229
UID : 85bc79a6-bff5-469b-bee6-18568e45e14a
Spec :
Common Name : hellonerd.miyunda.com
Dns Names :
hellonerd.miyunda.com
Duration : 2160h0m0s
Issuer Ref :
Group : cert-manager.io
Kind : Issuer
Name : vault-dev-approle
Private Key :
Algorithm : ECDSA
Rotation Policy : Always
Size : 384
Renew Before : 720h0m0s
Secret Name : hellonerd-example-tls-approle
Subject :
Countries :
CN
Localities :
Beijing
Organizational Units :
Marketing
Organizations :
Miyunda & Co Inc
Provinces :
Haidian
Xuanwu
Usages :
key agreement
digital signature
server auth
Status :
Conditions :
Last Transition Time : 2024-09-15T14:12:37Z
Message : Certificate is up to date and has not expired
Observed Generation : 1
Reason : Ready
Status : True
Type : Ready
Not After : 2024-12-14T13:31:50Z
Not Before : 2024-09-15T13:31:20Z
Renewal Time : 2024-11-14T13:31:50Z
Events : <none>
从minikube机器 上去访问网站,注意观察打印出的服务器端证书信息:
1
2
3
4
5
curl -o my-ca.crt $VAULT_ADDR/v1/ca-root-x1/ca/pem
curl -ivL \
--cacert my-ca.crt \
--resolve hellonerd.miyunda.com:443:192.168.49.2 \
https://hellonerd.miyunda.com
㊟ 503 Service Temporarily Unavailable 错误是正常的,因为后面根本就没有服务,这里只看证书,别的不管。
好了,Kubernetes用AppRole验证获取Vault证书的介绍就这么多了。我们可以看到它配置起来很简单,但是它有个明显的缺点,就是secret id会过期,生产环境中很少有人使用永不过期的密码。一旦过期了,还得有人更新。
下一片文章我们将验证方式改为Kubernetes,看看能不能有完全不用人工操作的自动化证书管理。
看过了就等于学会了。 下次见~ 📅