Marvin Pascale

[B.Log]

24 Settembre 2022

Crowdsec e TLS

Ad inizio anno, abbiamo visto come gestire in maniera centralizzata i bouncer di Crowdsec.

Partendo da quell’installazione possiamo migliorare la comincazione tra l’api centrale e i vari bouncers aggiungendo il TLS.

NB: dovremmo attendere la versione ufficiale 0.25 del firewall bouncer (che supporterà ufficialmente il TLS)

Cos’è Transport Layer Security (TLS)?

Il Transport Layer Security (per gli amici TLS), è un protocollo di sicurezza ampiamente diffuso progettato per facilitare la privacy e la sicurezza dei dati per le comunicazioni su Internet. Utilizzato tantissimo nelle comunicazioni http (https), il TLS può essere utilizzato anche per crittografare altre comunicazioni come e-mail, messaggistica e Voice over IP (VoIP).

Il TLS è stato proposto dalla Internet Engineering Task Force (IETF), un’organizzazione internazionale per gli standard, e la prima versione del protocollo è stata pubblicata nel 1999. La versione più recente è TLS 1.3, pubblicata nel 2018.

TLS con Crowdsec

Nello scenario di partenza abbiamo gli agenti in grado di comunicare con il server LAPI principale, utilizzando la comunicazione in chiaro (http). Partendo da questo scenario, quindi, dobbiamo passare a un’infrastruttura basata su certificati.

In questa simulazione creeremo dei certificati autofirmati; ma, nel caso in cui tu abbia dei certificati validi per il tuo dominio, puoi utilizzare quelli.

Per generare i certificati utilizzeremo l’utility go golang-cfssl. Per installarlo su Debian e derivate

# apt install golang-cfssl

a questo punto creiamo una cartella cfssl e all’interno di quest’ultima inseriamo il file profiles.json

{
    "signing": {
      "default": {
        "expiry": "8760h"
      },
      "profiles": {
        "intermediate_ca": {
          "usages": [
              "signing",
              "digital signature",
              "key encipherment",
              "cert sign",
              "crl sign",
              "server auth",
              "client auth"
          ],
          "expiry": "8760h",
          "ca_constraint": {
              "is_ca": true,
              "max_path_len": 0,
              "max_path_len_zero": true
          }
        },
        "server": {
          "usages": [
            "signing",
            "digital signing",
            "key encipherment",
            "server auth"
          ],
          "expiry": "8760h"
        },
        "client": {
          "usages": [
            "signing",
            "digital signature",
            "key encipherment",
            "client auth"
          ],
          "expiry": "8760h"
        }
      }
    }
  }

e la nostra CA

{
  "CN": "Marvin Lan CA",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
  {
    "C": "IT",
    "L": "Bologna",
    "O": "MarvinPascale",
    "OU": "Marvin",
    "ST": "Italy"
  }
 ]
}

anche l’intermediate.json

{
    "CN": "Marvin LAN CA Intermediate",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
    {
      "C": "IT",
      "L": "Bologna",
      "O": "MarvinPascale",
      "OU": "Marvin Intermediate",
      "ST": "Italy"
    }
   ],
   "ca": {
    "expiry": "42720h"
  }
  }

nel server.json invece dovete anche impostare la subnet corretta

{
    "CN": "localhost",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
    {
      "C": "IT",
      "L": "Bologna",
      "O": "MarvinPascale",
      "OU": "Crowdsec Server",
      "ST": "Italy"
    }
    ],
    "hosts": [
      "127.0.0.1",
      "localhost"
      "10.17.60.43"
    ]
  }

Infine ci sono i certificati di agenti e buttafuori. Ogni agente e buttafuori dovrebbe avere il proprio certificato (il CN di ciascuno in deve corrispondere).

agent[123].json

{
    "CN": "agent[123]",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
    {
      "C": "IT",
      "L": "Bologna",
      "O": "MarvinPascale",
      "OU": "agent-ou",
      "ST": "Italy"
    }
    ]
  }

bouncer-agent[123].json

{
    "CN": "bouncer-agent-[123]",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
    {
      "C": "IT",
      "L": "Bologna",
      "O": "MarvinPascale",
      "OU": "bouncer-ou",
      "ST": "Italy"
    }
    ]
  }

Creiamo la CA

# cfssl gencert --initca ./cfssl/ca.json 2>/dev/null | cfssljson --bare "/tmp/ca"

e i certificati degli agent e buttafuori

# cfssl gencert --initca ./cfssl/intermediate.json 2>/dev/null | cfssljson --bare "/tmp/inter"
# cfssl sign -ca "/tmp/ca.pem" -ca-key "/tmp/ca-key.pem" -config ./cfssl/profiles.json -profile intermediate_ca "/tmp/inter.csr" 2>/dev/null | cfssljson --bare "/tmp/inter"

Server side certificate

# cfssl gencert -ca "/tmp/inter.pem" -ca-key "/tmp/inter-key.pem" -config ./cfssl/profiles.json -profile=server ./cfssl/server.json 2>/dev/null | cfssljson --bare "/tmp/server"

Client certificate per gli agenti

# cfssl gencert -ca "/tmp/inter.pem" -ca-key "/tmp/inter-key.pem" -config ./cfssl/profiles.json -profile=client ./cfssl/agent[123].json 2>/dev/null | cfssljson --bare "/tmp/agent[123]"

Client certificate per i bouttafuori

# cfssl gencert -ca "/tmp/inter.pem" -ca-key "/tmp/inter-key.pem" -config ./cfssl/profiles.json -profile=client ./cfssl/bouncer.json 2>/dev/null | cfssljson --bare "/tmp/bouncer"

Per poter far verificare i certificate al server LAPI centrale avremmo bisogno sia della CA che dell’intermediate (fullchain).

# cat /tmp/ca.pem /tmp/inter.pem > /tmp/fullchain.pem

copiamo tutti i certificati in /etc/ssl/certs

# cp /tmp/*.pem /etc/ssl/certs

Ora siamo pronti per poter utilizzare i certificati sia sul server centra che sugli agent e i buttafuori.

Sul server LAPI aditiamo il file /etc/crowdsec/config.yaml

api:
 server:
   tls:
    cert_file: /etc/ssl/certs/server.pem #Server side cert
    key_file: /etc/ssl/certs/server-key.pem #Server side key
    ca_cert_path: /etc/ssl/fullchain.pem #certificate used to verify client certs
    bouncers_allowed_ou: #OU allowed for bouncers
      - bouncer-ou
    agents_allowed_ou: #OU allowed for agents
      - agent-ou

per gli agenti invece /etc/crowdsec/local_api_credentials.yaml

url: https://10.17.60.43:8080
ca_cert_path: /etc/ssl/certs/ca-combined.pem #certificate used to verify client certs
key_path: /etc/ssl/certs/agent[123]-key.pem #Client key.
cert_path: /tmp/agent[123].pem #Client cert

per i buttafuori editimo /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml

url: https://10.17.60.43:8080
cert_path: /etc/ssl/certs/bouncer-agent-[123].pem
key_path: /etc/ssl/certs/bouncer-agent-[123]-key.pem
ca_cert_path: /etc/ssl/certs/fullchain.pem
#api_key: <api key>


Non ci resta che riavviare tutti i servizi e controllare dai log che sia ripartito tutto correttamente.


Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.

Risorse: