Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions defaults/settings.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dynamic_ip: false
data_folder: /mnt/storage
tz: "Europe/Berlin"
notifications_email: example@mail.com
use_crowdsec: true
cloudflare:
tag_ddns: latest
tag_companion: latest
Expand Down Expand Up @@ -176,7 +177,11 @@ speedtesttracker:
folder: /opt/speedtesttracker
subdomain: speedtesttracker
crowdsec:
tag: latest-debian
folder: /opt/crowdsec
subdomain: crowdsec
console_enrollment_key: console_enrollment_key
firewall_bouncer_key: firewall_bouncer_key
traefik_bouncer_key: traefik_bouncer_key
tinymotd:
folder: /opt/tinymotd
19 changes: 19 additions & 0 deletions roles/crowdsec/tasks/config/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- name: Wait for CrowdSec container to be healthy
become: true
community.docker.docker_container_info:
name: crowdsec
register: crowdsec_info
until: crowdsec_info.container.State.Running
retries: 10
delay: 3

- name: Enroll CrowdSec console
community.docker.docker_container_exec:
container: crowdsec
command: "cscli console enroll {{ crowdsec.console_enrollment_key }}"

- name: Enroll CrowdSec Firewall Bouncer
community.docker.docker_container_exec:
container: crowdsec
command: "crowdsec cscli bouncers add firewall-bouncer --key {{ crowdsec.firewall_bouncer_key }}"
35 changes: 35 additions & 0 deletions roles/crowdsec/tasks/firewall/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
- name: Install syslog-ng
become: yes
ansible.builtin.apt:
name: syslog-ng
state: present
update_cache: yes

- name: Install CrowdSec Repository
become: yes
ansible.builtin.shell: |
curl -s https://install.crowdsec.net | sh
args:
executable: /bin/bash

- name: Install CrowdSec firewall bouncer
become: yes
ansible.builtin.apt:
name: crowdsec-firewall-bouncer-iptables
state: present
update_cache: yes

- name: Create firewall bouncer config file
template:
src: firewall-bouncer.yaml.j2
dest: /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
force: yes
owner: root
group: root
mode: 0600

- name: Enable and start CrowdSec Firewall Bouncer
ansible.builtin.systemd:
name: crowdsec-firewall-bouncer
enabled: true
state: started
57 changes: 57 additions & 0 deletions roles/crowdsec/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
- name: Create directories
file:
path: "{{ item }}"
state: directory
owner: "{{ user }}"
group: "{{ group }}"
mode: 0775
recurse: yes
loop:
- "{{ crowdsec.folder }}"
- "{{ crowdsec.folder }}/config"
- "{{ crowdsec.folder }}/database"

- name: "Create acquis config file"
template:
src: acquis.yaml.j2
dest: "{{ crowdsec.folder }}/acquis.yaml"
force: yes
owner: "{{ user }}"
group: "{{ group }}"
mode: 0775

- name: Create and start container
docker_container:
name: crowdsec
image: "crowdsecurity/crowdsec:{{ crowdsec.tag }}"
pull: yes
recreate: true
volumes:
- "{{ crowdsec.folder }}/config:/etc/crowdsec"
- "{{ crowdsec.folder }}/acquis.yaml:/etc/crowdsec/acquis.yaml"
- "{{ crowdsec.folder }}/database:/var/lib/crowdsec/data"
# System logs
- /var/log/auth.log:/var/log/auth.log:ro
- /var/log/syslog:/var/log/syslog.log:ro
- /var/log/kern.log:/var/log/kern.log:ro
# Traefik logs
- "{{ traefik.folder }}/logs:/var/log/traefik:ro"
networks:
- name: web
aliases:
- crowdsec
ports:
- 127.0.0.1:9876:8080 # port mapping for local firewall bouncer
restart_policy: unless-stopped
state: started
labels:
env:
GID: "{{ gid | int }}"
COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/base-http-scenarios crowdsecurity/sshd crowdsecurity/appsec-generic-rules crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-crs"

- name: Configure Crowdsec
include_tasks: "config/main.yml"

