Validating client (non-istio) certificate at the Ingress gateway in my AKS cluster - ssl

I have a scenario where an external app (not on Istio) is calling our services to get some data. Client sends in it's certificate in the WebRequestHandler that we validate as a way to authenticate the client. Can this be done at the ingress-gateway level?
Please note that I am also terminating the TLS traffic at the gateway and forwarding the request to the corresponding services on different pods based on http url-regex matching. I am also okay to validate the certificate in my service's code given it reaches the service as it is (excuse me for sounding naive here, I am very new to this).
Thank you!

If you want mutual TLS between an external service and Istio's Ingress Gateway then that's possible and is documented here: https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/

Related

Istio Service Mesh TLS Config

I am trying to convert an Istio service mesh running on k8s from http to https but stumbled upon many problems. I don't really understand what are all the steps required to do that.
As I know, there are 2 kinds of traffic that requires TLS in a mesh:
between internal services: scramming through Istio docs let me know that Istio will somehow automatically configure mTLS between services so all of them will communicate securely without any extra configuration. However, I still don't understand deeply how they implement this mTLS. How does it differ from normal TLS and what is mTLS role in the other kind of traffic (client outside to service inside)?
from client outside to a service inside: this is where I don't know what to do. I know that in order for a service to have TLS it needs TLS certificate by a trusted CA. However, as the outer client will not talk directly to the service inside but only through the Istio ingress gateway. Do I need to provide cert for every service or only the ingress gateway? All of my services are now exposing port 80 for HTTP. Do I need to convert all of them to port 443 and HTTPS or just the ingress gateway is enough?
Regarding the certificates, if I just use self-signing certs for now, can I just create cert and key with openssl and create secrets from it (maybe sync between namespaces with kubed), then all services use the same cert and key? Everywhere suggests me to use cert-manager. However, I don't know if it is worth the effort?
I would be really thankful if anyone can explain with some illustrations.
In general, if you need a good explanation of the issues related to Istio (also with pictures), I recommend that you check the documentation. You can find around 540 topics related to TLS in Istio.
Istio is a very well documented service. Here you can find more information about Understanding TLS Configuration. You can also find good article about Mutual TLS Migration.
However I still don't understand deeply how they implement this mTLS, how does it differ from normal TLS and what is mTLS role in the other kind of traffic (client outside to service inside).
Mutual TLS, or mTLS for short, is a method for mutual authentication. mTLS ensures that the parties at each end of a network connection are who they claim to be by verifying that they both have the correct private key. The information within their respective TLS certificates provides additional verification. You can read more about it here. Additionally yo can also see page about HTTP Traffic (mTLS is required for this case).
All of my services are now exposing port 80 for HTTP. Do I need to convert all of them to port 443 and HTTPS or just the ingress gateway is enough?
It is possible to create Ingress Gateway without TLS Termination:
The Securing Gateways with HTTPS task describes how to configure HTTPS ingress access to an HTTP service. This example describes how to configure HTTPS ingress access to an HTTPS service, i.e., configure an ingress gateway to perform SNI passthrough, instead of TLS termination on incoming requests.
EDIT (added more explanation and documentation links):
Service mesh uses a proxy to intercept all your network traffic, allowing a broad set of application-aware features based on configuration you set.
Istio securely provisions strong identities to every workload with X.509 certificates. Istio agents, running alongside each Envoy proxy, work together with istiod to automate key and certificate rotation at scale. The following diagram shows the identity provisioning flow.
Peer authentication: used for service-to-service authentication to verify the client making the connection. Istio offers mutual TLS as a full stack solution for transport authentication, which can be enabled without requiring service code changes.
Peer authentication modes that are supported: Permissive, Strict, and Disable.
In order to answer this question:
All of my services are now exposing port 80 for HTTP. Do I need to convert all of them to port 443 and HTTPS or just the ingress gateway is enough?
fully we could have informed the customer that using Istio Gateway can expose services from Istio service mesh to the outside using plain HTTP, with TLS termination or in PASSTHROUGH TLS mode. Incoming TLS termination could be improved (using TLS certificate approved by a trusted CA or using cert-manger with Istio Gateway). You can read more about this topic here.

Securing Kubernetes Service with TLS

