Consul TLS verification from k8s cluster to Consul Server

I am working on implementing Consul with end-to-end TLS in our environment, and have run into an issue similar to the one that @thecosmicfrog experienced in this thread. Kubernetes init containers used in the Connect pod and CatalogSync pod are failing to get the CA root certificates from the Consul CA. However, the workaround presented by [user] doesn’t seem to be viable for me.

The Consul architecture is 3 servers installed on Ubuntu 18.04 VMs, with Consul configured as client-only on our Kubernetes cluster. I can get Consul to securely discover services on the cluster, so long as they have the Consul annotations in their deployment spec. However, when trying to enable Consul Connect or CatalogSync, the injector pods get stuck in Init:0/1. The container getting stuck is get-auto-encrypt-client-ca, with error 2020-07-21T16:16:51.166Z [ERROR] Error retrieving CA roots from Consul: err="Get "https://<ip>:8501/v1/agent/connect/ca/roots": dial tcp <ip>:8501: connect: connection refused"

Reading the above thread, I tried execing into the containers to get the certificates copied into the container CA store, but the containers are running as nonroot, so I can’t get the files copied from/consul/tls/ca/ to /usr/local/share/ca-certificates/. It looks like I could possibly adjust the Helm _helpers.tpl file to do it as part of the container’s startup script, but I’m not sure if that’s a good idea.

Helm Chart (disabled parts redacted where indicated)…I have tried enabling certs.secretName and using the consul-agent-ca.pem as the caBundle, but it makes no difference.

global:
  enabled: true
  name: consul
  domain: consul
  image: "consul:1.8.0"
  imagePullSecrets: []
  imageK8S: "hashicorp/consul-k8s:0.17.0"
  imageEnvoy: envoyproxy/envoy:v1.14.2
  datacenter: sv-consul
  enablePodSecurityPolicies: false
  gossipEncryption:
    secretName: "consul-gossip-encryption-key"
    secretKey: "key"
  tls:
    enabled: true
    enableAutoEncrypt: true
    serverAdditionalDNSSANs: []
    serverAdditionalIPSANs: []
    verify: false
    httpsOnly: false
    caCert:
      secretName: consul-ca-cert
      secretKey: tls.crt
    caKey:
      secretName: consul-ca-key
      secretKey: tls.key
  enableConsulNamespaces: false
  acls:
    manageSystemACLs: false
    bootstrapToken:
      secretName: null
      secretKey: null
    createReplicationToken: false
    replicationToken:
      secretName: null
      secretKey: null
  federation:
    enabled: false
    createFederationSecret: false
server:
  enabled: false
<redacted>
externalServers:
  enabled: true
  hosts: [<redacted>]
  httpsPort: 8501
  tlsServerName: null
  useSystemRoots: false
  k8sAuthMethodHost: null
client:
  enabled: true
  image: "consul:1.8.0"
  join: [<redacted>]
  dataDirectoryHostPath: null
  grpc: true
  exposeGossipPorts: true
  resources:
    requests:
      memory: "100Mi"
      cpu: "100m"
    limits:
      memory: "100Mi"
      cpu: "100m"
  extraConfig: |
    {}
  extraVolumes: []
  tolerations: ""
  nodeSelector: null
  affinity: {}
  priorityClassName: ""
  annotations: null
  extraEnvironmentVars: {}
  dnsPolicy: null
  hostNetwork: false
  updateStrategy: null
  snapshotAgent:
    enabled: false
    replicas: 2
    configSecret:
      secretName: null
      secretKey: null
    resources:
      requests:
        memory: "50Mi"
        cpu: "50m"
      limits:
        memory: "50Mi"
        cpu: "50m"
    caCert: null
dns:
  enabled: "-"
  clusterIP: null
  annotations: null
ui:
  enabled: "-"
  service:
    enabled: true
    type: null
    annotations: null
    additionalSpec: null
syncCatalog:
  enabled: true
  image: null
  default: true # true will sync by default, otherwise requires annotation
  toConsul: true
  toK8S: false
  k8sPrefix: null
  k8sAllowNamespaces: ["*"]
  k8sDenyNamespaces: ["kube-system", "kube-public"]
  k8sSourceNamespace: null
  consulNamespaces:
    consulDestinationNamespace: "default"
    mirroringK8S: false
    mirroringK8SPrefix: ""
  addK8SNamespaceSuffix: true
  consulPrefix: null
  k8sTag: null
  syncClusterIPServices: true
  nodePortSyncType: ExternalFirst
  aclSyncToken:
    secretName: null
    secretKey: null
  nodeSelector: null
  affinity: null
  tolerations: null
  resources:
    requests:
      memory: "50Mi"
      cpu: "50m"
    limits:
      memory: "50Mi"
      cpu: "50m"
  logLevel: info
  consulWriteInterval: null
