<p>I am trying to make my ingress run over https but I'm getting <code>HTTP ERROR 403</code>, and I don't know what am I missing here.</p>
<p>I am trying to access them on <code>my-local-domain.com</code> and I added that entry on my <code>etc/hosts</code> file as
<code>127.0.0.1 my-local-domain.com</code> so I can access it that way.</p>
<p>Here's my Issuer</p>
<pre><code>apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: cert-issuer
  namespace: my-namespace
spec:
  selfSigned: {}
</code></pre>
<p>Here's my Certificate</p>
<pre><code>apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: self-signed-cert
  namespace: my-namespace
spec:
  secretName: my-secret-tls
  dnsNames:
    - my-local-domain.com
    - www.my-local-domain.com
  issuerRef:
    name: cert-issuer
</code></pre>
<p>While here is my nginx ingress:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-service
  labels:
      name: ingress-service
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/backend-protocol: &quot;HTTPS&quot;
    nginx.ingress.kubernetes.io/ssl-redirect: 'true'
    namespace: my-namespace
spec:
  tls:
    - hosts:
      - my-local-domain.com
      - www.my-local-domain.com
      secretName: my-secret-tls
  rules:
  - host: my-local-domain.com
    http:
      paths:
      - path: /api/(.*)
        pathType: Prefix
        backend:
          service:
            name: web-api
            port:
              number: 443
      - path: /(.*)
        pathType: Prefix
        backend:
          service:
            name: web-client
            port:
              number: 80
</code></pre>
<p>nginx.conf for my web-client service</p>
<pre><code>server {
        listen 80;

        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        gzip  on; 
    }
</code></pre>
<p>And when I try to access it with <code>https://my-local-domain.com</code></p>
<pre><code>Access to my-local-domain.com was denied
You don't have authorization to view this page.
HTTP ERROR 403
</code></pre>
<p>I also tried to run</p>
<pre><code>openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj &quot;//CN=my-local-domain.com\O=my-local-domain.com&quot; -addext &quot;subjectAltName = DNS:my-local-domain.com&quot;

kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n my-namespace
</code></pre>
<p>remove <code>Certificate</code> and <code>CertificateIssuer</code> and add <code>tls-secret</code> as <code>secretName</code> in ingress, as well as added those <code>tls.key</code> and <code>tls.crt</code> to my web-client nginx and updated it to:</p>
<pre><code>    server {
      listen 443 ssl default_server;

      ssl_protocols SSLv3 TLSv1;

      server_name www.my-local-domain.com my-local-domain.com;

      access_log /var/log/nginx/access.log;
      error_log  /var/log/nginx/error.log info;

      keepalive_timeout 75 75;

      ssl_certificate /etc/ssl/certs/self-signed.crt;
      ssl_certificate_key /etc/ssl/private/self-signed.key;
      ssl_session_timeout  5m;

      add_header Strict-Transport-Security &quot;max-age=7200&quot;;
      
      location / {
          root /usr/share/nginx/html;
          index index.html index.htm;
          try_files $uri $uri/ /index.html;
      }
    }

</code></pre>
<p>p.s. when doing this, i run everyrhing on port <code>443</code> instead of <code>80</code>.</p>
<p>When I remove the <code>tls</code> part from my ingress, then it does work through HTTP. And I also tried to change my dns/host from <code>my-local-domain.com</code> to be only <code>localhost</code> but still the same. And even if I try to access <code>https://localhost</code> I get that <code>HTTP ERROR 403</code>.</p>

Ertan Hasani
<p>I don't know if this will help, but here are some advices:</p>
<ol>
<li><p><strong>Determine the source of your error</strong><br />
You provide us a lot of code, but no details of the error. Is the 403 thrown by your webservice, your api or by your ingress-controller? You can check that in the error-page. Errors from ingress-controller usally contains somethink like &quot;openresty&quot; in footer. But it hardly depends on your ingress-controller which are you using in your k8s.<br />
You can also check the logs of your containers (nginx write the logs to <code>/var/log/nginx/error.log</code>). Here you can find some more detailed informations why you're getting a 403.</p>
</li>
<li><p><strong>Let the cluster handle SSL-termination</strong><br />
Don't put the ssl-certifications into the containers. It will increase hardly the complexity of your app(s).<br />
It is a lot easier, when the cluster take care about that. So your app can be faster deployed on other clusters with others environments.</p>
</li>
<li><p><strong>Avoid the cert-manager, when using self-signed certs</strong><br />
As you already tested, but I suggest to use the cert-manager only, when you need certificates from lets encrypt. Otherwise it will increase the complexity again.</p>
</li>
<li><p><strong>Don't mix up HTTP and HTTPS</strong><br />
Your webapi using HTTPS for the internal communication (internal means: ingress-controller -&gt; webapi-service, which is usually unencrypted) ... but not for your web-server.<br />
Keep things simple - HTTPS for all or for nobody.</p>
</li>
<li><p><strong>Try to avoid url-rewrite</strong><br />
Whenever when possible, try to avoid url-rewrite. I see very often problems with it, so I suggest to avoid it.<br />
I know this is not always possible, but when all componets are developed by you ... why did you need it at all? Here is your ingress in &quot;easy&quot;:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
   name: ingress-service
   labels:
      name: ingress-service
   namespace: my-namespace
   annotations:
      nginx.ingress.kubernetes.io/ssl-redirect: 'true'

spec:
   tls:
      - hosts:
         - my-local-domain.com
         - www.my-local-domain.com
      secretName: my-secret-tls
   rules:
      - host: my-local-domain.com
        http:
           paths:
              - path: /api/       
                backend:
                   service:
                      name: web-api
                      port:
                         number: 80
              - path: /
                backend:
                   service:
                   name: web-client
                   port:
                      number: 80  
</code></pre>
</li>
<li><p><strong>Rootless is the best</strong><br />
Not very important for your problem, but instead of the standard nginx-image, use the unprivileged nginx-image. If your service (in this case <code>nginx</code>) got hacked, then the hacker has the same privileges like nginx. This means, he can easily install tools into the nginx-container and do very bad things.<br />
If you're using the unprivileged image, than the hacker can ... almost nothing. He needs a second exploit to escalate his rights.</p>
</li>
</ol>
<p>Good luck to find your error. We are happy, when you share your next steps with us.</p>
