Ho abbandonato l’hosting – Hardening

Per migliorare la sicurezza del mio vps, ho pensato che non potevo lasciarlo solo con un “semplice” firewall e basta.

Per prima cosa, visto che ho installato WireGuard sia sul server VPS che sul mio client, ho spostato tutte le comnessioni da “any” per le interfacce di ftp, al wg0, linterfaccia di wireGuard

[ 7] 21/tcp on wg0              ALLOW IN    10.20.0.0/24              
[ 8] 50000:50999/tcp on wg0     ALLOW IN    10.20.0.0/24    

Facendo un controolo sul failban incorporato nel docker del mail sercve faccio una pessima scoperta (ma prevedibile)

docker exec -it mailserver iptables -L -n
OCI runtime exec failed: exec failed: unable to start container process: exec: "iptables": executable file not found in $PATH

Quindi il failban inserito nel container, non solo non fa il suo lavoro, ma come potrebbe farlo se modifica il caneuto del firewall all0interno di un container che non contiene iptables ?

Per tutelare la macchina allora dovrei installare failban a livello di SO, ma girovagando zmi sono imbattuto in CrowdSec che è un IDS/IPS ed anche WAF: perfetto !

In soldoni CrowdSec analizza i log e verifica se sono attacchi o meno.

per installarlo

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash
apt install -y crowdsec crowdsec-firewall-bouncer-iptables

Per prima cosa, allora ho disabilitato all’interno del container del mail server fail2ban

ENABLE_FAIL2BAN=0

e poi

docker compose restart mailserver

e cosiderato che CS deve leggere i log, ho modificato dove scrivere i log in modo che possano essere analizzati

il reverse proxy in

  - /var/log/docker/nginx:/var/log/nginx

ed il mail server in

- /var/log/docker/mail:/var/log/mail

ho lasciato il “resto” nei path preimpostati.

I log sono definiti nel file

/etc/crowdsec/acquis.d/prod.yaml

ed il cui contenuto deve essere il seguente