connectInject:
  enabled: true
  image: hashicorp/consul-k8s:latest # image for consul-k8s that contains the injector
  default: false # true will inject by default, otherwise requires annotation
  imageConsul: consul:1.8.0
  resources:
    requests:
      memory: "50Mi"
      cpu: "50m"
    limits:
      memory: "50Mi"
      cpu: "50m"
  imageEnvoy: envoyproxy/envoy:v1.14.2
  namespaceSelector: null
  k8sAllowNamespaces: ["*"]
  k8sDenyNamespaces: []
  consulNamespaces:
    consulDestinationNamespace: "default"
    mirroringK8S: false
    mirroringK8SPrefix: ""
  certs:
    #secretName: consul-connect-inject-ca
    secretName: null
    #caBundle: <redacted>
    caBundle: ""
    certName: tls.crt
    keyName: tls.key
  nodeSelector: null
  affinity: null
  tolerations: null
  aclBindingRuleSelector: "serviceaccount.name!=default"
  overrideAuthMethodName: ""
  aclInjectToken:
    secretName: null
    secretKey: null
  centralConfig:
    enabled: true
    defaultProtocol: null
    proxyDefaults: |
      {}
  sidecarProxy:
    resources:
      requests:
        memory: 100Mi
        cpu: 100m
      limits:
        memory: 100Mi
        cpu: 100m
meshGateway:
  enabled: false
<redacted>
ingressGateways:
  enabled: false
<redacted>
terminatingGateways:
  enabled: false
<redacted>
tests:
  enabled: true

consul.hcl on the servers. have tried flipping verify_* to false, but no effect. At some point we need verification anyway.

server = true
datacenter = "sv-consul"
data_dir = "/opt/consul"
encrypt = “<redacted>"
server = true
client_addr = "0.0.0.0"
ui = true
ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/sv-consul-server-consul-0.pem"
key_file = "/etc/consul.d/sv-consul-server-consul-0-key.pem"
verify_incoming = true
verify_outgoing = true
verify_server_hostname = true
auto_encrypt = {
  allow_tls = true
}
retry_join = [<redacted>]
acl = {
  enabled = true
  default_policy = "allow"
  enable_token_persistence = true
}
performance {
  raft_multiplier = 1
}

server.hcl on the servers:

server = true
bootstrap_expect = 3
ui = true
client_addr = "0.0.0.0"
connect {
  enabled = true
}

Any guidance would be appreciated.

Thanks,

Chris

1 Like

Hey Chris,

Thanks for reaching out. A quick follow up question regarding the error message you observed in the get-auto-encrypt-client-ca job: 2020-07-21T16:16:51.166Z [ERROR] Error retrieving CA roots from Consul: err="Get "https://<ip>:8501/v1/agent/connect/ca/roots": dial tcp <ip>:8501: connect: connection refused". Given the error appears to be connection refused and not certificate signed by Unknown Authority, I wonder if it is a firewall issue and not a certificate one.

One you have exec-ed into the container, can you try curling that endpoint? The init-container that is failing should use the ca certificate provided in the tls.caCert.secretKey values in the values file.

I would verify if traffic from the nodes are allowed to reach the consul servers.
Happy to follow up based on the result.

Cheers,
Ashwin

Hi Ashwin,

Thank you for the quick response. The port wasn’t firewalled off, but I hadn’t checked to see if anything was listening on that port. netstat -tulpn | grep LISTEN told me that nothing was actually listening on that port. So, I adjusted consul.hcl to add

ports = {
  http = 8500
  https = 8501
}

After restarting the service, consul is now listening on 8501. The init container now throws the error: [ERROR] Error retrieving CA roots from Consul: err="Get "https://<ip>:8501/v1/agent/connect/ca/roots": x509: certificate is valid for 127.0.0.1, not <ip>"

Trying to curl that endpoint from the init container still results in an error, albeit a different one:

$ curl https://1<ip>:8501/v1/agent/connect/ca/roots
curl: (60) SSL certificate problem: unable to get local issuer certificate

Interestingly, when I use openssl s_client -connect :8501 -CAfile consul-agent-ca.pem, it works perfectly.

When I created the CA, I used consul tls ca create without any switches. Maybe I need to specify name constraints and have the clients try to access the servers via DNS name?

