Which channels should use SSL in a Kubernetes cluster? - ssl

I have the following Kubernetes setup (forgive the poor ASCII art):
Azure SQL DB_1 > deployment_1 > service_1 \
Azure SQL DB_2 > deployment_2 > service_2 > -> nginx_ingress
Azure SQL DB_N > deployment_N > service_N /
The DBs are outside the Kubernetes cluster. They are exposed through a Private Endpoint to the VNet the Kubernetes cluster is on. They obtain a private IP address inside that VNet, and are otherwise unreachable.
Every deployment is a different microservice. Each one has a service in front of it to handle communication. In turn, all these services can be reached through the NGINX ingress. All services are configured as ClusterIPs, so they cannot be reached from outside the cluster. The only entrypoint from outside the VNet is through the ingress.
My question is, which of these channels should be secured with SSL, and where is it not worth it (for example, because of impact on performance)?
The Ingress of course, will have SSL in front of it. This is a given.
Should there be SSL between the ingress and the services?
Should there be SSL between the services and the microservices behind them?
The DB itself seems to already do encrypted connections automatically. Is there any reason why this would be unnecessary, or conversely, can/should it be made more secure somehow?
Of course, I understand that more encryption is usually A Good Thing. But for example, is it worth generating and keeping track of certificates for comms between the microservices and the services, since these are internal to the cluster and cannot be reached in any other way?
Thank you for any information / examples / experiences you can provide!

simple is to terminate the TLS at ingress layer only, as it is inside AKS ( I am assuming ) and AKS' VNET is secure, so no direct exposure to external world and only ingress nginx controller will be exposed to external world.
The DB based communication , if you are using SQL server , then is already under the hood of TLS.
Apart from this you can define CORS too, wherever required.

Related

Kubernetes application authentication

Maybe this is a dumb question, but I really don't know if I have to secure applications with tokens etc. within a kubernetes cluster.
So for example I make a grpc-call from a client within the cluster to a server within the cluster.
I thought this should be secure without authenticating the client with a token or something like that, because (if I understood it right) kubernetes pods and services work within a VPN which won't be exposed as long as it's not told to.
But is this really secure, should I somehow build an authorization system within my cluster?
Also how can I use a service to load balance the grpc-calls over the server pods without exposing the server outside the cluster?
If you have a service, it already has built-in load balancer when you have more than one replica out of the box.
Also Kubernetes traffic is internal within the cluster out of the box, unless you explicitly expose traffic using LoadBalancer, Ingress or NodePort.
Does it mean traffic is safe? No.
By default, everything is allowed within Kubernetes cluster so every service can reach every service or pod in StatefulSet apps.
You can use NetworkPolicy to allow traffic from one service to another service and nothing else. That would increase security.
Does it mean traffic is safe now? It depends.
Authentication would add an additional security layer in case container is hacked. There could be more scenarios, but I can't think of for now.
So internal authentication is usually used to improve security in production systems.
I hope it answers the question.

Certificates per cluster or certificate per service provider?

We have service provider that takes a request and creates cluster of elastic search.
What is the best practice to issue ssl certificate ?
1. Should we issue certificate per cluster ?
2. or One cluster for my service provider should be enough which will be used to access clusters ?
I am assuming issuing new certificate while creating cluster is better.
Please provide me the input.
Also, inside the cluster, do I really need to enable ssl so that pods talk to each other passing certificate ?
Yes, you should definitely use TLS to encrypt network traffic to, from, and within your Elasticsearch clusters run on shared and managed K8S version (GKE).
Additionally I would opt for a maximum separation of customer spaces with:
Kubernetes namespaces
namespaced serviceaccounts/rolebindings
and even PD-SSD based volumes with customer supplied encryption keys
I'm not sure if you are aware of existence of 'Elastic Cloud on Kubernetes' (ECK) - it applies Kubernetes Operator pattern for running and operating Elasticsearch clusters on your own K8S cluster in GCP. Treat it also like a collection of a best practices for running Elasticsearch cluster in most secure way, here is a quick start tutorial.

Can I use kafka over Internet?

