Showing posts with label tls. Show all posts
Showing posts with label tls. Show all posts

Thursday, April 08, 2021

Tip: error: failed to load key pair tls: failed to parse private key

 Symptom:

    When we kubectl create secret tls ..., we hit below error

error: failed to load key pair tls: failed to parse private key

Reason:

    It is likely the private key file is encrypted with a passphrase.

   Use openssl to unencrypt it and use the new key for kubectl 

openssl rsa -in encrypted-private.key -out unencrypted.key

 Enter pass phrase for ...... 

 

 

Saturday, April 03, 2021

Tip: Istio TLS secrets, Gateway, VirtualService namespace scope

There is some confusion about where we should put istio objects. Is it in the istio-system or users namespace?

Here are some tips:

For TLS,mTLS CA, certs, key management in istio, the Kubernetes secrets should be created in the istio-system. Not in users' namespace

Gateway and VirtualService need to be created on the users' namespace 

Tuesday, November 10, 2020

Tip: OpenSSL SSL_connect: SSL_ERROR_SYSCALL

 Symptoms:

We use curl -v https://<domain> to test if the network traffic is allowed
The expected result would be like 
*  Trying 12.12.12.12:443...
* TCP_NODELAY set
* Connected to ***  port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
However, we see this error :
*  Trying 12.12.12.12:443...
* TCP_NODELAY set
* Connected to *** port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to *** :443

Solution:

From the output, we see 443 is open but the TLS handshake, Server hello is missing. We have mid-tiers to handle TLS certificates. So it is very likely that the network is interrupted between  LB and mid-tiers where TLS is being handled.  It would be a good approach to double-check firewall ports between them. :)

Another reason is ingress controller pods were stuck may bounce or scale up to workaround it


Wednesday, March 04, 2020

How To Add TLS Certificate Into Ingress in OKE

Requirement:

         In order to secure the traffic, we need to deploy  TLS certificates into our ingress running in OKE.  We are going to use self-signed certificates to demonstrate it. 

Solution:

  • Generate self-signed certificates via openssl
    • openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt  -config req.conf -extensions 'v3_req'
    • req.conf:
      
      [req]
      distinguished_name = ingress_tls_prometheus_test
      x509_extensions = v3_req
      prompt = no
      [ingress_tls_prometheus_test]
      C = US
      ST = VA
      L = NY
      O = BAR
      OU = BAR
      CN = www.bar.com
      [v3_req]
      keyUsage = keyEncipherment, dataEncipherment
      extendedKeyUsage = serverAuth
      subjectAltName = @alt_names
      [alt_names]
      DNS.1 = prometheus.bar.com
      DNS.2 = grafana.bar.com
      DNS.3 = alertmanager.bar.com

    • To verify it:    openssl x509 -in tls.crt -noout -text
  • Create Kubernetes TLS secret for that
    • kubectl create secret tls tls-prometheus-test --key tls.key --cert tls.crt -n monitoring
  • Add TLS section into the ingress yaml file. Example:
    • apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: prometheus-ingress
        namespace: monitoring
        annotations:
          kubernetes.io/ingress.class: "nginx"
      spec:
        tls:
        - hosts:
          - prometheus.bar.com
          secretName: tls-prometheus-test
        - hosts:
          - grafana.bar.com
          secretName: tls-prometheus-test
        - hosts:
          - alertmanager.bar.com
          secretName: tls-prometheus-test
        rules:
        - host: prometheus.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: prometheus-k8s
                servicePort: 9090
        - host: grafana.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: grafana
                servicePort: 3000
        - host: alertmanager.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: alertmanager-main
                servicePort: 9093
      
      
  • Ingress controller would redirect http traffic to https traffic automatically for these 3 domains 
  • Spoof IP address for DNS names via the below entry and take off www proxy of the browser if necessary.

Wednesday, February 12, 2020

Cross Namespace Ingress Usage Example in OKE

Requirement:

      The normal use case to create ingress is to create one in the application namespace where application services and TLS certificates/keys are sitting.
      In the enterprise world, the security team is not comfortable to store TLS private keys in the application namespace. TLS private keys need to be stored securely in the namespace of the ingress controller.   In this case, we need to create ingress in "ingress controller" namespace instead of the application namespace.   We need to find a way to let ingress in "ingress controller" namespace to point to services in the application namespace (cross namespace service ).  Below is the solution of how we can achieve that in OKE ( Oracle Kubernetes Engine).