Best Regards,

Chris

@ctew I think you’re right on the money there. You can provide additional DNSnames and IPs to the consul tls ca create which should allow you to specify both IPs and DNSnames. Maybe the quickest way to validate this would be to create one with the IP, and if that does work, create the CA with the DNS name and have the agents reach the servers via the DNS name.

Here is hoping it works :slight_smile:

Cheers!!

Hey Chris,
Did you manage to solve the problem?
I had similar problem which I solved by generating new certs for my consul servers including their IP addresses:

consul tls cert create -server -dc $dcname -additional-ipaddress=$nodeip

After replacing cert on all consul servers I’m now getting another type of error which is:

Failure: calling /agent/self to get datacenter: err="Get "https://consulserverip:8501/v1/agent/self": remote error: tls: bad certificate"

I have checked the CA certificate in init container and it’s looks OK. curl’ing endpoint gives me an error:

curl: (60) SSL certificate problem: unable to get local issuer certificate

curl -k (which should allow insecure connection) gives:

curl: (56) OpenSSL SSL_read: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate, errno 0

@andriktr I did. Thank you for reminding me to update.

I resolved it by creating a new CA with

sudo consul tls ca create -name-constraint -additional-name-constraint=<SAN1> -additional-name-constraint=<SAN2> --additional-name-constraint=<SAN3>

SAN1 is the DNS name of the cluster, SAN2 is the IP of the CA server, SAN3 is the hostname of the CA server. I’m not sure if using the IP as a SAN was really needed, but it didn’t hurt.

then I created a san.cnf file with

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
[ req_distinguished_name ]
countryName                 = <country>
stateOrProvinceName         = <state>
localityName               = <locale>
organizationName           = <org>
commonName                 = <CN>
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1   = <SAN1>
DNS.2   = <SAN2>
DNS.3   = <SAN3>

and the certificate + key for each server, which I put into /etc/consul.d and chowned to consul:consul

sudo openssl x509 -extensions req_ext -req -in <server hostname>.csr -CA consul-agent-ca.pem -CAkey consul-agent-ca-key.pem -CAcreateserial -extfile san.cnf -out <server hostname>.crt

finally the consul.hcl

ca_file = "/etc/consul.d/consul-agent-ca.pem"
cert_file = "/etc/consul.d/<server hostname>.crt"
key_file = "/etc/consul.d/<server hostname>.key"
verify_incoming = false
verify_outgoing = false
verify_server_hostname = false
auto_encrypt = {
  allow_tls = true
}
ports = {
  http = 8500
  https = 8501
  grpc = 8502
  serf_lan = 8301
  serf_wan = 8302
  server = 8300
}

TLS between the cluster and Consul servers now works, and I can spin up Consul Connect and CatalogSync sidecars (although we’re having severe issues with Connect causing pod evictions that I haven’t been able to gather enough data on to fully troubleshoot). I haven’t yet tried full verification or disabling http, but will try and report back.

Hi Thanks for clarification. I also have found a root cause of my problem. It just was needed to set

manageSystemACLs: false

Are you sure that auto_encrypt is working properly in your setup in your consul.hcl
you set the

verify_incoming = false
verify_outgoing = false
verify_server_hostname = false

but according the tutorial in consul servers this should be set to true

For what I need (Consul Connect sidecars in Kubernetes to init and run properly), auto_encrypt appears to be working. If I set the verify_* values to true, I run into errors on the Consul servers complaining that the certificate is not valid for server.<consul_dc>.consul. If I create new certificates with that hostname as a SAN, the errors start complaining that other SANs are not not permitted by any constraint, even though I put those SANS in the additional-name-constraint keys when creating the consul CA.

While I’d like to figure out what’s going on with that, it would require me to set everything back up from scratch, which I don’t have time for now.

Hello guys,

I have exactly the same pb. I have 3 VMs for consul servers, 1 consul client in a VM and a kubernetes cluster in which there is 3 clients. All clients are able to connect to consul servers except connect inject who is throwing msg “consul-connect-injector-webhook-deployment-6c75d8b79d-m8lck get-auto-encrypt-client-ca 2020-09-01T07:19:00.278Z [ERROR] Error retrieving CA roots from Consul: err=“Get “https://XXXXX:8501/v1/agent/connect/ca/roots”: remote error: tls: bad certificate””.

