Dashdot is a modern server dashboard that displays system metrics in a visually appealing interface. As a dashboard that collects and displays system information, Dashdot requires proper security configuration to prevent information disclosure and unauthorized access. This guide covers security measures for production Dashdot deployments.
Dashdot architecture includes these security-sensitive components:
Key security concerns include web interface exposure, system information disclosure, WebSocket security, and host system access.
Configure firewall rules for Dashdot:
# Dashdot web interface (default port 3001)
ufw allow from 10.0.0.0/8 to any port 3001 proto tcp
ufw allow from 192.168.1.0/24 to any port 3001 proto tcp
# Block external access
ufw deny from any to any port 3001 proto tcp
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dashdot-network-policy
spec:
podSelector:
matchLabels:
app: dashdot
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 3001
Configure Dashdot binding:
# Run Dashdot with specific binding
docker run \
-d \
-p 127.0.0.1:3001:3001 \
-v /:/hostfs:ro \
--name dashdot \
mauricenino/dashdot
Environment variables for configuration:
# .env file
HOST=127.0.0.1
PORT=3001
# Bind to localhost for reverse proxy
Configure reverse proxy:
# /etc/nginx/sites-available/dashdot
server {
listen 80;
server_name dashdot.company.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name dashdot.company.com;
ssl_certificate /etc/nginx/certs/dashdot.crt;
ssl_certificate_key /etc/nginx/certs/dashdot.key;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Configure authentication via reverse proxy:
Nginx with Basic Auth:
location / {
auth_basic "Dashdot Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Nginx with OAuth2:
location / {
auth_request /oauth2/auth;
error_page 401 =200 /oauth2/start;
proxy_pass http://localhost:3001;
}
Manage users:
# Create admin user
htpasswd -c /etc/nginx/.htpasswd admin
# Add additional users
htpasswd /etc/nginx/.htpasswd username
Configure authentication in Kubernetes:
# Use ingress with authentication
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashdot
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: dashdot-auth
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
spec:
rules:
- host: dashdot.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dashdot
port:
number: 3001
Create auth secret:
# Create auth secret
htpasswd -c auth admin
kubectl create secret generic dashdot-auth --from-file=auth
Dashdot doesn’t have a traditional API, but WebSocket connections should be protected:
# WebSocket security
location / {
auth_basic "Dashdot Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Configure session security via reverse proxy:
# Session cookie settings
proxy_cookie_path / "/; secure; HttpOnly; SameSite=Strict";
Configure HTTPS via reverse proxy:
# /etc/nginx/sites-available/dashdot
server {
listen 443 ssl http2;
server_name dashdot.company.com;
ssl_certificate /etc/nginx/certs/dashdot.crt;
ssl_certificate_key /etc/nginx/certs/dashdot.key;
ssl_trusted_certificate /etc/nginx/certs/ca-bundle.crt;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src * data:; font-src 'self' data:; connect-src 'self' wss:;" always;
location / {
auth_basic "Dashdot Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Secure WebSocket connections:
# WebSocket secure proxy
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket timeout
proxy_read_timeout 86400;
}
Generate and manage certificates:
# Generate self-signed certificate
openssl req -new -x509 -days 365 -nodes \
-out /etc/nginx/certs/dashdot.crt \
-keyout /etc/nginx/certs/dashdot.key \
-subj "/CN=dashdot.company.com/O=Company"
# Or use Let's Encrypt
certbot --nginx -d dashdot.company.com
Configure web interface security:
# Rate limiting
limit_req_zone $binary_remote_addr zone=dashdot:10m rate=10r/s;
server {
location / {
limit_req zone=dashdot burst=20 nodelay;
auth_basic "Dashdot Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3001;
}
}
Limit exposed system information:
# Run with limited host access
docker run \
-d \
-p 127.0.0.1:3001:3001 \
-v /proc:/hostfs/proc:ro \
-v /sys:/hostfs/sys:ro \
# Don't mount entire root filesystem
--name dashdot \
mauricenino/dashdot
Run Dashdot securely:
# Kubernetes security context
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Set resource limits:
# Kubernetes resource limits
resources:
requests:
cpu: 50m
memory: 100Mi
limits:
cpu: 200m
memory: 256Mi
Limit host system access:
# Minimal volume mounts
docker run \
-d \
-p 127.0.0.1:3001:3001 \
-v /proc:/hostfs/proc:ro \
-v /sys:/hostfs/sys:ro \
-v /etc/os-release:/hostfs/etc/os-release:ro \
--read-only \
--tmpfs /tmp \
--name dashdot \
mauricenino/dashdot
Secure Dashdot logs:
# Configure log driver
docker run \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
mauricenino/dashdot
Protect configuration:
# Set restrictive permissions on .env file
chown root:root /opt/dashdot/.env
chmod 600 /opt/dashdot/.env
Secure sensitive configuration:
# Use Docker secrets or environment variables
docker run \
-d \
-e HOST=127.0.0.1 \
-e PORT=3001 \
--secret source=dashdot_auth,target=/run/secrets/auth \
mauricenino/dashdot
Enable logging:
# Dashdot logs to stdout/stderr
# Configure Docker logging
docker logs dashdot
Configure reverse proxy access logging:
# /etc/nginx/sites-available/dashdot
access_log /var/log/nginx/dashdot_access.log combined;
error_log /var/log/nginx/dashdot_error.log warn;
Monitor Dashdot for security events:
# Prometheus alerting rules
groups:
- name: dashdot-security
rules:
- alert: DashdotHighRequestRate
expr: rate(nginx_http_requests_total{server="dashdot.company.com"}[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "High request rate to Dashdot"
- alert: DashdotAuthFailures
expr: increase(nginx_http_requests_total{server="dashdot.company.com",status="401"}[5m]) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "Multiple authentication failures on Dashdot"
Forward logs to SIEM:
# /etc/rsyslog.d/dashdot.conf
# Forward Nginx access logs
/var/log/nginx/dashdot_access.log @siem.company.com:514