Solution:

  • Create TLS secrets in ingress controller namespace. Refer doc
    • $ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt  -config req.conf -extensions 'v3_req'
      
      req.conf:
      [req]
      distinguished_name = ingress_tls_prometheus_test
      x509_extensions = v3_req
      prompt = no
      [ingress_tls_prometheus_test]
      C = US
      ST = VA
      L = NY
      O = BAR
      OU = BAR
      CN = www.bar.com
      [v3_req]
      keyUsage = keyEncipherment, dataEncipherment
      extendedKeyUsage = serverAuth
      subjectAltName = @alt_names
      [alt_names]
      DNS.1 = prometheus.bar.com
      DNS.2 = grafana.bar.com
      DNS.3 = alertmanager.bar.com
    • kubectl create secret tls tls-prometheus-test  --key tls.key --cert tls.crt -n ingress-nginx
  • The key to using services in different namespaces is ExternalName.  It is working in OKE, but may not be working other  Cloud providers. One of the externalname examples is:
    • apiVersion: v1
      kind: Service
      metadata:
        annotations:
        name: prometheus-k8s-svc
        namespace: ingress-nginx
      spec:
        externalName: prometheus-k8s.monitoring.svc.cluster.local
        ports:
        - port: 9090
          protocol: TCP
          targetPort: 9090
        type: ExternalName
  • Create ingress in ingress controller namespace.
    • apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: prometheus-ingress
        namespace: ingress-nginx
        annotations:
          kubernetes.io/ingress.class: "nginx"
      spec:
        tls:
        - hosts:
          - prometheus.bar.com
          - grafana.bar.com
          - alertmanager.bar.com
          secretName: tls-prometheus-test
        rules:
        - host: prometheus.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: prometheus-k8s-svc
                servicePort: 9090
        - host: grafana.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: grafana-svc
                servicePort: 3000
        - host: alertmanager.bar.com
          http:
            paths:
            - path: /
              backend:
                serviceName: alertmanager-main-svc
                servicePort: 9093

Tuesday, February 11, 2020

How To Generate Self-Signed Multiple SAN Certificate Using OpenSSL

Requirement:

    In our development services, we often need to have self-signed certificates. Sometimes we need to add SAN into such a certificate.  Below is how we use OpenSSL to achieve it.

Solution:

$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout tls.key -out tls.crt  -config req.conf -extensions 'v3_req'

req.conf:

[req]
distinguished_name = ingress_tls_prometheus_test
x509_extensions = v3_req
prompt = no
[ingress_tls_prometheus_test]
C = US
ST = VA
L = NY
O = BAR
OU = BAR
CN = www.bar.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = prometheus.bar.com
DNS.2 = grafana.bar.com
DNS.3 = alertmanager.bar.com

To verify it:    openssl x509 -in tls.crt -noout -text

Wednesday, September 18, 2019

Tip: Create tls secret with key cert and ca cert files in Kubernetes

Requirement:

    We need to create tls secrets in Kubernetes for our oracle OCI balancer. Refer doc. However, the command only accepts key and cert files.

"kubectl create secret tls ssl-certificate-secret --key tls.key --cert tls.crt"

There is no option to add the CA certificate file here.

Solution:

    We need to combine CA certificate files with the cert file to form 1 cert file for Kubernetes. We simply copy the content of CA certificate files and append at the end of the cert file.

Saturday, May 04, 2019

Error: net/http: TLS handshake timeout via kubectl

Symptom:

  When we try to use kubectl logs <pod> or kubectl exec it  <pod> /bin/bash ....etc , we get below error:
.........  net/http: TLS handshake timeout.

While TLS certificates are valid and kubectl get nodes, kubectl cluster-info are working fine

Solution:

Use -v=8 flag to enable more details kubectl rest API call details
We found such HTTP 500 error when kubectl contacts API masterserver

GET https://Your-Master-node:6443/api/v1/namespaces/default/pods/test-deployment-6669d6df59-vdnk5/log
I0424 04:47:05.882800   11526 round_trippers.go:408] Response Status: 500 Internal Server Error in 10100 milliseconds
..
I0424 05:28:52.001101   21195 request.go:942] Response Body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Get https://10.0.64.2:10250/containerLogs/default/test-deployment-6669d6df59-vdnk5/django: net/http: TLS handshake timeout","code":500}

10.0.64.2 is the private ip of the Node and 10250 is the listening port of kubelet
It turns out TLS error is on kubelet side of the node though TLS certificates are valid
kubectl get nodes ,kubectl cluster-info are fine as apiserver don't need to contact kubelet while kubectl logs needs apiserver to contact kubelet
It could be potential a bug.  We upgrade k8s of worker node to fix it.
Similar github issue link