My Ca setup is:
consul tls ca create -name-constraint
-additional-name-constraint={EXTERNAL_DOMAIN} \ -additional-name-constraint={FQDN_OF_CONSUL_SERVER01}
-additional-name-constraint={FQDN_OF_CONSUL_SERVER02} \ -additional-name-constraint={FQDN_OF_CONSUL_SERVER03}

consul tls cert create -server -dc euw1 -additional-dnsname={EXTERNAL_DOMAIN} -additional-dnsname={FQDN_OF_CONSUL_SERVER01}
consul tls cert create -server -dc euw1 -additional-dnsname={EXTERNAL_DOMAIN} -additional-dnsname={FQDN_OF_CONSUL_SERVER02}
consul tls cert create -server -dc euw1 -additional-dnsname={EXTERNAL_DOMAIN} -additional-dnsname={FQDN_OF_CONSUL_SERVER03}

Here is the config of my 1st consul server (almost the same for the 2 others):
{
“acl”: {
“default_policy”: “allow”,
“enable_token_persistence”: true,
“enabled”: true
},
“advertise_addr”: “IP_OF_SERVER01”,
“auto_encrypt”: {
“allow_tls”: true
},
“bind_addr”: “0.0.0.0”,
“bootstrap_expect”: 3,
“ca_file”: “/etc/consul.d/euw1-consul-agent-ca.pem”,
“cert_file”: “/etc/consul.d/euw1-server-consul.pem”,
“client_addr”: “0.0.0.0”,
“connect”: {
“enabled”: true
},
“data_dir”: “/data/consul”,
“datacenter”: “euw1”,
“encrypt”: “XXXXX”,
“key_file”: “/etc/consul.d/euw1-server-consul-key.pem”,
“log_level”: “DEBUG”,
“node_name”: “${FQDN_OF_CONSUL_SERVER01}”,
“performance”: {
“raft_multiplier”: 1
},
“ports”: {
“grpc”: 8502,
“https”: 8501
},
“retry_join”: [
“IP_OF_SERVER01”,
“IP_OF_SERVER02”,
“IP_OF_SERVER03”
],
“server”: true,
“ui”: true,
“verify_incoming”: true,
“verify_outgoing”: true,
“verify_server_hostname”: true
}

So in order to verify if the certificates are good or not, I performed my curl command:

curl -vvvk --cert euw1-consul-agent-ca.pem --key /root/consul-agent-ca-key.pem https://XXXXX:8501/v1/agent/connect/ca/roots --cacert euw1-consul-agent-ca.pem

And the certificate is verified as I have the message “SSL certificate verify ok”:

* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=server.euw1.consul
*  start date: Sep  1 06:26:40 2020 GMT
*  expire date: Jun 17 07:26:40 2294 GMT
*  issuer: C=US; ST=CA; L=San Francisco; street=101 Second Street; postalCode=94105; O=HashiCorp Inc.; CN=Consul Agent CA 251292510108551272556755631721680811671
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5649639eef50)
> GET /v1/agent/connect/ca/roots HTTP/2
> Host: XXXXX:8501
> User-Agent: curl/7.64.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200 
< age: 0
< content-type: application/json
< vary: Accept-Encoding
< x-cache: HIT
< x-consul-index: 3828
< x-consul-knownleader: false
< x-consul-lastcontact: 0
< content-length: 1435
< date: Tue, 01 Sep 2020 06:45:31 GMT

So without TLS Handshake issues, I don’t understand why connect-inject is not able to verify the servers.
I check the secrets for the tls.crt and tls.key and they are the right ones.

Following the same issue here Remote error: tls: bad certificate for K8S consul clients I tried to make the same with ACLs and the issue was the same “tls bad certificate”.

My helm values.yaml are:

global:
  enabled: false
  name: consul
  domain: consul
  image: "consul:1.8.3"
  imagePullSecrets: []
  imageK8S: "hashicorp/consul-k8s:0.18.1"
  imageEnvoy: "envoyproxy/envoy-alpine:v1.14.2"
  datacenter: euw1
  enablePodSecurityPolicies: false
  gossipEncryption:
    secretName: "consul-secrets"
    secretKey: "gossipEncryptionKey"
  tls:
    enabled: true
    enableAutoEncrypt: true
    serverAdditionalDNSSANs: []
    serverAdditionalIPSANs: []
    verify: true
    httpsOnly: true
    caCert:
      secretName: "consul-secrets"
      secretKey: tls.crt
    caKey:
      secretName: "consul-secrets"
      secretKey: tls.key
  enableConsulNamespaces: false
  acls:
    manageSystemACLs: true
    bootstrapToken:
      secretName: consul-secrets
      secretKey: token_mgmt
    createReplicationToken: false
    replicationToken:
      secretName: null
      secretKey: null
  federation:
    enabled: false
    createFederationSecret: false
  lifecycleSidecarContainer:
    resources:
      requests:
        memory: "25Mi"
        cpu: "20m"
      limits:
        memory: "50Mi"
        cpu: "20m"
