Nginx ingress controller still redirect to SSL - kubernetes

I am experiencing this issue. My application needs to receive connection under SSL only with WebSocket. HTTP requests should be forced to not being redirected. My ingress configuration is
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: in-camonline
namespace: cl5
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/websocket-services: "svc-ws-api"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
ingress.kubernetes.io/affinity: "ClientIP"
spec:
tls:
- hosts:
- foo.bar.com
secretName: cl5-secret
rules:
- host: foo.bar.com
http:
paths:
- path: /socket.io
backend:
serviceName: svc-ws-api
servicePort: 8000
- path: /
backend:
serviceName: svc-http-service
servicePort: 80
I also disabled the ssl-redirect globally adding an item into the ConfigMap
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
#use-proxy-protocol: "false"
ssl-redirect: "false"
Now if I do request using curl, requests won't being redirected. If I try to run my front-end application every request after the WSS will be forced to being redirected to use HTTPS
Request URL: http://foo.bar.com/2/symbols
Request Method: OPTIONS
Status Code: 307 Internal Redirect
Referrer Policy: no-referrer-when-downgrade
Any suggestion about how to achieve that?

Finally, I sorted it out. If someone is reading this, easy you are not alone!
Jokes aside, nginx-controller was setting header Strict-Transport-Security after the first HTTPS call (socket.io polling in my case). This header forces the browser to use TLS for the next requests. You can read more about this header here https://developer.mozilla.org/it/docs/Web/HTTP/Headers/Strict-Transport-Security
What I did is to disable the option adding the entry hsts: false on the ingress-controller's ConfigMap object.
You can find more here https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#hsts
Hope this can help you :)

There is another solution.
If you want to disable HSTS just make the max-age zero. like this!!
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($scheme = https) {
add_header Strict-Transport-Security "max-age=0;";
}
link : https://justin-g.tistory.com/176

Related

Kubernetes ingress hsts not enabled

my current ingress configuration is:
apiVersion: "networking.k8s.io/v1"
kind: "Ingress"
metadata:
name: "app-ingress"
annotations:
kubernetes.io/ingress.global-static-ip-name: "app-external-ip"
kubernetes.io/ingress.class: "gce"
spec:
tls:
- hosts:
- "example.app"
secretName: "app-tls"
rules:
- host: "example.app"
http:
paths:
- path: "/"
pathType: "Prefix"
backend:
service:
name: "app-service"
port:
number: 80
now i struggle with not HSTS enabled. I can enter example.app with http and https protocol, but i want to strict it to https only. I tried:
using nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - still http available
using kubernetes.io/ingress.allow-http: "false" - creates google managed certificate (im using self signed one app-tls) which makes ssl cert error in browser.
I'm pretty sure second one should be the option and i'm doing something wrong or misconfigure something.
Your ingress class is GCE and might be using the GCE ingress so Nginx annotation should not work.
So you have to create the
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: my-frontend-config
spec:
redirectToHttps:
enabled: true
responseCodeName: MOVED_PERMANENTLY_DEFAULT
Read more at : Doc ref

Nginx Ingress path rewriting does not forward to specified endpoint in Kubernetes Cluster

In our Kubernetes Cluster we have a micro frontend, which is accessable under image-self-service:8080 without any additional path. To be able to use it in a bigger application I want to use an Nginx-Ingress to reroute from url-to-site/profile to image-self-service:8080/.
I have found and read this SO post, thats basically asking the same thing:
Remove routing path from Kubernetes ingress and the linked documentation here:
https://github.com/kubernetes/ingress-nginx/blob/main/docs/examples/rewrite/README.md
which resulted in me using a .yaml for my Ingress that looks like this: (sensitive Information removed)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS, DELETE"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,X-LANG,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Api-Key,X-Device-Id,Access-Control-Allow-Origin"
nginx.ingress.kubernetes.io/rewrite-target: /
name: intranet-backend-ingress
namespace: intranet
spec:
rules:
- host: xxx-test.xxx.xxx
http:
paths:
- backend:
service:
name: image-self-service
port:
number: 8080
path: /profile(/|$)(.*)
pathType: Prefix
- backend:
service:
name: intranet-ui
port:
number: 8080
path: /
pathType: Prefix
...
For readability I also removed other endpoints which are more specific as I don't think those interfere.
I have tried using nginx.ingress.kubernetes.io/rewrite-target: / and nginx.ingress.kubernetes.io/rewrite-target: /$2
If I remove the rewrite-target and add a specific path, the forwarding works but with the additional path, so it results in a 404 from the underlying webservice. The Response I get using the rewriting is simply: 404 page not found which I believe to be an Ingress message.

