You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2023-07-04-build-a-multi-tenant-functions-platform.md
+78-3
Original file line number
Diff line number
Diff line change
@@ -443,11 +443,86 @@ spec:
443
443
444
444
In addition in both OpenFaaS Standard and OpenFaaS for Enterprises, `AllowPrivilegeEscalation` is set to false by default and cannot be changed on functions.
445
445
446
-
We also disable the EnableServiceLinks feature in Kubernetes which can expose information about other services and endpoints to functions.
446
+
**EnableServiceLinks**
447
447
448
-
Remember to create network policies with your Container Networking Interface (CNI) driver of choice to prevent functions from accessing the Kubernetes API or other services.
448
+
Functions have the EnableServiceLinks configuration set to `false`. Service Links were an early feature in Kubernetes used to help with service discovery by injecting environment variables of the name of services within the namespace.
449
449
450
-
Various CNI drivers and service meshes offer encryption of traffic between pods, so you may want to introduce this in addition to network policies. For an example of how to do this with Istio, see: [Learn how Istio can provide a service mesh for your functions](https://www.openfaas.com/blog/istio-functions/)
450
+
Why would you want to disable this? The values can be enumerated to discover other functions, or services deployed to the namespace.
451
+
452
+
Once disabled, there will still be an environment variable printed for the Kubernetes API server itself. This is hard-coded in the Go code for Kubernetes and presents absolutely no risk whatsoever. When some users see this, they mistakenly assume that `EnableServiceLinks` is not working or being set appropriately.
453
+
454
+
```
455
+
KUBERNETES_SERVICE_PORT=443
456
+
KUBERNETES_SERVICE_PORT_HTTPS=443
457
+
KUBERNETES_PORT=tcp://10.43.0.1:443
458
+
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
459
+
KUBERNETES_PORT_443_TCP_PROTO=tcp
460
+
KUBERNETES_PORT_443_TCP_PORT=443
461
+
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
462
+
KUBERNETES_SERVICE_HOST=10.43.0.1
463
+
```
464
+
465
+
If in double, you can do the following:
466
+
467
+
```bash
468
+
$ faas-cli store deploy env
469
+
470
+
$ kubectl get deploy/env -n openfaas-fn -o yaml|grep -i servicelink
471
+
enableServiceLinks: false
472
+
```
473
+
474
+
**The default Service account for Functions**
475
+
476
+
Functions can assume a named service account through the `com.openfaas.serviceaccount` annotation. This is useful for functions that need to access the Kubernetes API, or other resources within the cluster.
477
+
478
+
It is recommended that you restrict the annotations that are applied to functions for your tenants, so that they cannot use this environment variable, however bear in mind that this can only be used to select a pre-existing service account within the tenant's namespace, and there is no way for them to create one through the OpenFaaS APIs.
479
+
480
+
All functions will obtain a token from the default Service Account in the tenant namespace:
481
+
482
+
```sh
483
+
$ kubectl get serviceaccount -n openfaas-fn
484
+
NAME SECRETS AGE
485
+
default 0 235d
486
+
487
+
$ kubectl get serviceaccount -n dev
488
+
NAME SECRETS AGE
489
+
default 0 150d
490
+
```
491
+
492
+
The default service account has no privileges, and presents no risk to the cluster if a customer's code was to attempt to use it with the Kubernetes API server.
493
+
494
+
If you really wish, you can disable the automatic mounting of the service account.
495
+
496
+
After creating a namespace for a tenant, patch the Service Account:
Learn more: [Configure Service Accounts for Pods](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
504
+
505
+
**Cloud IAM and Metadata endpoints**
506
+
507
+
Certain cloud platforms such as AWS EC2 make a metadata endpoint available to all virtual machines, which can be used to retrieve temporary credentials for the cloud provider's API.
508
+
509
+
Unless you've explicitly granted privileges to the virtual machine, there should be empty, or very minimal read-only privileges granted to the instance.
510
+
511
+
That said, each cloud provider has its own security model, and you should review the documentation for the cloud provider you are using.
512
+
513
+
From the "Security Practices for Multi-Tenant SaaS Applications using Amazon EKS" documentation: [Restrict the use of host networking and block access to instance metadata service](https://docs.aws.amazon.com/whitepapers/latest/security-practices-multi-tenant-saas-applications-eks/restrict-the-use-of-host-networking-and-block-access-to-instance-metadata-service.html)
514
+
515
+
**Network policies to control access to the core services**
516
+
517
+
Remember to create [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) with your Container Networking Interface (CNI) driver of choice to prevent functions from accessing the Kubernetes API or services in other namespaces.
518
+
519
+
**Encrypting of traffic at the network level / mTLS**
520
+
521
+
Various CNI drivers and service meshes offer encryption of traffic between pods, so you may want to introduce this in addition to network policies.
522
+
523
+
Istio and Linkerd offer an alternative to encryption at the network level by injecting sidecars to each Pod and redirecting all traffic through a proxy using mutual TLS (mTLS). For an example of how to do this with Istio, see: [Learn how Istio can provide a service mesh for your functions](https://www.openfaas.com/blog/istio-functions/)
524
+
525
+
**Limit ranges and quotas for the namespace**
451
526
452
527
For the namespace, you may also wish to add a [Limit Range](https://kubernetes.io/docs/concepts/policy/limit-range/). A Limit Range may restrict a customer to using a maximum of 5 vCPU and 8GB of RAM for instance, across all replicas of his or her functions.
0 commit comments