mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 14:47:17 -07:00
Translated ['src/pentesting-cloud/kubernetes-security/exposing-services-
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Ci sono **diversi modi per esporre i services** in Kubernetes così che sia gli endpoint **internal** sia quelli **external** possano accedervi. Questa configurazione Kubernetes è piuttosto critica perché l'administrator potrebbe dare accesso a **attackers a services a cui non dovrebbero poter accedere**.
|
||||
Ci sono **diversi modi per esporre services** in Kubernetes così che sia gli endpoint **interni** che quelli **esterni** possano accedervi. Questa configurazione di Kubernetes è piuttosto critica perché l'amministratore potrebbe dare accesso a **attackers a services a cui non dovrebbero poter accedere**.
|
||||
|
||||
### Enumerazione Automatica
|
||||
### Automatic Enumeration
|
||||
|
||||
Prima di iniziare a enumerare i modi che K8s offre per esporre i services al pubblico, sappi che se puoi elencare namespaces, services e ingresses, puoi trovare tutto ciò che è esposto al pubblico con:
|
||||
Prima di iniziare a enumerare i modi che K8s offre per esporre services al pubblico, sappi che se puoi elencare namespaces, services e ingresses, puoi trovare tutto ciò che è esposto al pubblico con:
|
||||
```bash
|
||||
kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do
|
||||
echo "Namespace: $ns"
|
||||
@@ -20,17 +20,17 @@ done | grep -v "ClusterIP"
|
||||
```
|
||||
### ClusterIP
|
||||
|
||||
Un servizio **ClusterIP** è il **service** Kubernetes **predefinito**. Ti offre un **service interno** al tuo cluster che altre app all'interno del cluster possono raggiungere. **Non** c'è **accesso esterno**.
|
||||
Un **ClusterIP** service è il **default** Kubernetes **service**. Ti fornisce un **service inside** il tuo cluster che altre app all’interno del tuo cluster possono raggiungere. **Non** c’è **external access**.
|
||||
|
||||
Tuttavia, questo può essere accessibile usando il Kubernetes Proxy:
|
||||
Tuttavia, può essere accesso tramite il Kubernetes Proxy:
|
||||
```bash
|
||||
kubectl proxy --port=8080
|
||||
```
|
||||
Ora puoi navigare attraverso la Kubernetes API per accedere ai servizi usando questo schema:
|
||||
Ora puoi navigare attraverso il Kubernetes API per accedere ai servizi usando questo schema:
|
||||
|
||||
`http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/`
|
||||
|
||||
Per esempio, potresti usare il seguente URL:
|
||||
Per esempio, puoi usare il seguente URL:
|
||||
|
||||
`http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/`
|
||||
|
||||
@@ -50,7 +50,7 @@ port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
```
|
||||
_Questo metodo richiede di eseguire `kubectl` come **authenticated user**._
|
||||
_Questo metodo richiede di eseguire `kubectl` come un **authenticated user**._
|
||||
|
||||
Elenca tutti i ClusterIPs:
|
||||
```bash
|
||||
@@ -58,7 +58,7 @@ kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.nam
|
||||
```
|
||||
### NodePort
|
||||
|
||||
Quando viene utilizzato **NodePort**, una porta designata viene resa disponibile su tutti i Nodes (che rappresentano le Virtual Machines). Il **traffico** diretto a questa porta specifica viene quindi sistematicamente **instradato verso il service**. In genere, questo metodo non è raccomandato a causa dei suoi svantaggi.
|
||||
Quando viene utilizzato **NodePort**, una porta designata viene resa disponibile su tutti i Nodes (che rappresentano le Virtual Machines). Il **traffico** diretto a questa porta specifica viene quindi **instradato al service**. In genere, questo metodo non è consigliato a causa dei suoi svantaggi.
|
||||
|
||||
Elenca tutti i NodePorts:
|
||||
```bash
|
||||
@@ -81,13 +81,24 @@ targetPort: 80
|
||||
nodePort: 30036
|
||||
protocol: TCP
|
||||
```
|
||||
Se **non specifichi** il **nodePort** nel yaml (è la porta che verrà aperta), verrà usata una porta nell'**intervallo 30000–32767**.
|
||||
Se **non specifichi** il **nodePort** nel yaml (è la porta che verrà aperta) verrà usata una porta nell'**intervallo 30000–32767**.
|
||||
|
||||
Quando esamini i servizi NodePort o LoadBalancer, controlla anche i campi traffic-policy perché modificano quali nodi e backend sono utili da una determinata origine:
|
||||
```bash
|
||||
kubectl get services --all-namespaces \
|
||||
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,ETP:.spec.externalTrafficPolicy,ITP:.spec.internalTrafficPolicy,AFFINITY:.spec.sessionAffinity,DIST:.spec.trafficDistribution,NODEPORTS:.spec.ports[*].nodePort'
|
||||
```
|
||||
- `externalTrafficPolicy: Local` preserva l'indirizzo IP sorgente originale del client per il traffico NodePort/LoadBalancer e evita l'inoltro verso endpoint su altri nodi. Un nodo senza un endpoint locale pronto può scartare il traffico anche se il Service ha endpoint altrove.
|
||||
- `externalTrafficPolicy: Cluster` è il valore predefinito e può inoltrare tramite qualsiasi nodo, ma i log del backend possono vedere gli IP dei nodi invece dell'IP reale del client esterno.
|
||||
- `internalTrafficPolicy: Local` limita il traffico del Service in-cluster agli endpoint locali al nodo sorgente. Si tratta di locality routing, non di un boundary di autorizzazione.
|
||||
- `sessionAffinity: ClientIP` può far sì che test ripetuti da un client colpiscano lo stesso backend, nascondendo altri endpoint pronti durante i controlli manuali.
|
||||
- `trafficDistribution` e i topology hints di EndpointSlice possono preferire endpoint nello stesso zone o nello stesso nodo nei cluster più recenti; trattali come preferenze di routing e non come policy di sicurezza rigida.
|
||||
|
||||
### LoadBalancer
|
||||
|
||||
Espone il Service esternamente **usando il load balancer di un cloud provider**. Su GKE, questo avvierà un [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) che ti fornirà un singolo indirizzo IP che inoltrerà tutto il traffico al tuo service. Su AWS avvierà un Load Balancer.
|
||||
Espone il Service esternamente **usando il load balancer di un cloud provider**. Su GKE, questo avvierà un [Network Load Balancer](https://cloud.google.com/compute/docs/load-balancing/network/) che ti darà un singolo indirizzo IP che inoltrerà tutto il traffico al tuo service. In AWS avvierà un Load Balancer.
|
||||
|
||||
Devi pagare un LoadBalancer per ogni servizio esposto, e questo può essere costoso.
|
||||
Devi pagare per un LoadBalancer per ogni service esposto, e può essere costoso.
|
||||
|
||||
Elenca tutti i LoadBalancers:
|
||||
```bash
|
||||
@@ -96,15 +107,15 @@ kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.nam
|
||||
### External IPs
|
||||
|
||||
> [!TIP]
|
||||
> Gli External IPs sono esposti dai servizi di tipo Load Balancers e vengono generalmente usati quando viene utilizzato un external Cloud Provider Load Balancer.
|
||||
> External IPs sono esposti da servizi di tipo Load Balancers e sono generalmente usati quando viene utilizzato un external Cloud Provider Load Balancer.
|
||||
>
|
||||
> Per individuarli, controlla i load balancers con valori nel campo `EXTERNAL-IP`.
|
||||
> Per trovarli, controlla i load balancers con valori nel campo `EXTERNAL-IP`.
|
||||
|
||||
Il traffico che entra nel cluster con l'**external IP** (come **destination IP**), sulla porta del Service, verrà **instradato verso uno degli endpoint del Service**. `externalIPs` non sono gestiti da Kubernetes e sono responsabilità dell'amministratore del cluster.
|
||||
Il traffico che entra nel cluster con l'**external IP** (come **destination IP**), sulla porta del Service, verrà **instradato a uno degli endpoint del Service**. `externalIPs` non sono gestiti da Kubernetes e sono responsabilità dell'amministratore del cluster.
|
||||
|
||||
`externalIPs` è un campo sensibile per il route-control perché un utente che può impostarlo potrebbe rivendicare traffico per un indirizzo IP che il proprietario del Service non dovrebbe controllare se la rete circostante instrada quell'IP verso il cluster. Kubernetes ha annunciato la deprecazione e la rimozione pianificata di Service `externalIPs` in v1.36, quindi preferisci meccanismi di exposure gestiti dal controller come le integrazioni LoadBalancer o Gateway API dove possibile, e limita/autorizza questo campo con attenzione finché esiste.
|
||||
`externalIPs` è un campo sensibile di route-control perché un utente che può impostarlo potrebbe rivendicare traffico per un indirizzo IP che il proprietario del Service non dovrebbe controllare se la rete circostante instrada quell'IP verso il cluster. Kubernetes ha annunciato la deprecazione e la rimozione pianificata di Service `externalIPs` in v1.36, quindi preferisci meccanismi di esposizione gestiti dal controller come le integrazioni LoadBalancer o Gateway API dove possibile, e limita/consenti questo campo con attenzione finché esiste ancora.
|
||||
|
||||
Nella spec del Service, `externalIPs` può essere specificato insieme a qualsiasi `ServiceTypes`. Nell'esempio qui sotto, "`my-service`" può essere accessibile dai client su "`80.11.12.10:80`" (`externalIP:port`)
|
||||
Nella spec del Service, `externalIPs` può essere specificato insieme a qualsiasi `ServiceTypes`. Nell'esempio seguente, "`my-service`" può essere accessibile dai client su "`80.11.12.10:80`" (`externalIP:port`)
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -123,9 +134,9 @@ externalIPs:
|
||||
```
|
||||
### ExternalName
|
||||
|
||||
[**From the docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) I Service di tipo ExternalName **mappano un Service a un DNS name**, non a un tipico selector come `my-service` o `cassandra`. Questi Services si specificano con il parametro `spec.externalName`.
|
||||
[**Dai docs:**](https://kubernetes.io/docs/concepts/services-networking/service/#externalname) I Services di tipo ExternalName **mappano un Service a un nome DNS**, non a un tipico selector come `my-service` o `cassandra`. Definisci questi Services con il parametro `spec.externalName`.
|
||||
|
||||
Questa definizione di Service, per esempio, mappa il Service `my-service` nel namespace `prod` a `my.database.example.com`:
|
||||
Questa definizione di Service, ad esempio, mappa il Service `my-service` nel namespace `prod` a `my.database.example.com`:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -136,7 +147,7 @@ spec:
|
||||
type: ExternalName
|
||||
externalName: my.database.example.com
|
||||
```
|
||||
Quando si cerca l'host `my-service.prod.svc.cluster.local`, il DNS Service del cluster restituisce un record `CNAME` con il valore `my.database.example.com`. Accedere a `my-service` funziona allo stesso modo degli altri Services, ma con la differenza cruciale che **la redirection avviene a livello DNS** anziché tramite proxying o forwarding.
|
||||
Quando si cerca l'host `my-service.prod.svc.cluster.local`, il cluster DNS Service restituisce un record `CNAME` con il valore `my.database.example.com`. Accedere a `my-service` funziona allo stesso modo degli altri Services, ma con la differenza cruciale che **la redirezione avviene a livello DNS** invece che tramite proxying o forwarding.
|
||||
|
||||
Elenca tutti gli ExternalNames:
|
||||
```bash
|
||||
@@ -144,7 +155,7 @@ kubectl get services --all-namespaces | grep ExternalName
|
||||
```
|
||||
### EndpointSlices
|
||||
|
||||
Gli EndpointSlices mostrano gli indirizzi e le porte backend concrete verso cui un Service instrada attualmente il traffico. Sono particolarmente utili quando un Service non ha selector, quando le label non spiegano il percorso del traffico, o quando solo alcuni backend sono ready.
|
||||
Gli EndpointSlices mostrano gli indirizzi backend concreti e le porte verso cui un Service instrada attualmente il traffico. Sono particolarmente utili quando un Service non ha selector, quando le labels non spiegano il percorso del traffico, o quando solo alcuni backend sono ready.
|
||||
|
||||
Elenca gli EndpointSlices associati ai Services:
|
||||
```bash
|
||||
@@ -153,17 +164,17 @@ kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service-
|
||||
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service-name> \
|
||||
-o custom-columns='NAME:.metadata.name,ADDR:.endpoints[*].addresses,READY:.endpoints[*].conditions.ready,PORTS:.ports[*].port'
|
||||
```
|
||||
Quando esamini l’esposizione, confronta il Service selector con il `targetRef` dell’EndpointSlice, gli indirizzi degli endpoint, le condizioni di readiness e le porte. Un Service senza selector può essere associato a EndpointSlices gestiti manualmente e instradare il traffico verso destinazioni non-Pod o inattese.
|
||||
Durante la revisione dell’esposizione, confronta il selector del Service con `targetRef` dell’EndpointSlice, gli endpoint addresses, le readiness conditions e le ports. Un Service senza selector può essere associato a EndpointSlices gestiti manualmente e instradare il traffico verso destinazioni non-Pod o inaspettate.
|
||||
|
||||
### Ingress
|
||||
|
||||
A differenza di tutti gli esempi precedenti, **Ingress NON è un tipo di service**. Invece, si colloca **davanti a più services e funge da “smart router”** o punto di ingresso nel tuo cluster.
|
||||
A differenza di tutti gli esempi sopra, **Ingress NON è un tipo di service**. Invece, si posiziona **davanti a più services e agisce come un “smart router”** o entrypoint nel tuo cluster.
|
||||
|
||||
Puoi fare molte cose diverse con un Ingress, e ci sono **molti tipi di Ingress controllers che hanno capacità diverse**.
|
||||
|
||||
L’Ingress controller predefinito di GKE avvierà per te un [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/). Questo ti permetterà di fare sia routing basato sul path sia routing basato sul subdomain verso backend services. Per esempio, puoi inviare tutto ciò che arriva su foo.yourdomain.com al service foo, e tutto ciò che si trova sotto il path yourdomain.com/bar/ al service bar.
|
||||
L’ingress controller predefinito di GKE avvierà per te un [HTTP(S) Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/). Questo ti permetterà di fare sia routing basato sul path sia routing basato su subdomain verso backend services. Per esempio, puoi inviare tutto ciò che arriva su foo.yourdomain.com al service foo, e tutto ciò che si trova sotto il path yourdomain.com/bar/ al service bar.
|
||||
|
||||
Il YAML per un oggetto Ingress su GKE con un [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) potrebbe apparire così:
|
||||
Il YAML per un oggetto Ingress su GKE con un [L7 HTTP Load Balancer](https://cloud.google.com/compute/docs/load-balancing/http/) potrebbe assomigliare a questo:
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
@@ -201,13 +212,13 @@ Elenca tutti gli ingress:
|
||||
```bash
|
||||
kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'
|
||||
```
|
||||
Anche se in questo caso è meglio ottenere le informazioni di ciascuno una alla volta per leggerle meglio:
|
||||
Anche se in questo caso è meglio ottenere le informazioni di ciascuno una per una per leggerle meglio:
|
||||
```bash
|
||||
kubectl get ingresses --all-namespaces -o=yaml
|
||||
```
|
||||
### Gateway API
|
||||
|
||||
Gateway API è la nuova Kubernetes API per esporre i Services. Separa gli oggetti Gateway, di proprietà dell'infrastruttura, dagli oggetti Route, di proprietà dell'applicazione, come HTTPRoute. Questo è utile per la delega, ma significa anche che l'esposizione può essere distribuita tra namespace diversi.
|
||||
Gateway API è la nuova Kubernetes API per esporre Services. Separa gli oggetti Gateway di proprietà dell’infrastruttura dagli oggetti Route di proprietà dell’application, come HTTPRoute. Questo è utile per la delegation, ma significa anche che l’esposizione può essere suddivisa tra namespace.
|
||||
|
||||
Elenca gli oggetti di esposizione Gateway API:
|
||||
```bash
|
||||
@@ -217,13 +228,16 @@ kubectl get httproutes --all-namespaces
|
||||
kubectl get gateway -n <namespace> <gateway-name> -o yaml
|
||||
kubectl get httproute -n <namespace> <route-name> -o yaml
|
||||
```
|
||||
Controlla i listener del Gateway, i namespace consentiti per le route, i `parentRefs` della Route, gli hostname, i filter, i backend references e le condizioni di status, come ad esempio se la route è stata accepted. Una Route accepted da un shared Gateway può esporre un backend anche quando non esiste alcun oggetto Ingress legacy.
|
||||
Controlla i listener del Gateway, i namespace di route consentiti, `parentRefs` della Route, i `hostname`, i filter, i backend references e le status conditions, come ad esempio se la route è stata accepted. Una Route accepted da un shared Gateway può esporre un backend anche quando non esiste alcun oggetto Ingress legacy.
|
||||
|
||||
### References
|
||||
|
||||
- [https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/service/](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||
- [https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/)
|
||||
- [https://kubernetes.io/docs/tutorials/services/source-ip/](https://kubernetes.io/docs/tutorials/services/source-ip/)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)
|
||||
- [https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)
|
||||
- [https://gateway-api.sigs.k8s.io/](https://gateway-api.sigs.k8s.io/)
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
## Architecture & Basics
|
||||
|
||||
### Cosa fa Kubernetes?
|
||||
### What does Kubernetes do?
|
||||
|
||||
- Permette di eseguire container/s in un container engine.
|
||||
- Schedule permette ai container di essere gestiti in modo efficiente.
|
||||
- Permette di eseguire container in un container engine.
|
||||
- La schedule permette ai container di essere gestiti in modo efficiente.
|
||||
- Mantiene i container attivi.
|
||||
- Permette la comunicazione tra container.
|
||||
- Permette le comunicazioni tra container.
|
||||
- Permette tecniche di deployment.
|
||||
- Gestisce volumi di informazioni.
|
||||
|
||||
@@ -20,45 +20,47 @@
|
||||

|
||||
|
||||
- **Node**: sistema operativo con pod o pod.
|
||||
- **Pod**: Wrapper attorno a un container o a più container. Un pod dovrebbe contenere solo una applicazione (quindi di solito un pod esegue solo 1 container). Il pod è il modo in cui kubernetes astrae la tecnologia dei container in esecuzione.
|
||||
- **Service**: Ogni pod ha 1 **indirizzo IP** interno dall'intervallo interno del node. Tuttavia, può essere anche esposto tramite un service. Il **service ha anche un indirizzo IP** e il suo obiettivo è mantenere la comunicazione tra i pod, così se uno muore il **nuovo sostituto** (con un IP interno diverso) **sarà accessibile** esposto nello **stesso IP del service**. Può essere configurato come interno o esterno. Il service agisce anche come **load balancer quando 2 pod sono connessi** allo stesso service.\
|
||||
Quando un **service** viene **creato** puoi trovare gli endpoint di ogni service eseguendo `kubectl get endpoints`
|
||||
- **Pod**: Wrapper attorno a un container o a più container. Un pod dovrebbe contenere una sola applicazione (quindi di solito un pod esegue solo 1 container). Il pod è il modo in cui kubernetes astrae la tecnologia container in esecuzione.
|
||||
- **Service**: Ogni pod ha 1 **indirizzo IP** interno dall'intervallo interno del node. Tuttavia, può essere esposto anche tramite un service. Il **service ha anch'esso un indirizzo IP** e il suo obiettivo è mantenere la comunicazione tra i pod, così se uno muore il **nuovo sostituto** (con un IP interno diverso) **sarà accessibile** esposto nello **stesso IP del service**. Può essere configurato come interno o esterno. Il service agisce anche come **load balancer quando 2 pod sono collegati** allo stesso service.\
|
||||
Quando viene **creato un service** puoi trovare gli endpoint di ciascun service eseguendo `kubectl get endpoints`
|
||||
- **Kubelet**: agente principale del node. Il componente che stabilisce la comunicazione tra node e kubectl, e può eseguire solo pod (tramite API server). Il kubelet non gestisce container che non sono stati creati da Kubernetes.
|
||||
- **Kube-proxy**: è il service incaricato delle comunicazioni (services) tra l'apiserver e il node. La base è IPtables per i node. Gli utenti più esperti potrebbero installare altri kube-proxy di altri vendor.
|
||||
- **Sidecar container**: I sidecar container sono i container che dovrebbero eseguire insieme al container principale nel pod. Questo pattern sidecar estende e migliora la funzionalità dei container attuali senza modificarli. Oggi sappiamo che usiamo la tecnologia dei container per racchiudere tutte le dipendenze necessarie affinché l'applicazione possa eseguire ovunque. Un container fa una sola cosa e la fa molto bene.
|
||||
- **Kube-proxy**: è il servizio incaricato delle comunicazioni (services) tra l'apiserver e il node. La base è una IPtables per i node. Gli utenti più esperti potrebbero installare altri kube-proxy di altri vendor.
|
||||
- **Sidecar container**: I sidecar container sono i container che dovrebbero eseguire insieme al container principale nel pod. Questo pattern sidecar estende e migliora la funzionalità dei container attuali senza modificarli. Oggi sappiamo che usiamo la tecnologia container per racchiudere tutte le dipendenze affinché l'applicazione possa eseguirsi ovunque. Un container fa una sola cosa e la fa molto bene.
|
||||
- **Master process:**
|
||||
- **Api Server:** È il modo in cui gli utenti e i pod usano per comunicare con il master process. Dovrebbero essere consentite solo request autenticate.
|
||||
- **Scheduler**: Scheduling si riferisce a garantire che i Pod siano associati ai Node in modo che Kubelet possa eseguirli. Ha abbastanza intelligenza per decidere quale node ha più risorse disponibili e assegnare il nuovo pod a quello. Nota che lo scheduler non avvia nuovi pod, comunica solo con il processo Kubelet in esecuzione all'interno del node, che lancerà il nuovo pod.
|
||||
- **Kube Controller manager**: Controlla risorse come replica sets o deployments per verificare che, per esempio, sia in esecuzione il numero corretto di pod o node. Nel caso in cui manchi un pod, comunicherà con lo scheduler per avviarne uno nuovo. Controlla la replication, i token e i servizi degli account verso l'API.
|
||||
- **etcd**: Data storage, persistente, coerente e distribuito. È il database di Kubernetes e lo storage key-value in cui mantiene lo stato completo dei cluster (ogni modifica viene registrata qui). Componenti come lo Scheduler o il Controller manager dipendono da questi date per sapere quali cambiamenti sono avvenuti (available resourced dei node, numero di pod in esecuzione...)
|
||||
- **Cloud controller manager**: È il controller specifico per flow controls e applications, ad esempio: se hai cluster in AWS o OpenStack.
|
||||
- **Api Server:** È il modo in cui gli utenti e i pod usano per comunicare con il master process. Dovrebbero essere consentite solo richieste autenticate.
|
||||
- **Scheduler**: Scheduling significa assicurarsi che i Pod siano assegnati ai Node in modo che Kubelet possa eseguirli. Ha abbastanza intelligenza per decidere quale node ha più risorse disponibili e assegnargli il nuovo pod. Nota che lo scheduler non avvia nuovi pod, comunica solo con il processo Kubelet in esecuzione all'interno del node, che lancerà il nuovo pod.
|
||||
- **Kube Controller manager**: Controlla risorse come replica sets o deployments per verificare, per esempio, che il numero corretto di pod o node sia in esecuzione. In caso manchi un pod, comunicherà con lo scheduler per avviarne uno nuovo. Controlla replication, tokens e account services verso l'API.
|
||||
- **etcd**: Archiviazione dati, persistente, consistente e distribuita. È il database di Kubernetes e lo storage key-value dove conserva lo stato completo dei cluster (ogni modifica viene registrata qui). Componenti come lo Scheduler o il Controller manager dipendono da questi date per sapere quali cambiamenti sono avvenuti (risorse disponibili dei node, numero di pod in esecuzione...)
|
||||
- **Cloud controller manager**: È il controller specifico per flow controls e applications, cioè: se hai cluster in AWS o OpenStack.
|
||||
|
||||
Nota che, poiché potrebbero esserci diversi node (che eseguono diversi pod), potrebbero esserci anche diversi master process con il loro accesso all'Api server bilanciato e il loro etcd sincronizzato.
|
||||
Nota che, poiché possono esserci diversi node (che eseguono diversi pod), possono esserci anche diversi master process, il cui accesso all'Api server è load balanced e il cui etcd è sincronizzato.
|
||||
|
||||
**Volumes:**
|
||||
|
||||
Quando un pod crea dati che non dovrebbero andare persi quando il pod scompare, dovrebbero essere archiviati in un physical volume. **Kubernetes permette di collegare un volume a un pod per persistere i dati**. Il volume può essere nella macchina locale o in uno **storage remoto**. Se stai eseguendo pod in diversi node fisici dovresti usare uno storage remoto così tutti i pod possono accedervi.
|
||||
Quando un pod crea dati che non dovrebbero andare persi quando il pod scompare, dovrebbero essere salvati in un volume fisico. **Kubernetes consente di collegare un volume a un pod per persistere i dati**. Il volume può trovarsi sulla macchina locale o in uno **storage remoto**. Se esegui pod su node fisici diversi dovresti usare uno storage remoto così tutti i pod possono accedervi.
|
||||
|
||||
Kubernetes supporta anche **image volumes** nelle versioni recenti. Un volume `image` monta un OCI image o artifact come sorgente filesystem **read-only** dentro il Pod, usando campi come `volumes[].image.reference` e `volumes[].image.pullPolicy`. Il kubelet scarica l'artifact con le stesse credential sources usate per le container images, incluse le credenziali del node, i `imagePullSecrets` del Pod e i `imagePullSecrets` del ServiceAccount. Durante una security review, tratta gli image volumes come runtime inputs e supply-chain dependencies: verifica se il reference è fissato da digest, quali registry credentials possono scaricarlo, dove viene montato e se `subPath` limita la directory visibile.
|
||||
|
||||
**Other configurations:**
|
||||
|
||||
- **ConfigMap**: Puoi configurare **URLs** per accedere ai services. Il pod otterrà dati da qui per sapere come comunicare con il resto dei services (pod). Nota che questo non è il posto consigliato per salvare credenziali!
|
||||
- **Secret**: Questo è il posto per **memorizzare dati segreti** come password, API keys... codificati in B64. Il pod potrà accedere a questi dati per usare le credenziali richieste.
|
||||
- **Deployments**: Qui vengono indicati i componenti da eseguire da kubernetes. Di solito un utente non lavora direttamente con i pod, i pod sono astratti in **ReplicaSets** (numero di pod uguali replicati), che vengono eseguiti tramite deployments. Nota che i deployments sono per applicazioni **stateless**. La configurazione minima per un deployment è il nome e l'image da eseguire.
|
||||
- **StatefulSet**: Questo componente è pensato specificamente per applicazioni come **database** che devono **accedere allo stesso storage**.
|
||||
- **ConfigMap**: Puoi configurare **URL** per accedere ai services. Il pod otterrà da qui i dati per sapere come comunicare con il resto dei services (pod). Nota che questo non è il posto raccomandato per salvare credential!
|
||||
- **Secret**: Questo è il posto per **memorizzare dati segreti** come password, API keys... codificati in B64. Il pod potrà accedere a questi dati per usare le credential richieste.
|
||||
- **Deployments**: Qui vengono indicati i componenti da eseguire da kubernetes. Di solito un utente non lavora direttamente con i pod, i pod sono astratti in **ReplicaSets** (numero di pod uguali replicati), che vengono eseguiti tramite deployments. Nota che i deployments sono per applicazioni **stateless**. La configurazione minima per un deployment è il name e l'image da eseguire.
|
||||
- **StatefulSet**: Questo componente è pensato specificamente per applicazioni come **database** che hanno bisogno di **accedere allo stesso storage**.
|
||||
- **Ingress**: Questa è la configurazione usata per **esporre pubblicamente l'applicazione con un URL**. Nota che questo può essere fatto anche usando external services, ma questo è il modo corretto per esporre l'applicazione.
|
||||
- Se implementi un Ingress dovrai creare **Ingress Controllers**. L'Ingress Controller è un **pod** che sarà l'endpoint che riceverà le request e le controllerà e le bilancerà verso i services. l'ingress controller **invierà la request in base alle ingress rules configurate**. Nota che le ingress rules possono puntare a percorsi diversi o persino a subdomain diversi verso differenti internal kubernetes services.
|
||||
- Una migliore pratica di sicurezza sarebbe usare un cloud load balancer o un proxy server come entrypoint per non avere nessuna parte del Kubernetes cluster esposta.
|
||||
- Quando viene ricevuta una request che non corrisponde a nessuna ingress rule, l'ingress controller la indirizzerà al "**Default backend**". Puoi `describe` l'ingress controller per ottenere l'indirizzo di questo parametro.
|
||||
- Se implementi un Ingress dovrai creare **Ingress Controllers**. L'Ingress Controller è un **pod** che sarà l'endpoint che riceverà le richieste e le controllerà e le bilancerà verso i services. l'ingress controller **inoltrerà la richiesta in base alle ingress rules configurate**. Nota che le ingress rules possono puntare a path diversi o persino a subdomain diversi verso differenti internal kubernetes services.
|
||||
- Una pratica di sicurezza migliore sarebbe usare un cloud load balancer o un proxy server come entrypoint per non avere nessuna parte del Kubernetes cluster esposta.
|
||||
- Quando viene ricevuta una richiesta che non corrisponde a nessuna ingress rule, l'ingress controller la indirizzerà al "**Default backend**". Puoi usare `describe` sull'ingress controller per ottenere l'indirizzo di questo parametro.
|
||||
- `minikube addons enable ingress`
|
||||
|
||||
### PKI infrastructure - Certificate Authority CA:
|
||||
|
||||

|
||||
|
||||
- CA è la root trusted per tutti i certificates all'interno del cluster.
|
||||
- Permette ai componenti di validarsi a vicenda.
|
||||
- Tutti i certificates del cluster sono firmati dalla CA.
|
||||
- ETCd ha il proprio certificate.
|
||||
- CA è la root attendibile per tutti i certificati all'interno del cluster.
|
||||
- Permette ai componenti di validarsi tra loro.
|
||||
- Tutti i certificati del cluster sono firmati dalla CA.
|
||||
- ETCd ha il suo certificato.
|
||||
- types:
|
||||
- apiserver cert.
|
||||
- kubelet cert.
|
||||
@@ -68,7 +70,7 @@ Quando un pod crea dati che non dovrebbero andare persi quando il pod scompare,
|
||||
|
||||
### Minikube
|
||||
|
||||
**Minikube** può essere usato per eseguire alcuni **quick tests** su kubernetes senza dover deployare un intero ambiente kubernetes. Eseguirà i processi di **master e node in una sola macchina**. Minikube userà virtualbox per eseguire il node. Vedi [**qui come installarlo**](https://minikube.sigs.k8s.io/docs/start/).
|
||||
**Minikube** può essere usato per eseguire alcuni **quick tests** su kubernetes senza dover distribuire un intero ambiente kubernetes. Eseguirà i processi **master e node su una sola macchina**. Minikube userà virtualbox per eseguire il node. Vedi [**qui come installarlo**](https://minikube.sigs.k8s.io/docs/start/).
|
||||
```
|
||||
$ minikube start
|
||||
😄 minikube v1.19.0 on Ubuntu 20.04
|
||||
@@ -105,7 +107,7 @@ $ minikube delete
|
||||
```
|
||||
### Kubectl Basics
|
||||
|
||||
**`Kubectl`** è lo strumento da riga di comando per i cluster kubernetes. Comunica con il Api server del processo master per eseguire azioni in kubernetes o per richiedere dati.
|
||||
**`Kubectl`** è lo strumento da riga di comando per i cluster kubernetes. Comunica con l'Api server del processo master per eseguire azioni in kubernetes o per richiedere dati.
|
||||
```bash
|
||||
kubectl version #Get client and server version
|
||||
kubectl get pod
|
||||
@@ -138,7 +140,7 @@ kubectl apply -f deployment.yml
|
||||
```
|
||||
### Minikube Dashboard
|
||||
|
||||
Il dashboard consente di vedere più facilmente cosa sta eseguendo minikube, puoi trovare l'URL per accedervi in:
|
||||
Il dashboard ti consente di vedere più facilmente cosa sta eseguendo minikube, puoi trovare l'URL per accedervi in:
|
||||
```
|
||||
minikube dashboard --url
|
||||
|
||||
@@ -153,12 +155,12 @@ http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kube
|
||||
```
|
||||
### Esempi di file di configurazione YAML
|
||||
|
||||
Ogni file di configurazione ha 3 parti: **metadata**, **specification** (cosa deve essere avviato), **status** (stato desiderato).\
|
||||
All'interno della specification del file di configurazione del deployment puoi trovare il template definito con una nuova struttura di configurazione che definisce l'immagine da eseguire:
|
||||
Ogni file di configurazione ha 3 parti: **metadata**, **specification** (ciò che deve essere avviato), **status** (stato desiderato).\
|
||||
All'interno della specification del file di configurazione del deployment puoi trovare il template definito con una nuova struttura di configurazione che definisce l'image da eseguire:
|
||||
|
||||
**Esempio di Deployment + Service dichiarati nello stesso file di configurazione (da** [**qui**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**
|
||||
|
||||
Poiché un service è solitamente collegato a un deployment, è possibile dichiararli entrambi nello stesso file di configurazione (il service dichiarato in questa config è accessibile solo internamente):
|
||||
Poiché un service è di solito collegato a un deployment, è possibile dichiararli entrambi nello stesso file di configurazione (il service dichiarato in questa config è accessibile solo internamente):
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@@ -205,9 +207,9 @@ ports:
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
```
|
||||
**Esempio di configurazione di external service**
|
||||
**Esempio di configurazione di un servizio esterno**
|
||||
|
||||
Questo service sarà accessibile esternamente (controlla gli attributi `nodePort` e `type: LoadBlancer`):
|
||||
Questo servizio sarà accessibile esternamente (controlla gli attributi `nodePort` e `type: LoadBlancer`):
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -225,7 +227,7 @@ targetPort: 8081
|
||||
nodePort: 30000
|
||||
```
|
||||
> [!NOTE]
|
||||
> Questo è utile per i test, ma in produzione dovresti avere solo servizi interni e un Ingress per esporre l'applicazione.
|
||||
> Questo è utile per i test ma per la produzione dovresti avere solo servizi interni e un Ingress per esporre l'applicazione.
|
||||
|
||||
**Example of Ingress config file**
|
||||
|
||||
@@ -260,7 +262,7 @@ mongo-root-password: cGFzc3dvcmQ=
|
||||
```
|
||||
**Esempio di ConfigMap**
|
||||
|
||||
Una **ConfigMap** è la configurazione che viene fornita ai pod in modo che sappiano come individuare e accedere ad altri servizi. In questo caso, ogni pod saprà che il nome `mongodb-service` è l'indirizzo di un pod con cui può comunicare (questo pod eseguirà un mongodb):
|
||||
Una **ConfigMap** è la configurazione fornita ai pod in modo che sappiano come individuare e accedere ad altri servizi. In questo caso, ogni pod saprà che il nome `mongodb-service` è l'indirizzo di un pod con cui può comunicare (questo pod eseguirà un mongodb):
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@@ -269,7 +271,7 @@ name: mongodb-configmap
|
||||
data:
|
||||
database_url: mongodb-service
|
||||
```
|
||||
Allora, all'interno di una **deployment config** questo indirizzo può essere specificato nel seguente modo, così viene caricato nell'env del pod:
|
||||
Poi, all'interno di una **deployment config** questo indirizzo può essere specificato nel seguente modo così da essere caricato nell'env del pod:
|
||||
```yaml
|
||||
[...]
|
||||
spec:
|
||||
@@ -290,16 +292,16 @@ name: mongodb-configmap
|
||||
key: database_url
|
||||
[...]
|
||||
```
|
||||
**Esempio di volume config**
|
||||
**Esempio di configurazione del volume**
|
||||
|
||||
Puoi trovare diversi esempi di file yaml di storage configuration in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
|
||||
**Nota che i volumes non sono dentro namespaces**
|
||||
Puoi trovare diversi esempi di file yaml di configurazione dello storage in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
|
||||
**Nota che i volumes non sono dentro i namespaces**
|
||||
|
||||
### Namespaces
|
||||
|
||||
Kubernetes supporta **multiple virtual clusters** supportati dallo stesso physical cluster. Questi virtual clusters sono chiamati **namespaces**. Sono pensati per essere usati in ambienti con molti utenti distribuiti tra più team o projects. Per cluster con pochi o fino a decine di utenti, non dovresti aver bisogno di creare o pensare ai namespaces per niente. Dovresti iniziare a usare i namespaces solo per avere un miglior controllo e organizzazione di ogni parte dell'applicazione deployata in kubernetes.
|
||||
Kubernetes supporta **multiple virtual clusters** supportati dallo stesso physical cluster. Questi virtual clusters sono chiamati **namespaces**. Sono pensati per essere usati in ambienti con molti utenti distribuiti tra più team o progetti. Per cluster con pochi o decine di utenti, non dovresti aver bisogno di creare o considerare i namespaces affatto. Dovresti iniziare a usare i namespaces solo per avere un controllo migliore e una migliore organizzazione di ciascuna parte dell'application deployata in kubernetes.
|
||||
|
||||
I namespaces forniscono un scope per i names. I names delle resources devono essere unici all'interno di un namespace, ma non tra namespaces. I namespaces non possono essere annidati l'uno dentro l'altro e **each** Kubernetes **resource** può essere solo **in** **one** **namespace**.
|
||||
I namespaces forniscono un scope per i names. I names delle resources devono essere unici all'interno di un namespace, ma non tra namespaces. I namespaces non possono essere annidati uno dentro l'altro e **each** Kubernetes **resource** può essere solo **in** **one** **namespace**.
|
||||
|
||||
Ci sono 4 namespaces di default se stai usando minikube:
|
||||
```
|
||||
@@ -310,20 +312,20 @@ kube-node-lease Active 1d
|
||||
kube-public Active 1d
|
||||
kube-system Active 1d
|
||||
```
|
||||
- **kube-system**: Non è pensato per l'uso degli utenti e non dovresti toccarlo. È per i processi master e kubectl.
|
||||
- **kube-system**: Non è pensato per gli utenti e non dovresti toccarlo. È per i processi master e kubectl.
|
||||
- **kube-public**: Dati accessibili pubblicamente. Contiene un configmap che contiene informazioni sul cluster
|
||||
- **kube-node-lease**: Determina la disponibilità di un node
|
||||
- **kube-node-lease**: Determina la disponibilità di un nodo
|
||||
- **default**: Il namespace che l'utente userà per creare risorse
|
||||
```bash
|
||||
#Create namespace
|
||||
kubectl create namespace my-namespace
|
||||
```
|
||||
> [!NOTE]
|
||||
> Nota che la maggior parte delle risorse Kubernetes (ad esempio pods, services, replication controllers e altre) si trovano in alcuni namespaces. Tuttavia, altre risorse come le namespace resources e le risorse low-level, come nodes e persistenVolumes, non si trovano in un namespace. Per vedere quali risorse Kubernetes sono e non sono in un namespace:
|
||||
> Nota che la maggior parte delle risorse Kubernetes (ad esempio pods, services, replication controllers e altre) si trovano in alcuni namespace. Tuttavia, altre risorse come le namespace resources e le risorse di basso livello, come nodes e persistenVolumes, non si trovano in un namespace. Per vedere quali risorse Kubernetes sono e non sono in un namespace:
|
||||
>
|
||||
> ```bash
|
||||
> kubectl api-resources --namespaced=true #In un namespace
|
||||
> kubectl api-resources --namespaced=false #Non in un namespace
|
||||
> kubectl api-resources --namespaced=true #In a namespace
|
||||
> kubectl api-resources --namespaced=false #Not in a namespace
|
||||
> ```
|
||||
|
||||
Puoi salvare il namespace per tutti i successivi comandi kubectl in quel contesto.
|
||||
@@ -332,7 +334,7 @@ kubectl config set-context --current --namespace=<insert-namespace-name-here>
|
||||
```
|
||||
### Helm
|
||||
|
||||
Helm è il **package manager** per Kubernetes. Consente di creare package di file YAML e distribuirli in repository pubblici e privati. Questi package sono chiamati **Helm Charts**.
|
||||
Helm è il **package manager** per Kubernetes. Permette di impacchettare file YAML e distribuirli in repository pubblici e privati. Questi pacchetti si chiamano **Helm Charts**.
|
||||
```
|
||||
helm search <keyword>
|
||||
```
|
||||
@@ -340,9 +342,9 @@ Helm is also a template engine that allows to generate config files with variabl
|
||||
|
||||
## Kubernetes secrets
|
||||
|
||||
A **Secret** è un oggetto che **contiene dati sensibili** come una password, un token o una key. Tali informazioni altrimenti potrebbero essere inserite in una specifica Pod o in un'immagine. Gli utenti possono creare Secrets e anche il sistema crea Secrets. Il nome di un oggetto Secret deve essere un **DNS subdomain name** valido. Leggi qui [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||
Un **Secret** is an object that **contains sensitive data** such as a password, a token or a key. Such information might otherwise be put in a Pod specification or in an image. Users can create Secrets and the system also creates Secrets. The name of a Secret object must be a valid **DNS subdomain name**. Read here [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||
|
||||
I Secrets possono essere cose come:
|
||||
Secrets might be things like:
|
||||
|
||||
- API, SSH Keys.
|
||||
- OAuth tokens.
|
||||
@@ -350,7 +352,7 @@ I Secrets possono essere cose come:
|
||||
- Information or comments.
|
||||
- Database connection code, strings… .
|
||||
|
||||
Ci sono diversi tipi di secrets in Kubernetes
|
||||
There are different types of secrets in Kubernetes
|
||||
|
||||
| Builtin Type | Usage |
|
||||
| ----------------------------------- | ----------------------------------------- |
|
||||
@@ -370,7 +372,7 @@ Ci sono diversi tipi di secrets in Kubernetes
|
||||
|
||||

|
||||
|
||||
Il seguente file di configurazione definisce un **secret** chiamato `mysecret` con 2 coppie chiave-valore `username: YWRtaW4=` e `password: MWYyZDFlMmU2N2Rm`. Definisce anche un **pod** chiamato `secretpod` che avrà `username` e `password` definiti in `mysecret` esposti nelle **environment variables** `SECRET_USERNAME` \_\_ e \_\_ `SECRET_PASSWOR`. Inoltre farà il **mount** del secret `username` dentro `mysecret` nel path `/etc/foo/my-group/my-username` con permessi `0640`.
|
||||
The following configuration file defines a **secret** called `mysecret` with 2 key-value pairs `username: YWRtaW4=` and `password: MWYyZDFlMmU2N2Rm`. It also defines a **pod** called `secretpod` that will have the `username` and `password` defined in `mysecret` exposed in the **environment variables** `SECRET_USERNAME` \_\_ and \_\_ `SECRET_PASSWOR`. It will also **mount** the `username` secret inside `mysecret` in the path `/etc/foo/my-group/my-username` with `0640` permissions.
|
||||
```yaml:secretpod.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -422,25 +424,25 @@ env | grep SECRET && cat /etc/foo/my-group/my-username && echo
|
||||
```
|
||||
### Segreti in etcd <a href="#discover-secrets-in-etcd" id="discover-secrets-in-etcd"></a>
|
||||
|
||||
**etcd** è un **key-value store** consistente e altamente disponibile usato come backing store di Kubernetes per tutti i dati del cluster. Accediamo ai secrets memorizzati in etcd:
|
||||
**etcd** è un **key-value store** consistente e altamente disponibile usato come backing store di Kubernetes per tutti i dati del cluster. Accediamo ai secrets archiviati in etcd:
|
||||
```bash
|
||||
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
|
||||
```
|
||||
Vedrai certs, keys e URL che si trovano nel FS. Una volta ottenuti, potrai connetterti a etcd.
|
||||
Vedrai certs, keys e url’s dove si trovano nel FS. Una volta ottenuti, sarai in grado di connetterti a etcd.
|
||||
```bash
|
||||
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] health
|
||||
|
||||
ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health
|
||||
```
|
||||
Una volta stabilita la comunicazione, potrai ottenere i secrets:
|
||||
Una volta stabilita la comunicazione, potresti ottenere i secrets:
|
||||
```bash
|
||||
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] get <path/to/secret>
|
||||
|
||||
ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] get /registry/secrets/default/secret_02
|
||||
```
|
||||
**Aggiunta della crittografia a ETCD**
|
||||
**Aggiungere la cifratura a ETCD**
|
||||
|
||||
Per default tutti i secrets sono **archiviati in chiaro** dentro etcd a meno che non applichi un layer di crittografia. Il seguente esempio è basato su [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
|
||||
Per impostazione predefinita tutti i secrets sono **memorizzati in testo normale** all'interno di etcd, a meno che non applichi un layer di cifratura. Il seguente esempio è basato su [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
|
||||
```yaml:encryption.yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
@@ -454,14 +456,14 @@ keys:
|
||||
secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key
|
||||
- identity: {}
|
||||
```
|
||||
Dopo di ciò, devi impostare il flag `--encryption-provider-config` su `kube-apiserver` per puntare alla posizione del file di configurazione creato. Puoi modificare `/etc/kubernetes/manifest/kube-apiserver.yaml` e aggiungere le seguenti righe:
|
||||
Dopo di ciò, devi impostare il flag `--encryption-provider-config` su `kube-apiserver` in modo che punti alla posizione del file di configurazione creato. Puoi modificare `/etc/kubernetes/manifest/kube-apiserver.yaml` e aggiungere le seguenti righe:
|
||||
```yaml
|
||||
containers:
|
||||
- command:
|
||||
- kube-apiserver
|
||||
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
|
||||
```
|
||||
Scorri verso il basso in volumeMounts:
|
||||
Scorri verso il basso in `volumeMounts`:
|
||||
```yaml
|
||||
- mountPath: /etc/kubernetes/etcd
|
||||
name: etcd
|
||||
@@ -474,9 +476,9 @@ path: /etc/kubernetes/etcd
|
||||
type: DirectoryOrCreate
|
||||
name: etcd
|
||||
```
|
||||
**Verificando che i dati siano crittografati**
|
||||
**Verifying that data is encrypted**
|
||||
|
||||
I dati sono crittografati quando vengono scritti in etcd. Dopo aver riavviato il tuo `kube-apiserver`, qualsiasi secret creato o aggiornato di recente dovrebbe essere crittografato quando viene memorizzato. Per verificarlo, puoi usare il programma a riga di comando `etcdctl` per recuperare il contenuto del tuo secret.
|
||||
I dati sono encrypted quando vengono scritti in etcd. Dopo aver riavviato il tuo `kube-apiserver`, qualsiasi secret appena creato o aggiornato dovrebbe essere encrypted quando memorizzato. Per verificare, puoi usare il programma da riga di comando `etcdctl` per recuperare il contenuto del tuo secret.
|
||||
|
||||
1. Crea un nuovo secret chiamato `secret1` nel namespace `default`:
|
||||
|
||||
@@ -484,29 +486,29 @@ I dati sono crittografati quando vengono scritti in etcd. Dopo aver riavviato il
|
||||
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
|
||||
```
|
||||
|
||||
2. Usando il commandline `etcdctl`, leggi quel secret da etcd:
|
||||
2. Usando la commandline di etcdctl, leggi quel secret da etcd:
|
||||
|
||||
`ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C`
|
||||
|
||||
dove `[...]` devono essere gli argomenti aggiuntivi per connettersi al server etcd.
|
||||
dove `[...]` deve essere l'ulteriore argomento per connettersi al server etcd.
|
||||
|
||||
3. Verifica che il secret memorizzato sia prefissato con `k8s:enc:aescbc:v1:` che indica che il provider `aescbc` ha crittografato i dati risultanti.
|
||||
4. Verifica che il secret venga decrittografato correttamente quando viene recuperato tramite l'API:
|
||||
3. Verifica che il secret memorizzato sia prefissato con `k8s:enc:aescbc:v1:` che indica che il provider `aescbc` ha encrypted i dati risultanti.
|
||||
4. Verifica che il secret sia correttamente decrypted quando viene recuperato tramite l'API:
|
||||
|
||||
```
|
||||
kubectl describe secret secret1 -n default
|
||||
```
|
||||
|
||||
dovrebbe corrispondere a `mykey: bXlkYXRh`, mydata è codificato, controlla [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) per decodificare completamente il secret.
|
||||
dovrebbe corrispondere a `mykey: bXlkYXRh`, mydata è encoded, controlla [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) per decodificare completamente il secret.
|
||||
|
||||
**Poiché i secrets sono crittografati in scrittura, eseguire un aggiornamento su un secret crifrerà quel contenuto:**
|
||||
**Since secrets are encrypted on write, performing an update on a secret will encrypt that content:**
|
||||
```
|
||||
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
|
||||
```
|
||||
**Suggerimenti finali:**
|
||||
|
||||
- Cerca di non tenere segreti nel FS, prendili da altri posti.
|
||||
- Dai un’occhiata a [https://www.vaultproject.io/](https://www.vaultproject.io) per aggiungere più protezione ai tuoi segreti.
|
||||
- Dai un'occhiata a [https://www.vaultproject.io/](https://www.vaultproject.io) per aggiungere più protezione ai tuoi segreti.
|
||||
- [https://kubernetes.io/docs/concepts/configuration/secret/#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks)
|
||||
- [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm)
|
||||
|
||||
@@ -520,4 +522,12 @@ https://sickrov.github.io/
|
||||
https://www.youtube.com/watch?v=X48VuDVv0do
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
https://kubernetes.io/docs/concepts/storage/volumes/#image
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
+42
-36
@@ -6,79 +6,85 @@
|
||||
|
||||
[**Dalla documentazione:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)
|
||||
|
||||
Quando specifichi il security context di un Pod puoi usare diversi attributi. Dal punto di vista della difesa dovresti considerare:
|
||||
Quando specifichi il security context di un Pod puoi usare diversi attributi. Dal punto di vista della sicurezza difensiva dovresti considerare:
|
||||
|
||||
- Avere **runASNonRoot** come **True**
|
||||
- Avere **runASNonRoot** impostato su **True**
|
||||
- Configurare **runAsUser**
|
||||
- Se possibile, considera di **limitare** i **permessi** indicando **seLinuxOptions** e **seccompProfile**
|
||||
- **NON** dare accesso al **group** di **privilege** tramite **runAsGroup** e **supplementaryGroups**
|
||||
- **NON** dare accesso al **gruppo** con **privilegio** tramite **runAsGroup** e **supplementaryGroups**
|
||||
|
||||
| Parameter | Description |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroup</strong></a><br><em>integer</em></p> | <p>Un gruppo supplementare speciale che si applica a <strong>tutti i container in un pod</strong>. Alcuni tipi di volume consentono a Kubelet di <strong>cambiare la ownership di quel volume</strong> in modo che appartenga al pod:<br>1. Il GID proprietario sarà il FSGroup<br>2. Il bit setgid è impostato (i nuovi file creati nel volume saranno di proprietà di FSGroup)<br>3. I bit di permission vengono combinati con rw-rw---- Se non impostato, Kubelet non modificherà la ownership e i permission di alcun volume</p> |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroup</strong></a><br><em>integer</em></p> | <p>Un gruppo supplementare speciale che si applica a <strong>tutti i container in un pod</strong>. Alcuni tipi di volume permettono al Kubelet di <strong>cambiare la ownership di quel volume</strong> in modo che appartenga al pod:<br>1. Il GID proprietario sarà il FSGroup<br>2. Il bit setgid è impostato (i nuovi file creati nel volume saranno di proprietà di FSGroup)<br>3. I bit di permesso sono OR'd con rw-rw---- Se non impostato, il Kubelet non modificherà la ownership e i permessi di alcun volume</p> |
|
||||
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroupChangePolicy</strong></a><br><em>string</em></p> | Definisce il comportamento di **cambio di ownership e permission del volume** prima che venga esposto all'interno del Pod. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | Il **GID usato per eseguire l'entrypoint del processo del container**. Usa il valore predefinito del runtime se non impostato. Può anche essere impostato in SecurityContext. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | Indica che il container deve essere eseguito come utente non root. Se true, Kubelet validerà l'immagine a runtime per assicurarsi che non venga eseguita come UID 0 (root) e impedirà l'avvio del container se lo fa. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | L'**UID usato per eseguire l'entrypoint del processo del container**. Per impostazione predefinita usa l'utente specificato nei metadati dell'immagine se non viene specificato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | Il **contesto SELinux da applicare a tutti i container**. Se non specificato, il container runtime assegnerà un contesto SELinux casuale per ogni container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a><br><em>More info about</em> <em><strong>Seccomp</strong></em></p> | Le **opzioni seccomp da usare dai container** in questo pod. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>supplementalGroups</strong></a><br><em>integer array</em></p> | Un elenco di **gruppi applicati al primo processo eseguito in ogni container**, oltre al GID primario del container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>sysctls</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#sysctl-v1-core"><em>Sysctl</em></a> <em>array</em><br><em>More info about</em> <a href="https://www.garron.me/en/go2linux/sysctl-linux.html"><em><strong>sysctls</strong></em></a></p> | I Sysctls contengono un elenco di **sysctls namespaced usati per il pod**. I Pod con sysctls non supportati (dal container runtime) potrebbero non riuscire ad avviarsi. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | Le impostazioni specifiche di Windows applicate a tutti i container. Se non specificate, verranno usate le opzioni presenti nel SecurityContext di un container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>fsGroupChangePolicy</strong></a><br><em>string</em></p> | Questo definisce il comportamento di **cambio della ownership e dei permessi del volume** prima di essere esposto all'interno del Pod. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | Il **GID da usare per eseguire l'entrypoint del processo del container**. Usa il default del runtime se non impostato. Può anche essere impostato in SecurityContext. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | Indica che il container deve essere eseguito come utente non-root. Se true, il Kubelet convaliderà l'immagine a runtime per assicurarsi che non venga eseguita come UID 0 (root) e fallirà l'avvio del container se lo fa. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | Il **UID da usare per eseguire l'entrypoint del processo del container**. Per impostazione predefinita usa l'utente specificato nei metadati dell'immagine se non specificato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | Il **contesto SELinux da applicare a tutti i container**. Se non specificato, il container runtime assegnerà un contesto SELinux casuale a ogni container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a><br><em>More info about</em> <em><strong>Seccomp</strong></em></p> | Le **opzioni seccomp da usare per i container** in questo pod. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>supplementalGroups</strong></a><br><em>integer array</em></p> | Un elenco di **gruppi applicati al primo processo eseguito in ciascun container**, oltre al GID primario del container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>sysctls</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#sysctl-v1-core"><em>Sysctl</em></a> <em>array</em><br><em>More info about</em> <a href="https://www.garron.me/en/go2linux/sysctl-linux.html"><em><strong>sysctls</strong></em></a></p> | I Sysctls contengono un elenco di **sysctls namespaced usati per il pod**. I pod con sysctls non supportati (dal container runtime) potrebbero non riuscire ad avviarsi. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | Le impostazioni specifiche di Windows applicate a tutti i container. Se non specificato, verranno usate le opzioni all'interno del SecurityContext di un container. |
|
||||
|
||||
## SecurityContext
|
||||
|
||||
[**Dalla documentazione:**](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)
|
||||
|
||||
Questo context è impostato all'interno delle **definizioni dei container**. Dal punto di vista della difesa dovresti considerare:
|
||||
Questo context è impostato all'interno delle **definizioni dei container**. Dal punto di vista della sicurezza difensiva dovresti considerare:
|
||||
|
||||
- **allowPrivilegeEscalation** su **False**
|
||||
- Non aggiungere **capabilities** sensibili (e rimuovere quelle non necessarie)
|
||||
- **privileged** su **False**
|
||||
- Se possibile, imposta **readOnlyFilesystem** come **True**
|
||||
- Imposta **runAsNonRoot** su **True** e imposta un **runAsUser**
|
||||
- **allowPrivilegeEscalation** a **False**
|
||||
- Non aggiungere **capabilities** sensibili (e rimuovere quelle che non ti servono)
|
||||
- **privileged** a **False**
|
||||
- Se possibile, impostare **readOnlyFilesystem** su **True**
|
||||
- Impostare **runAsNonRoot** su **True** e impostare un **runAsUser**
|
||||
- Se possibile, considera di **limitare** i **permessi** indicando **seLinuxOptions** e **seccompProfile**
|
||||
- **NON** dare accesso al **group** di **privilege** tramite **runAsGroup.**
|
||||
- **NON** dare accesso al **gruppo** con **privilegio** tramite **runAsGroup.**
|
||||
|
||||
Nota che, per gli attributi impostati sia in **SecurityContext che in PodSecurityContext**, il valore specificato in **SecurityContext** ha **precedenza**.
|
||||
Nota che gli attributi impostati in **sia SecurityContext che PodSecurityContext**, il valore specificato in **SecurityContext** ha **precedenza**.
|
||||
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>allowPrivilegeEscalation</strong></a><br><em>boolean</em></p> | **AllowPrivilegeEscalation** controlla se un processo può **ottenere più privilege** del suo processo padre. Questo bool controlla direttamente se il flag no_new_privs verrà impostato sul processo del container. AllowPrivilegeEscalation è sempre true quando il container viene eseguito come **Privileged** o ha **CAP_SYS_ADMIN** |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>allowPrivilegeEscalation</strong></a><br><em>boolean</em></p> | **AllowPrivilegeEscalation** controlla se un processo può **ottenere più privilegi** del suo processo padre. Questo bool controlla direttamente se il flag no_new_privs verrà impostato sul processo del container. AllowPrivilegeEscalation è sempre true quando il container viene eseguito come **Privileged** o ha **CAP_SYS_ADMIN** |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>capabilities</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#capabilities-v1-core"><em>Capabilities</em></a><br><em>More info about</em> <em><strong>Capabilities</strong></em></p> | Le **capabilities da aggiungere/rimuovere durante l'esecuzione dei container**. Per impostazione predefinita usa il set di capabilities predefinito. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>privileged</strong></a><br><em>boolean</em></p> | Esegue il container in modalità privileged. I processi nei container privileged sono essenzialmente **equivalenti a root sull'host**. Il valore predefinito è false. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>procMount</strong></a><br><em>string</em></p> | procMount indica il **tipo di mount proc da usare per i container**. Il valore predefinito è DefaultProcMount, che usa i default del container runtime per i path in sola lettura e i masked path. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>capabilities</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#capabilities-v1-core"><em>Capabilities</em></a><br><em>More info about</em> <em><strong>Capabilities</strong></em></p> | Le **capabilities da aggiungere/rimuovere quando si eseguono i container**. Per impostazione predefinita usa il set di capabilities predefinito. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>privileged</strong></a><br><em>boolean</em></p> | Esegui il container in modalità privileged. I processi nei container privileged sono essenzialmente **equivalenti a root sull'host**. Il valore predefinito è false. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>procMount</strong></a><br><em>string</em></p> | procMount indica il **tipo di proc mount da usare per i container**. Il valore predefinito è DefaultProcMount, che usa i default del container runtime per i percorsi in sola lettura e i percorsi mascherati. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>readOnlyRootFilesystem</strong></a><br><em>boolean</em></p> | Indica se questo **container ha un filesystem root in sola lettura**. Il valore predefinito è false. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | Il **GID usato per eseguire l'entrypoint** del processo del container. Usa il valore predefinito del runtime se non impostato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | Indica che il container deve **essere eseguito come utente non root**. Se true, Kubelet validerà l'immagine a runtime per assicurarsi che non venga eseguita come UID 0 (root) e impedirà l'avvio del container se lo fa. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | L'**UID usato per eseguire l'entrypoint** del processo del container. Per impostazione predefinita usa l'utente specificato nei metadati dell'immagine se non viene specificato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | Il **contesto SELinux da applicare al container**. Se non specificato, il container runtime assegnerà un contesto SELinux casuale per ogni container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a></p> | Le **opzioni seccomp** da usare da questo container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsGroup</strong></a><br><em>integer</em></p> | Il **GID da usare per eseguire l'entrypoint** del processo del container. Usa il default del runtime se non impostato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsNonRoot</strong></a><br><em>boolean</em></p> | Indica che il container deve **essere eseguito come utente non-root**. Se true, il Kubelet convaliderà l'immagine a runtime per assicurarsi che non venga eseguita come UID 0 (root) e fallirà l'avvio del container se lo fa. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>runAsUser</strong></a><br><em>integer</em></p> | Il **UID da usare per eseguire l'entrypoint** del processo del container. Per impostazione predefinita usa l'utente specificato nei metadati dell'immagine se non specificato. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seLinuxOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#selinuxoptions-v1-core"><em>SELinuxOptions</em></a><br><em>More info about</em> <em><strong>seLinux</strong></em></p> | Il **contesto SELinux da applicare al container**. Se non specificato, il container runtime assegnerà un contesto SELinux casuale a ogni container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>seccompProfile</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#seccompprofile-v1-core"><em>SeccompProfile</em></a></p> | Le **opzioni seccomp** da usare per questo container. |
|
||||
| <p><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core"><strong>windowsOptions</strong></a><br><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#windowssecuritycontextoptions-v1-core"><em>WindowsSecurityContextOptions</em></a></p> | Le **impostazioni specifiche di Windows** applicate a tutti i container. |
|
||||
|
||||
## Practical workload review checklist
|
||||
|
||||
Quando analizzi un Pod o un workload template, controlla sia `spec.securityContext` sia ogni `securityContext` a livello di container sotto `containers`, `initContainers` e `ephemeralContainers`. I campi a livello di container possono sovrascrivere i default del pod, quindi un pod apparentemente sicuro non garantisce che ogni container sia sicuro.
|
||||
Quando esamini un Pod o un template di workload, controlla sia `spec.securityContext` sia ogni `securityContext` a livello di container sotto `containers`, `initContainers` e `ephemeralContainers`. I campi a livello di container possono sovrascrivere i default a livello di pod, quindi un default del pod apparentemente sicuro non garantisce che ogni container lo sia.
|
||||
|
||||
Combinazioni ad alto rischio da prioritizzare:
|
||||
|
||||
- `privileged: true`, soprattutto con `hostPID`, `hostIPC`, `hostNetwork`, `hostPath`, host ports o mount del runtime socket.
|
||||
- `privileged: true`, specialmente con `hostPID`, `hostIPC`, `hostNetwork`, `hostPath`, host ports o mount di runtime socket.
|
||||
- Capabilities aggiunte come `SYS_ADMIN`, `NET_ADMIN`, `SYS_PTRACE`, `SYS_MODULE`, `DAC_READ_SEARCH` o `DAC_OVERRIDE`.
|
||||
- `allowPrivilegeEscalation: true` o non impostato in container che possono eseguire codice controllato dall'attaccante.
|
||||
- `allowPrivilegeEscalation: true` o non impostato in container che possono eseguire codice controllato da un attaccante.
|
||||
- `seccompProfile: Unconfined`, `procMount: Unmasked` o profili runtime mancanti su workload sensibili.
|
||||
- Root filesystem scrivibili o mount di volumi ampiamente scrivibili in workload che elaborano input non fidato.
|
||||
- Mancanza di richieste e limiti di CPU, memory o ephemeral-storage in namespace multi-tenant.
|
||||
- Mancanza di request e limit di CPU, memoria o ephemeral-storage in namespace multi-tenant.
|
||||
- Mancanza di budget `spec.resources` a livello di pod o budget non realistici, e principal con `patch` o `update` sul subresource `resize` del Pod, perché i cluster supportati possono cambiare lo stato desiderato di CPU e memoria in esecuzione senza ricreare il Pod.
|
||||
|
||||
Per la maggior parte dei workload applicativi, una buona base è eseguire come UID non root, impostare `runAsNonRoot: true`, impostare `allowPrivilegeEscalation: false`, rimuovere tutte le capabilities e aggiungere solo quelle minime richieste, usare `seccompProfile: RuntimeDefault`, preferire un root filesystem in sola lettura ed evitare host namespaces, mount hostPath e modalità privileged.
|
||||
I controlli delle risorse non fanno parte di `securityContext`, ma vanno esaminati nello stesso passaggio del workload perché definiscono il confine di disponibilità. Le versioni moderne di Kubernetes possono definire budget di CPU, memoria e hugepage a livello di Pod sotto `spec.resources` oltre ai `resources` a livello di container. Un Pod con sidecar può essere limitato da un envelope aggregato del Pod anche se un container non ha limiti individuali, mentre l'ephemeral storage locale richiede ancora limiti separati `ephemeral-storage`, `emptyDir.sizeLimit`, LimitRanges e ResourceQuotas. Confronta anche le risorse desiderate nello spec del Pod con `status.containerStatuses[].resources` dopo una richiesta di resize in-place; un resize fallito o in sospeso può lasciare il valore richiesto in `spec` mentre il kubelet mantiene la precedente allocazione runtime e riporta una condizione `PodResizePending`.
|
||||
|
||||
A livello di cluster, usa i label del namespace di [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) per applicare, dove possibile, i [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) di Kubernetes. Usa `restricted` per i namespace che lo supportano, almeno `baseline` per i namespace applicativi ordinari, e mantieni le eccezioni privileged limitate, documentate e isolate in namespace di piattaforma fidati o node pool fidati.
|
||||
Per la maggior parte dei workload applicativi, una buona baseline è eseguire come UID non-root, impostare `runAsNonRoot: true`, impostare `allowPrivilegeEscalation: false`, rimuovere tutte le capabilities e aggiungere solo quelle minime necessarie, usare `seccompProfile: RuntimeDefault`, preferire un root filesystem in sola lettura ed evitare host namespaces, mount `hostPath` e modalità privileged.
|
||||
|
||||
A livello di cluster, usa le label dei namespace di [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) per applicare gli [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) di Kubernetes dove possibile. Usa `restricted` per i namespace che lo supportano, almeno `baseline` per i namespace applicativi ordinari, e mantieni le eccezioni privileged strette, documentate e isolate a namespace di piattaforma fidati o node pool.
|
||||
|
||||
## References
|
||||
|
||||
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#podsecuritycontext-v1-core)
|
||||
- [https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#securitycontext-v1-core)
|
||||
- [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
- [https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)
|
||||
- [https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/](https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/)
|
||||
- [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
|
||||
- [https://kubernetes.io/docs/concepts/security/pod-security-admission/](https://kubernetes.io/docs/concepts/security/pod-security-admission/)
|
||||
- [https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/)
|
||||
- [https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/](https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user