新聞中心
前言
Vault 是安全應(yīng)用維護人員最喜歡的 hashcorp 產(chǎn)品之一 。Vault 是存儲機密、證書、管理策略、加密數(shù)據(jù)等內(nèi)容的安全工具。Vault 使用受信任的身份集中密碼和控制訪問權(quán)限,以此減少對靜態(tài)、硬編碼憑證的需求。它使用集中托管和受保護的加密密鑰來動態(tài)和靜態(tài)加密敏感數(shù)據(jù),所有一切均可通過單個工作流和 API 實現(xiàn)。

長順網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),長順網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為長順1000多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請找那個售后服務(wù)好的長順做網(wǎng)站的公司定做!
Istio 非常重要的一個功能是能夠鎖定并且保護網(wǎng)格內(nèi)的來往流量。本文的目的是基于 TLS 啟動一個簡單的 Web 應(yīng)用程序,然后使用 Vault 生成對應(yīng)的安全證書,從而保證 Istio 管理的服務(wù)安全。
簡單點說,使用 TLS 時候,當您建立連接時,服務(wù)器會提供一個公鑰,您可以使用此密鑰對傳輸中的數(shù)據(jù)進行加密,一旦被目標服務(wù)器接收,數(shù)據(jù)將使用私鑰解密。為了驗證密鑰是否有效,可以使用 CA(通常 CA 是付費服務(wù)),但我們可以通過 vault 創(chuàng)建一個自簽名 CA)。
現(xiàn)在先讓我們忽略 vault,讓我們在系統(tǒng)上創(chuàng)建一個測試環(huán)境。為此使用 kind (https://kind.sigs.k8s.io/) 來快速創(chuàng)建一個測試環(huán)境。
用 kind 建立一個 kubernetes 集群
下載 kind 后,我們可以定義一個 kind 配置文件來啟動 4 個 worker。我們還可以配置一些端口映射,以確保我們可以直接訪問入口網(wǎng)關(guān)。
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: worker
使用 kind 來創(chuàng)建我們的集群
kind create cluster --name chris --config ~/kube.cfg
節(jié)點已啟動
kubectl get nodes
NAME STATUS ROLES AGE VERSION
chris-control-plane Ready control-plane 21h v1.24.0
chris-worker Ready21h v1.24.0
chris-worker2 Ready21h v1.24.0
chris-worker3 Ready21h v1.24.0
chris-worker4 Ready21h v1.24.0
使用istioctl (https://github.com/istio/istio/releases) 命令安裝 istio 。首先讓我們定義一下配置內(nèi)容。因為我們在本地運行,所以我們降低了一些資源要求。
---
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-system
安裝 istio
istioctl manifest install -f ~/istio.cfg
刪除默認類型的 istio-ingressgateway 的 service。
kubectl delete svc istio-ingressgateway -n istio-system
創(chuàng)建一個 NodePort 服務(wù),從而實現(xiàn)從節(jié)點端口訪問 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-ingressgateway
應(yīng)用一下
kubectl apply -f svc.yml
此時,istio 應(yīng)該正常運行。
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 21h
我們將創(chuàng)建一個虛擬網(wǎng)關(guān)進行測試
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:
- "*"
同時應(yīng)用
kubectl apply -f gateway.yml
使用 curl,我們能夠從我們客戶端去訪問 istio 入口。注意:404 是預(yù)期的結(jié)果,因為我們還沒有配置任何應(yīng)用程序或 istio 虛擬服務(wù)。
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 Not Found
< date: Thu, 28 Jul 2022 21:44:50 GMT
< server: istio-envoy
< content-length: 0
<
* Connection #0 to host localhost left intact
* Closing connection 0
我們不僅連接了(即使我們得到了 404 ),而且您可以看到服務(wù)器是 istio-envoy 響應(yīng),這意味著 envoy 正在處理流量。
最后一步,讓我們創(chuàng)建一個命名空間并將其標記為 istio 注入以供將來工作。
kubectl create ns web
kubectl label namespace web istio-injection=enabled --overwrite
安裝 Vault
如果這是一個生產(chǎn)環(huán)境,我們會按照嚴格標準去調(diào)整以及安裝 vault,但當前只是一個一次性的測試環(huán)境,所以我們不做任何優(yōu)化調(diào)整。
使用 helm 安裝 Vault Chart
kubectl create namespace vault
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --namespace vault
Vault pod 啟動了,但它還沒有就緒,因為它當前處于鎖定狀態(tài)。在 pod 中執(zhí)行以下命令以解封。
kubectl -n vault exec vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > /tmp/token.json
從 /tmp/token.josn 中取出 unseal_keys_b64 密鑰,并使用它來解封 vault。
kubectl exec -n vault vault-0 -- vault operator unseal
現(xiàn)在,vault 應(yīng)該已解封并處于就緒狀態(tài)。
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 6m29s
現(xiàn)在,我們可以使用 port-forward 來轉(zhuǎn)發(fā)訪問 vault,并使用可以在 /tmp/token.json 中找到的根令牌登錄 vault。
kubectl port-forward vault-0 8200 -n vault
# Open a browser to localhost:8200
現(xiàn)在 vault 已準備就緒,讓我們創(chuàng)建一個新的 secret engine,啟用新 engine -> PKI Certificates,我使用的是 pki/ 路徑?;蛘?,如果啟用了 cli,您可以使用以下命令
vault secrets enable pki
將 vault 二進制文件下載到您本地并設(shè)置 vault 地址和令牌。
brew install vault
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=
現(xiàn)在我們可以從 cli 與 Vault 進行交互了
vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.10.3
Build Date n/a
Storage Type file
Cluster Name vault-cluster-d4e826eb
Cluster ID 76196d6e-0033-b892-4826-2674b6befe23
HA Enabled false
我們想給 istio 一個證書以供 CA 驗證,所以讓我們在 Vault 中創(chuàng)建一個。首先調(diào)整一些租期時間(10 年)。
vault secrets tune -max-lease-ttl=87600h pki
創(chuàng)建一個名為 allowit 的角色,然后定義要發(fā)送到 CA 的 CSR 的路徑。本處將使用域名 somecompany.com 進行所有測試。
# create a 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"
我們當前在做的是為訪問路徑設(shè)置角色以與 CA 一起使用。
現(xiàn)在是時候獲得中間證書了。CA 雖然很不錯,它確認了證書屬于正確的人,但它有很大的權(quán)力。中間證書基本上是一種從另一個 CA 創(chuàng)建 CA 的方法。最佳做法是使用中間證書。根證書將能夠撤銷任何中間 CA。
但如下所見,步驟類似,我們現(xiàn)在使用的是 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.csr
vault 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.pem
仍然使用 somecompany.com 域名,確保頒發(fā)者名稱與根 CA 和中間 CA 的頒發(fā)者名稱相同(在此示例中僅稱為 root)。
將簽名的證書寫回 vault 。
vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
現(xiàn)在我們的 CA 和中間證書已經(jīng)創(chuàng)建好了。我們應(yīng)該為它創(chuàng)建一個角色。
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"
目前,我們都準備好了!我們已經(jīng)創(chuàng)建了一個帶有 vault 的 CA 和中間 CA!
讓我們測試一下!讓我們向 vault 申請 chris.somecompany.com 的 24 小時有效證書。(這將返回 CA、證書和私鑰)
vault write pki_int/issue/allowit common_name="chris.somecompany.com" ttl="24h"
本處只關(guān)心證書,所以將上面命令返回的base64復(fù)制并粘貼到一個臨時文件中,然后使用openssl 進行檢查。
openssl x509 -in site -text | head -n 10
Certificate:
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.com Intermediate Authority
Validity
Not Before: Jul 29 20:32:09 2022 GMT
Not After : Jul 30 20:32:39 2022 GMT
Subject: CN=chris.somecompany.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
從上面的輸出可以看出,證書有效期為 24 小時,對 chris.somecompany.com 有效,包含我們要求的所有內(nèi)容!
目前的操作都是通過命令行,忽略使用 vault UI,但我們也可以使用 UI 來執(zhí)行上述所有步驟。例如,我們可以在 UI 上看到我們的證書。
Cert manager
kubernetes、istio 和 vault 就這樣配置好了。我們的最終目標是啟動一個使用 vault 的 TLS 證書的應(yīng)用程序。
Cert-manager (https://cert-manager.io/) 允許我們向 kubernetes secret api 請求和寫入證書。然后 istio 將這些證書與網(wǎng)關(guān) crd 一起使用。
使用 helm 安裝Cert-manager。
helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.9.1
當前可以確認 pod 已在 cert-manager 命名空間中啟動,我們也可以看到 cert-manager crds 被創(chuàng)建了。
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:11Z
當前 cert-manager 已經(jīng)啟動并運行,它如何對 vault 進行身份驗證?Authrole 允許我們設(shè)置一個密鑰來與 vault 對話。
通過如下命令啟用審批
vault auth enable approle
創(chuàng)建 policy.hcl 文件,它可以訪問 pki/ 和 pki-int 路徑
#policy.hcl
path "pki*" { capabilities = ["create", "read", "update", "delete", "list", "sudo"]}
寫入 vault
vault policy write pki_policy policy.hcl
創(chuàng)建一個 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_policy
我們現(xiàn)在有一個 role_id
vault read auth/approle/role/certmanager/role-id
Key Value
--- -----
role_id bb3cdc37-9fe0-f99f-99d4-1ff80d26ab1d
讓我們來寫入一個 secret
vault write -f auth/approle/role/certmanager/secret-id
這將返回一個 secret_id(你的密鑰),獲取,base64 ,然后創(chuàng)建一個 kubernetes secret并上傳
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: cert-manager
namespace: istio-system
data:
secretId:
看起來內(nèi)容比較多,但我們所做的只是告訴 Vault 創(chuàng)建一個密鑰。我們可以使用此密鑰進行身份驗證以進行保管。
配置 cert-manager
現(xiàn)在 cert-manager 可以與 vault 通信,讓我們配置 cert-manager。
issuer 用于與 vault 對話,傳遞我們的應(yīng)用角色密鑰和路徑。
本處,我們將所有這些東西都放在了 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: secretIda
然后我們創(chuàng)建一個證書 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.com
等待 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 5m57s
最重要的是,我們的證書是否已準備好用作 kubernetes secret?
kubectl -n istio-system get secret my-certNAME TYPE DATA AGEmy-cert kubernetes.io/tls 3 6m43s
在這個過程中,可以通過 kubectl describe 命令來查看詳細信息。。
創(chuàng)建示例應(yīng)用
一切準備就緒,讓我們在 web 命名空間中啟動一個 nginx pod 虛擬服務(wù)。請記住,我們標記了命名空間,因此該命名空間內(nèi)啟動的 pod 也將獲得 istio sidecar。
kubectl -n web create deploy nginx --image=nginx --port 80
kubectl -n web expose deploy nginx --port 80
對于 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: nginx
此外,創(chuàng)建一個使用我們來自 vault 的新證書的網(wǎng)關(guān)
---
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-cer
在真實環(huán)境中,我們會在 istio ingress 前面添加一個負載均衡器,但是因為我們使用的是 kind,所以本處會將主機添加到 /etc/hosts 并進行端口轉(zhuǎn)發(fā)。
kubectl -n istio-system port-forward istio-ingressgateway-5f86977657-qfxrs 8443
在我們點擊頁面之前,讓我們從 k8s 中獲取公共 CA 并信任它。
kubectl -n istio-system get secret my-cert -o json | jq -r '.data["ca.crt"]' | base64 -d > ca.crt
open ca.crt
# mark as always trust
在瀏覽器中打開,我們現(xiàn)在可以使用由 vault 簽名的有效 TLS 證書訪問我們的 nginx 服務(wù)器 (https://chris.somecompany.com:8443)!
總結(jié)
通過本文,我們學(xué)習(xí)了如何使用 vault 來保存證書等密鑰信息,如何使用 cert-manager 來申請免費的證書以及 istio 如何去使用這些信息,最終實現(xiàn)了一個基于 istio 的安全 web 應(yīng)用。
新聞名稱:使用K8s/Istio/Cert-manager和Vault保障應(yīng)用的Tls安全
轉(zhuǎn)載注明:http://www.dlmjj.cn/article/cdpeodo.html


咨詢
建站咨詢
