Scrutiny is a web-based hard drive health monitoring tool that collects and analyzes SMART data from storage devices. As a system with direct access to hardware information and potential for privileged operations, Scrutiny requires proper security configuration. This guide covers security measures for production Scrutiny deployments.
Scrutiny architecture includes these security-sensitive components:
Key security concerns include web interface protection, API access control, drive access permissions, database security, and preventing unauthorized hardware access.
Configure firewall rules for Scrutiny:
# Scrutiny web interface (default port 8080)
ufw allow from 10.0.0.0/8 to any port 8080 proto tcp
ufw allow from 10.0.0.0/8 to any port 443 proto tcp
# Block external access
ufw deny from any to any port 8080 proto tcp
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: scrutiny-network-policy
spec:
podSelector:
matchLabels:
app: scrutiny
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 8080
Configure Scrutiny binding:
# /opt/scrutiny/config/scrutiny.yaml
web:
listen:
port: 8080
host: 127.0.0.1 # Bind to localhost for reverse proxy
basepath: ''
Configure reverse proxy:
# /etc/nginx/sites-available/scrutiny
server {
listen 80;
server_name scrutiny.company.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name scrutiny.company.com;
ssl_certificate /etc/nginx/certs/scrutiny.crt;
ssl_certificate_key /etc/nginx/certs/scrutiny.key;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
Configure authentication via reverse proxy:
Nginx with Basic Auth:
location / {
auth_basic "Scrutiny Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Manage users:
# Create admin user
htpasswd -c /etc/nginx/.htpasswd admin
# Add additional users
htpasswd /etc/nginx/.htpasswd username
Configure Scrutiny authentication (if supported):
# /opt/scrutiny/config/scrutiny.yaml
auth:
enabled: true
session_timeout: 3600
password_min_length: 12
Configure user roles:
Role Permissions:
- admin: Full access including configuration
- operator: Can view drives and run tests
- viewer: Read-only access to drive data
Secure API access:
# Generate API token
# Via web UI or CLI
scrutiny token create --name "Monitoring Integration"
# Use token for API access
curl -H "Authorization: Bearer ${API_TOKEN}" \
http://localhost:8080/api/v1/devices
Configure HTTPS via reverse proxy:
# /etc/nginx/sites-available/scrutiny
server {
listen 443 ssl http2;
server_name scrutiny.company.com;
ssl_certificate /etc/nginx/certs/scrutiny.crt;
ssl_certificate_key /etc/nginx/certs/scrutiny.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;
# 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;
location / {
auth_basic "Scrutiny Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
If Scrutiny supports native TLS:
# /opt/scrutiny/config/scrutiny.yaml
web:
listen:
tls:
enabled: true
cert_file: /etc/scrutiny/ssl/scrutiny.crt
key_file: /etc/scrutiny/ssl/scrutiny.key
Generate and manage certificates:
# Generate self-signed certificate
openssl req -new -x509 -days 365 -nodes \
-out /etc/nginx/certs/scrutiny.crt \
-keyout /etc/nginx/certs/scrutiny.key \
-subj "/CN=scrutiny.company.com/O=Company"
# Or use Let's Encrypt
certbot --nginx -d scrutiny.company.com
Secure Scrutiny API endpoints:
| Endpoint | Risk Level | Access Control |
|---|---|---|
GET /api/v1/devices |
Low | Authenticated |
GET /api/v1/devices/{id} |
Low | Authenticated |
POST /api/v1/devices/{id}/test |
High | Admin only |
PUT /api/v1/settings |
High | Admin only |
DELETE /api/v1/devices/{id} |
Critical | Admin only |
Implement API rate limiting:
# Nginx rate limiting for Scrutiny API
limit_req_zone $binary_remote_addr zone=scrutiny_api:10m rate=30r/s;
location /api/ {
limit_req zone=scrutiny_api burst=50 nodelay;
proxy_pass http://localhost:8080;
}
Restrict drive access permissions:
# Create scrutiny group
groupadd scrutiny
# Add scrutiny user to group
usermod -a -G scrutiny scrutiny
# Set disk access permissions
chown root:scrutiny /dev/sd[a-z]
chmod 640 /dev/sd[a-z]
# Or use udev rules
# /etc/udev/rules.d/99-scrutiny.rules
KERNEL=="sd[a-z]", GROUP="scrutiny", MODE="0640"
Secure smartctl access:
# Set restrictive permissions on smartctl
chown root:scrutiny /usr/sbin/smartctl
chmod 750 /usr/sbin/smartctl
# Configure sudo for smartctl access
# /etc/sudoers.d/scrutiny
scrutiny ALL=(ALL) NOPASSWD: /usr/sbin/smartctl
Configure web UI security:
# /opt/scrutiny/config/scrutiny.yaml
web:
security:
csrf_enabled: true
session_timeout: 3600
secure_cookies: true
Secure Scrutiny database:
# SQLite - set restrictive permissions
chown scrutiny:scrutiny /opt/scrutiny/data/scrutiny.db
chmod 640 /opt/scrutiny/data/scrutiny.db
# Use encrypted filesystem
# Mount /opt/scrutiny/data on encrypted volume
For PostgreSQL:
-- Create dedicated database user
CREATE USER scrutiny WITH PASSWORD '${DB_PASSWORD}';
CREATE DATABASE scrutiny OWNER scrutiny;
GRANT ALL PRIVILEGES ON DATABASE scrutiny TO scrutiny;
-- Enable SSL requirement
ALTER USER scrutiny WITH PASSWORD '${DB_PASSWORD}';
Enable data encryption:
# Use encrypted filesystem for data directory
# Mount /opt/scrutiny/data on encrypted volume
# Or encrypt database file
# For SQLite, use SQLCipher
Secure sensitive configuration:
# /opt/scrutiny/config/scrutiny.yaml
# Use environment variables
database:
password: ${SCRUTINY_DB_PASSWORD}
# Or use external secrets file
# include: /etc/scrutiny/secrets.yaml
Protect secrets file:
# Set restrictive permissions
chown root:scrutiny /etc/scrutiny/secrets.yaml
chmod 640 /etc/scrutiny/secrets.yaml
Protect Scrutiny configuration:
# Set restrictive permissions
chown scrutiny:scrutiny /opt/scrutiny/config/scrutiny.yaml
chmod 640 /opt/scrutiny/config/scrutiny.yaml
Enable logging:
# /opt/scrutiny/config/scrutiny.yaml
logging:
level: info
file: /var/log/scrutiny/scrutiny.log
# Audit logging
audit:
enabled: true
file: /var/log/scrutiny/audit.log
Configure reverse proxy access logging:
# /etc/nginx/sites-available/scrutiny
access_log /var/log/nginx/scrutiny_access.log combined;
error_log /var/log/nginx/scrutiny_error.log warn;
Monitor Scrutiny for security events:
#!/bin/bash
# /usr/local/bin/check-scrutiny-security.sh
# Check for failed authentication
FAILED_AUTH=$(grep -c "401" /var/log/nginx/scrutiny_access.log 2>/dev/null || echo 0)
if [ "$FAILED_AUTH" -gt 10 ]; then
echo "CRITICAL: Multiple authentication failures"
exit 2
fi
# Check for unauthorized drive access
UNAUTH=$(grep -c "permission denied" /var/log/scrutiny/scrutiny.log 2>/dev/null || echo 0)
if [ "$UNAUTH" -gt 5 ]; then
echo "WARNING: Unauthorized drive access attempts"
exit 1
fi
Forward logs to SIEM:
# /etc/rsyslog.d/scrutiny.conf
:programname, isequal, "scrutiny" /var/log/scrutiny/syslog.log
:programname, isequal, "scrutiny" @siem.company.com:514