文件
k3s/apps/infra/net/crowdsec/helmchart.yaml
T
2026-01-19 19:24:47 +08:00

234 行
8.5 KiB
YAML

apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: crowdsec
namespace: infra-net
spec:
repo: https://crowdsecurity.github.io/helm-charts
chart: crowdsec
targetNamespace: infra-net
version: 0.21.1
valuesContent: |-
container_runtime: containerd
image:
tag: v1.7.4
agent:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: loki
topologyKey: kubernetes.io/hostname
namespaceSelector: {}
isDeployment: true
additionalAcquisition:
- source: loki
log_level: info
url: http://loki.infra-monitor:3100/
limit: 1000
query: |
{job="infra-net/ingress-nginx"}
labels:
type: nginx
env:
- name: COLLECTIONS
value: "crowdsecurity/base-http-scenarios crowdsecurity/http-dos"
- name: SCENARIOS
value: "crowdsecurity/nginx-req-limit-exceeded"
persistentVolume:
config:
enabled: false
appsec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: topology.kubernetes.io/region
operator: In
values:
- cn-hk
enabled: false
acquisitions:
- source: appsec
listen_addr: "0.0.0.0:7422"
path: /
appsec_config: crowdsecurity/crs-vpatch
labels:
type: appsec
configs:
mycustom-appsec-config.yaml: |
name: crowdsecurity/crs-vpatch
default_remediation: ban
#log_level: debug
outofband_rules:
- crowdsecurity/crs
inband_rules:
- crowdsecurity/base-config
- crowdsecurity/vpatch-*
env:
- name: COLLECTIONS
value: "crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-crs"
lapi:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: topology.kubernetes.io/region
operator: In
values:
- cn-hk
resources:
requests:
cpu: 150m
memory: 100Mi
persistentVolume:
config:
enabled: false
data:
enabled: false
config:
# api config.yaml配置
config.yaml.local: |
db_config:
type: postgresql
host: cnpg17-cluster-hk-rw.infra-data
port: 5432
db_name: crowdsec
user: app
password: FybaFtf6NV5jnxhj5bOPpHbO6KypZeHiyiskgAWkM5nioW2j82HtCf6GnW9xVKjE
sslmode: require
api:
server:
auto_registration:
enabled: true
token: "${REGISTRATION_TOKEN}"
allowed_ranges:
- "127.0.0.1/32"
- "192.168.0.0/16"
- "172.16.0.0/12"
- "10.0.0.0/8"
# api profiles.yaml配置
profiles.yaml: |
name: captcha_remediation
filters:
# 规则过滤条件 1.范围为Ip 2.触发场景为http或nginx 3.24小时内决策次数小于等于3
- Alert.Remediation == true && Alert.GetScope() == "Ip" &&
(Alert.GetScenario() contains "http" || Alert.GetScenario() contains "nginx") &&
GetDecisionsSinceCount(Alert.GetValue(), "24h") <= 3
decisions:
- type: captcha
duration: 4h
on_success: break
---
name: default_ip_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
- type: ban
duration: 4h
on_success: break
---
name: default_range_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Range"
decisions:
- type: ban
duration: 4h
on_success: break
# agent parsers 配置
parsers:
s01-parse:
# 新增nginx json日志解析
nginx-logs.yaml: |
filter: "evt.Parsed.program startsWith 'nginx'"
onsuccess: next_stage
name: crowdsecurity/nginx-logs
description: "Parse nginx access and error logs"
pattern_syntax:
NGCUSTOMURIPATH: "(?:/[A-Za-z0-9$.+!*'\\(\\)\\{\\},~:;=@\\#%&_\\-]*)+"
NGCUSTOMURIPATHPARAM: '%{NGCUSTOMURIPATH}(?:%{URIPARAM})?'
nodes:
# nginx access logs
- filter: TrimSpace(evt.Parsed.message) startsWith "{" && UnmarshalJSON(evt.Parsed.message, evt.Unmarshaled, "nginx") in ["", nil]
statics:
- meta: service
value: http
- meta: log_type
value: http_access-log
- target: evt.StrTime
expression: evt.Unmarshaled.nginx.time_local
- meta: source_ip
expression: evt.Unmarshaled.nginx.remote_addr
- meta: http_status
expression: evt.Unmarshaled.nginx.status
- meta: http_path
expression: evt.Unmarshaled.nginx.request_uri
- meta: http_verb
expression: evt.Unmarshaled.nginx.request_method
- meta: http_user_agent
expression: evt.Unmarshaled.nginx.http_user_agent
- meta: target_fqdn
expression: evt.Unmarshaled.nginx.server_name
# nginx error logs
- grok:
pattern: '(%{IPORHOST:target_fqdn} )?%{NGINXERRTIME:time} \[%{LOGLEVEL:loglevel}\] %{NONNEGINT:pid}#%{NONNEGINT:tid}: (\*%{NONNEGINT:cid} )?%{GREEDYDATA:message}, client: %{IPORHOST:remote_addr}, server: %{DATA:target_fqdn}, request: "%{WORD:verb} ([^/]+)?%{NGCUSTOMURIPATHPARAM:request}( HTTP/%{NUMBER:http_version})?", host: "%{IPORHOST}(:%{NONNEGINT})?"'
apply_on: message
statics:
- meta: service
value: http
- meta: log_type
value: http_error-log
- target: evt.StrTime
expression: evt.Parsed.time
- meta: source_ip
expression: evt.Parsed.remote_addr
- meta: http_status
expression: evt.Parsed.status
- meta: http_path
expression: evt.Parsed.request
- meta: http_verb
expression: evt.Parsed.verb
- meta: http_user_agent
expression: evt.Parsed.http_user_agent
- meta: target_fqdn
expression: evt.Parsed.target_fqdn
pattern_syntax:
NO_DOUBLE_QUOTE: '[^"]+'
onsuccess: next_stage
nodes:
- filter: "evt.Parsed.message contains 'was not found in'"
pattern_syntax:
USER_NOT_FOUND: 'user "%{NO_DOUBLE_QUOTE:username}" was not found in "%{NO_DOUBLE_QUOTE}"'
grok:
pattern: '%{USER_NOT_FOUND}'
apply_on: message
statics:
- meta: sub_type
value: "auth_fail"
- meta: username
expression: evt.Parsed.username
- filter: "evt.Parsed.message contains 'password mismatch'"
pattern_syntax:
PASSWORD_MISMATCH: 'user "%{NO_DOUBLE_QUOTE:username}": password mismatch'
grok:
pattern: '%{PASSWORD_MISMATCH}'
apply_on: message
statics:
- meta: sub_type
value: "auth_fail"
- meta: username
expression: evt.Parsed.username
- filter: "evt.Parsed.message contains 'limiting requests, excess'"
statics:
- meta: sub_type
value: "req_limit_exceeded"