Crowdsec e Docker compose
In questo articolo vedremo come mettere al sicuro uno stack docker gestito con docker compose.
L’architettura
In questo esempio vedremo come mettere in sicurezza un’infrastruttura costituita da un reverse proxy fatto con Nginx, un applicazione servita da Apache 2 e due container per Crowdsec (uno dei quali dedicato alla dashboard). Per rendere accessibili i log giocheremo con i volumi di docker.
Diamo un’occhiata al file docker-compose.yml
version: '3'
services:
#the application itself : static html served by apache2.
#the html can be found in ./app/
app:
image: httpd:alpine
restart: unless-stopped
volumes:
- ./app/:/usr/local/apache2/htdocs/
networks:
- crowdsec_test
#the reverse proxy that will serve the application
#you can see nginx's config in ./reverse-proxy/nginx.conf
reverse-proxy:
image: nginx:alpine
restart: unless-stopped
ports:
- 8000:80
depends_on:
- 'app'
volumes:
- ./reverse-proxy/nginx.conf:/etc/nginx/nginx.conf
- logs:/var/log/nginx
networks:
- crowdsec_test
#crowdsec : it will be fed nginx's logs
#and later we're going to plug a firewall bouncer to it
crowdsec:
image: crowdsecurity/crowdsec:latest
restart: unless-stopped
environment:
#this is the list of collections we want to install
#https://hub.crowdsec.net/author/crowdsecurity/collections/nginx
COLLECTIONS: "crowdsecurity/nginx"
GID: "${GID-1000}"
depends_on:
- 'reverse-proxy'
ports:
- 127.0.0.1:8080:8080
volumes:
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
- logs:/var/log/nginx
- crowdsec-db:/var/lib/crowdsec/data/
- crowdsec-config:/etc/crowdsec/
networks:
- crowdsec_test
#metabase, because security is cool, but dashboards are cooler
dashboard:
#we're using a custom Dockerfile so that metabase pops with pre-configured dashboards
build: ./crowdsec/dashboard
restart: unless-stopped
ports:
- 3000:3000
environment:
MB_DB_FILE: /data/metabase.db
MGID: "${GID-1000}"
depends_on:
- 'crowdsec'
volumes:
- crowdsec-db:/metabase-data/
networks:
- crowdsec_test
volumes:
logs:
crowdsec-db:
crowdsec-config:
networks:
crowdsec_test:
Per fare i test possiamo clonare questo progetto su GitHub . In questo repository troveremo tutto il necessario; le modifiche che ho apportato al file docker-compose.yml sono:
- restart: unless-stopped
- rimozione di ip “statici”
- esposizione in locale della porta 8080 per il container crowdsec
Dopo aver clonato il progetto lo possiamo avviare
# docker-compose up -d
verifichiamo che sia tutto up e running
# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------------
example-docker-compose_app_1 httpd-foreground Up 80/tcp
example-docker-compose_crowdsec_1 /bin/sh -c /bin/sh docker_ ... Up
example-docker-compose_dashboard_1 /app/run_metabase.sh Up 0.0.0.0:3000->3000/tcp
example-docker-compose_reverse-proxy_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp
e testiamo la nostra applicazione
# curl http://localhost:8000/
Hello world !%
quali parser saranno attivi?
# docker-compose exec crowdsec cscli metrics
INFO[26-02-2022 09:07:42 PM] Acquisition Metrics:
+----------------------------------------+------------+--------------+----------------+------------------------+
| SOURCE | LINES READ | LINES PARSED | LINES UNPARSED | LINES POURED TO BUCKET |
+----------------------------------------+------------+--------------+----------------+------------------------+
| file:/var/log/nginx/example.access.log | 1 | 1 | - | - |
+----------------------------------------+------------+--------------+----------------+------------------------+
INFO[26-02-2022 09:07:42 PM] Parser Metrics:
+--------------------------------+------+--------+----------+
| PARSERS | HITS | PARSED | UNPARSED |
+--------------------------------+------+--------+----------+
| child-crowdsecurity/http-logs | 3 | 1 | 2 |
| child-crowdsecurity/nginx-logs | 1 | 1 | - |
| crowdsecurity/dateparse-enrich | 1 | 1 | - |
| crowdsecurity/geoip-enrich | 1 | 1 | - |
| crowdsecurity/http-logs | 1 | - | 1 |
| crowdsecurity/nginx-logs | 1 | 1 | - |
| crowdsecurity/non-syslog | 1 | 1 | - |
| crowdsecurity/whitelists | 1 | 1 | - |
+--------------------------------+------+--------+----------+
INFO[26-02-2022 09:07:42 PM] Local Api Metrics:
+--------------------+--------+------+
| ROUTE | METHOD | HITS |
+--------------------+--------+------+
| /v1/watchers/login | POST | 2 |
+--------------------+--------+------+
Crowdsec ha riconosciuto Nginx e Apache http server e sta già monitorando i log.
# docker-compose exec crowdsec cscli hub list
INFO[26-02-2022 09:08:48 PM] Loaded 23 collecs, 28 parsers, 36 scenarios, 3 post-overflow parsers
INFO[26-02-2022 09:08:48 PM] PARSERS:
-------------------------------------------------------------------------------------------------------------
NAME 📦 STATUS VERSION LOCAL PATH
-------------------------------------------------------------------------------------------------------------
crowdsecurity/sshd-logs ✔️ enabled 1.3 /etc/crowdsec/parsers/s01-parse/sshd-logs.yaml
crowdsecurity/http-logs ✔️ enabled 0.6 /etc/crowdsec/parsers/s02-enrich/http-logs.yaml
crowdsecurity/dateparse-enrich ✔️ enabled 0.1 /etc/crowdsec/parsers/s02-enrich/dateparse-enrich.yaml
crowdsecurity/nginx-logs ✔️ enabled 0.8 /etc/crowdsec/parsers/s01-parse/nginx-logs.yaml
crowdsecurity/geoip-enrich ✔️ enabled 0.2 /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml
crowdsecurity/whitelists ✔️ enabled 0.2 /etc/crowdsec/parsers/s02-enrich/whitelists.yaml
crowdsecurity/syslog-logs ✔️ enabled 0.4 /etc/crowdsec/parsers/s00-raw/syslog-logs.yaml
-------------------------------------------------------------------------------------------------------------
INFO[26-02-2022 09:08:48 PM] SCENARIOS:
--------------------------------------------------------------------------------------------------------------------------
NAME 📦 STATUS VERSION LOCAL PATH
--------------------------------------------------------------------------------------------------------------------------
crowdsecurity/http-open-proxy ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-open-proxy.yaml
crowdsecurity/http-xss-probing ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-xss-probing.yaml
ltsich/http-w00tw00t ✔️ enabled 0.1 /etc/crowdsec/scenarios/http-w00tw00t.yaml
crowdsecurity/http-generic-bf ✔️ enabled 0.1 /etc/crowdsec/scenarios/http-generic-bf.yaml
crowdsecurity/http-path-traversal-probing ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-path-traversal-probing.yaml
crowdsecurity/ssh-bf ✔️ enabled 0.1 /etc/crowdsec/scenarios/ssh-bf.yaml
crowdsecurity/http-backdoors-attempts ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-backdoors-attempts.yaml
crowdsecurity/http-bad-user-agent ✔️ enabled 0.4 /etc/crowdsec/scenarios/http-bad-user-agent.yaml
crowdsecurity/http-probing ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-probing.yaml
crowdsecurity/http-sensitive-files ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-sensitive-files.yaml
crowdsecurity/http-crawl-non_statics ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-crawl-non_statics.yaml
crowdsecurity/ssh-slow-bf ✔️ enabled 0.2 /etc/crowdsec/scenarios/ssh-slow-bf.yaml
crowdsecurity/http-sqli-probing ✔️ enabled 0.2 /etc/crowdsec/scenarios/http-sqli-probing.yaml
--------------------------------------------------------------------------------------------------------------------------
INFO[26-02-2022 09:08:48 PM] COLLECTIONS:
------------------------------------------------------------------------------------------------------------
NAME 📦 STATUS VERSION LOCAL PATH
------------------------------------------------------------------------------------------------------------
crowdsecurity/base-http-scenarios ✔️ enabled 0.5 /etc/crowdsec/collections/base-http-scenarios.yaml
crowdsecurity/sshd ✔️ enabled 0.2 /etc/crowdsec/collections/sshd.yaml
crowdsecurity/linux ✔️ enabled 0.2 /etc/crowdsec/collections/linux.yaml
crowdsecurity/nginx ✔️ enabled 0.1 /etc/crowdsec/collections/nginx.yaml
------------------------------------------------------------------------------------------------------------
INFO[26-02-2022 09:08:48 PM] POSTOVERFLOWS:
--------------------------------------
NAME 📦 STATUS VERSION LOCAL PATH
--------------------------------------
--------------------------------------
Possiamo sempre tenere sotto controllo i dati graficamente con la dashboard http://127.0.0.1:3000/ utilizzando l’username [email protected]
e la password !!Cr0wdS3c_M3t4b4s3??
Bloccare gli attacchi
Ora che riusciamo a rilevare gli attacchi dobbiamo proteggerci e per far questo dobbiamo installare e configurare il buttafuori (bouncer). Installiamo il Crowdsec iptables bouncer sulla macchina host (nel mio caso una Rocky Linux 8.5)
# curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.rpm.sh | bash
# dnf install crowdsec-firewall-bouncer-iptables
come visto nell’articolo di Crowdsec centralizzato per poter segnalare al buttafuori gli ip malevoli è necessario generare una chiave api univoca
# docker-compose exec crowdsec cscli bouncers add HostFirewallBouncer
Api key for 'HostFirewallBouncer':
81d55de358ef393e27768594057cf40b
Please keep this key since you will not be able to retrieve it!
editiamo il file /etc/crowdsec/cs-firewall-bouncer/cs-firewall-bouncer.yaml e impostiamo:
- api_url
- api_key
- iptables_chains
- disable_ipv6
mode: iptables
piddir: /var/run/
update_frequency: 10s
daemonize: true
log_mode: file
log_dir: /var/log/
log_level: info
api_url: http://172.20.0.4:8080/
api_key: 81d55de358ef393e27768594057cf40b
disable_ipv6: true
#if present, insert rule in those chains
iptables_chains:
- DOCKER-USER
e riavviamo il bouncer
# systemctl restart crowdsec-firewall-bouncer.service
Spero che questa piccola guida vi sia da ispirazione per i vostri stack.
Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.
Risorse: