HTTP is not disabled after adding allow-http configuration in Ingress - nginx

I have tried to block http and allow only https for the application which deployed in GCP. For the routing, using ningx ingress and tcp loadbalancer to route the traffic from client to the application.
Even after adding the below configuration in ingress yaml , still application serves http.
kubernetes.io/ingress.allow-http: "false"
Thanks in advance.

I reproduced your issue and solved it by deleting ingress resource and deploying new one with kubernetes.io/ingress.allow-http: "false" annotation. According to GCP docs:
Note: For an existing Ingress, the HTTP load balancer resources are not deleted automatically on adding the
kubernetes.io/ingress.allow-http annotation with its value set to
false. A workaround for this is to delete the Ingress and recreate
it with the annotation added. Beginning with GKE version
1.16.4-gke.25, the HTTP load balancer resources are automatically deleted on updating an Ingress to disable HTTP load balancing.
So if you have GKE version prior to 1.16.4-gke.25 ingress resource has to be deleted and then new ingress has to be created with this annotation.

Related

How to disable http access to service using Kubernetes Nginx ingress controller?

I have a service providing an API that I want to only be accessible over https. I don't want http to redirect to https because that will expose credentials and the caller won't notice. Better to get an error response.
How to do I configure my ingress.yaml? Note that I want to maintain the default 308 redirect from http to https for other services in the same cluster.
Thanks.
In the documentation: you can read the following sentence about HTTPS enforcement through redirect:
By default the controller redirects (308) to HTTPS if TLS is enabled for that ingress. If you want to disable this behavior globally, you can use ssl-redirect: "false" in the NGINX ConfigMap.
To configure this feature for specific ingress resources, you can use the nginx.ingress.kubernetes.io/ssl-redirect: "false" annotation in the particular resource.
You can also create two separate configurations: one with http and https and the other one only for http.
Using kubernetes.io/ingress.class annotation you can choose the ingress controller to be used.
This mechanism also provides users the ability to run multiple NGINX ingress controllers (e.g. one which serves public traffic, one which serves "internal" traffic).
See also this and this similar questions.

How can I use ingress to control the routing between two instances?

I have a service deployed on Kubernetes and it has url app.io (using ingress).
What if I need a user to every time go to app.io and:
if it's running okay with no errors, it redirects to the app.io (on k8s)
and if not running well or have an error, it would redirect on a backup service on Heroku for example with url backup.io.
How can I do that?
Thanks in advance
Fallback routing like you describe is not part of the Ingress standard. It only does routing based on incoming Host header and request path. It's possible some specific Ingress Controller supports this as a custom extension but I don't know of any that do.
I think you may need to put a L7 load balancer like HAproxy in front. Configure your backup location in backend pool, and HAProxy will take care of the rest.
You may want to configure ingress befault-backendto be some sort of fallback service. With most of the cases people tend to use that for some custom 404 but you might just direct it to another service, for example backup-io:
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: "/"
nginx.ingress.kubernetes.io/default-backend: backup-io
That's of course assuming you're using nginx controller. Kong has also fallback service instructions.

Nginx Ingress Controller with Nginx Reverse Proxy

I am a bit confused with the architecture of load-balancing K8s traffic with Nginx ingress controller.
I learned that an ingress controller is supposed to configure the load-balancer you're using according to ingress configurations.
So if I want to use Nginx ingress controller and I have a Physical server that is running Nginx that stands in front of my network, how can I make the ingress controller configure it?
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource. You must have an Ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect. Take a look at the example graph below:
Nginx Ingress Controller is using service of type LoadBalancer to get the traffic enter the controller and then to get rerouted to particular services.
I strongly suggest going through the official documentation in order to get a good understanding of the topic and see some examples of using it.
is the nginx ingress controller supposed to (or can) configure an
Nginx machine?
NGINX Ingress Controller works with both NGINX and NGINX Plus and supports the standard Ingress features - content-based routing and TLS/SSL termination.

How to fix catch-22 with GCLB and Wordpress returning 301

