Best practices per la sicurezza su OpenShift

banner

OpenShift è una piattaforma di containerizzazione che si basa su Kubernetes, ma con alcune differenze significative rispetto a Docker. Se stai pensando di migrare i tuoi container da Docker a OpenShift, ci sono alcune best practices da considerare:

  • Immagini compatibili: Assicurati che le tue immagini siano compatibili con OpenShift. OpenShift supporta immagini OCI e Docker, ma è importante verificare che non ci siano dipendenze specifiche di Docker che potrebbero causare problemi.
  • UID arbitrari: OpenShift consente l’esecuzione di container con UID arbitrari, il che significa che puoi eseguire i tuoi container come un utente non root. Questo è importante per la sicurezza e per evitare conflitti di permessi.
  • Configurazione del SecurityContext: Configura il SecurityContext per i tuoi pod e container. Questo ti permette di specificare le politiche di sicurezza, come l’uso di un utente non root, la gestione dei volumi e altre impostazioni di sicurezza.
  • ServiceAccount e ImagePullSecret: Utilizza i ServiceAccount per gestire le autorizzazioni dei tuoi container e configura gli ImagePullSecret per accedere a registri privati. Questo è importante per garantire che i tuoi container possano essere eseguiti correttamente in OpenShift.
  • Persistenza dei dati: Se i tuoi container gestiscono dati persistenti, considera l’uso di PersistentVolumeClaim (PVC) per gestire i volumi in modo più efficiente. OpenShift gestisce i volumi in modo diverso rispetto a Docker, quindi è importante adattare la tua configurazione di conseguenza.
  • Sicurezza e best practices: OpenShift ha un modello di sicurezza più rigoroso rispetto a Docker, quindi è importante seguire le best practices per garantire che i tuoi container siano sicuri. Questo include l’uso di SecurityContextConstraints (SCC) e la configurazione corretta delle autorizzazioni.

Esempio di Dockerfile per OpenShift

Immagina di avere un’applicazione Node.js che vuoi eseguire su OpenShift. Ecco un esempio di Dockerfile che segue le best practices:

FROM node:20-alpine
USER 1001
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY ../../draft .
EXPOSE 3000
CMD ["node", "server.js"]

Questo Dockerfile:

  • Utilizza un’immagine base di Node.js.
  • Esegue il container come utente non root (UID 1001).
  • Imposta la directory di lavoro su /app.
  • Copia i file di configurazione e installa le dipendenze.
  • Espone la porta 3000 per l’applicazione.
  • Esegue il server Node.js grazie all’istruzione CMD.

Una volta preparato il Dockerfile, puoi eseguire la build dell’immagine ed eseguirne il deploy su OpenShift utilizzando i comandi oc o tramite l’interfaccia web di OpenShift a partire dal registry dell’immagine che hai utilizzato.

Se hai dubbi su come portare la tua immagine su un registry privato, dai un’occhiata a questo articolo dove spieghiamo come portare la tua applicazione su Kubernetes in Vite.js da zero utilizzando Quay.io o Docker Hub.

Su OpenShift è possibile utilizzare i template per semplificare il processo di deploy. Ecco un esempio di template che puoi utilizzare:

apiVersion: template.openshift.io/v1
kind: Template
metadata:
  name: my-node-app
objects:
- apiVersion: v1
  kind: Service
  metadata:
    name: my-node-app
  spec:
    ports:
    - port: 3000
      targetPort: 3000
    selector:
      app: my-node-app
- apiVersion: apps/v1
  kind: Deployment
  metadata:
      name: my-node-app
  spec:
    replicas: 1
    selector:
    matchLabels:
      app: my-node-app
    template:
    metadata:
      labels:
        app: my-node-app
      spec:
        containers:
        - name: my-node-app
          image: myregistry/my-node-app:latest
          ports:
          - containerPort: 3000
          securityContext:
            runAsUser: 1001

In questo esempio, il template definisce un servizio e un deployment per l’applicazione Node.js. Il deployment specifica l’immagine da utilizzare e le impostazioni di sicurezza per eseguire il container come utente non root. In particolare, l’istruzione runAsUser: 1001 garantisce che il container venga eseguito con un UID non privilegiato, migliorando la sicurezza dell’applicazione.

Per aggiungere uno strato di sicurezza ulteriore, è possibile configurare i SecurityContextConstraints (SCC) per limitare le azioni che i container possono eseguire. Ad esempio, puoi creare un SCC personalizzato che consente solo l’esecuzione di container con un UID specifico e limita l’accesso a determinate risorse del sistema, oppure utilizzare la direttiva allowPrivilegeEscalation: false per impedire l’escalation dei privilegi all’interno del container.

