Hi, I'm having trouble getting wazuh to work behind traefik.
I installed wazuh in a proxmox container and connected via traefik, installed in another container running docker and where traefik is installed.
Questa è la configurazione del dynamics file :
dynamics.yml:
http:
routers:
wazuh-router:
rule: "Host(`wazuh.example.com`)"
entryPoints:
- websecure
service: wazuh-service
tls:
certResolver: dns01
services:
wazuh-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "https://10.20.40.2:443"
tcp:
routers:
wazuh-r1515:
entryPoints:
- 1515/tcp
rule: "HostSNI(`wazuh.example.com`)"
service: wazuh-s1515
tls:
certResolver: dns01
services:
wazuh-s1515:
loadBalancer:
servers:
- address: 10.20.40.2:1515
In the static configuration I created an entrypoint:
entryPoints:
1515/tcp:
address: :1515/tcp
the traefik dashboard shows no errors.
I have an internal DNS server with bind9 and I pointed the domain towards traefik, in fact the wazuh dashboard is reachable, but if I configure the wazuh agent with wazuh.example.com it doesn't work. On Traefik open all the TCP ports that Wazuh requires, to simplify I have given you the example of one since I configured the others in the exact same way.
if I try to nmap wazuh.example.com -p 1515 I get the port open:
Host is up (0.014s latency).
PORT STATE SERVICE
1515/tcp open ifor-protocol
But if I configure the agent the connection does not occur, unlike making it point directly to the IP, same result with zabbix.
I can't figure out if it's a traefik configuration error or I need to look elsewhere.
Any suggestions?
1 Like
Share your full Traefik static and dynamic config, and docker-compose.yml
if used.
Enable and check Traefik debug log.
I recommend to use regular alphanumeric characters for names/labels. We see in Traefik examples that -
works, too. Would not use other special characters like /
.
Dynamics:
http:
routers:
bookstack-router:
rule: "Host(`kb.lab.local`)"
entryPoints:
- websecure
service: bookstack-service
tls:
certResolver: production
proxmox-router:
rule: "Host(`proxmox.lab.local`)"
entryPoints:
- websecure
service: proxmox-service
tls:
certResolver: dns01
portainer-router:
rule: "Host(`portainer.lab.local`)"
entryPoints:
- websecure
service: portainer-service
tls:
certResolver: dns01
wazuh-router:
rule: "Host(`wazuh.lab.local`)"
entryPoints:
- websecure
service: wazuh-service
tls:
certResolver: dns01
zabbix-router:
rule: "Host(`zabbix.lab.local`)"
entryPoints:
- websecure
service: zabbix-service
tls:
certResolver: dns01
##############################################################
services:
bookstack-service:
loadBalancer:
servers:
- url: "http://10.20.40.9:443"
proxmox-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "https://10.20.40.1:8006"
portainer-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "https://10.20.40.6:9443"
wazuh-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "https://10.20.40.2:443"
zabbix-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "http://10.20.40.8/zabbix"
# Middlewares http
# ---
middlewares:
crowdsec-bouncer:
forwardauth:
address: http://bouncer-traefik:8080/api/v1/forwardAuth
trustForwardHeader: true
serversTransports:
insecureTransport:
insecureSkipVerify: true
#########TCP##############################
tcp:
routers:
wazuh-r55000:
entryPoints:
- 55000/tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s55000
tls:
certResolver: dns01
wazuh-r1514tcp:
entryPoints:
- 1514/tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s1514tcp
tls:
certResolver: dns01
wazuh-r1515:
entryPoints:
- 1515/tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s1515
tls:
certResolver: dns01
wazuh-r1516:
entryPoints:
- 1516/tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s1516
tls:
certResolver: dns01
zabbix-r10050:
entryPoints:
- 10050/tcp
rule: "HostSNI(`zabbix.lab.local`)"
service: zabbix-s10050
tls:
certResolver: dns01
zabbix-r10051:
entryPoints:
- 10051/tcp
rule: "HostSNI(`zabbix.lab.local`)"
service: zabbix-s10051
tls:
certResolver: dns01
services:
wazuh-s55000:
loadBalancer:
servers:
- address: 10.20.40.2:55000
wazuh-s1514tcp:
loadBalancer:
servers:
- address: 10.20.40.2:1514
wazuh-s1515:
loadBalancer:
servers:
- address: 10.20.40.2:1515
wazuh-s1516:
loadBalancer:
servers:
- address: 10.20.40.2:1516
zabbix-s10050:
loadBalancer:
servers:
- address: 10.20.40.8:10050
zabbix-s10051:
loadBalancer:
servers:
- address: 10.20.40.8:10051
static:
global:
checkNewVersion: true
sendAnonymousUsage: false # true by default
# (Optional) Log information
# ---
log:
level: DEBUG # DEBUG, INFO, WARNING, ERROR, CRITICAL
format: common # common, json, logfmt
filePath: /var/log/traefik/traefik.log
# (Optional) Accesslog
# ---
accesslog:
format: common # common, json, logfmt
filePath: /var/log/traefik/access.log
# (Optional) Enable API and Dashboard
# ---
api:
dashboard: true # true by default
insecure: true # Don't do this in production!
# Entry Points configuration
# ---
entryPoints:
web:
address: :80
http:
middlewares:
- crowdsec-bouncer@file
# (Optional) Redirect to HTTPS
# ---
# http:
# redirections:
# entryPoint:
# to: websecure
# scheme: https
websecure:
address: :443
http:
middlewares:
- crowdsec-bouncer@file
1514/tcp:
address: :1514/tcp
1515/tcp:
address: :1515/tcp
1516/tcp:
address: :1516/tcp
55000/tcp:
address: :55000/tcp
10050/tcp:
address: :10050/tcp
10051/tcp:
address: :10051/tcp
certificatesResolvers:
# staging:
# acme:
# email: your-email@example.com
# storage: /etc/traefik/certs/acme.json
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
# httpChallenge:
# entryPoint: web
#
production:
acme:
email: <MYEMAIL>
storage: acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: web
dns01:
acme:
email: <MYEMAIL>
storage: acme.json
dnsChallenge:
provider: cloudflare
disablePropagationCheck: true
delayBeforeCheck: 60
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
# (Optional) Overwrite Default Certificates
# tls:
# stores:
# default:
# defaultCertificate:
# certFile: /etc/traefik/certs/cert.pem
# keyFile: /etc/traefik/certs/cert-key.pem
# (Optional) Disable TLS version 1.0 and 1.1
# options:
# default:
# minVersion: VersionTLS12
providers:
docker:
exposedByDefault: false # Default is true
watch: true
file:
# watch for dynamic configuration changes
directory: /dynamic_config
watch: true
Docker Compose:
version: '3'
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: always
ports:
- "80:80" #web
- "443:443" #websecure
#Dashboard
- "8080:8080"
- "1514:1514"
- "1514:1514/udp"
- "1515:1515"
- "1516:1516"
- "55000:55000/tcp"
- "514:514/udp"
networks:
proxynet:
ipv4_address: 172.18.0.2
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
#Dati
- /mnt/docker/volumi/traefik/:/etc/traefik #configurazione traefik
- /mnt/docker/volumi/traefik/log:/var/log/traefik/
- /mnt/docker/volumi/traefik/cert/acme.json:/acme.json #certificati ssl
- /mnt/docker/volumi/traefik/dynamic_config/:/dynamic_config:ro
environment:
- "CF_API_EMAIL=<MYEMAIL>"
- "CF_API_KEY=<KEY>"
networks:
proxynet:
external: true
Debug log shows no errors for wazuh configuration
Which wazuh image do you run? Did you try to connect your client directly to the target container port?
The way you configured it, Traefik will terminate TLS and forward unencrypted data. Does wazuh expect an encrypted connection?
Wazuh is installed inside a lxc proxmox container, I followed the instructions in their documentation for installing on debian.
If I use the server's IP address, communication is ok.
I tried to edit like this but it does not work:
wazuh-r1515:
entryPoints:
- p1515tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s1515
tls:
passthrough: true
if I eliminate the passthrough instead and set HostSNI(*) it works:
wazuh-r1515:
entryPoints:
- p1515tcp
rule: "HostSNI(`wazuh.lab.local`)"
service: wazuh-s1515
On wazuh there are self-signed certificates, from traefik I set let's encrypt, could this be the problem?
Yeah, TLS in front and back is always a bit more complicated.
tls:
passthrough: true
only works when Traefik and target service share the same cert.
When Traefik uses LetsEncrypt, this is a challenge because you would need to export the LE cert like every 3 months and share it with the target service.
If you want to use different certs in front an back, you need to tell Traefik service
to use the cert or a insecureskipverify
transport.
If you want to use the custom cert from your target service, then you need to share it with Traefik to use regular HostSNI()
with domain name.
If Traefik does not have a cert, then you can not activate any TLS on the entrypoint (port) and only use a TCP router with HostSNI(`*`)
.