| 前言 Vault 是使用安全应用维护人员最喜欢的 hashcorp 产品之一 。Vault 是保障存储机密 、证书、应用管理策略、安全加密数据等内容的使用安全工具。Vault 使用受信任的保障身份集中密码和控制访问权限 ,以此减少对静态、应用硬编码凭证的安全需求 。它使用集中托管和受保护的使用加密密钥来动态和静态加密敏感数据 ,所有一切均可通过单个工作流和 API 实现 。建站模板保障 Istio 非常重要的应用一个功能是能够锁定并且保护网格内的来往流量。本文的安全目的是基于 TLS 启动一个简单的 Web 应用程序 ,然后使用 Vault 生成对应的使用安全证书 ,从而保证 Istio 管理的保障服务安全 。 简单点说,应用使用 TLS 时候,当您建立连接时,模板下载服务器会提供一个公钥 ,您可以使用此密钥对传输中的数据进行加密 ,一旦被目标服务器接收,数据将使用私钥解密 。为了验证密钥是否有效,可以使用 CA(通常 CA 是付费服务) ,但我们可以通过 vault 创建一个自签名 CA) 。 现在先让我们忽略 vault,让我们在系统上创建一个测试环境。为此使用 kind (https://kind.sigs.k8s.io/) 来快速创建一个测试环境 。 用 kind 建立一个 kubernetes 集群下载 kind 后,我们可以定义一个 kind 配置文件来启动 4 个 worker 。我们还可以配置一些端口映射,源码库以确保我们可以直接访问入口网关 。 复制kind:Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes:- role: control-plane extraPortMappings:- containerPort: 30725 hostPort: 8080 listenAddress: "127.0.0.1" protocol:TCP - containerPort: 32652 hostPort: 8443 listenAddress: "127.0.0.1" protocol:TCP - role:worker - role:worker - role:worker - role: worker1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.使用 kind 来创建我们的集群 复制kind create cluster --name chris --config ~/kube.cfg1.节点已启动 复制kubectl get nodes NAME STATUS ROLES AGE VERSION chris-control-plane Ready control-plane 21h v1.24.0chris-worker Ready <none> 21h v1.24.0chris-worker2 Ready <none> 21h v1.24.0chris-worker3 Ready <none> 21h v1.24.0chris-worker4 Ready <none> 21h v1.24.01.2.3.4.5.6.7.使用istioctl (https://github.com/istio/istio/releases) 命令安装 istio 。首先让我们定义一下配置内容。因为我们在本地运行,所以我们降低了一些资源要求。 复制--- apiVersion: install.istio.io/v1alpha1 kind:IstioOperator metadata: namespace: istio-system name: installed-state spec: components: ingressGateways: - enabled: name: istio-ingressgateway namespace: istio-system pilot: k8s: hpaSpec: maxReplicas: 2 minReplicas: 1 resources: requests: cpu: 512m memory: 512Mi profile:default values: global: istioNamespace: istio-system1.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.安装 istio 复制istioctl manifest install -f ~/istio.cfg1.删除默认类型的 istio-ingressgateway 的 service 。 复制kubectl delete svc istio-ingressgateway -n istio-system1.创建一个 NodePort 服务,从而实现从节点端口访问 istio-ingressgateway 。 复制apiVersion:v1 kind:Service metadata: labels: app: istio-ingressgateway istio:ingressgateway name: istio-ingressgateway namespace: istio-system spec: type:NodePort ports: - name:http nodePort: 30725 port: 8080 protocol:TCP targetPort: 8080 - name:https nodePort: 32652 port: 443 protocol:TCP targetPort: 8443 selector: app: istio-ingressgateway1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.应用一下 复制kubectl apply -f svc.yml1.此时,istio 应该正常运行。 复制kubectl get pods -n istio-system NAME READY STATUS RESTARTS AGE istio-ingressgateway-5f86977657-qfxrs 1/1 Running 0 21h istiod-67db665bd9-4d8nl 1/1 Running 0 21h1.2.3.4.我们将创建一个虚拟网关进行测试 复制apiVersion: networking.istio.io/v1alpha3 kind:Gateway metadata: name:gateway namespace: istio-system spec: selector: app: istio-ingressgateway servers: - port: number: 8080 name:http protocol:HTTP hosts: - "*"1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.同时应用 复制kubectl apply -f gateway.yml1.使用 curl ,我们能够从我们客户端去访问 istio 入口。注意 :404 是高防服务器预期的结果 ,因为我们还没有配置任何应用程序或 istio 虚拟服务 。 复制curl localhost:8080 -vs * Trying 127.0.0.1... * TCP_NODELAY set* Connected to localhost (127.0.0.1) port 8080 (#0)> GET / HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.64.1> Accept: */*>< HTTP/1.1 404 NotFound < date: Thu, 28 Jul 2022 21:44:50GMT < server: istio-envoy < content-length: 0<*Connection #0 to host localhost left intact * Closing connection 01.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.我们不仅连接了(即使我们得到了 404 ),而且您可以看到服务器是 istio-envoy 响应,这意味着 envoy 正在处理流量。 最后一步 ,让我们创建一个命名空间并将其标记为 istio 注入以供将来工作。 复制kubectl createns web kubectl label namespace web istio-injection=enabled --overwrite1.2. 安装 Vault如果这是一个生产环境,我们会按照严格标准去调整以及安装 vault,但当前只是一个一次性的测试环境,所以我们不做任何优化调整。源码下载 使用 helm 安装 Vault Chart 复制kubectl createnamespace vault helm repo add hashicorp https://helm.releases.hashicorp.comhelm install vault hashicorp/vault --namespace vault1.2.3.Vault pod 启动了 ,但它还没有就绪,因为它当前处于锁定状态 。在 pod 中执行以下命令以解封。 复制kubectl -n vault exec vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > /tmp/token.json1.从 /tmp/token.josn 中取出 unseal_keys_b64 密钥 ,并使用它来解封 vault。 复制kubectl exec -n vault vault-0 -- vault operator unseal <key>1.现在,vault 应该已解封并处于就绪状态 。 复制kubectl get pods -n vault NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 6m28s vault-agent-injector-5d4c695bf4-zzgq5 1/1 Running 0 6m29s1.2.3.4.现在 ,我们可以使用 port-forward 来转发访问 vault ,并使用可以在 /tmp/token.json 中找到的根令牌登录 vault。 复制kubectl port-forward vault-0 8200 -n vault # Open a browser to localhost:82001.2.现在 vault 已准备就绪 ,让我们创建一个新的 secret engine,启用新 engine -> PKI Certificates,亿华云我使用的是 pki/ 路径 。或者,如果启用了 cli,您可以使用以下命令 复制vault secrets enable pki1.将 vault 二进制文件下载到您本地并设置 vault 地址和令牌。 复制brew install vault export VAULT_ADDR=http://127.0.0.1:8200export VAULT_TOKEN=<key>1.2.3.现在我们可以从 cli 与 Vault 进行交互了 复制vault status Key Value --- -----Seal Type shamir Initialized trueSealed falseTotal Shares 1Threshold 1Version 1.10.3Build Date n/a Storage Type file Cluster Name vault-cluster-d4e826eb Cluster ID 76196d6e-0033-b892-4826-2674b6befe23 HA Enabled false1.2.3.4.5.6.7.8.9.10.11.12.13.14.我们想给 istio 一个证书以供 CA 验证,所以让我们在 Vault 中创建一个。首先调整一些租期时间(10 年) 。 复制vault secrets tune -max-lease-ttl=87600h pki1.创建一个名为 allowit 的角色,然后定义要发送到 CA 的 CSR 的路径。本处将使用域名 somecompany.com 进行所有测试。 复制# createa role vault write pki/roles/allowit allow_any_name=true# generate vault write -field=certificate pki/root/generate/internal \ common_name="somecompany.com"\ issuer_name="root"\ ttl=87600h > ca.crt# config vault write pki/config/urls \ issuing_certificates="$VAULT_ADDR/v1/pki/ca"\ crl_distribution_points="$VAULT_ADDR/v1/pki/crl"1.2.3.4.5.6.7.8.9.10.11.我们当前在做的是为访问路径设置角色以与 CA 一起使用。 现在是时候获得中间证书了。CA 虽然很不错,它确认了证书属于正确的人,但它有很大的权力 。中间证书基本上是一种从另一个 CA 创建 CA 的方法 。最佳做法是使用中间证书 。根证书将能够撤销任何中间 CA 。 但如下所见 ,步骤类似,我们现在使用的是 pki_int 路径。 复制vault secrets enable -path=pki_int pki vault secrets tune -max-lease-ttl=43800h pki_int vault write -format=json pki_int/intermediate/generate/internal \ common_name="somecompany.com Intermediate Authority"\ issuer_name="somecompany-intermediate"\ | jq -r .data.csr > pki_intermediate.csrvault write -format=json pki/root/sign-intermediate \ issuer_ref="root"\ csr=@pki_intermediate.csr\ format=pem_bundle ttl="43800h"\ | jq -r .data.certificate > intermediate.cert.pem1.2.3.4.5.6.7.8.9.10.11.仍然使用 somecompany.com 域名 ,确保颁发者名称与根 CA 和中间 CA 的颁发者名称相同(在此示例中仅称为 root)。 将签名的证书写回 vault 。 复制vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem1.现在我们的 CA 和中间证书已经创建好了。我们应该为它创建一个角色 。 复制vault write pki_int/roles/example-dot-com \ issuer_ref="$(vault read -field=default pki_int/config/issuers)"\ allowed_domains="somecompany.com"\ allow_subdomains=true\ max_ttl="720h"1.2.3.4.5.目前,我们都准备好了!我们已经创建了一个带有 vault 的 CA 和中间 CA! 让我们测试一下 !让我们向 vault 申请 chris.somecompany.com 的 24 小时有效证书。(这将返回 CA、证书和私钥) 复制vault write pki_int/issue/allowit common_name="chris.somecompany.com" ttl="24h"1.本处只关心证书 ,所以将上面命令返回的base64复制并粘贴到一个临时文件中 ,然后使用openssl 进行检查 。 复制openssl x509 -in site -text | head -n 10Certificate: Data: Version: 3 (0x2) Serial Number: 4f:87:f9:6f:eb:68:db:2a:39:f5:06:1e:43:32:98:04:32:2e:df:4d Signature Algorithm:sha256WithRSAEncryption Issuer: CN=somecompany.comIntermediate Authority Validity Not Before: Jul 29 20:32:09 2022GMT Not After : Jul 30 20:32:39 2022GMT Subject: CN=chris.somecompany.com Subject Public Key Info: Public Key Algorithm: rsaEncryption1.2.3.4.5.6.7.8.9.10.11.12.13.14.从上面的输出可以看出,证书有效期为 24 小时,对 chris.somecompany.com 有效 ,包含我们要求的所有内容! 目前的操作都是通过命令行 ,忽略使用 vault UI,但我们也可以使用 UI 来执行上述所有步骤。例如,我们可以在 UI 上看到我们的证书 。
kubernetes、istio 和 vault 就这样配置好了。我们的最终目标是启动一个使用 vault 的 TLS 证书的应用程序 。 Cert-manager (https://cert-manager.io/) 允许我们向 kubernetes secret api 请求和写入证书 。然后 istio 将这些证书与网关 crd 一起使用。 使用 helm 安装Cert-manager 。 复制helm repo add jetstack https://charts.jetstack.iohelm repo updatekubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yamlhelm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.9.11.2.3.4.5.6.7.8.当前可以确认 pod 已在 cert-manager 命名空间中启动,我们也可以看到 cert-manager crds 被创建了。 复制kubectl get crd |grep cert certificaterequests.cert-manager.io 2022-07-29T20:59:11Z certificates.cert-manager.io 2022-07-29T20:59:11Z challenges.acme.cert-manager.io 2022-07-29T20:59:11Z clusterissuers.cert-manager.io 2022-07-29T20:59:11Z issuers.cert-manager.io 2022-07-29T20:59:11Z orders.acme.cert-manager.io 2022-07-29T20:59:11Z1.2.3.4.5.6.7.当前 cert-manager 已经启动并运行,它如何对 vault 进行身份验证?Authrole 允许我们设置一个密钥来与 vault 对话。 通过如下命令启用审批 复制vault auth enable approle1.创建 policy.hcl 文件 ,它可以访问 pki/ 和 pki-int 路径 复制#policy.hclpath "pki*" { capabilities = ["create", "read", "update", "delete", "list", "sudo"]}1.2.写入 vault 复制vault policy write pki_policy policy.hcl1.创建一个 certmanager 角色,该角色附加到 pki_policy vault策略 复制vault write auth/approle/role/certmanager secret_id_ttl=8760h token_num_uses=0 token_ttl=20m token_max_ttl=30m secret_id_num_uses=0 policies=pki_policy1.我们现在有一个 role_id 复制vault read auth/approle/role/certmanager/role-id Key Value --- -----role_id bb3cdc37-9fe0-f99f-99d4-1ff80d26ab1d1.2.3.4.让我们来写入一个 secret 复制vault write -f auth/approle/role/certmanager/secret-id1.这将返回一个 secret_id(你的密钥) ,获取,base64 ,然后创建一个 kubernetes secret并上传 复制apiVersion:v1 kind:Secret type:Opaque metadata: name: cert-manager namespace: istio-system data: secretId: <base64 key>1.2.3.4.5.6.7.8.看起来内容比较多,但我们所做的只是告诉 Vault 创建一个密钥 。我们可以使用此密钥进行身份验证以进行保管。 配置 cert-manager现在 cert-manager 可以与 vault 通信 ,让我们配置 cert-manager。 issuer 用于与 vault 对话,传递我们的应用角色密钥和路径 。 本处 ,我们将所有这些东西都放在了 istio-system 命名空间中 。 复制---apiVersion: cert-manager.io/v1 kind:Issuer metadata: name:istio namespace: istio-system spec: vault: path: pki_int/sign/allowit server: http://vault-internal.vault.svc.cluster.local:8200 auth: appRole: path:approle roleId: "bb3cdc37-9fe0-f99f-99d4-1ff80d26ab1d" secretRef: name: cert-manager key: secretIda1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.然后我们创建一个证书 CRD 来定义我们的证书信息并告诉它把我们生成的证书放在哪里(在这个例子中是 my-cert ) 。 复制---apiVersion: cert-manager.io/v1 kind:Certificate metadata: name:istio namespace: istio-system spec: secretName: my-cert issuerRef: name:istio commonName: chris.somecompany.com dnsNames: - chris.somecompany.com1.2.3.4.5.6.7.8.9.10.11.12.13.等待 30s ,如果没有意外 ,那么 cert-manager 将去 vault 请求一个证书,并将其保存为一个可以使用的密钥。 复制kubectl -n istio-system get Issuer NAME READY AGE istio True 5m34s kubectl -n istio-system get Certificate NAME READY SECRET AGE istio True my-cert 5m57s1.2.3.4.5.6.最重要的是,我们的证书是否已准备好用作 kubernetes secret ? 复制kubectl -n istio-system get secret my-certNAME TYPE DATA AGEmy-cert kubernetes.io/tls 3 6m43s1.在这个过程中 ,可以通过 kubectl describe 命令来查看详细信息。。 创建示例应用一切准备就绪 ,让我们在 web 命名空间中启动一个 nginx pod 虚拟服务 。请记住,我们标记了命名空间 ,因此该命名空间内启动的 pod 也将获得 istio sidecar。 复制kubectl -n web create deploy nginx --image=nginx --port 80kubectl -n web expose deploy nginx --port 801.2.对于 istio,我们需要一个 VirtualService 来进行路由 。 复制apiVersion: networking.istio.io/v1alpha3 kind:VirtualService metadata: name:nginx namespace:web spec: gateways: - istio-system/https hosts: - "chris.somecompany.com" http: - route: - destination: host: nginx1.2.3.4.5.6.7.8.9.10.11.12.13.14.此外,创建一个使用我们来自 vault 的新证书的网关 复制---apiVersion: networking.istio.io/v1alpha3 kind:Gateway metadata: name:https namespace: istio-system spec: selector: app: istio-ingressgateway servers: - port: number: 8443 name:https protocol:HTTPS hosts: - "chris.somecompany.com" tls: mode:SIMPLE credentialName: my-cer1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.在真实环境中,我们会在 istio ingress 前面添加一个负载均衡器,但是因为我们使用的是 kind,所以本处会将主机添加到 /etc/hosts 并进行端口转发。 复制kubectl -n istio-system port-forward istio-ingressgateway-5f86977657-qfxrs 84431.在我们点击页面之前,让我们从 k8s 中获取公共 CA 并信任它 。 复制kubectl -n istio-system get secret my-cert -o json | jq -r .data["ca.crt"] | base64 -d > ca.crtopen ca.crt# mark as always trust1.2.3.在浏览器中打开,我们现在可以使用由 vault 签名的有效 TLS 证书访问我们的 nginx 服务器 (https://chris.somecompany.com:8443)!
通过本文 ,我们学习了如何使用 vault 来保存证书等密钥信息 ,如何使用 cert-manager 来申请免费的证书以及 istio 如何去使用这些信息,最终实现了一个基于 istio 的安全 web 应用 。 |
数据中心电源的五大趋势M8peg与750比较(一探M8peg和750处理器之间的差异与应用场景选择)中兴A2015顶配(性能强大,拍照出色,超高性价比引领市场潮流)从Win10升级到Win7(如何将笔记本电脑系统由Win10改为Win7)小米膜的优点和特点(为你的手机屏幕保驾护航)蒸汽吸尘器的清洁效果及优点(以蒸汽吸尘器为主题的家居清洁新选择)尼康D700(探索尼康D700的出色性能和多功能特点)如何找回ID账号和密码?(有效方法帮助你找回丢失的账号和密码)体验XboxOneX的卓越性能与极致画质(探索一台引领游戏娱乐新纪元的游戏机)华为Mate9拍摄视频全方位评测(华为Mate9拍视频功能强大,画质出色,满足各类拍摄需求)源码库网站建设企业服务器云服务器亿华云b2b信息平台香港物理机