Dapr mTLS 安全
这是讲什么呢?在我们开发应用的时候有些地方需要注意安全的访问,比如通过TLS加密的访问,这就让开发人员觉得很麻烦。dapr通过mTLS正是解决这个问题的。
它通过每个应用所对应的dapr边车与其他dapr边车通信时将进行加密通信,通信时使用的证书可以不用开发人员管,将会由一个dapr Sentry服务进行管理。
mTLS工作原理
TLS:客户端根据服务端证书验证其身份
mTLS:客户端、服务端彼此都验证对方身份
mTLS自托管
关于mTLS自托管是由下图所示,由运营商提供或由 Sentry 服务生成的根/颁发者证书为应用程序颁发证书,这些证书存储在某个文件夹中。
服务配置
下面展示的是mTLS的配置,如果是使用的是Kubernetes将其部署到dapr-system
命名空间中。在Dapr中默认是禁用状态需要将其启动。
vim ~/config.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
使用自己的证书
如果有证书的可以跳过这一步,或者使用的他自带的证书也是可以的。
安装证书相关工具:step与step-ca
# https://github.com/smallstep/cli/releases/tag/v0.18.0
wget -O step.tar.gz https://github.com/smallstep/cli/releases/download/v0.18.0/step_linux_0.18.0_amd64.tar.gz
tar -xf step.tar.gz
sudo cp step_0.18.0/bin/step /usr/bin
# https://github.com/smallstep/certificates/releases/tag/v0.18.0
wget -O step-ca.tar.gz https://github.com/smallstep/certificates/releases/download/v0.18.0/step-ca_linux_0.18.0_amd64.tar.gz
tar -xf step-ca.tar.gz
sudo cp step-ca_0.18.0/bin/step-ca /usr/bin
关于step与step-ca的使用大家可以参考:https://smallstep.com/docs/step-ca/installation
为 Sentry 服务创建一个目录以创建自签名根证书:
mkdir -p $HOME/.dapr/certs
到该目录创建根证书:
cd $HOME/.dapr/certs
step certificate create cluster.local ca.crt ca.key --profile root-ca --no-password --insecure
创建颁发者证书:
step certificate create cluster.local issuer.crt issuer.key --ca ca.crt --ca-key ca.key --profile intermediate-ca --not-after 8760h --no-password --insecure
运行Sentry服务
为了运行Sentry服务,首先我们需要安装Sentry服务。我们可以通过如下链接找到相关包。
https://github.com/dapr/dapr/releases
接着我们可通过如下命令进行安装(这里是Linux资源包,请选择合适的包进行下载)
cd ~
wget https://github.com/dapr/dapr/releases/download/v1.5.1/sentry_linux_amd64.tar.gz
tar zxvf sentry_linux_amd64.tar.gz
mv sentry /usr/bin
然后启动 Sentry:
sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=~/config.yaml
参数 | 描述 |
---|---|
--issuer-credentials |
保存颁发者数据的凭据目录的路径(默认值/var/run/dapr/credentials ) |
--trust-domain |
CA信任域(默认为localhost ) |
--config |
配置文件的路径或配置对象的名称(默认为daprsystem ) |
拉取测试案例
打开一个新的终端,拉取测试代码
cd ~
git clone https://github.com/dapr/quickstarts.git
cd quickstarts/hello-world/node
为每个 Dapr sidecar 实例提供 TLS 证书。您可以通过在运行 Dapr 实例之前设置以下环境变量来实现:
export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt`
export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt`
export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key`
export NAMESPACE=default
如果使用 Dapr CLI,将 Dapr 指向上面的配置文件以运行启用 mTLS 的 Dapr 实例:
npm install
dapr run --app-id myapp --app-port 3000 --dapr-http-port 3500 --config ~/config.yaml node app.js
在成功运行启动后,十秒内未发现异常,mTLS启动成功。
Sentry 服务配置
以下是将工作负载证书 TTL 更改为 25 秒的 Sentry 配置示例:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "25s"
allowedClockSkew
允许的时间偏差,多久更新一次证书:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "25s"
allowedClockSkew: "15m"
Kubernetes 中的 mTLS
下图显示了 Sentry 系统服务如何根据由运营商提供或由 Sentry 服务生成并存储为 Kubernetes 机密的根/颁发者证书为应用程序颁发证书
检测Kubernetes是否启用mTLS
dapr mtls -k
Sentry 服务配置
我们可以通过如下命令可查看Sentry配置
kubectl get configurations/daprsystem --namespace dapr-system -o yaml
我们可以看到默认的工作负载证书TTL为24小时,默认情况下允许15分钟的时钟偏移。允许时钟偏移是为了避免由于时差导致的证书验证错误。
# 编辑 Sentry 服务配置
kubectl edit configurations/daprsystem --namespace dapr-system
保存更改后,对控制平面执行滚动更新:
kubectl rollout restart deploy/dapr-sentry -n dapr-system
kubectl rollout restart deploy/dapr-operator -n dapr-system
kubectl rollout restart statefulsets/dapr-placement-server -n dapr-system
通过Helm添加自带证书
使用 Helm,您可以提供 PEM 编码的根证书、颁发者证书和私钥,这些证书将填充到 Sentry 服务使用的 Kubernetes 机密中。
建用于生成证书的配置文件,这是生成带有 SAN(主题替代名称)扩展字段的 v3 证书所必需的。首先将以下内容保存到名为 的文件中root.conf
:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = Daprville
O = dapr.io/sentry
OU = dapr.io/sentry
CN = cluster.local
[v3_req]
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = serverAuth, clientAuth
[alt_names]
DNS.1 = cluster.local
对 重复此操作issuer.conf
,将相同的内容粘贴到文件中,但添加pathlen:0到 basicConstraints 行的末尾,如下所示:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = Daprville
O = dapr.io/sentry
OU = dapr.io/sentry
CN = cluster.local
[v3_req]
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = serverAuth, clientAuth
[alt_names]
DNS.1 = cluster.local
basicConstraints = critical, CA:true, pathlen:0
运行以下命令以生成根证书和密钥
openssl ecparam -genkey -name prime256v1 | openssl ec -out root.key
openssl req -new -nodes -sha256 -key root.key -out root.csr -config root.conf -extensions v3_req
openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM -out root.pem -extfile root.conf -extensions v3_req
接下来运行以下命令以生成颁发者证书和密钥:
openssl ecparam -genkey -name prime256v1 | openssl ec -out issuer.key
openssl req -new -sha256 -key issuer.key -out issuer.csr -config issuer.conf -extensions v3_req
openssl x509 -req -in issuer.csr -CA root.pem -CAkey root.key -CAcreateserial -outform PEM -out issuer.pem -days 365 -sha256 -extfile issuer.conf -extensions v3_req
安装 Helm 并通过配置将根证书、颁发者证书和颁发者密钥传递给 Sentry:
kubectl create ns dapr-system
helm install \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
更新根证书或颁发者证书
现在您拥有新证书,您可以更新保存它们的 Kubernetes 密钥。编辑 Kubernetes 机密:
将Kubernetes 机密中的ca.crt
,issuer.crt
和issuer.key
密钥替换为新证书中的相应值。 注意:这些值必须是 base64 编码的
如果您使用不同的私钥对新的证书根进行签名,请重新启动所有启用 Dapr 的 pod。推荐的方法是执行部署的 rollout 重新启动:
kubectl rollout restart deploy/myapp
检查根证书的过期时间
dapr mtls expiry
将根 CA、颁发者证书和密钥从 Kubernetes 导出到本地文件
dapr mtls export -o ./certs
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739