- name: Configure Firewall Bouncer
include_tasks: "firewall/main.yml"
20 changes: 20 additions & 0 deletions roles/crowdsec/templates/acquis.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
filenames:
- /var/log/auth.log
- /var/log/syslog
- /var/log/kern.log
labels:
type: syslog
---
poll_without_inotify: false
filenames:
- /var/log/traefik/*.log
labels:
type: traefik
---
listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/appsec-default
name: myAppSecComponent
source: appsec
labels:
type: appsec
63 changes: 63 additions & 0 deletions roles/crowdsec/templates/firewall-bouncer.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
mode: iptables
update_frequency: 10s
log_mode: file
log_dir: /var/log/
log_level: info
log_compression: true
log_max_size: 100
log_max_backups: 3
log_max_age: 30
api_url: http://127.0.0.1:9876/
api_key: {{ crowdsec.firewall_bouncer_key }}
## TLS Authentication
# cert_path: /etc/crowdsec/tls/cert.pem
# key_path: /etc/crowdsec/tls/key.pem
# ca_cert_path: /etc/crowdsec/tls/ca.crt
insecure_skip_verify: false
disable_ipv6: false
deny_action: DROP
deny_log: false
supported_decisions_types:
- ban
#to change log prefix
#deny_log_prefix: "crowdsec: "
#to change the blacklists name
blacklists_ipv4: crowdsec-blacklists
blacklists_ipv6: crowdsec6-blacklists
#type of ipset to use
ipset_type: nethash
#if present, insert rule in those chains
iptables_chains:
- INPUT
# - FORWARD
# - DOCKER-USER
iptables_add_rule_comments: true

## nftables
nftables:
ipv4:
enabled: true
set-only: false
table: crowdsec
chain: crowdsec-chain
priority: -10
ipv6:
enabled: true
set-only: false
table: crowdsec6
chain: crowdsec6-chain
priority: -10

nftables_hooks:
- input
- forward

# packet filter
pf:
# an empty string disables the anchor
anchor_name: ""

prometheus:
enabled: false
listen_addr: 127.0.0.1
listen_port: 60601
1 change: 1 addition & 0 deletions roles/hardening/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- name: Install Fail2Ban
include_tasks: "fail2ban/main.yml"
when: not use_crowdsec | bool

- name: Install Unattended Upgrades
include_tasks: "unattendedupgrades/main.yml"
19 changes: 16 additions & 3 deletions roles/traefik/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
loop:
- "{{ traefik.folder }}"
- "{{ traefik.folder }}/certificates"
- "{{ traefik.folder }}/logs"

- name: Download Cloudflare certificate for mTLS
ansible.builtin.get_url:
Expand Down Expand Up @@ -41,6 +42,11 @@
dest: "{{ traefik.folder }}/dynamic.yml"
mode: 0600

- name: Ensure access.log file exists
file:
path: "{{ traefik.folder }}/logs/access.log"
state: touch

- name: Create the web network
docker_network:
name: web
Expand All @@ -59,9 +65,10 @@
volumes:
- "{{ traefik.folder }}/traefik.yml:/etc/traefik/traefik.yml"
- "{{ traefik.folder }}/dynamic.yml:/etc/traefik/dynamic/dynamic.yml"
- "{{ traefik.folder }}/certificates/cf_authenticated_origin_pull_ca.pem:/etc/traefik/dynamic/authenticated_origin_pull_ca.pem"
- "{{ traefik.folder }}/certificates/origin_certificate.pem:/etc/traefik/dynamic/{{ domain }}.pem"
- "{{ traefik.folder }}/certificates/origin_certificate.key:/etc/traefik/dynamic/{{ domain }}.key"
- "{{ traefik.folder }}/certificates/cf_authenticated_origin_pull_ca.pem:/etc/traefik/dynamic/authenticated_origin_pull_ca.pem:ro"
- "{{ traefik.folder }}/certificates/origin_certificate.pem:/etc/traefik/dynamic/{{ domain }}.pem:ro"
- "{{ traefik.folder }}/certificates/origin_certificate.key:/etc/traefik/dynamic/{{ domain }}.key:ro"
- "{{ traefik.folder }}/logs/access.log:/var/log/traefik/access.log"
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
labels:
Expand All @@ -83,3 +90,9 @@
env:
CF_API_KEY: "{{ cloudflare.api_key }}"
CF_API_EMAIL: "{{ cloudflare.api_email }}"

- name: Enroll Traefik Firewall Bouncer
community.docker.docker_container_exec:
container: crowdsec
command: "crowdsec cscli bouncers add traefik-bouncer --key {{ crowdsec.traefik_bouncer_key }}"
when: use_crowdsec | bool
29 changes: 29 additions & 0 deletions roles/traefik/templates/dynamic.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,32 @@ tls:
defaultCertificate:
certFile: /etc/traefik/dynamic/{{ domain }}.pem
keyFile: /etc/traefik/dynamic/{{ domain }}.key

{% if use_crowdsec %}
http:
middlewares:
crowdsec:
plugin:
bouncer:
enabled: true
defaultDecisionSeconds: 60
crowdsecMode: live
crowdsecAppsecEnabled: false
crowdsecAppsecHost: crowdsec:7422
crowdsecAppsecFailureBlock: true
crowdsecAppsecUnreachableBlock: true
crowdsecLapiKey: {{ crowdsec.traefik_bouncer_key }}
crowdsecLapiHost: crowdsec:8080
crowdsecLapiScheme: http
crowdsecLapiTLSInsecureVerify: false
forwardedHeadersTrustedIPs:
# private class ranges
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
clientTrustedIPs:
# private class ranges
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
{% endif %}
Loading