We have some spring-boot containers which use oauth2 for authorisation
Unfortunately they were not compiled with jwks
Is it possible to use jwt in istio without configuring jwksUri or jwks?
According to istio documentation about JWT Rule the jwksUri and jwks are not required fields for jwtRule. However the issuer field is required.
Example configuration:
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
name: "jwt-example"
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
jwtRules:
- issuer: "testing#secure.istio.io"
This configuration should only check if the issuer of JWT matches.
Also from envoy documentation it is mentioned that JWT without verification is possible:
This message specifies a Jwt requirement. An empty message means JWT verification is not required.
Hope this helps.
As of Istio 1.5 this is not possible. Envoy will not add a Listener without a valid jwks
Related
Using istio with requestauth and a jwt issuer, but currently need to exclude certain paths traffic to the sidecar from actually validating any incoming jwt headers, is that possible? else istio tries to validate the jwt header ( even if not in issuerurl ) it receives.
added authpolicy to ignore those paths but the sidecar still decodes incoming authorization headers and validates them with my issuer.
Yes, this is possible with an AuthorizationPolicy that looks like this:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: my-auth-policy
spec:
rules:
- from:
- source:
requestPrincipals: ["*"]
- to:
- operation:
paths: ["/insecure"]
This authz policy defines two rules. The first is for all authenticated request principals to access everything. The second rule is for any source to access the /insecure path.
With this authz policy, an unauthenticated request can successfully reach the /insecure route, and only that one.
I successfully deployed a simple Voila dashboard using Google Cloud Run for Anthos. However, since I created the deployment using a GitLab CI pipeline, by default the service was assigned a long and obscure domain name (e.g. http://sudoku.dashboards-19751688-sudoku.k8s.proteinsolver.org/).
I followed the instructions in mapping custom domains to map a shorter custom domain to the service described above (e.g http://sudoku.k8s.proteinsolver.org). However, while the static assets load fine from this new custom domain, the interactive dashboard does not load, and the javascript console is populated with errors:
default.js:64 WebSocket connection to 'wss://sudoku.k8s.proteinsolver.org/api/kernels/5bcab8b9-11d5-4de0-8a64-399e35258aa1/channels?session_id=7a0eed38-77bb-40e8-ad77-d05632b5fa1b' failed: Error during WebSocket handshake: Unexpected response code: 503
_createSocket # scheduler.production.min.js:10
[...]
Is there a way to get web sockets to work with custom domains? Am I doing something wrong?
TLDR, the following yaml needs to be applied to make websocket work:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: allowconnect-cluser-local-gateway
namespace: gke-system
spec:
workloadSelector:
labels:
app: cluster-local-gateway
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
"#type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
http2_protocol_options:
allow_connect: true
Here is the explanation.
For the custom domain feature, the request path is
client ---> istio-ingress envoy pods ---> cluster-local-gateway envoy pods ---> user's application.
Specifically for websocket request, it needs cluster-local-gateway envoy pods to support extended CONNECT feature.
The EnvoyFilter yaml enables the extended CONNECT feature by setting allow_connect to true within the cluster-local-gateway pods.
I tried it by myself, and it works for me.
I don't know anything about your GitLab CI pipeline. By default, Knative (Cloud Run for Anthos) assigns external domain names like {name}.{namespace}.example.com where example.com can be customized based on your domain.
You can find this domain at Cloud Console or kubectl get ksvc.
First try if this domain works correctly with websockets. If so, indeed it's a "custom domain" issue. (If you are not sure, please edit your title/question to not to mention "custom domains".)
Also, you need to explicitly mark your container port as h2c on Knative for websockets to work. See ports section below, specifically name: h2c:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: hello
spec:
template:
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
ports:
- name: h2c
containerPort: 8080
I also see that the response code to your requests is HTTP 503, likely indicating a server error. Please check your application’s logs.
I've got a use case of an application that needs to authenticate with mTLS to hundreds of different destination servers outside of the mesh with a different client certificate. I thought offloading this procedure form the app to Istio is that even possible?
Yes it is possible.
You can follow this guide to configure mutual TLS orgination for egress traffic.
Then for each destination modify the DestinationRule to use different certificate like in this example:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: db-mtls
spec:
host: mydbserver.prod.svc.cluster.local
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/myclientcert.pem
privateKey: /etc/certs/client_private_key.pem
caCertificates: /etc/certs/rootcacerts.pem
Hope it helps.
I configured Istio Ingress Gateway to accept my URLs (using https) like microservices.myexample.com, grafana.myexample.com and so on.
Everything is working but all the urls are public.
Beacause of that I was asked to configure ingress gateway to protect urls inside microservices.myexample.com (Grafana has a login page). The idea is allow acess only if the request contains a token inside the header.
But when I applied this yml file all the URLs are blocked and they require the header including grafana.myexample.com:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ingress
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
rules:
- from: []
to:
- operation:
#paths: ["/customers*"] # I also tried with paths. Every microservice has a path after microservices.myexample.com
hosts: ["microservices.myexample.com"]
when:
- key: request.headers[token]
values: ["test123"]
We did it.
Just in case if someone is stuck at the same problem. The following code will be applied to all services in mynamespace. All the urls will require the token except the ones ending with /actuator/health
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: token-authorization
namespace: mynamespace
spec:
rules:
- to:
- operation:
paths: ["*/actuator/health"]
- to:
- operation:
paths: ["/*"]
when:
- key: request.headers[token]
values: ["test123"]
This will not work.
This is because in Your AuthorizationPolicy the hosts under operation: does not support HTTPS protocol.
According to Istio documentation:
Optional. A list of hosts, which matches to the “request.host” attribute.
If not set, any host is allowed. Must be used only with HTTP.
This is because the host header in HTTPS traffic is encrypted. More info about this is here.
The same goes for request header token.
We've designed our API to use Istio JWT authentication which is mandatory and at the same time we've used the CORS. The problem is our JS code will do ajax call and HTTP Option pre-flight request will be called without JWT Authorization header. Unfornately the pre-flight request will be blocked by Istio. How to solve it?
Not sure if I understood your question correctly, but I think Service Entry will solve this.
ServiceEntry enables adding additional entries into Istio’s internal service registry, so that auto-discovered services in the mesh can access/route to these manually specified services. A service entry describes the properties of a service (DNS name, VIPs, ports, protocols, endpoints). These services could be external to the mesh (e.g., web APIs) or mesh-internal services that are not part of the platform’s service registry (e.g., a set of VMs talking to services in Kubernetes).
Service Entry for your example might look like the following:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- api.foobar.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
resolution: DNS