Setup crowdsec with ssh/firewall/traefik
This commit is contained in:
parent
2adadb30e8
commit
dc03244a3c
6
nixos/viridian/services/crowdsec/acquis.d/appsec.yaml
Normal file
6
nixos/viridian/services/crowdsec/acquis.d/appsec.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
listen_addr: 127.0.0.1:7422
|
||||||
|
appsec_config: crowdsecurity/appsec-default
|
||||||
|
name: traefik
|
||||||
|
source: appsec
|
||||||
|
labels:
|
||||||
|
type: appsec
|
94
nixos/viridian/services/crowdsec/default.nix
Normal file
94
nixos/viridian/services/crowdsec/default.nix
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
{ config, inputs, pkgs, ... }:
|
||||||
|
let
|
||||||
|
port = "8080";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.crowdsec.nixosModules.crowdsec
|
||||||
|
inputs.crowdsec.nixosModules.crowdsec-firewall-bouncer
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
inputs.crowdsec.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
age.secrets.enrollment-key = {
|
||||||
|
rekeyFile = ./enrollment_key.age;
|
||||||
|
owner = "crowdsec";
|
||||||
|
group = "crowdsec";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.crowdsec = let
|
||||||
|
yaml = (pkgs.formats.yaml {}).generate;
|
||||||
|
acquisitions_file = yaml "acquisitions.yaml" {
|
||||||
|
source = "journalctl";
|
||||||
|
journalctl_filter = ["_SYSTEMD_UNIT=sshd.service"];
|
||||||
|
labels.type = "syslog";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
allowLocalJournalAccess = true;
|
||||||
|
enrollKeyFile = config.age.secrets.enrollment-key.path;
|
||||||
|
settings = {
|
||||||
|
api.server = {
|
||||||
|
listen_uri = "127.0.0.1:${port}";
|
||||||
|
};
|
||||||
|
crowdsec_service.acquisition_path = acquisitions_file;
|
||||||
|
crowdsec_service.acquisition_dir = ./acquis.d;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.crowdsec-firewall-bouncer = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
api_key = "2025f0be-35ca-406c-8737-810321c918c2";
|
||||||
|
api_url = "http://localhost:${port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.crowdsec.serviceConfig = {
|
||||||
|
ExecStartPre = let
|
||||||
|
bouncer = pkgs.writeScriptBin "register-bouncer" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
if ! cscli bouncers list | grep -q "firewall-bouncer"; then
|
||||||
|
cscli bouncers add "firewall-bouncer" --key "2025f0be-35ca-406c-8737-810321c918c2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! cscli bouncers list | grep -q "traefik-bouncer"; then
|
||||||
|
cscli bouncers add "traefik-bouncer" --key "18c725d5-3a22-4331-a8e8-abfd3018a7c0"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
scenario = pkgs.writeScriptBin "install-scenario" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
if ! cscli collections list | grep -q "crowdsecurity/linux"; then
|
||||||
|
cscli collections install "crowdsecurity/linux"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! cscli collections list | grep -q "crowdsecurity/appsec-virtual-patching"; then
|
||||||
|
cscli collections install "crowdsecurity/appsec-virtual-patching"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! cscli collections list | grep -q "crowdsecurity/appsec-generic-rules"; then
|
||||||
|
cscli collections install "crowdsecurity/appsec-generic-rules"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
in [
|
||||||
|
"${bouncer}/bin/register-bouncer"
|
||||||
|
"${scenario}/bin/install-scenario"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.persistence."/persist" = {
|
||||||
|
directories = [
|
||||||
|
{ directory = "/var/lib/crowdsec"; user = "crowdsec"; group = "crowdsec"; }
|
||||||
|
];
|
||||||
|
hideMounts = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
BIN
nixos/viridian/services/crowdsec/enrollment_key.age
Normal file
BIN
nixos/viridian/services/crowdsec/enrollment_key.age
Normal file
Binary file not shown.
BIN
nixos/viridian/services/crowdsec/firewall-bouncer-key.age
Normal file
BIN
nixos/viridian/services/crowdsec/firewall-bouncer-key.age
Normal file
Binary file not shown.
9
nixos/viridian/services/crowdsec/traefik-bouncer-key.age
Normal file
9
nixos/viridian/services/crowdsec/traefik-bouncer-key.age
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> piv-p256 hdSnGw A6O6zvEq05hpB3GxDsrj2rUxr0P031TKreOe3ZAfUpJs
|
||||||
|
Ww8Qg1MV5dJoCYQEGSNLUnZdX7dO1cGu3XaQTyn97PA
|
||||||
|
-> 0(D-grease b? xbW Qg ~cDE0j!
|
||||||
|
s5z0LGzRiWS6lMMphO19nB7qmvXkto4RJrcTSrOtPHbY9Iam2aeYA0qN4faK40Zs
|
||||||
|
XPc
|
||||||
|
--- q1PoY78SatX6wOKNW549+ndCCrNhveA8dHcHQpF+slk
|
||||||
|
l
<0A>¾ß`òŠæ¨=(¡¾è;>Y[)Pfwú.§…óQ²¹¸W5áòØØL©Ã—K£DˆTœY$’µŸ
|
||||||
|
ý’Ù¿zñ¨Ã]
|
|
@ -3,6 +3,7 @@
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./traefik
|
./traefik
|
||||||
|
./crowdsec
|
||||||
./minecraft
|
./minecraft
|
||||||
./borgbackup.nix
|
./borgbackup.nix
|
||||||
./forgejo.nix
|
./forgejo.nix
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
"websecure"
|
"websecure"
|
||||||
];
|
];
|
||||||
middlewares = [
|
middlewares = [
|
||||||
|
"crowdsec"
|
||||||
"geoblock"
|
"geoblock"
|
||||||
];
|
];
|
||||||
service = "forgejo";
|
service = "forgejo";
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"websecure"
|
"websecure"
|
||||||
];
|
];
|
||||||
middlewares = [
|
middlewares = [
|
||||||
|
"crowdsec"
|
||||||
"geoblock"
|
"geoblock"
|
||||||
];
|
];
|
||||||
service = "lighttpd";
|
service = "lighttpd";
|
||||||
|
|
|
@ -53,10 +53,17 @@
|
||||||
|
|
||||||
# Install plugins
|
# Install plugins
|
||||||
experimental.plugins = {
|
experimental.plugins = {
|
||||||
|
# Block or allow requests based on their country of origin.
|
||||||
geoblock = {
|
geoblock = {
|
||||||
moduleName = "github.com/PascalMinder/geoblock";
|
moduleName = "github.com/PascalMinder/geoblock";
|
||||||
version = "v0.2.7";
|
version = "v0.2.7";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Authorize or block requests from IPs based on there reputation and behaviour.
|
||||||
|
bouncer = {
|
||||||
|
moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin";
|
||||||
|
version = "v1.3.2";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Network entry points into Traefik
|
# Network entry points into Traefik
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
{ ... }:
|
{ config, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
# Crowdsec Local API key for the bouncer.
|
||||||
|
age.secrets.traefik-bouncer-key = {
|
||||||
|
rekeyFile = ../crowdsec/traefik-bouncer-key.age;
|
||||||
|
owner = "traefik";
|
||||||
|
group = "traefik";
|
||||||
|
};
|
||||||
|
|
||||||
# Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service
|
# Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service
|
||||||
services.traefik.dynamicConfigOptions.http.middlewares = {
|
services.traefik.dynamicConfigOptions.http.middlewares = {
|
||||||
# Restrict access to admin devices only
|
# Restrict access to admin devices only
|
||||||
|
@ -9,12 +16,14 @@
|
||||||
"192.168.1.101" # fuchsia
|
"192.168.1.101" # fuchsia
|
||||||
"10.100.0.2" # Pixel 6 Pro
|
"10.100.0.2" # Pixel 6 Pro
|
||||||
];
|
];
|
||||||
|
|
||||||
# Restrict access to internal networks
|
# Restrict access to internal networks
|
||||||
internal.ipwhitelist.sourcerange = [
|
internal.ipwhitelist.sourcerange = [
|
||||||
"127.0.0.1/32" # localhost
|
"127.0.0.1/32" # localhost
|
||||||
"192.168.1.1/24" # lan
|
"192.168.1.1/24" # lan
|
||||||
"10.100.0.0/24" # wireguard clients
|
"10.100.0.0/24" # wireguard clients
|
||||||
];
|
];
|
||||||
|
|
||||||
# Restrict access based on geo-location
|
# Restrict access based on geo-location
|
||||||
geoblock.plugin.geoblock = {
|
geoblock.plugin.geoblock = {
|
||||||
silentStartUp = "false";
|
silentStartUp = "false";
|
||||||
|
@ -42,6 +51,17 @@
|
||||||
# Even if an IP stays in the cache for a period of a month, it must be fetch again after a month.
|
# Even if an IP stays in the cache for a period of a month, it must be fetch again after a month.
|
||||||
forceMonthlyUpdate = "true";
|
forceMonthlyUpdate = "true";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Disable Crowdsec IP checking but apply Crowdsec Appsec checking. This mode is intended to be used when Crowdsec IP checking is applied at the Firewall Level.
|
||||||
|
crowdsec.plugin.bouncer = {
|
||||||
|
enabled = "true";
|
||||||
|
crowdsecMode = "appsec";
|
||||||
|
crowdsecLapiKeyFile = config.age.secrets.traefik-bouncer-key.path;
|
||||||
|
crowdsecLapiScheme = "http";
|
||||||
|
crowdsecLapiHost = "127.0.0.1:8080";
|
||||||
|
crowdsecAppsecEnabled = "true";
|
||||||
|
crowdsecAppsecHost = "127.0.0.1:7422";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue