mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
Exemples -> Examples (#116)
* Exemples -> Examples * Exemples -> Examples * Uppercase * Uppercase v2 * Uppercase v3 * Uppercases * Another one * Add whoami because .gitignore is ignoring conf folder
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
RUN apt-get update && apt-get install -y curl wget
|
||||
RUN VERSION=$(curl --silent "https://api.github.com/repos/cloudflare/cfssl/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') && VNUMBER=${VERSION#"v"} && wget https://github.com/cloudflare/cfssl/releases/download/${VERSION}/cfssl_${VNUMBER}_linux_amd64 -O cfssl && chmod +x cfssl && mv cfssl /usr/local/bin
|
||||
|
||||
RUN VERSION=$(curl --silent "https://api.github.com/repos/cloudflare/cfssl/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') && \
|
||||
VNUMBER=${VERSION#"v"} && \
|
||||
wget https://github.com/cloudflare/cfssl/releases/download/${VERSION}/cfssljson_${VNUMBER}_linux_amd64 -O cfssljson && \
|
||||
chmod +x cfssljson && \
|
||||
mv cfssljson /usr/local/bin && \
|
||||
cfssljson -version
|
||||
|
||||
COPY gencerts.sh /gencerts.sh
|
||||
RUN chmod +x /gencerts.sh
|
||||
|
||||
CMD [ "/gencerts.sh" ]
|
||||
@@ -0,0 +1,93 @@
|
||||
# Example
|
||||
## Using https communication and tls authentication with Crowdsec
|
||||
|
||||
##### Summary
|
||||
This example demonstrates the use of https between the Traefik plugin and the Crowdsec LAPI.
|
||||
|
||||
It is possible to communicate with the LAPI in https and still authenticate with API key.
|
||||
You can add the client TLS certificate generated to authenticate without any Token in the plugin.
|
||||
|
||||
However, note that it is not possible to authenticate with TLS client certificate without https setup for the LAPI.
|
||||
|
||||
##### Details
|
||||
|
||||
Simple HTTPS communication: It is possible to talk to Crowdsec LAPI which is configured with a self-signed certificate
|
||||
In that case the setting **crowdsecLapiTLSInsecureVerify** must be set to true.
|
||||
|
||||
It is recommended to validate the certificate presented by Crowdsec LAPI using the Certificate Authority which created it.
|
||||
|
||||
You can provide the Certificate Authority using:
|
||||
* A file path readable by Traefik
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
crowdsec:
|
||||
plugin:
|
||||
bouncer:
|
||||
crowdsecLapiTlsCertificateAuthorityFile: /etc/traefik/certs/crowdsecCA.pem
|
||||
```
|
||||
* The PEM encoded certificate as a text variable
|
||||
|
||||
In the static file configuration of Traefik
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
crowdsec:
|
||||
plugin:
|
||||
bouncer:
|
||||
crowdsecLapiTlsCertificateAuthority: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT
|
||||
MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK
|
||||
...
|
||||
C6qNieSwcvWL7C03ri0DefTQMY54r5wP33QU5hJ71JoaZI3YTeT0Nf+NRL4hM++w
|
||||
Q0veeNzBQXg1f/JxfeA39IDIX1kiCf71tGlT
|
||||
-----END CERTIFICATE-----
|
||||
```
|
||||
In a dynamic configuration of a provider (ex docker) as a Label
|
||||
```yaml
|
||||
services:
|
||||
whoami-foo:
|
||||
image: traefik/whoami
|
||||
labels:
|
||||
- |
|
||||
traefik.http.middlewares.crowdsec-foo.plugin.bouncer.crowdsecLapiTlsCertificateAuthority=
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEBzCCAu+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT
|
||||
MRAwDgYDVQQHDAdTZWF0dGxlMRMwEQYDVQQIDApXYXNoaW5ndG9uMSIwIAYDVQQK
|
||||
...
|
||||
C6qNieSwcvWL7C03ri0DefTQMY54r5wP33QU5hJ71JoaZI3YTeT0Nf+NRL4hM++w
|
||||
Q0veeNzBQXg1f/JxfeA39IDIX1kiCf71tGlT
|
||||
-----END CERTIFICATE-----
|
||||
```
|
||||
|
||||
The example tls-auth presents 2 services, foo and bar which comes with the bouncer.
|
||||
At startup, certificates are created in a shared docker volume by a sidecar container which exits after.
|
||||
|
||||
Traefik will use client and CA certificates.
|
||||
The Bouncer will use server and CA certificates.
|
||||
|
||||
The service `whoami-foo` will authenticate with an **API key** over HTTPS after verifying the server certificate with CA.
|
||||
The service `whoami-bar` will authenticate with a **client certificate** signed by the CA.
|
||||
|
||||
Access to a route that communicate via https and authenticate with API-key:
|
||||
```
|
||||
curl http://localhost:80/foo
|
||||
```
|
||||
Access to a route that communicate via https and authenticate with a client certificate:
|
||||
```
|
||||
curl http://localhost:80/bar
|
||||
```
|
||||
Access to the traefik dashboard
|
||||
```
|
||||
curl http://localhost:8080/dashboard/#/
|
||||
```
|
||||
|
||||
To play the demo environnement run:
|
||||
```bash
|
||||
make run_tlsauth
|
||||
```
|
||||
|
||||
Note:
|
||||
> This example is still in Beta and use a new version of Crowdsec (v1.4.3) at time of writing
|
||||
A functionnality has been disabled in Crowdsec in order to make the example work DISABLE_AGENT: "true"
|
||||
@@ -0,0 +1,4 @@
|
||||
filenames:
|
||||
- /var/log/traefik/access.log
|
||||
labels:
|
||||
type: traefik
|
||||
@@ -0,0 +1,62 @@
|
||||
common:
|
||||
daemonize: false
|
||||
pid_dir: /var/run/
|
||||
log_media: stdout
|
||||
log_level: info
|
||||
log_dir: /var/log/
|
||||
working_dir: .
|
||||
config_paths:
|
||||
config_dir: /etc/crowdsec/
|
||||
data_dir: /var/lib/crowdsec/data/
|
||||
simulation_path: /etc/crowdsec/simulation.yaml
|
||||
hub_dir: /etc/crowdsec/hub/
|
||||
index_path: /etc/crowdsec/hub/.index.json
|
||||
notification_dir: /etc/crowdsec/notifications/
|
||||
plugin_dir: /usr/local/lib/crowdsec/plugins/
|
||||
crowdsec_service:
|
||||
acquisition_path: /etc/crowdsec/acquis.yaml
|
||||
parser_routines: 1
|
||||
plugin_config:
|
||||
user: nobody
|
||||
group: nobody
|
||||
cscli:
|
||||
output: human
|
||||
db_config:
|
||||
log_level: info
|
||||
type: sqlite
|
||||
db_path: /var/lib/crowdsec/data/crowdsec.db
|
||||
#user:
|
||||
#password:
|
||||
#db_name:
|
||||
#host:
|
||||
#port:
|
||||
flush:
|
||||
max_items: 5000
|
||||
max_age: 7d
|
||||
api:
|
||||
client:
|
||||
insecure_skip_verify: false
|
||||
credentials_path: /etc/crowdsec/local_api_credentials.yaml
|
||||
server:
|
||||
log_level: info
|
||||
listen_uri: 0.0.0.0:8080
|
||||
profiles_path: /etc/crowdsec/profiles.yaml
|
||||
trusted_ips: # IP ranges, or IPs which can have admin API access
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
online_client: # Central API credentials (to push signals and receive bad IPs)
|
||||
#credentials_path: /etc/crowdsec/online_api_credentials.yaml
|
||||
tls:
|
||||
cert_file: /etc/crowdsec/certs/server.pem #Server side cert
|
||||
key_file: /etc/crowdsec/certs/server-key.pem #Server side key
|
||||
ca_cert_path: /etc/crowdsec/certs/inter.pem #CA used to verify the client certs
|
||||
bouncers_allowed_ou: #OU allowed for bouncers
|
||||
- bouncer-ou
|
||||
agents_allowed_ou: #OU allowed for agents
|
||||
- agent-ou
|
||||
|
||||
prometheus:
|
||||
enabled: true
|
||||
level: full
|
||||
listen_addr: 0.0.0.0
|
||||
listen_port: 6060
|
||||
@@ -0,0 +1,4 @@
|
||||
url: https://localhost:8080
|
||||
ca_cert_path: /etc/crowdsec/certs/inter.pem #CA to trust the server certificate
|
||||
key_path: /etc/crowdsec/certs/agent-key.pem #Client key
|
||||
cert_path: /etc/crowdsec/certs/agent.pem #Client cert
|
||||
@@ -0,0 +1,111 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.10.4"
|
||||
container_name: "traefik"
|
||||
restart: unless-stopped
|
||||
command:
|
||||
# - "--log.level=DEBUG"
|
||||
- "--accesslog"
|
||||
- "--accesslog.filepath=/var/log/traefik/access.log"
|
||||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
|
||||
- "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
- "--experimental.plugins.bouncer.version=v1.1.13"
|
||||
# - "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- ./LAPIKEY:/etc/traefik/LAPIKEY:ro
|
||||
- logs-tls-auth:/var/log/traefik
|
||||
- crowdsec-certs-tls-auth:/etc/traefik/crowdsec-certs
|
||||
# - ./../../:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
|
||||
ports:
|
||||
- 80:80
|
||||
- 8080:8080
|
||||
depends_on:
|
||||
- crowdsec
|
||||
|
||||
# Use HTTPS scheme but with lapikey authentication
|
||||
# whoami-foo:
|
||||
# image: traefik/whoami
|
||||
# container_name: "simple-service-foo"
|
||||
# restart: unless-stopped
|
||||
# labels:
|
||||
# - "traefik.enable=true"
|
||||
# - "traefik.http.routers.router-foo.rule=Path(`/foo`)"
|
||||
# - "traefik.http.routers.router-foo.entrypoints=web"
|
||||
# - "traefik.http.routers.router-foo.middlewares=crowdsec-foo@docker"
|
||||
# - "traefik.http.services.service-foo.loadbalancer.server.port=80"
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.enabled=true"
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.loglevel=DEBUG"
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapikey=40796d93c2958f9e58345514e67740e5"
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapischeme=https"
|
||||
# - "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateAuthorityFile=/etc/traefik/crowdsec-certs/inter.pem"
|
||||
|
||||
# Use HTTPS scheme with TLS cert authentication
|
||||
whoami-bar:
|
||||
image: traefik/whoami
|
||||
container_name: "simple-service-bar"
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.router-bar.rule=Path(`/bar`)"
|
||||
- "traefik.http.routers.router-bar.entrypoints=web"
|
||||
- "traefik.http.routers.router-bar.middlewares=crowdsec-bar@docker"
|
||||
- "traefik.http.services.service-bar.loadbalancer.server.port=80"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.enabled=true"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.loglevel=DEBUG"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdseclapischeme=https"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateAuthorityFile=/etc/traefik/crowdsec-certs/inter.pem"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateBouncerFile=/etc/traefik/crowdsec-certs/bouncer.pem"
|
||||
- "traefik.http.middlewares.crowdsec.plugin.bouncer.crowdsecLapiTLSCertificateBouncerKeyFile=/etc/traefik/crowdsec-certs/bouncer-key.pem"
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.5.2
|
||||
container_name: "crowdsec"
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
COLLECTIONS: crowdsecurity/traefik
|
||||
CUSTOM_HOSTNAME: crowdsec
|
||||
# whoami-foo is authenticating with api key over https
|
||||
# whoami-bar is authenticating with tls cert over https
|
||||
BOUNCER_KEY_TRAEFIK_FOO: 40796d93c2958f9e58345514e67740e5
|
||||
LOCAL_API_URL: https://127.0.0.1:8080
|
||||
USE_TLS: "true"
|
||||
CERT_FILE: "/etc/crowdsec/certs/server.pem"
|
||||
KEY_FILE: "/etc/crowdsec/certs/server-key.pem"
|
||||
CACERT_FILE: "/etc/crowdsec/certs/inter.pem"
|
||||
AGENTS_ALLOWED_OU: "agent-ou"
|
||||
BOUNCERS_ALLOWED_OU: "bouncer-ou"
|
||||
LEVEL_DEBUG: "true"
|
||||
# Disabled because it restart in loop otherwise
|
||||
DISABLE_AGENT: "true"
|
||||
# Disabled for the examples
|
||||
DISABLE_ONLINE_API: "true"
|
||||
volumes:
|
||||
- ./config/acquis.yaml:/etc/crowdsec/acquis.yaml
|
||||
# - ./config/config.yaml:/etc/crowdsec/config_local.yaml
|
||||
# - ./config/local_api_credentials.yaml:/etc/crowdsec/local_api_credentials.yaml:ro
|
||||
- crowdsec-certs-tls-auth:/etc/crowdsec/certs/:ro
|
||||
- logs-tls-auth:/var/log/traefik:ro
|
||||
- crowdsec-db-tls-auth:/var/lib/crowdsec/data/
|
||||
- crowdsec-config-tls-auth:/etc/crowdsec/
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
gencert:
|
||||
build: .
|
||||
volumes:
|
||||
- crowdsec-certs-tls-auth:/out
|
||||
- ./in:/in:ro
|
||||
|
||||
volumes:
|
||||
logs-tls-auth:
|
||||
crowdsec-db-tls-auth:
|
||||
crowdsec-config-tls-auth:
|
||||
crowdsec-certs-tls-auth:
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
stdout=/out/res.log
|
||||
cfssl gencert --initca /in/ca.json 2>${stdout} | cfssljson --bare "/out/ca" && \
|
||||
# Generate an intermediate certificate that will be used to sign the client certificates
|
||||
cfssl gencert --initca /in/intermediate.json 2>${stdout} | cfssljson --bare "/out/inter" && \
|
||||
cfssl sign -ca "/out/ca.pem" -ca-key "/out/ca-key.pem" -config /in/profiles.json -profile intermediate_ca "/out/inter.csr" 2>${stdout} | cfssljson --bare "/out/inter" && \
|
||||
# Generate a server side certificate
|
||||
cfssl gencert -ca "/out/inter.pem" -ca-key "/out/inter-key.pem" -config /in/profiles.json -profile=server /in/server.json 2>${stdout} | cfssljson --bare "/out/server" && \
|
||||
# Generate a client certificate for the bouncer whoami
|
||||
cfssl gencert -ca "/out/inter.pem" -ca-key "/out/inter-key.pem" -config /in/profiles.json -profile=client /in/bouncer.json 2>${stdout} | cfssljson --bare "/out/bouncer" && \
|
||||
# Generate a client certificate for the agent
|
||||
cfssl gencert -ca "/out/inter.pem" -ca-key "/out/inter-key.pem" -config /in/profiles.json -profile=client /in/agent.json 2>${stdout} | cfssljson --bare "/out/agent"
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"CN": "myagent",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "FR",
|
||||
"L": "Paris",
|
||||
"O": "Crowdsec",
|
||||
"OU": "agent-ou",
|
||||
"ST": "France"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"CN": "crowdsec",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "FR",
|
||||
"L": "Paris",
|
||||
"O": "Crowdsec",
|
||||
"OU": "bouncer-ou",
|
||||
"ST": "France"
|
||||
}
|
||||
],
|
||||
"hosts": [
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
"crowdsec"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"CN": "CrowdSec Test CA",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "FR",
|
||||
"L": "Paris",
|
||||
"O": "Crowdsec",
|
||||
"OU": "Crowdsec",
|
||||
"ST": "France"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"CN": "CrowdSec Test CA Intermediate",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "FR",
|
||||
"L": "Paris",
|
||||
"O": "Crowdsec",
|
||||
"OU": "Crowdsec Intermediate",
|
||||
"ST": "France"
|
||||
}
|
||||
],
|
||||
"ca": {
|
||||
"expiry": "42720h"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"signing": {
|
||||
"default": {
|
||||
"expiry": "8760h"
|
||||
},
|
||||
"profiles": {
|
||||
"intermediate_ca": {
|
||||
"usages": [
|
||||
"signing",
|
||||
"digital signature",
|
||||
"key encipherment",
|
||||
"cert sign",
|
||||
"crl sign",
|
||||
"server auth",
|
||||
"client auth"
|
||||
],
|
||||
"expiry": "8760h",
|
||||
"ca_constraint": {
|
||||
"is_ca": true,
|
||||
"max_path_len": 0,
|
||||
"max_path_len_zero": true
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"usages": [
|
||||
"signing",
|
||||
"digital signing",
|
||||
"key encipherment",
|
||||
"server auth"
|
||||
],
|
||||
"expiry": "8760h"
|
||||
},
|
||||
"client": {
|
||||
"usages": [
|
||||
"signing",
|
||||
"digital signature",
|
||||
"key encipherment",
|
||||
"client auth"
|
||||
],
|
||||
"expiry": "8760h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"CN": "crowdsec",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [
|
||||
{
|
||||
"C": "FR",
|
||||
"L": "Paris",
|
||||
"O": "Crowdsec",
|
||||
"OU": "Crowdsec Server",
|
||||
"ST": "France"
|
||||
}
|
||||
],
|
||||
"hosts": [
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
"crowdsec"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user