filenames:
  - /var/log/auth.log
  - /var/log/nginx/*.log
  - /var/log/mail.log
  - /var/log/docker/mail/*.log
  - /var/log/docker/nginx/*.log

labels:
  type: syslog

riavviamo

systemctl restart crowdsec

e vediamo che succede

cscli metrics
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Acquisition Metrics                                                                                                              │
├────────────────────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────┤
│ Source                                 │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/var/log/auth.log                 │ 209        │ 179          │ 30             │ 581                    │ -                 │
│ file:/var/log/docker/mail/clamav.log   │ 40         │ -            │ 40             │ -                      │ -                 │
│ file:/var/log/docker/mail/fail2ban.log │ 45         │ -            │ 45             │ -                      │ -                 │
│ file:/var/log/docker/mail/mail.log     │ 27         │ 2            │ 25             │ 1                      │ -                 │
│ file:/var/log/docker/nginx/access.log  │ 324        │ -            │ 324            │ -                      │ -                 │
│ file:/var/log/docker/nginx/error.log   │ 1          │ -            │ 1              │ -                      │ -                 │
│ file:/var/log/kern.log                 │ 61         │ -            │ 61             │ -                      │ -                 │
│ file:/var/log/syslog                   │ 100        │ -            │ 100            │ -                      │ -                 │
╰────────────────────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯

bene: stiamo loggndo il traffico.

Ulteriore conferma da

cscli bouncers list
─────────────────────────────────────────────────────────────────────────────────
 Name                 IP Address  Valid  Last API pull  Type  Version  Auth Type 
─────────────────────────────────────────────────────────────────────────────────
 cs-firewall-bouncer              ✔️                                   api-key   
─────────────────────────────────────────────────────────────────────────────────

CrowdSec blocca gli ip PRIMA del loro arrivo sul container

AzioneComando
IP bannaticscli decisions list
Sblocca IPcscli decisions delete --ip X.X.X.X
Metrichecscli metrics

per verificare che l’estensioni del fireall siamo installate

il comando rowdsec-firewall-bouncer -version deve rispondere

rowdsec-firewall-bouncer -version
version: v0.0.34-debian-pragmatic-amd64-4144555453620958398aee64253dfd90bbc1f698
BuildDate: 2025-08-04_10:04:33
GoVersion: 1.24.5
Platform: linux

e con iptables -S | grep CROWDSEC abbiamo la conferma che il iptables hasubito un’aggiunta

-N CROWDSEC_CHAIN
-A INPUT -j CROWDSEC_CHAIN
-A CROWDSEC_CHAIN -m set --match-set crowdsec-blacklists-1 src -m comment --comment "CrowdSec: CAPI" -j DROP
-A CROWDSEC_CHAIN -m set --match-set crowdsec-blacklists-0 src -m comment --comment "CrowdSec: crowdsec" -j DROP

Il database gestito da CrowdSec non va bene in sqlite (secondo la mia testa) ed alloa utilizzo postresql in container il cui file docker-compose.yaml in /opt/postgis è

services:
  postgres:
    container_name: postgiis_container
    image: postgis/postgis:16-3.5
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: defaultpassword
      PGDATA: /var/lib/postgresql/data
      POSTGRES_LOGGING_COLLECTOR: "off"
    volumes:
      - ./data:/var/lib/postgresql/data
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
      - ./pg_hba.conf:/etc/postgresql/pg_hba.conf
    ports:
      - "5432:5432"
    restart: always
    command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf",
               "-c", "hba_file=/etc/postgresql/pg_hba.conf",]
volumes:
  data:
    driver: local
  logs:
    driver: local
definire db ed utente di postgresql
sudo -u postgres psql
CREATE DATABASE crowdsec;

CREATE USER crowdsec WITH PASSWORD 'PASSWORD_FORTE';
GRANT ALL PRIVILEGES ON DATABASE crowdsec TO crowdsec;
GRANT USAGE, CREATE ON SCHEMA public TO crowdsec;
GRANT CONNECT ON DATABASE crowdsec TO crowdsec;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO crowdsec;
ALTER SCHEMA public OWNER TO crowdsec;

CREATE USER crowdsec_ro WITH PASSWORD 'PASSWORD_RO';
GRANT CONNECT ON DATABASE crowdsec TO crowdsec_ro;
GRANT USAGE ON SCHEMA public TO crowdsec_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO crowdsec_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
\q

l’utente crowdsec_ro potrebbe serivire per leggere le tabelle di postgresql.

ho impostato postgres_logging_collector a off in quanto mi dava problemi per la reazione del file di log, ma essendo un database solo per CrowdSec non mi ci ho pensato due volte as togliere ilfile di log.

modifichiamo il file /etc/crowdsec/config.yaml per togliere sqllite ed instanziare postgresql: da

db_config:
  type: sqlite
  db_path: /var/lib/crowdsec/data/crowdsec.db

a

db_config:
  type: postgresql
  host: 127.0.0.1
  port: 5432
  user: crowdsec
  password: PASSWORD_FORTE
  db_name: crowdsec
  sslmode: disable

a questo punto

systemctl restart crowdsec

eseguendo

sudo -u root psql crowdsec -c "\dt"

devono apparire le seguenti tabelle

crowdsec=> \dt
                   List of relations
 Schema |            Name            | Type  |  Owner   
--------+----------------------------+-------+----------
 public | alerts                     | table | crowdsec
 public | allow_list_allowlist_items | table | crowdsec
 public | allow_list_items           | table | crowdsec
 public | allow_lists                | table | crowdsec
 public | bouncers                   | table | crowdsec
 public | config_items               | table | crowdsec
 public | decisions                  | table | crowdsec
 public | events                     | table | crowdsec
 public | locks                      | table | crowdsec
 public | machines                   | table | crowdsec
 public | meta                       | table | crowdsec
 public | metrics                    | table | crowdsec
(12 rows)

allora tutto bene!

Siccome abbiamo cambiato le carte in tavola, crowdsec potrebbe non essere contento del cambio.

Potrebbe essere necessario eseguire

rm -f /etc/crowdsec/local_api_credentials.yaml

che non fa altro che cancellare il vecchio riferimento e per ricrearlo bisogna eseguire

cscli machines add localhost --auto

il cui output deve essere

Machine 'localhost' successfully added

ed allora far ripartire crowdsec

systemctl restart crowdsec

e vedere il risultato da

cscli alerts list
cscli alerts inspect "alert da sopra"
cscli decisions list

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.