kubernetes ingress returns incorrect mimetype on rewrite-target

I am having a problems with content response from a k8s version: 1.20.15, the ingress redirects to 2 applications based on the same domain (domains bellow are hypothetical). One service being an API and the other a website.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTP
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
labels:
app.kubernetes.io/name: frontend-explorer
name: frontend-explorer
spec:
rules:
- host: dev-explorer.test.org
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: frontend-explorer-svc
port:
number: 8081
- path: /api/(.*)
backend:
service:
name: backend-explorer-svc
port:
number: 3000
A request like dev-explorer.test.org/api/settings will be forward to the backend-explorer-svc and its url will become dev-explorer.test.org/, to the backend service
The services seem to working without any problems, but when accessing https://dev-explorer.test.org, there are errors like:
Loading module from “https://dev-explorer.test.org/main-es2015.3c58a0782b71050b1782.js”
was blocked because of a disallowed MIME type (“text/html”).
You can use a curl to fetch the content, but the ingress responds with
content-type: text/html instead of content-type: application/js, forcing the browser to block the website
Not certain if this is a problem on the ingress, or the JS code it self. Any ideas on how to get the correct content-type ?
Somehow the ingress was responding with content-type: text/html as if it was dealing with a pre-flight CORS request The solution was to disable CORS on ingress and configure it on the app.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
...
nginx.ingress.kubernetes.io/enable-cors: "false"
...

Kubernetes ingress-nginx not returning http response header

im encountering an issue whereby ingress-nginx(reverse proxy) is not returning http response header (ETag) from application container.
It works fine without ingress.
Missing http response header
Any help will be greatly appreciated.
The following is a snippet of Ingress yaml file
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ng-api-ngress
namespace: ng-prod
labels:
app: numbergenerator
annotations:
#nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: etag
nginx.ingress.kubernetes.io/cors-expose-headers: etag
#nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
spec:
rules:
- host: kubernetes.docker.internal.api
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: ng-backend
port:
number: 80
You can add this Nginx ingress annotation :
nginx.ingress.kubernetes.io/server-snippet: |
etag on;
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "server: hide";
if Gzip is enabled Nginx ingress won't add or pass etag.
As much as i know etag wont generated by Nginx in reverse proxy configuration however if require you can generate and manage from backend code.

Kubernetes Ingress Gateway for Response Content Manipulation

In our Kubernetes Cluster, We have a requirement to do a string replace in our Response body. Is there such a thing in Istio for response content modification. I could only find header manipulation.
Can Nginx Ingress Controller do this?
The respone contains html content with hrefs as: <>"/static/myimages/logo.png"<>
We would like to modify this response to prefix it with <>"/myapp/static/myimages/logo.png"<>
Does anyone have a recommendation for a gateway that can do this content rewrite.
Do you have samples to share?
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: resource-manager
spec:
hosts:
- "*"
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /myapp/
rewrite:
uri: "/"
route:
- destination:
host: myapp.voting.svc.cluster.local
port:
number: 9099
headers:
response:
add:
foo: bar
I started looking at other Ingress Controllers and found that NGINX-Ingress can do response manipulation. Here is an ingress route I setup which does content manipulation. Sharing that here:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app1-ingress
namespace: app1
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
sub_filter '<title>My title' '<title>My updated title'; #This changes title that Chrome Shows on Top
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- backend:
serviceName: app1
servicePort: 8080
path: /app1/(.*)
AFAIK, istio does not offer body modification by default. It might not even be possible with custom envoy filters.