Search code examples
kubernetessslkubernetes-ingress

kubernetes ingress not accepting the self signed ssl


My kubernetes ingress is not accepting the self signed certificate and instead when opening the url on firefox the Kubernetes Ingress Controller Fake Certificate is added.

All the things done locally on pc with minikube in Kali Linus. Kali linus is running in a Virtual Machine by VMWare software.The doc which I am referring is - https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl

The Ingress Yaml file.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: first-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
      - example.com
    secretName: myssl
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: first-service
            port:
              number: 8080

The "192.168.49.2" is the ingress ip address. So https://192.68.49.2 opens my app on the browser.

The certificate is generated with Openssl with the following commands:

openssl genrsa -out s.key 2048
openssl req -new -key s.key -out s.csr -subj "/CN=example.com"
openssl x509 -req -days 365 -in s.csr -signkey s.key -out s.crt

The certificate is added to k8s secret.

kubectl create secret tls myssl --cert s.crt --key s.key

The curl -kv https://192.168.49.2 command output is:

* Trying 192.168.49.2:443...
* Connected to 192.168.49.2 (192.168.49.2) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
*  start date: Oct 22 09:57:19 2022 GMT
*  expire date: Oct 22 09:57:19 2023 GMT
*  issuer: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
*  SSL certificate verify result: self-signed certificate (18), continuing anyway.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: 192.168.49.2]
* h2h3 [user-agent: curl/7.85.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x561c242ff950)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: 192.168.49.2
> user-agent: curl/7.85.0
> accept: */*
> 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200 
< date: Sat, 22 Oct 2022 10:05:50 GMT
< content-type: text/html; charset=utf-8
 ..... html of the page
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host 192.168.49.2 left intact

Kindly help.

Update 2 days Later:

I debugged and found I have installed nginx ingress with the command:

minikube addons enable ingress

It installs the ingress in ingress-nginx namespace while my secret is in default namespace. Can this be the problem, if so what is the solution?


Solution

  • You have an error in your ingress manifest, here:

    rules:
    - host: example.com
    - http:
        paths:
    

    You have created two rules, the first matches host: example.com but defines no paths or backends; the second matches path / but doesn't set a host. You want:

    rules:
    - host: example.com
      http:
        paths:
    

    It installs the ingress in ingress-nginx namespace while my secret is in default namespace. Can this be the problem, if so what is the solution?

    This is not a problem: it is the expected configuration. Your SSL secrets should be installed in the same namespace as your application and Ingress.


    I've been playing with this a bit over the past couple of days, and I'm not sure you can get this to operate the way you want without using a hostname. Fortunately, setting up a hostname to use during local development is relatively straightforward.

    In most cases you can edit your /etc/hosts file. For example, if your application is hosted on 192.168.49.2, then you would add an entry like this to /etc/hosts to access your application at https://example.com:

    192.168.49.2    example.com
    

    You can add multiple hostname aliases, which allows you to use multiple hostname-based Ingress resources on your cluster:

    192.168.49.2    example.com myapp.internal anotherapp.dev
    

    When you're testing with curl, you can use the --resolve option to accomplish the same thing:

    curl --resolve example.com:443:192.168.49.2 -kv https://example.com
    

    So for example, if I deploy the following Ingress on my local cluster:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: whoami
    spec:
      tls:
        - secretName: myssl
          hosts:
            - example.com
      rules:
        - host: example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: whoami
                    port:
                      name: http
    

    With the following entry in /etc/hosts:

    $ grep example.com /etc/hosts
    193.168.1.200 example.com
    

    Running curl -skv https://example.com shows that the ingress is using my custom certificate rather than the default ingress certificate:

    [...]
    * Server certificate:
    *  subject: CN=example.com
    *  start date: Oct 23 12:52:45 2022 GMT
    *  expire date: Oct 23 12:52:45 2023 GMT
    *  issuer: CN=example.com
    [...]