Project:
Deploy a staging API (Symfony) on a Kubernetes cluster on GCloud
With its services (MariaDB, RabbitMQ ...)
issue:
All Pods and Services start correctly
Access to the API from outside
is problematic:
I deploy the API via a LoadBalancer service and the API is accessible but always removes the header "Authorization" which makes the API unusable.
I deploy the API via a Nginx-Ingress, the set of links to the correct air (the Ingress is well linked to the service and the pods of the API), I receive an external IP, but when I access this IP, the site is inaccessible (requests are lost and do not arrive at the servers).
If you are using Apache with CGI/FastCGI, then you might get an error message about missing authorization headers. This is because Apache does not, by default, pass authorization headers to PHP.
The Fix
You need to edit your Apache site configuration to add a line to your vhost config <VirtualHost> directive.
<VirtualHost>
# ...
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# ...
</VirtualHost>
Related
I have set up Keycloak (docker container) on the GCP Compute Engine (VM). After setting the sslRequired=none, I'm able to access Keycloak over a public IP (e.g. http://33.44.55.66:8080) and manage the realm.
I have configured the GCP CLassic (HTTPS) Load Balancer and added two front-ends as described below. The Load Balancer forwards the request to the Keycloak instance on the VM.
HTTP: http://55.44.33.22/keycloak
HTTPS: https://my-domain.com/keycloak
In the browser, the HTTP URL works fine and I'm able to login to Keycloak and manage the realm. However, for the HTTPS URL, I get the below error
Mixed Content: The page at 'https://my-domain.com/auth/admin/master/console/' was loaded over HTTPS, but requested an insecure script 'http://my-domain.com/auth/js/keycloak.js?version=gyc8p'. This request has been blocked; the content must be served over HTTPS.
Note: I tried this suggestion, but it didn't work
Can anyone help with this, please?
I would never expose Keycloak on plain http protocol. Keyclok admin console itself is secured via OIDC protocol and OIDC requires to use https protocol. So default sslRequired=EXTERNAL is safe and smart configuration option from the vendor.
SSL offloading must be configured properly:
Keycloak container with PROXY_ADDRESS_FORWARDING=true
loadbalancer/reverse proxy (nginx, GCP Classic Load Balancer, AWS ALB, ...) with proper request header X-Forwarded-* configuration, so Keycloak container will know correct protocol, domain which is used for the users
I have a microservice architecture (implemented in Spring Boot) deployed in Google Kubernetes Engine. For this microservice architecture I have setup the following:
domain: comanddev.tk (free domain from Freenom)
a certificate for this domain
the following Ingress config:
The problem is that when I invoke an URL that I know it should be working https://comanddev.tk/customer-service/actuator/health, the response I get is ERR_TIMEDOUT. I checked Ingress Controller and I don't receive any request in the ingress although URL forwarding is set.
Update: I tried to set a "glue record" like in the following picture and the response I get is that the certificate is not valid (i have certificate for comanddev.tk not dev.comanddev.tk) and I get 401 after agreeing to access unsecure url.
I've digged a bit into this.
As I mentioned when you $ curl -IL http://comanddev.tk/customer-service/actuator/health you will received nginx ingress response.
As domain intercepts the request and redirect to the destination server I am not sure if there is point to use TLS.
I would suggest you to use nameserver instead of URL Forwarding, just use IP of your Ingress. In this option you would redirect request to your Ingress. When you are using Port Forwarding you are using Freenom redirection and I am not sure how its handled on their side.
We have some Restful services on a certain URI and we wanted to publish our services on the web to use them in our mobile app(written in java),
Our services was on a server which cannot handle too much requests at a same time and used it's proxy_pass functionality for this,
So I used Nginx on an intermediate server to control access to our REST server,
Now we want to protect our services by Oauth2 with Password or Client Credentials(as our mobile users should not login into our servers we cannot display any login page to them),
I setup a Keycloak server which is working and I could get token for my client. I'm going to give my auth/token URI to our mobile developers to get Oauth2 token at first and use it in their requests.
The problem is I don't know how to configure Nginx to authorize incoming REST requests with provided token in request header.
Should I config Keycloak to Handle requests and forward authorized ones to NGINX?
Thanks for your help
After some tries I found this solution:
1- you have to add njs module to nginx this is necessary, you have to compile it first(so in windows it will be much trouble, I tried mingw and stopped at a dependency called expect which is not written for mingw and it wasted a lot of time from me, actually I moved our IAM to ubuntu and compiling njs and nginx in there was done in few minutes!)
2- Introspection is the key subject here, and keycloak supports it, its URI is the same as token URI plus introspect, using Basic Authorization in header and token in body
3- nginx also supports introspection after adding njs module to it, which will let nginx support js code inculde inside config file, a great exaple is NGINX Demoes- Oauth2 Introspection OSS, just copy config file and oauth2.js file and its done. I added api directive at location tag in nginx config file to let callers know it is protected.
4- create one client for nginx in keycloak to do the introspection operation, it should be in confidential mode and Service Accounts should be enabled for it.
5- nginx should forward(proxy pass) auth/token request to IAM, so a location for this should be added in config file.
6- [for ubuntu] I have an error in nginx which tells me it cannot resolve localhost! and installing Bind 9 fixes this for me(another time wasting effort was done here).
7- So any one wants to use our service should request token first and then sends its request attached with token to nginx, nginx introspects token and if token was ok and {"active": true} were received forwards request to resource and passws reply to requester.
All done.
I want to remove Host header at ingress controller before sending the request to backend service. Will appreciate your insight.
My backend service is NOT expecting any Host header.
Thank you !
Google Cloud Platform is working on richer routing and transforms with HTTP(s) Load Balancer, used by Kubernetes Engine Ingress. No ETA is available.
In the meantime, you can use a proxy service in front of the application. See this answer on how to remove a header with nginx.
Kubernetes surfaces an API proxy, which allows querying the internal services via eg: https://myhost.com/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/
This is all well, and good. However, for security & compliance reasons, all of our services expose an HTTPS endpoint. Attempting to access them by going to https://myhost/api/v1/proxy/namespaces/default/services/myhttpsservice:3000/ results in
Error: 'read tcp 172.20.122.129:48830->100.96.29.113:3000: read: connection reset by peer'
Trying to reach: 'http://100.96.29.113:3000/'
Because the endpoint, 100.96.29.113:3000 is in fact https.
Is there any way to configure the proxy to apply SSL to specific service endpoints?
(Edit: If this is not currently possible, a relevant github issue link for tracking the feature request is also acceptable answer until it will be)
As documented at https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#manually-constructing-apiserver-proxy-urls, (and pointed out on slack), you can access services behind HTTPS by prefixing the servicename with "https:" ;
Using the example from above, correctly it would be: https://myhost/api/v1/proxy/namespaces/default/services/https:myhttpsservice:3000/