server:
  enabled: "-"
  image: null
  replicas: 3
  enterpriseLicense:
    secretName: null
    secretKey: null
  storage: 10Gi
  storageClass: null
  connect: true
  resources:
    requests:
      memory: "100Mi"
      cpu: "100m"
    limits:
      memory: "100Mi"
      cpu: "100m"
  updatePartition: 0
  disruptionBudget:
    enabled: true
    maxUnavailable: null
  extraConfig: |
    {}
  extraVolumes: []
  affinity: |
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: {{ template "consul.name" . }}
              release: "{{ .Release.Name }}"
              component: server
          topologyKey: kubernetes.io/hostname
  tolerations: ""
  nodeSelector: null
  priorityClassName: ""
  extraLabels: null
  annotations: null
  service:
    annotations: null
  extraEnvironmentVars: {}
  disableFsGroupSecurityContext : false
externalServers:
  enabled: true
  hosts:
  - [REDACTED]
  httpsPort: 8501
  tlsServerName: null
  useSystemRoots: false
  k8sAuthMethodHost: https://172.16.0.82
client:
  enabled: true
  image: null
  join:
  - [REDACTED]
  dataDirectoryHostPath: null
  grpc: true
  exposeGossipPorts: true
  resources:
    requests:
      memory: "100Mi"
      cpu: "100m"
    limits:
      memory: "100Mi"
      cpu: "100m"
  extraConfig: |
    {
      "auto_encrypt": {
        "tls": true
      }
    }
  extraVolumes:
  - type: secret
    name: consul-secrets
  tolerations: ""
  nodeSelector: null
  affinity: |
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: node-role.kubernetes.io/master
            operator: DoesNotExist
  priorityClassName: "consul"
  annotations: null
  extraEnvironmentVars: {}
  dnsPolicy: null
  hostNetwork: false
  updateStrategy: |
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  snapshotAgent:
    enabled: false
    replicas: 2
    configSecret:
      secretName: null
      secretKey: null
    resources:
      requests:
        memory: "50Mi"
        cpu: "50m"
      limits:
        memory: "50Mi"
        cpu: "50m"
    caCert: null
dns:
  enabled: "-"
  clusterIP: null
  annotations: null
ui:
  enabled: "-"
  service:
    enabled: true
    type: null
    annotations: null
    additionalSpec: null
syncCatalog:
  enabled: false
  image: null
  toConsul: true
  toK8S: true
  k8sPrefix: null
  k8sAllowNamespaces: ["*"]
  k8sDenyNamespaces: ["kube-system", "kube-public"]
  k8sSourceNamespace: null
  consulNamespaces:
    consulDestinationNamespace: "default"
    mirroringK8S: false
    mirroringK8SPrefix: ""
  addK8SNamespaceSuffix: true
  consulPrefix: null
  k8sTag: null
  syncClusterIPServices: true
  nodePortSyncType: ExternalFirst
  aclSyncToken:
    secretName: null
    secretKey: null
  nodeSelector: null
  affinity: null
  tolerations: null
  resources:
    requests:
      memory: "50Mi"
      cpu: "50m"
    limits:
      memory: "50Mi"
      cpu: "50m"
  logLevel: info
  consulWriteInterval: null
connectInject:
  enabled: true
  imageConsul: null
  resources:
    requests:
      memory: "50Mi"
      cpu: "50m"
    limits:
      memory: "50Mi"
      cpu: "50m"
  imageEnvoy: null
  namespaceSelector: null
  k8sAllowNamespaces: ["*"]
  k8sDenyNamespaces: []
  consulNamespaces:
    consulDestinationNamespace: "default"
    mirroringK8S: false
    mirroringK8SPrefix: ""
  certs:
    secretName: null
    caBundle: ""
    certName: tls.crt
    keyName: tls.key
  nodeSelector: null
  affinity: null
  tolerations: null
  aclBindingRuleSelector: "serviceaccount.name!=default"
  overrideAuthMethodName: ""
  aclInjectToken:
    secretName: null
    secretKey: null
  centralConfig:
    enabled: true
    defaultProtocol: null
    proxyDefaults: |
      {}
  sidecarProxy:
    resources:
      requests:
        memory: 100Mi
        cpu: 100m
      limits:
        memory: 100Mi
        cpu: 100m
  initContainer:
    resources:
      requests:
        memory: "25Mi"
        cpu: "50m"
      limits:
        memory: "150Mi"
        cpu: "50m"
