You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过kubectl port-forward无法在HTTPS下运行Vault UI求助

问题描述

在AWS EKS的Kubernetes集群中运行Vault集群,已完成初始化与解封。执行kubectl port-forward service/vault 8200:8200端口转发后,访问https://localhost:8200时收到提示Client sent an HTTP request to an HTTPS server.,查看Vault Pod日志发现错误:http: TLS handshake error from 127.0.0.1:38678: remote error: tls: unknown certificate。

问题根源
  1. 协议混淆:部分请求误以HTTP方式访问了HTTPS端口,触发第一个错误;
  2. 证书信任缺失:本地客户端未信任Vault使用的EKS签发证书,导致TLS握手失败;
  3. 证书生成脚本错误:脚本中获取签发证书时指定了错误的命名空间,导致生成的证书无效。
修复步骤

1. 修正证书生成脚本的命名空间错误

脚本中获取签发证书的命令指定了错误的命名空间kubecf,需替换为Vault所在的${NAMESPACE}变量:

# 原错误命令
serverCert=$(kubectl get csr ${CSR_NAME} -n kubecf -o jsonpath='{.status.certificate}')
# 修正后
serverCert=$(kubectl get csr ${CSR_NAME} -n ${NAMESPACE} -o jsonpath='{.status.certificate}')

2. 确保访问时携带CA证书

本地访问Vault必须指定信任的CA证书,否则客户端无法验证证书合法性:

  • 使用Vault CLI访问:
    export VAULT_ADDR=https://localhost:8200
    export VAULT_CACERT=/path/to/your/vault.ca  # 替换为你本地的vault.ca文件路径
    vault status
    
  • 使用浏览器访问:
    将vault.ca导入浏览器的根证书信任库,或临时手动确认信任该证书(仅测试环境可用)。

3. 验证证书内容正确性

重新生成证书后,检查证书的SAN字段是否包含127.0.0.1及相关域名:

openssl x509 -in /tmp/vault.crt -text -noout | grep -A 10 "Subject Alternative Name"

确认输出中包含IP Address:127.0.0.1以及Vault服务的DNS域名。

4. 检查Vault Pod的证书挂载情况

确认Vault Pod已正确挂载证书secret:

kubectl exec -n vault vault-0 -- ls /vault/userconfig/vault-server-tls/

应输出vault.crt、vault.key、vault.ca三个文件,且文件内容非空。

原始配置参考

Vault Terraform Helm配置

resource "helm_release" "vault" {
  name       = "vault"
  namespace  = kubernetes_namespace.vault.id
  chart      = "vault"
  repository = "https://helm.releases.hashicorp.com"
  version    = "0.22.0"

  values = [
    <<EOF
global:
  tlsDisable: false
ui:
  enabled: true
server:
  extraEnvironmentVars:
    VAULT_CACERT: /vault/userconfig/vault-server-tls/vault.ca
  extraVolumes:
    - type: secret
      name: vault-server-tls
  nodeSelector: |
    eks.amazonaws.com/nodegroup: "vault-${var.environment}"
  tolerations:
    - key: "nodegroup"
      operator: "Equal"
      value: "vault"
      effect: "NoSchedule"
  logLevel: "debug"
  ha:
    enabled: true
    nodes: 3
    raft:
      enabled: true
      setNodeId: true
      config: |
        ui = true

        listener "tcp" {
          tls_disable = 0
          tls_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
          tls_key_file  = "/vault/userconfig/vault-server-tls/vault.key"
          tls_client_ca_file = "/vault/userconfig/vault-server-tls/vault.ca"
          address = "[::]:8200"
          cluster_address = "[::]:8201"
        }

        storage "raft" {
          path    = "/vault/data"
        }

        service_registration "kubernetes" {}

        seal "awskms" {
          region     = "${var.aws_region}"
          kms_key_id = "${aws_kms_key.vault.key_id}"
        }
EOF
    ,
  ]
}

修正后的证书生成脚本

#!/bin/bash -e

SERVICE=vault
SECRET_NAME=vault-server-tls
TMPDIR=/tmp
SLEEP_TIME=15
KUBECTL_INSTALLATION_URL=https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl

# Name of the CSR
echo "Name the CSR: vault-csr"
export CSR_NAME=vault-csr

# Install OpenSSL
echo "Install openssl"
yum install -y openssl 2>&1

# Install Kubernetes cli
echo "Install Kubernetes cli"
curl -o kubectl ${KUBECTL_INSTALLATION_URL}
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
kubectl version --short --client

# Create a private key
echo "Generate certificate Private key"
openssl genrsa -out ${TMPDIR}/vault.key 2048

# Create CSR
echo "Create CSR file"
cat <<EOF >${TMPDIR}/csr.conf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${SERVICE}
DNS.2 = ${SERVICE}.${NAMESPACE}
DNS.3 = ${SERVICE}.${NAMESPACE}.svc
DNS.4 = ${SERVICE}.${NAMESPACE}.svc.cluster.local
DNS.5 = vault-0.vault-internal
DNS.6 = vault-1.vault-internal
DNS.7 = vault-2.vault-internal
IP.1 = 127.0.0.1
EOF

# Sign the CSR
echo "Sign the CSR"
openssl req -new -key ${TMPDIR}/vault.key -subj "/CN=${SERVICE}.${NAMESPACE}.svc" -out ${TMPDIR}/server.csr -config ${TMPDIR}/csr.conf

echo "Create a CSR Manifest file"
cat <<EOF >${TMPDIR}/csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: ${CSR_NAME}
spec:
  groups:
  - system:authenticated
  request: $(cat ${TMPDIR}/server.csr | base64 | tr -d '\n')
  signerName: beta.eks.amazonaws.com/app-serving
  usages:
  - digital signature
  - key encipherment
  - server auth
EOF

echo "Create CSR from manifest file"
kubectl create -f ${TMPDIR}/csr.yaml

sleep ${SLEEP_TIME}
echo "Fetch the CSR from kubernetes"
kubectl get csr ${CSR_NAME}

# Approve Cert
echo "Approve the Certificate"
kubectl certificate approve ${CSR_NAME}

# 修正命名空间错误
serverCert=$(kubectl get csr ${CSR_NAME} -n ${NAMESPACE} -o jsonpath='{.status.certificate}')
echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/vault.crt

echo "Fetch Kubernetes CA Certificate"
kubectl get secret -o jsonpath="{.items[?(@.type==\"kubernetes.io/service-account-token\")].data['ca\.crt']}" | base64 --decode > ${TMPDIR}/vault.ca 2>/dev/null || true

echo "Create secret containing the TLS Certificates and key"
echo kubectl create secret generic ${SECRET_NAME} \
--namespace "${NAMESPACE}" \
--from-file=vault.key=${TMPDIR}/vault.key \
--from-file=vault.crt=${TMPDIR}/vault.crt \
--from-file=vault.ca=${TMPDIR}/vault.ca

kubectl create secret generic ${SECRET_NAME} \
--namespace "${NAMESPACE}" \
--from-file=vault.key=${TMPDIR}/vault.key \
--from-file=vault.crt=${TMPDIR}/vault.crt \
--from-file=vault.ca=${TMPDIR}/vault.ca

内容的提问来源于stack exchange,提问作者Murakami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:01:16