Un altro esempio è l’uso della direttiva readOnlyRootFilesystem: true, che rende il filesystem di root del container in sola lettura, impedendo modifiche non autorizzate ai file di sistema. Questo è particolarmente utile per applicazioni che non necessitano di scrivere sul filesystem di root e contribuisce a ridurre la superficie di attacco.

Esiste poi anche la direttiva runAsNonRoot che, se impostata su true, garantisce che il container venga eseguito come un utente non root, migliorando ulteriormente la sicurezza.

Infine, la direttiva capabilities può essere utilizzata per limitare le capacità del container, ad esempio rimuovendo capacità come NET_ADMIN o SYS_ADMIN, che potrebbero essere utilizzate per compromettere la sicurezza del sistema, così come l’uso di seccompProfile per applicare profili di sicurezza specifici che limitano le chiamate di sistema disponibili al container.

Per capacità nel contesto di un sistema Unix-based si intende un insieme di privilegi che possono essere assegnati a un processo. Queste capacità consentono di eseguire operazioni specifiche senza dover eseguire il processo come root, migliorando la sicurezza e la granularità dei permessi. Alcuni esempi sono CAP_NET_ADMIN per la gestione della rete, CAP_SYS_ADMIN per operazioni di amministrazione del sistema, e CAP_DAC_OVERRIDE per ignorare le regole di accesso ai file. In OpenShift, puoi configurare le capacità dei container tramite il SecurityContext, specificando quali capacità devono essere aggiunte o rimosse dal container.

L’esempio precedente rivisto è il seguente:

apiVersion: template.openshift.io/v1
kind: Template
metadata:
  name: my-node-app
objects:
- apiVersion: v1
  kind: Service
  metadata:
    name: my-node-app
  spec:
    ports:
    - port: 3000
      targetPort: 3000
    selector:
      app: my-node-app
- apiVersion: apps/v1
  kind: Deployment
  metadata:
      name: my-node-app
  spec:
    replicas: 1
    selector:
    matchLabels:
      app: my-node-app
    template:
    metadata:
      labels:
        app: my-node-app
      spec:
        containers:
        - name: my-node-app
          image: myregistry/my-node-app:latest
          ports:
          - containerPort: 3000
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
              - ALL # Rimuove tutte le capabilities, lasciando solo quelle di base
            readOnlyRootFilesystem: true
            runAsNonRoot: true
            runAsUser: 1001

Considerazioni finali

Per quanto OpenShift sia uno dei prodotti di punta di Red Hat, è importante tenere a mente alcune considerazioni quando si lavora con i container: il fatto che la soluzione che mettete in esecuzione sia compatibile con OpenShift non implica necessariamente che sia sicura o conforme alle best practices di sicurezza. Ecco perché è fondamentale seguire le best practices di sicurezza e configurazione per garantire che i tuoi container siano sicuri e funzionino correttamente in OpenShift, tra cui quelle descritte in questo articolo.

Se poi vuoi approfondire ulteriormente come migrare da Docker a OpenShift, ti consiglio di dare un’occhiata a questo articolo dove descriviamo in dettaglio le best practices per la migrazione e l’ottimizzazione dei container su OpenShift.

Risorse utili

Post correlati

TheRedCode.it - Il mondo #tech a piccoli #bit

Partners

Community, aziende e persone che supportano attivamente il blog

Logo di Codemotion
Logo di GrUSP
Logo di Python Milano
Logo di Schrodinger Hat
Logo di Python Biella Group
Logo di Fuzzy Brains
Logo di Django Girls
Logo di Improove
Logo del libro open source
Logo di NgRome
Logo de La Locanda del Tech
Logo di Tomorrow Devs
Logo di DevDojo
Logo di Cloud Native Days 2025

Non perderti gli ultimi aggiornamenti, iscriviti a TheRedCode Digest!

La tecnologia corre, e tu devi correre più veloce per rimanere sempre sul pezzo! 🚀

Riceverai una volta al mese (o anche meno) con codici sconto per partecipare agli eventi del settore, quiz per vincere dei gadget e i recap degli articoli più interessanti pubblicati sul blog

Ci sto!

Vuoi diventare #tech content creator? 🖊️

Se vuoi raccontare la tua sul mondo #tech con dei post a tema o vuoi condividere la tua esperienza con la community, sei nel posto giusto! 😉

Manda una mail a collaborazioni[at]theredcode.it con la tua proposta e diventa la prossima penna del blog!

Ma sì, facciamolo!