Dapr mTLS 安全 电脑版发表于:2021/12/28 22:03  >#Dapr mTLS 安全 [TOC] tn2>这是讲什么呢?在我们开发应用的时候有些地方需要注意安全的访问,比如通过TLS加密的访问,这就让开发人员觉得很麻烦。dapr通过mTLS正是解决这个问题的。 它通过每个应用所对应的dapr边车与其他dapr边车通信时将进行加密通信,通信时使用的证书可以不用开发人员管,将会由一个dapr Sentry服务进行管理。 mTLS工作原理 ------------ tn2>TLS:客户端根据服务端证书验证其身份 mTLS:客户端、服务端彼此都验证对方身份  mTLS自托管 ------------ tn2>关于mTLS自托管是由下图所示,由运营商提供或由 Sentry 服务生成的根/颁发者证书为应用程序颁发证书,这些证书存储在某个文件夹中。  >### 服务配置 tn2>下面展示的是mTLS的配置,如果是使用的是Kubernetes将其部署到`dapr-system`命名空间中。在Dapr中默认是禁用状态需要将其启动。 ```bash vim ~/config.yaml ``` ```bash apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: daprsystem namespace: default spec: mtls: enabled: true ``` >### 使用自己的证书 tn2>如果有证书的可以跳过这一步,或者使用的他自带的证书也是可以的。 安装证书相关工具:step与step-ca ```bash # 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 ``` tn>关于step与step-ca的使用大家可以参考:https://smallstep.com/docs/step-ca/installation tn2>为 Sentry 服务创建一个目录以创建自签名根证书: ```bash mkdir -p $HOME/.dapr/certs ``` tn2>到该目录创建根证书: ```bash cd $HOME/.dapr/certs step certificate create cluster.local ca.crt ca.key --profile root-ca --no-password --insecure ``` tn2>创建颁发者证书: ```bash 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服务 tn2>为了运行Sentry服务,首先我们需要安装Sentry服务。我们可以通过如下链接找到相关包。 https://github.com/dapr/dapr/releases  tn2>接着我们可通过如下命令进行安装(这里是Linux资源包,请选择合适的包进行下载) ```bash 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 ``` tn2>然后启动 Sentry: ```bash 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`) | >### 拉取测试案例 tn2>打开一个新的终端,拉取测试代码 ```bash cd ~ git clone https://github.com/dapr/quickstarts.git cd quickstarts/hello-world/node ``` tn2>为每个 Dapr sidecar 实例提供 TLS 证书。您可以通过在运行 Dapr 实例之前设置以下环境变量来实现: ```bash 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 ``` tn2>如果使用 Dapr CLI,将 Dapr 指向上面的配置文件以运行启用 mTLS 的 Dapr 实例: ```bash npm install dapr run --app-id myapp --app-port 3000 --dapr-http-port 3500 --config ~/config.yaml node app.js ```  tn2>在成功运行启动后,十秒内未发现异常,mTLS启动成功。 >### Sentry 服务配置 tn2>以下是将工作负载证书 TTL 更改为 25 秒的 Sentry 配置示例: ```yaml apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: daprsystem namespace: default spec: mtls: enabled: true workloadCertTTL: "25s" ``` tn2>`allowedClockSkew`允许的时间偏差,多久更新一次证书: ```yaml apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: daprsystem namespace: default spec: mtls: enabled: true workloadCertTTL: "25s" allowedClockSkew: "15m" ``` Kubernetes 中的 mTLS ------------ tn2>下图显示了 Sentry 系统服务如何根据由运营商提供或由 Sentry 服务生成并存储为 Kubernetes 机密的根/颁发者证书为应用程序颁发证书  >### 检测Kubernetes是否启用mTLS ```bash dapr mtls -k ```  >### Sentry 服务配置 tn2>我们可以通过如下命令可查看Sentry配置 ```bash kubectl get configurations/daprsystem --namespace dapr-system -o yaml ```  tn2>我们可以看到默认的工作负载证书TTL为24小时,默认情况下允许15分钟的时钟偏移。允许时钟偏移是为了避免由于时差导致的证书验证错误。 ```bash # 编辑 Sentry 服务配置 kubectl edit configurations/daprsystem --namespace dapr-system ``` tn2>保存更改后,对控制平面执行滚动更新: ```bash 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添加自带证书 tn2>使用 Helm,您可以提供 PEM 编码的根证书、颁发者证书和私钥,这些证书将填充到 Sentry 服务使用的 Kubernetes 机密中。 建用于生成证书的配置文件,这是生成带有 SAN(主题替代名称)扩展字段的 v3 证书所必需的。首先将以下内容保存到名为 的文件中`root.conf`: ```bash [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 ``` tn2>对 重复此操作`issuer.conf`,将相同的内容粘贴到文件中,但添加pathlen:0到 basicConstraints 行的末尾,如下所示: ```bash [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 ``` tn2>运行以下命令以生成根证书和密钥 ```bash 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 ``` tn2>接下来运行以下命令以生成颁发者证书和密钥: ```bash 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 ``` tn2>安装 Helm 并通过配置将根证书、颁发者证书和颁发者密钥传递给 Sentry: ```bash 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 ``` >### 更新根证书或颁发者证书 tn2>现在您拥有新证书,您可以更新保存它们的 Kubernetes 密钥。编辑 Kubernetes 机密:  tn2>将Kubernetes 机密中的`ca.crt`,`issuer.crt`和`issuer.key`密钥替换为新证书中的相应值。 注意:这些值必须是 base64 编码的 如果您使用不同的私钥对新的证书根进行签名,请重新启动所有启用 Dapr 的 pod。推荐的方法是执行部署的 rollout 重新启动: ```bash kubectl rollout restart deploy/myapp ``` >### 检查根证书的过期时间 ```bash dapr mtls expiry ``` >### 将根 CA、颁发者证书和密钥从 Kubernetes 导出到本地文件 ```bash dapr mtls export -o ./certs ```