I have an application that is internal and exposed only to other application on the cluster by a service with cluster IP. Other services are accessing this application via it's DNS (serviceName-namespace.svc.cluster.local). This application handles sensitive data, so although all the communication is inside the cluster I would like to use TLS to secure the communications to this application.
My question is - how can I enable TLS on a service? Is there something already exist or should I handle it on the application code? Also, is there already a CA I can use on the cluster that can sign certificates for .svc.cluster.local?
To clarify, I know I can use ingress for this purpose. The only problem is keeping this service internal only - so only services inside the cluster will be able to access it.
Thanks,
Omer
I just found that Kubernetes API can be used to generate a certificate that will be trusted by all the pods running on the cluster. This option might be simpler than the alternatives. You can find the documentation here, including full flow of generating a certificate and using it.
Following #vonc comments from bellow, I think I have a solution:
Purchase a public valid domain for this service (e.g. something.mycompany.com).
Use CoreDNS to add override rule so all requests to something.mycompany.com will go to something-namesapce.svc.cluster.local, as the service is not exposed externally (this can be done also with normal A record for my use case).
Use Nginx or something else to handle TLS with the certificate for something.mycompany.com.
This sounds pretty complicated but might work. What do you think?
Check if the tutorial "Secure Kubernetes Services with Ingress, TLS and LetsEncrypt" could apply to you:
Ingress can be backed by different implementations through the use of different Ingress Controllers. The most popular of these is the Nginx Ingress Controller, however there are other options available such as Traefik, Rancher, HAProxy, etc. Each controller should support a basic configuration, but can even expose other features (e.g. rewrite rules, auth modes) via annotations.
Give it a domain name and enable TLS. LetsEncrypt is a free TLS certificate authority, and using the kube-lego controller we can automatically request and renew LetsEncrypt certificates for public domain names, simply by adding a few lines to our Ingress definition!
In order for this to work correctly, a public domain name is required and should have an A record pointing to the external IP of the Nginx service.
For limiting to inside the cluster domain though (svc.cluster.local), you might need CoreDNS.
On Google Cloud you can make load balancer service internal, like this:
annotations = {
"cloud.google.com/load-balancer-type" = "Internal"
}

When we create SSL enabled Service, do we have to hand out certificates to each client?

One of my teammate just enabled SSL on one of the service that we are using and I had to install a Certificate that he gave me to each of the client machines who intend to consume that service. Now, I am not very well-versed when it comes to SSL security and that raised a question in my mind that
WHENEVER we create a SSl enabled service, do we have to hand out certificate to all the clients
Is there any kind of configuration using which we create an SSL enabled service without having to hand out certificate to all the clients?
IF it is possible then how secured that service be than the service which requires each client to install certificate on the machine?
Also, is there any easy to understand article on WCF SSL security?
Que : WHENEVER we create a SSl enabled service, do we have to hand out certificate to all the clients
Ans : No. For SSL enabled service one do not need to handout certificates to clients.
SSL certificate on server (in this case service) side gives confidence to clients that they are talking to legitimate server.
Clients needs certificates only in case of when service needs its clients to prove their identity using client certificate. With client certificate server (service) gets confidence that its sending data to legitimate clients.
Que : Is there any kind of configuration using which we create an SSL enabled service without having to hand out certificate to all the clients?
Ans : Certainly there is way with which you can make service enabled without requiring client certificate. Check SSL Settings option for website where service is hosted.
Que: IF it is possible then how secured that service be than the service which requires each client to install certificate on the machine?
Ans : Obliviously using SSL certificate doesn't stop any clients from consuming it. Any client who knows service endpoint can consume it. Client certificate is one way to authenticate clients. Only those clients who has valid client certificate will be able to consume service.
Que: Also, is there any easy to understand article on WCF SSL security?
Ans : Check out this link : https://msdn.microsoft.com/en-us/library/ff650862.aspx Its WCF regarding security as whole and not just SSL security.

WCF transport security with encryption

I have client server application which using WCF service with Transport security mode and NetTCP binding. I heard like Transport security is best for local intranet, not for internet. Now my scenario is I need to access WCF service over internet (from another country), but dont want to use Message security (cause it need to purchase and install certificate on server and each client). I want to use Transport security and also encrypt my data, so no one can hack it from internet.
So please someone guide me how can I encrypt my data with Transport security ?
Thanks
Transport is just SSL, so after the initial setup on the host and client sides, there's really nothing special to it. SSL will encrypt all the bytes starting at byte 0 and only the host that distributed the public key portion of the SSL cert will be able to decrypt the transmission since it and only it should have the private key part of the certificate.
SSL does present some potential problems if you have a load balancer or proxy fronting your service - i.e. if the proxy or LB server didn't begin the SSL transmission, it won't know what to do with the inbound message. But SSL encryption can be offloaded to a LB or proxy, so there are ways around that.
Here's a link to a stackoverflow question about SSL over WCF
Enable SSL for my WCF service

Exchange Data between two webroles over an Https endpoint

I have two webroles, without a WCF communication between them (this is intentionally)
Communication and authentification is one sided. Thus one webrole allways sends requests and the other one allways accepts requests.
To make sure said controller only accepts requests from the other webrole we want to use an ssl certificate.
i installed the certificate - and iam now able to make https requests to said controller.
however this is now active for the whole webrole.
In the final version users should be able to connect to the webrole over https with a global trust certificate for obvious security reasons.
This would require one azure https endpoint.
another endpoint then would be needed for our internal communication ( with our internal certificate).
But: How to restrict the controller which is used only for internal communication to its specified https request? (based on the interrnal certificate)
On the other hand how do i validate on the client side ( the webrole which makes the request) that said certificate was valid ?
Is there a better way to ensure a secure communication between two webroles? maybe using internal endpoints?
Thanks in advance
I think you should look at defining internal endpoints for the role-to-role communication. Something like this should work:
<NetworkTrafficRules>
<OnlyAllowTrafficTo>
<Destinations>
<RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
</Destinations>
<AllowAllTraffic/>
<WhenSource matches="AnyRule">
<FromRole roleName="WebRole1"/>
</WhenSource>
</OnlyAllowTrafficTo>
</NetworkTrafficRules>
If you're communicating between roles through internal endpoints you shouldn't really need to invoke HTTPS.