I have setup a Kubernetes cluster on GKE. Installed the stable/wordpress Helm chart. Added an Ingress with a SSL certificate. But now the Google load balancer reports that my service is unhealthy. This is caused by the Wordpress pod that returns a 301 on the health check because it wants to enforce HTTPS, which is good. But the Google load balancer refuses to send a x-forwarded-proto: https header. So the pod thinks the health check was done over http. How can I work around this?
I have tried to add an .htaccess which always returns 200 for the GoogleHC User-agent but this is not possible with the helm chart which overrides the .htaccess after start-up.
Also see: https://github.com/kubernetes/ingress-gce/issues/937 and https://github.com/helm/charts/issues/18779
WAY : 1
If you are using Kubernetes cluster on GKE then you can use ingress indirectly it will create the Loadbalancer indirectly.
You can add SSL certificate store it inside secret and apply to ingress. For SSL you can also choose another approach to install cert-manager on GKE.
If you want to setup nginx-ingress with cert-manager you can follow this guide also :
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nginx-ingress-with-cert-manager-on-digitalocean-kubernetes
WAY : 2
Edit the helm chart locally add the liveness & readinesss probe to deployment and it will check wordpress health checkup over http only.
Update :
To add x-forwarded-proto in ingress you can use this annotation
nginx.ingress.kubernetes.io/server-snippet: |
location /service {
proxy_set_header X-Forwarded-Proto https;
}
As the HTTPS load balancer terminates the client SSL/TLS session at the LB, you would need to configure HTTPS between the load balancer and your application (wordpress). Health checks use HTTP by default, to use HTTPS health checks with your backend services, the backend services would also require their own SSL/TLS certificate(See #4 of HTTP load balancing which HTTPS load balancing inherits). To make the backend certificates simpler to configure, you can use self-signed certificates, which do not interfere with any client <-> load balancer encryption as the client session is terminated at the LB.
You can of course use HTTP health checks (less configuring!) for your backend(s), this will not cause any client traffic encryption issues, as it only affects the health check and not the data being sent to your application.
Why do you need https between Load Balancer and Wordpress in the first place? Wouldn't it be enough to have https on Load Balancer frontend side(between LB and outside world)?
Do you have SSL termination done twice?
This is what I did when I was migrating my Wordpress site to GKE:
Removed all Wordpress plugins related to https/ssl/tls. Lukily for me it didn't even require any Db changes.
Added Google-managed certificate. With Google-managed certificates, it's very easy to add it. GKE even has a separate definition for a certificate. On top of that you just need to update your DNS records:
apiVersion: networking.gke.io/v1beta2
kind: ManagedCertificate
metadata:
name: my-certificate
namespace: prod
spec:
domains:
#Wildcard domains are not supported(https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs).
- example.com
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: prod-ingress
namespace: prod
annotations:
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.global-static-ip-name: load-balancer-ip
networking.gke.io/managed-certificates: my-certificate
I realize you have helm on top of it, but there's always a way to edit it/or configs/params.

Using a Kubernete Ingress on GCE to Redirect/Force TLS

Am I currently forced to use an additional webserver (nginx) to redirect all Kubernete Ingress traffic to https when hosting on GCE?
I'm looking to deploy a Golang application into the wild. As a learning experiment, I thought I would use GCE to host & K8s to deploy/scale. I have deployments and services all working as expected returning traffic and created certs with Lets Encrypt for TLS termination.
I am at the point of implementing an Ingress now as Service LoadBalancers seem to be deprecated. At this stage I am using a static IP for the Ingress to use for backend requests - as follows
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: "kubernetes-ingress"
ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- secretName: web-ssl
backend:
serviceName: web
servicePort: 80
Of course I want all http traffic to go through https/TLS. Assigning the ingress.kubernetes.io/ssl-redirect: "true" entry has made no difference. As a sneaky attempt, I thought I may be able to alter the servicePort to 443. As my service is accepting requests on both 80/443 ports, valid responses were returned, but http was not forced to https.
At this stage I am guessing I will need to "bite the bullet" and create an nginx Ingress Controller. This will also help to update certs using Lego along with creating another abstraction should I need more service points.
But before I did, I just wanted to check first if there is no other way? Any help appreciated thanks.
An Ingress controller is needed to implement the Ingress manifest. Without it, installing the Ingress manifest doesn't do anything. Afaik, deploying an Ingress is the best way for HTTP redirection.
You can make the ingress redirect HTTP traffic to HTTPS. Check out this tutorial for TLS with traefik, and this tutorial for TLS with nginx.

Resources