Is kafka suitable for Internet-use?
More precisely, what I want is to expose kafka topics as "public interface", then external consumers (or producers) can connect to it. Is it possible?
I hear there are problems if I want to use the cluster in both internal and external networks, because it is then hard to configure advertised.host.name. Is that true?
And do I have to expose zookeeper as well? I think the new consumer/producer api no longer need that.
Kafka's wire protocol is TCP-based and works fine over the public internet. In the latest versions of Kafka you can configure multiple interfaces for both internal and external traffic. Examples of Kafka over the internet in production include several Kafka-as-a-Service offerings from Heroku, IBM MessageHub, and Confluent Cloud.
You do not need to expose zookeeper if the Kafka clients use the new consumer API.
You may also choose to expose a REST Proxy such as the open source Confluent REST Proxy as a more client firewall friendly interface since it runs over HTTP(S) and will not be blocked by most corporate or personal firewalls.
I would personally not expose the Kafka server directly to clients via TCP for these reasons, only to name a few:
If a bad client opens too many connections this may affect the stability of the Kafka platform and may affects other clients too
Too many open files on the Kafka server, HW/SW settings and OS tuning is needed to limit uncontrolled clients
If you need to add a Kafka server to increase scalability, you may need to go through a lot of low level configuration (firewall, IPs visibility, certificates, etc.) on both client and server side. Other product address these problems using gateways or proxies: Coherence uses extend proxy clients, tibco EMS uses routed destinations, other SW (many JMS servers) use Store&Forward mechanisms, etc.
Maintenance of the Kafka nodes, in case of clients attached to the Kafka servers, will have to consider also the needs of clients and the SLA (service level aggreement) that have been defined with the client (ex. 24*7*365)
If you use Kafka also as a back end service, a multi layered architecture should be taken into consideration: FE gateways and BE services, etc.
Other considerations require to understand what exacly you consider to be an external (over the internet) consumer/producer in your system. Is it a component of your system that needs to access the Kafka servers? Are they internal or external to your organization, etc.
...
Naturally all these considerations can be correctly addressed also using a TCP direct connection to the Kafka servers, but I would personally use a different solution.
HTTP proxies
Or at least I would use a dedicated FE Kafka server (or couple of servers for HA) dedicated for each client that forward the messages to the main Kafka group of servers
It is possible to expose Kafka over the internet (in fact, that's how managed Kafka providers such as Aiven and Instaclustr make their money) but you have to ensure that it is adequately secured. At minimum:
ZooKeeper nodes should reside in a private subnet and not be routable from outside. ZK's security is inadequate and, at any rate, it is no longer required to bootstrap Kafka clients with ZK address(es).
Limit access to the brokers at the network level. If all your clients connect from a trusted network, then set appropriate firewall rules. If in AWS, use VPC peering or Direct Connect if you are connecting cloud-to-cloud or cloud-to-ground. If most of your clients are on a trusted network but a relative minority are not, force the latter to go via a VPN tunnel. Finally, if you want to allow connectivity from arbitrary locations, you'll just have to allow * on port 9092 (or whichever port you configure the brokers to listen on); just make sure that the other ports are closed.
Enable TLS (SSL) for client-broker connections. This is easily configured with a self-signed CA. Depending on how you expose your listeners, you may need to disable SSL hostname verification on the client. (The certificate chain of trust breaks if the advertised host names don't match the certificate's common name.) The clients will need the CA certificate installed. (Same CA that signed the brokers' certs.)
Optionally, you may enable mutual TLS authentication; however, this is logistically more taxing, as it requires each client to have its own private key that is signed by a CA trusted by the broker.
Use SASL to authenticate the client to the broker and create individual users for each application and each person that is expected to access the cluster.
Issue minimally-sufficient cluster- and topic-level access privileges in the ACLs for each user, following the Principle of Least Privilege (PoLP).
One other thing to bear in mind: Not all tooling supports SASL/SSL connectivity and some tools actually require a connection to ZooKeeper nodes (which will not be reachable in the above setup). Make sure any tooling you rely on uses the 'new' style of connectivity directly to the Kafka brokers and does not require a Zookeeper connection.
Beyond configuring client TLS, brokers have to have public IPs which we try to avoid. Normally for other services we hide everything behind load balancers. Would this be possible with kafka?
I'm not sure the Confluent REST proxy hosted on a public server is a real option when you need the high performance batching of the java producer client.

Is there a real need to adopt ssl transport layer in a microservice architecture for internal lan-only Service to Service communication?

In a scenario where there are thousands of webservices are there reasons to use also a signed cert for each microservice or it's just going to add overhead? Services communicate via VPC sitting behind a firewall while Public endpoints are behind a nginx public facing a valid CA cert.
Services are on multiple servers on aws.
From my limited experience, I believe that it is overkill. If an attacker has access to listen in or interact with your internal network then there are most likely other issues which you should be contending with.
This article on auth0.com explains the use of SSL only on connections to the external client. I also share this view and believe implementing SSL at an individual service level would get extremely difficult unless you where running some form of proxy such as HAProxy or Nginx on each individual host which is sub-optimal, especially if you're using a form of managed cluster like Kubernetes or Docker Swarm.
My current thoughts are its fine to run SSL just for your edge services, ensure you lock down your AWS network using something like Scout2 and run unencrypted for inter-service communication on your lan.
unless all intranet in the cloud are fully VLAN-configured and isolated, is it possible for other hosts that you don't own that are on the same LAN to steal your password by running a simple tcpdump? if that's the case, we need ssl or other encryption internally on the cloud too.

SSL protocol on AWS architecture?

Here's my AWS architecture
1 Load Balancer
2 Web/Application server
1 DB server
If client - and my LB communicates with SSL(HTTPS) protocol,
would it be safe with internal LB-WEB/APP-DB server communicates with HTTP? Or should they communicate with same SSL certificates internally too?
You certainly can terminate SSL on your web instances, but it is probably much easier to have SSL on your load balancer, and communicate over http between ELB and web instance.
This assumes you're running inside of a VPC of course.
As you scale having SSL terminated at your LB and internal traffic non-SSL will save you a great deal of overhead.
Using Cloudfront
Another option is to create a Cloudfront distribution in-front of your ELB, where your SSL connection is terminated at the nearest Edge Location. From Cloudfront to LLB(In a particular region) it uses AWS WAN so if you can live with that level of security, you can get better performance also with static content cached and delivered from Edge location. Another advantage is that you can get free SSL certificates from AWS for Cloudfront regardless of your ELB region.
For the DB Server, normally it kept inside the same VPN as the WebServer and not allowed for external access. So I don't see a great deal in putting a separate certificate for DB access within the private network unless you have specific regulatory requirements.