meshGateway:
  enabled: false
  globalMode: local
  replicas: 2
  wanAddress:
    source: "Service"
    port: 443
    static: ""
  service:
    enabled: true
    type: LoadBalancer
    port: 443
    nodePort: null
    annotations: null
    additionalSpec: null
  imageEnvoy: envoyproxy/envoy-alpine:v1.14.2
  hostNetwork: false
  dnsPolicy: null
  consulServiceName: "mesh-gateway"
  containerPort: 8443
  hostPort: null
  resources:
    requests:
      memory: "100Mi"
      cpu: "100m"
    limits:
      memory: "100Mi"
      cpu: "100m"
  initCopyConsulContainer:
    resources:
      requests:
        memory: "25Mi"
        cpu: "50m"
      limits:
        memory: "150Mi"
        cpu: "50m"
  affinity: |
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: {{ template "consul.name" . }}
              release: "{{ .Release.Name }}"
              component: mesh-gateway
          topologyKey: kubernetes.io/hostname
  tolerations: null
  nodeSelector: null
  priorityClassName: ""
  annotations: null
ingressGateways:
  enabled: false
  defaults:
    replicas: 2
    service:
      type: ClusterIP
      ports:
        - port: 8080
          nodePort: null
        - port: 8443
          nodePort: null
      annotations: null
      additionalSpec: null
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
      limits:
        memory: "100Mi"
        cpu: "100m"
    initCopyConsulContainer:
      resources:
        requests:
          memory: "25Mi"
          cpu: "50m"
        limits:
          memory: "150Mi"
          cpu: "50m"
    affinity: |
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: {{ template "consul.name" . }}
                release: "{{ .Release.Name }}"
                component: ingress-gateway
            topologyKey: kubernetes.io/hostname
    tolerations: null
    nodeSelector: null
    priorityClassName: ""
    annotations: null
    consulNamespace: "default"
  gateways:
    - name: ingress-gateway
terminatingGateways:
  enabled: false
  defaults:
    replicas: 2
    extraVolumes: []
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
      limits:
        memory: "100Mi"
        cpu: "100m"
    initCopyConsulContainer:
      resources:
        requests:
          memory: "25Mi"
          cpu: "50m"
        limits:
          memory: "150Mi"
          cpu: "50m"
    affinity: |
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: {{ template "consul.name" . }}
                release: "{{ .Release.Name }}"
                component: terminating-gateway
            topologyKey: kubernetes.io/hostname
    tolerations: null
    nodeSelector: null
    priorityClassName: ""
    annotations: null
    consulNamespace: "default"
  gateways:
    - name: terminating-gateway
tests:
  enabled: true

So are you guys were able to make this kind of setup correctly? @ashwin-venkatesh @ishustava @lkysow any help please?

Ok so only for debug purpose I created this testing pod in order to execute consul-k8s get-consul-client-ca command:

apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: consul
spec:
  containers:
  - command:
    - /bin/sh
    tty: true
    image: hashicorp/consul-k8s:0.18.1
    imagePullPolicy: IfNotPresent
    name: get-auto-encrypt-client-ca
    securityContext:
      allowPrivilegeEscalation: true
      runAsUser: 0
    env:
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: CONSUL_CACERT
      value: /consul/tls/ca/tls.crt
    volumeMounts:
    - mountPath: /consul/tls/ca
      name: consul-ca-cert
    - mountPath: /consul/tls/client/ca
      name: consul-auto-encrypt-ca-cert
  volumes:
  - name: consul-ca-cert
    secret:
      defaultMode: 420
      items:
      - key: tls.crt
        path: tls.crt
      secretName: consul-secrets
  - emptyDir:
      medium: Memory
    name: consul-auto-encrypt-ca-cert

After few tests, the errors was still the same with:
[ERROR] Error retrieving CA roots from Consul: err=“Get “https://XXXXX:8501/v1/agent/connect/ca/roots”: remote erro
r: tls: bad certificate”

I finally ended up to set verify_incoming = false on consul servers and the connect injector webhook was up.

Too bad that connect inject has no mode with auto_encrypt.tls = true like the consul clients have.

Hope you guys will make few updates to make us enable verify_incoming.