- Add SECURITY.md policy with credential management, Docker security, SSL/TLS guidance - Add security audit report (2025-12-20) with 31 findings across 4 severity levels - Add pre-deployment security checklist template - Update CLAUDE_STATUS.md with security audit initiative - Expand services/README.md with comprehensive security sections - Add script validation report and container name fix guide Audit identified 6 CRITICAL, 3 HIGH, 2 MEDIUM findings 4-phase remediation roadmap created (estimated 6-13 min downtime) All security scripts validated and ready for execution Related: Security Audit Q4 2025, CRITICAL-001 through CRITICAL-006 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
992 lines
29 KiB
Markdown
992 lines
29 KiB
Markdown
# Docker Compose Services
|
|
|
|
This directory contains Docker Compose configurations for various services deployed in the homelab environment.
|
|
|
|
## Migration Information
|
|
|
|
**Migration Date**: 2025-12-02
|
|
**Source**: GitLab instance at https://vulcan.apophisnetworking.net/jramos/homelab
|
|
**Target**: Gitea instance at http://192.168.2.102:3060/jramos/homelab
|
|
**Migration Tool**: Claude Code automated migration
|
|
|
|
All service configurations have been migrated from the legacy GitLab instance to this repository as part of the infrastructure consolidation effort.
|
|
|
|
## Services Overview
|
|
|
|
### ByteStash
|
|
**Directory**: `bytestash/`
|
|
**Port**: 5000
|
|
**Description**: Code snippet and text snippet management system with JWT-based authentication
|
|
**Image**: ghcr.io/jordan-dalby/bytestash:latest
|
|
**Key Features**:
|
|
- Snippet storage and organization
|
|
- User account management
|
|
- OIDC/SSO support (configurable)
|
|
- Debug mode available
|
|
|
|
**Deployment**:
|
|
```bash
|
|
cd bytestash
|
|
docker compose up -d
|
|
```
|
|
|
|
### FileBrowser
|
|
**Directory**: `filebrowser/`
|
|
**Port**: 8095
|
|
**Description**: Web-based file browser providing file management through a web interface
|
|
**Image**: filebrowser/filebrowser:latest
|
|
**Key Features**:
|
|
- Full filesystem access (mounted at root `/`)
|
|
- User and group ID configuration
|
|
- SQLite database for settings
|
|
- Customizable via settings.json
|
|
|
|
**Deployment**:
|
|
```bash
|
|
cd filebrowser
|
|
docker compose up -d
|
|
```
|
|
|
|
**Note**: Review volume mounts before deployment - currently configured to mount entire filesystem.
|
|
|
|
### GitLab Utilities
|
|
**Directory**: `gitlab/`
|
|
**Description**: Quality of Life (QoL) scripts and systemd configurations for GitLab management
|
|
**Contents**:
|
|
- `QoL Scripts/sync-npm-certs.sh`: Script to sync Nginx Proxy Manager certificates
|
|
- `QoL Config Files/sync-npm-certs.service`: Systemd service unit
|
|
- `QoL Config Files/sync-npm-certs.timer`: Systemd timer for automated certificate sync
|
|
|
|
**Purpose**: Automates certificate synchronization between Nginx Proxy Manager and GitLab instance.
|
|
|
|
### Paperless-ngx
|
|
**Directory**: `paperless-ngx/`
|
|
**Port**: 8000
|
|
**URL**: https://atlas.apophisnetworking.net
|
|
**Description**: Document management system with OCR, full-text search, and automated organization
|
|
**Images**:
|
|
- ghcr.io/paperless-ngx/paperless-ngx:latest (webserver)
|
|
- postgres:17 (database)
|
|
- redis:8 (message broker)
|
|
- gotenberg:8.20 (document conversion)
|
|
- apache/tika:latest (text extraction)
|
|
|
|
**Key Features**:
|
|
- OCR for scanned documents
|
|
- Automated document processing
|
|
- Tag and organization system
|
|
- PostgreSQL backend
|
|
- Redis task queue
|
|
- Tika integration for file parsing
|
|
- Gotenberg for document conversion
|
|
|
|
**Deployment**:
|
|
```bash
|
|
cd paperless-ngx
|
|
docker compose up -d
|
|
```
|
|
|
|
**Environment Configuration**: Check `.env` file or Portainer environment variables for production deployment.
|
|
|
|
### Portainer
|
|
**Directory**: `portainer/`
|
|
**Ports**:
|
|
- 8000 (Edge agent)
|
|
- 9443 (Web UI - HTTPS)
|
|
|
|
**Description**: Docker container management platform with web UI
|
|
**Image**: portainer/portainer-ce:latest
|
|
**Key Features**:
|
|
- Docker container management
|
|
- Stack deployment
|
|
- Image registry management
|
|
- User access control
|
|
- Remote agent support
|
|
|
|
**Deployment**:
|
|
```bash
|
|
cd portainer
|
|
docker compose up -d
|
|
```
|
|
|
|
**Note**: Uses external volume `portainer_data` - ensure volume exists before deployment.
|
|
|
|
### Speedtest Tracker
|
|
**Directory**: `speedtest-tracker/`
|
|
**Ports**:
|
|
- 8180 (HTTP)
|
|
- 8143 (HTTPS)
|
|
|
|
**Description**: Automated internet speed test tracker with historical data and public dashboard
|
|
**Image**: lscr.io/linuxserver/speedtest-tracker:latest
|
|
**Key Features**:
|
|
- Scheduled speed tests (cron: daily at midnight)
|
|
- SQLite database
|
|
- Public dashboard view
|
|
- Historical speed test data
|
|
- LinuxServer.io image with PUID/PGID support
|
|
|
|
**Deployment**:
|
|
```bash
|
|
cd speedtest-tracker
|
|
docker compose up -d
|
|
```
|
|
|
|
## Monitoring Stack (VM-based)
|
|
|
|
**Deployment**: VM 101 (monitoring-docker) at 192.168.2.114
|
|
**Technology**: Docker Compose
|
|
**Components**: Grafana, Prometheus, PVE Exporter
|
|
|
|
### Overview
|
|
Comprehensive monitoring and observability stack for the Proxmox homelab environment providing real-time metrics, visualization, and alerting capabilities.
|
|
|
|
### Components
|
|
|
|
**Grafana** (Port 3000):
|
|
- Visualization and dashboards
|
|
- Pre-configured Proxmox VE dashboards
|
|
- User authentication and RBAC
|
|
- Alerting capabilities
|
|
- Access: http://192.168.2.114:3000
|
|
|
|
**Prometheus** (Port 9090):
|
|
- Metrics collection and time-series database
|
|
- PromQL query language
|
|
- 15-day retention (configurable)
|
|
- Service discovery
|
|
- Access: http://192.168.2.114:9090
|
|
|
|
**PVE Exporter** (Port 9221):
|
|
- Proxmox VE metrics exporter
|
|
- Connects to Proxmox API
|
|
- Exports node, VM, CT, and storage metrics
|
|
- Access: http://192.168.2.114:9221
|
|
|
|
### Key Features
|
|
- Real-time Proxmox infrastructure monitoring
|
|
- VM and container resource utilization tracking
|
|
- Storage pool capacity planning
|
|
- Network traffic analysis
|
|
- Backup job status monitoring
|
|
- Custom alerting rules
|
|
|
|
### Deployment
|
|
|
|
```bash
|
|
# Navigate to monitoring directory
|
|
cd /home/jramos/homelab/monitoring
|
|
|
|
# Deploy PVE Exporter
|
|
cd pve-exporter
|
|
docker compose up -d
|
|
|
|
# Deploy Prometheus
|
|
cd ../prometheus
|
|
docker compose up -d
|
|
|
|
# Deploy Grafana
|
|
cd ../grafana
|
|
docker compose up -d
|
|
|
|
# Verify all services
|
|
docker ps | grep -E 'grafana|prometheus|pve-exporter'
|
|
```
|
|
|
|
### Configuration
|
|
|
|
**PVE Exporter**:
|
|
- Environment file: `monitoring/pve-exporter/.env`
|
|
- Configuration: `monitoring/pve-exporter/pve.yml`
|
|
- Requires Proxmox API user with PVEAuditor role
|
|
|
|
**Prometheus**:
|
|
- Configuration: `monitoring/prometheus/prometheus.yml`
|
|
- Scrapes PVE Exporter every 30 seconds
|
|
- Targets: localhost:9090, pve-exporter:9221
|
|
|
|
**Grafana**:
|
|
- Default credentials: admin/admin (change on first login)
|
|
- Data source: Prometheus at http://prometheus:9090
|
|
- Recommended dashboard: Grafana ID 10347 (Proxmox VE)
|
|
|
|
### Maintenance
|
|
|
|
```bash
|
|
# Update images
|
|
cd /home/jramos/homelab/monitoring/<component>
|
|
docker compose pull
|
|
docker compose up -d
|
|
|
|
# View logs
|
|
docker compose logs -f
|
|
|
|
# Restart services
|
|
docker compose restart
|
|
```
|
|
|
|
### Troubleshooting
|
|
|
|
**PVE Exporter connection issues**:
|
|
1. Verify Proxmox API is accessible: `curl -k https://192.168.2.200:8006`
|
|
2. Check credentials in `.env` file
|
|
3. Verify user has PVEAuditor role: `pveum user list` (on Proxmox)
|
|
|
|
**Grafana shows no data**:
|
|
1. Verify Prometheus data source configuration
|
|
2. Check Prometheus targets: http://192.168.2.114:9090/targets
|
|
3. Test queries in Prometheus UI before using in Grafana
|
|
|
|
**High memory usage**:
|
|
1. Reduce Prometheus retention period
|
|
2. Limit Grafana concurrent queries
|
|
3. Increase VM 101 memory allocation
|
|
|
|
**Complete Documentation**: See `/home/jramos/homelab/monitoring/README.md`
|
|
|
|
---
|
|
|
|
## Twingate Connector
|
|
|
|
**Deployment**: CT 112 (twingate-connector)
|
|
**Technology**: LXC Container
|
|
**Purpose**: Zero-trust network access
|
|
|
|
### Overview
|
|
Lightweight connector providing secure remote access to homelab resources without traditional VPN complexity. Part of Twingate's zero-trust network access (ZTNA) solution.
|
|
|
|
### Features
|
|
- **Zero-Trust Architecture**: Grant access to specific resources, not entire networks
|
|
- **No VPN Required**: Simplified connection without VPN client configuration
|
|
- **Identity-Based Access**: User and device authentication
|
|
- **Automatic Updates**: Connector auto-updates for security patches
|
|
- **Low Resource Overhead**: Minimal CPU and memory footprint
|
|
|
|
### Architecture
|
|
```
|
|
External User → Twingate Cloud → Twingate Connector (CT 112) → Homelab Resources
|
|
```
|
|
|
|
### Deployment Considerations
|
|
|
|
**LXC vs Docker**:
|
|
- LXC chosen for lightweight, always-on service
|
|
- Minimal resource consumption
|
|
- System-level integration
|
|
- Quick restart and recovery
|
|
|
|
**Network Placement**:
|
|
- Deployed on homelab management network (192.168.2.0/24)
|
|
- Access to all internal resources
|
|
- No inbound port forwarding required
|
|
|
|
### Configuration
|
|
|
|
The Twingate connector is configured via the Twingate Admin Console:
|
|
|
|
1. **Create Connector** in Twingate Admin Console
|
|
2. **Generate Token** for connector authentication
|
|
3. **Deploy Container** with provided token
|
|
4. **Configure Resources** to route through connector
|
|
5. **Assign Users** to resources
|
|
|
|
### Maintenance
|
|
|
|
**Health Monitoring**:
|
|
- Check connector status in Twingate Admin Console
|
|
- Monitor CPU/memory usage on CT 112
|
|
- Review connection logs
|
|
|
|
**Updates**:
|
|
- Connector auto-updates by default
|
|
- Manual updates: Restart container or redeploy
|
|
|
|
**Troubleshooting**:
|
|
- Verify network connectivity to Twingate cloud
|
|
- Check connector token validity
|
|
- Review resource routing configuration
|
|
- Ensure firewall allows outbound HTTPS
|
|
|
|
### Security Best Practices
|
|
|
|
1. **Least Privilege**: Grant access only to required resources
|
|
2. **MFA Enforcement**: Require multi-factor authentication for users
|
|
3. **Device Trust**: Enable device posture checks
|
|
4. **Audit Logs**: Regularly review access logs in Twingate Console
|
|
5. **Connector Isolation**: Consider dedicated network segment for connector
|
|
|
|
### Integration with Homelab
|
|
|
|
**Protected Resources**:
|
|
- Proxmox Web UI (192.168.2.200:8006)
|
|
- Grafana Monitoring (192.168.2.114:3000)
|
|
- Nginx Proxy Manager (192.168.2.101:81)
|
|
- n8n Workflows (192.168.2.107:5678)
|
|
- Development VMs and services
|
|
|
|
**Access Policies**:
|
|
- Admin users: Full access to all resources
|
|
- Monitoring users: Read-only Grafana access
|
|
- Developers: Access to dev VMs and services
|
|
|
|
---
|
|
|
|
## General Deployment Instructions
|
|
|
|
### Prerequisites
|
|
- Docker Engine 20.10+
|
|
- Docker Compose v2.0+
|
|
- Sufficient disk space for volumes
|
|
- Network ports available (check port conflicts)
|
|
|
|
### Standard Deployment Workflow
|
|
|
|
1. **Review Configuration**
|
|
```bash
|
|
cd services/<service-name>
|
|
cat docker-compose.yaml
|
|
```
|
|
|
|
2. **Configure Environment Variables** (if applicable)
|
|
```bash
|
|
# Copy example env file if available
|
|
cp .env.example .env
|
|
# Edit with actual values
|
|
nano .env
|
|
```
|
|
|
|
3. **Create Required Directories**
|
|
```bash
|
|
# Ensure volume mount points exist
|
|
# Example for bytestash:
|
|
mkdir -p /home/jramos/docker/bytestash/data
|
|
```
|
|
|
|
4. **Deploy Stack**
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
5. **Verify Deployment**
|
|
```bash
|
|
docker compose ps
|
|
docker compose logs -f
|
|
```
|
|
|
|
6. **Configure Reverse Proxy** (if using NPM)
|
|
- Access Nginx Proxy Manager at http://192.168.2.101:81
|
|
- Create proxy host pointing to service IP:PORT
|
|
- Configure SSL certificate via Let's Encrypt
|
|
- Set appropriate forwarding scheme (http/https)
|
|
|
|
### Maintenance Commands
|
|
|
|
**View Logs**:
|
|
```bash
|
|
cd services/<service-name>
|
|
docker compose logs -f
|
|
```
|
|
|
|
**Restart Service**:
|
|
```bash
|
|
docker compose restart
|
|
```
|
|
|
|
**Update Service**:
|
|
```bash
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
**Stop Service**:
|
|
```bash
|
|
docker compose down
|
|
```
|
|
|
|
**Remove Service and Volumes** (DESTRUCTIVE):
|
|
```bash
|
|
docker compose down -v
|
|
```
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
services/
|
|
├── README.md # This file
|
|
├── bytestash/
|
|
│ ├── docker-compose.yaml
|
|
│ └── .gitkeep
|
|
├── filebrowser/
|
|
│ ├── docker-compose.yaml
|
|
│ └── .gitkeep
|
|
├── gitlab/
|
|
│ ├── QoL Config Files/
|
|
│ │ ├── sync-npm-certs.service
|
|
│ │ └── sync-npm-certs.timer
|
|
│ └── QoL Scripts/
|
|
│ └── sync-npm-certs.sh
|
|
├── paperless-ngx/
|
|
│ ├── docker-compose.yaml
|
|
│ └── .env
|
|
├── portainer/
|
|
│ ├── docker-compose.yaml
|
|
│ └── .gitkeep
|
|
└── speedtest-tracker/
|
|
├── docker-compose.yaml
|
|
└── .gitkeep
|
|
```
|
|
|
|
## Volume Mounts and Data Locations
|
|
|
|
Services use the following host paths for persistent data:
|
|
|
|
| Service | Host Path | Purpose |
|
|
|---------|-----------|---------|
|
|
| ByteStash | `/home/jramos/docker/bytestash/data` | Snippet storage |
|
|
| FileBrowser | `/home/docker/filebrowser/` | Database and settings |
|
|
| Paperless-ngx | `/home/jramos/paperless-ngx/consume` | Document intake directory |
|
|
| Speedtest Tracker | `/home/jramos/docker/speedtest-tracker/config` | Configuration and database |
|
|
| Portainer | `portainer_data` (Docker volume) | Application data |
|
|
|
|
**Important**: Ensure these directories exist with appropriate permissions before deploying services.
|
|
|
|
## Network Configuration
|
|
|
|
All services are configured to use host networking or specific port mappings. If deploying behind Nginx Proxy Manager (CT 102 at 192.168.2.101):
|
|
|
|
1. Services should be accessible via internal IPs and ports
|
|
2. NPM handles external HTTPS access and SSL termination
|
|
3. Use `http` scheme in NPM when forwarding to backend services
|
|
4. Enable "Force SSL" in NPM for external HTTPS access
|
|
|
|
## Security Considerations
|
|
|
|
### Environment Files
|
|
- `.env` files are excluded from git via `.gitignore`
|
|
- Never commit credentials or API keys
|
|
- Use strong, unique passwords for database services
|
|
- Rotate JWT secrets and app keys regularly
|
|
|
|
### Secrets in Docker Compose Files
|
|
Several services have embedded secrets in their docker-compose.yaml files:
|
|
- **ByteStash**: `JWT_SECRET: your-secret` (CHANGE THIS)
|
|
- **Paperless-ngx**: Database password `paperless` (CHANGE THIS)
|
|
- **Speedtest Tracker**: `APP_KEY` (already generated, but sensitive)
|
|
|
|
**Action Required**: Create `.env` files and move secrets out of docker-compose.yaml files.
|
|
|
|
### Network Exposure
|
|
- Review port mappings before deployment
|
|
- Consider using Docker networks instead of host port binding
|
|
- Use NPM for external access with SSL
|
|
- Implement authentication on all services
|
|
|
|
## Troubleshooting
|
|
|
|
### Service Won't Start
|
|
1. Check logs: `docker compose logs -f`
|
|
2. Verify port availability: `netstat -tulpn | grep <port>`
|
|
3. Check volume permissions: `ls -la /path/to/volume`
|
|
4. Validate docker-compose.yaml syntax: `docker compose config`
|
|
|
|
### Cannot Access Service Externally
|
|
1. Verify service is running: `docker compose ps`
|
|
2. Test local access: `curl http://localhost:<port>`
|
|
3. Check NPM proxy host configuration
|
|
4. Verify DNS resolution
|
|
5. Check firewall rules: `iptables -L -n -v`
|
|
|
|
### Database Connection Errors (Paperless-ngx)
|
|
1. Verify PostgreSQL container is running
|
|
2. Check database credentials in environment variables
|
|
3. Ensure database initialization completed: `docker compose logs db`
|
|
4. Verify network connectivity between containers
|
|
|
|
### Permission Denied Errors
|
|
1. Check PUID/PGID settings in docker-compose.yaml
|
|
2. Verify host directory ownership: `chown -R <user>:<group> /path/to/volume`
|
|
3. Check SELinux context (if applicable): `ls -Z /path/to/volume`
|
|
|
|
### Monitoring Stack Issues
|
|
|
|
**Metrics Not Appearing**:
|
|
1. Verify PVE Exporter can reach Proxmox API
|
|
2. Check Prometheus scrape targets status
|
|
3. Ensure Grafana data source is configured correctly
|
|
4. Review retention policies (data may be expired)
|
|
|
|
**Authentication Failures (PVE Exporter)**:
|
|
1. Verify Proxmox user credentials in `.env` file
|
|
2. Check user has PVEAuditor role
|
|
3. Test API access: `curl -k https://192.168.2.200:8006/api2/json/version`
|
|
|
|
**High Resource Usage**:
|
|
1. Adjust Prometheus retention: `--storage.tsdb.retention.time=7d`
|
|
2. Reduce scrape frequency in prometheus.yml
|
|
3. Limit Grafana query concurrency
|
|
4. Increase VM 101 resources if needed
|
|
|
|
### Twingate Connector Issues
|
|
|
|
**Connector Offline**:
|
|
1. Check CT 112 is running: `pct status 112`
|
|
2. Verify network connectivity from container
|
|
3. Check connector token validity in Twingate Console
|
|
4. Review container logs for error messages
|
|
|
|
**Cannot Access Resources**:
|
|
1. Verify resource is configured in Twingate Console
|
|
2. Check user has permission to access resource
|
|
3. Ensure connector is online and healthy
|
|
4. Verify network routes on CT 112
|
|
|
|
## Migration Notes
|
|
|
|
### Post-Migration Tasks
|
|
- [ ] Review all `.env` files and update with production values
|
|
- [ ] Change default passwords and secrets in docker-compose files
|
|
- [ ] Verify volume mount paths exist on target system
|
|
- [ ] Test each service deployment individually
|
|
- [ ] Configure NPM proxy hosts for external access
|
|
- [ ] Update DNS records if service URLs changed
|
|
- [ ] Backup existing service data before redeployment
|
|
- [ ] Document any service-specific configuration changes
|
|
|
|
### Known Issues
|
|
- **FileBrowser**: Mounts entire filesystem root - review and restrict as needed
|
|
- **Paperless-ngx**: Contains `.env` file with secrets - ensure it's excluded from git
|
|
- **GitLab Utilities**: May require path adjustments depending on GitLab installation location
|
|
|
|
## Contributing
|
|
|
|
When adding new services to this directory:
|
|
|
|
1. Create a new subdirectory with service name (lowercase, hyphenated)
|
|
2. Include `docker-compose.yaml` (or `docker-compose.yml`)
|
|
3. Add `.env.example` if service requires environment variables
|
|
4. Document service in this README under "Services Overview"
|
|
5. Update directory structure diagram
|
|
6. Test deployment from scratch before committing
|
|
7. Ensure `.gitignore` excludes sensitive files
|
|
|
|
## Additional Resources
|
|
|
|
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
|
- [Nginx Proxy Manager Docs](https://nginxproxymanager.com/guide/)
|
|
- [Proxmox Homelab Documentation](../CLAUDE.md)
|
|
- [n8n Setup Guide](../n8n/N8N-SETUP-PLAN.md)
|
|
|
|
## Support
|
|
|
|
For homelab-specific questions or issues:
|
|
- Check existing documentation in `/home/jramos/homelab/`
|
|
- Review `CLAUDE_STATUS.md` for current infrastructure state
|
|
- Consult service-specific documentation linked in each service section
|
|
|
|
---
|
|
|
|
## Docker Socket Security
|
|
|
|
### Overview
|
|
|
|
Direct Docker socket access (`/var/run/docker.sock`) provides complete control over the Docker daemon, equivalent to root access on the host system. This represents a significant security risk that must be carefully managed.
|
|
|
|
### Current Exposures
|
|
|
|
The following containers currently have direct Docker socket access:
|
|
|
|
| Service | Socket Mount | Risk Level | Purpose |
|
|
|---------|-------------|------------|---------|
|
|
| Portainer | `/var/run/docker.sock:/var/run/docker.sock` | CRITICAL | Container management UI |
|
|
| Nginx Proxy Manager | `/var/run/docker.sock:/var/run/docker.sock` | CRITICAL | Auto-discovery of containers |
|
|
| Speedtest Tracker | `/var/run/docker.sock:/var/run/docker.sock` | CRITICAL | Container self-management |
|
|
|
|
**Risk Assessment**: Any compromise of these containers grants an attacker root access to the host system via Docker API.
|
|
|
|
### Recommended Mitigation: Docker Socket Proxy
|
|
|
|
Implement a read-only socket proxy to restrict Docker API access:
|
|
|
|
**Architecture**:
|
|
```
|
|
Container → Docker Socket Proxy (read-only API) → Docker Daemon
|
|
(filtered access) (full access)
|
|
```
|
|
|
|
**Implementation**:
|
|
```yaml
|
|
# docker-socket-proxy/docker-compose.yml
|
|
version: '3.8'
|
|
services:
|
|
docker-socket-proxy:
|
|
image: tecnativa/docker-socket-proxy:latest
|
|
container_name: docker-socket-proxy
|
|
restart: unless-stopped
|
|
environment:
|
|
CONTAINERS: 1 # Allow container listing
|
|
NETWORKS: 1 # Allow network listing
|
|
SERVICES: 0 # Deny service operations
|
|
TASKS: 0 # Deny task operations
|
|
POST: 0 # Deny POST (create/start/stop)
|
|
DELETE: 0 # Deny DELETE operations
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
ports:
|
|
- 127.0.0.1:2375:2375
|
|
```
|
|
|
|
**Migration Steps**:
|
|
1. Deploy socket proxy: `cd docker-socket-proxy && docker compose up -d`
|
|
2. Update Portainer to use `tcp://docker-socket-proxy:2375`
|
|
3. Update NPM to use HTTP API instead of socket
|
|
4. Remove socket mounts from all containers
|
|
5. Verify functionality and remove socket proxy if not needed
|
|
|
|
**Reference**: `/home/jramos/homelab/scripts/security/docker-socket-proxy/`
|
|
|
|
---
|
|
|
|
## SSL/TLS Configuration
|
|
|
|
### Overview
|
|
|
|
Transport Layer Security (TLS/SSL) encrypts traffic between clients and servers, preventing eavesdropping and man-in-the-middle attacks. All externally accessible services MUST use HTTPS.
|
|
|
|
### Nginx Proxy Manager SSL Setup
|
|
|
|
**Recommended Approach**: Use Let's Encrypt for automatic certificate issuance and renewal.
|
|
|
|
**Configuration Steps**:
|
|
|
|
1. **Add Proxy Host**:
|
|
- Navigate to NPM UI: http://192.168.2.101:81
|
|
- Proxy Hosts → Add Proxy Host
|
|
- Domain: `service.apophisnetworking.net`
|
|
- Scheme: `http` (internal communication)
|
|
- Forward Hostname/IP: `192.168.2.xxx`
|
|
- Forward Port: `8080` (service port)
|
|
|
|
2. **Configure SSL**:
|
|
- SSL Tab → Request New Certificate
|
|
- Certificate Type: Let's Encrypt
|
|
- Email: your-email@domain.com
|
|
- Toggle "Force SSL" (redirects HTTP → HTTPS)
|
|
- Toggle "HTTP/2 Support"
|
|
- Agree to Let's Encrypt ToS
|
|
|
|
3. **Advanced Options** (Optional):
|
|
```nginx
|
|
# Custom headers for security
|
|
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;
|
|
```
|
|
|
|
### Certificate Management
|
|
|
|
**Automatic Renewal**:
|
|
- Let's Encrypt certificates renew automatically 30 days before expiration
|
|
- NPM handles renewal process transparently
|
|
- Monitor renewal logs in NPM UI
|
|
|
|
**Manual Certificate Upload**:
|
|
For internal certificates or custom CAs:
|
|
1. SSL Certificates → Add SSL Certificate
|
|
2. Certificate Type: Custom
|
|
3. Paste certificate, private key, and intermediate certificates
|
|
4. Save and apply to proxy hosts
|
|
|
|
### Internal Service SSL
|
|
|
|
**When to Use**:
|
|
- Communication between NPM and backend services can use HTTP (internal network)
|
|
- Use HTTPS only if service contains highly sensitive data or requires end-to-end encryption
|
|
|
|
**Self-Signed Certificate Generation**:
|
|
```bash
|
|
# Generate self-signed certificate for internal service
|
|
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \
|
|
-subj "/C=US/ST=State/L=City/O=Homelab/CN=service.local"
|
|
```
|
|
|
|
### SSL Verification Warnings
|
|
|
|
**Issue**: Some services (PVE Exporter, NetBox) use self-signed certificates causing verification errors.
|
|
|
|
**Workarounds**:
|
|
- **Option 1**: Disable SSL verification (NOT recommended for production)
|
|
```yaml
|
|
environment:
|
|
- VERIFY_SSL=false
|
|
```
|
|
- **Option 2**: Add self-signed CA to trusted store
|
|
```bash
|
|
# Copy CA certificate to trusted store
|
|
cp /path/to/ca.crt /usr/local/share/ca-certificates/homelab-ca.crt
|
|
update-ca-certificates
|
|
```
|
|
- **Option 3**: Use Let's Encrypt for all services (recommended)
|
|
|
|
---
|
|
|
|
## Credential Rotation Schedule
|
|
|
|
Regular credential rotation reduces the impact of credential compromise and is a security best practice.
|
|
|
|
### Rotation Frequencies
|
|
|
|
| Credential Type | Rotation Frequency | Automation Status | Script |
|
|
|----------------|-------------------|-------------------|--------|
|
|
| Proxmox API Tokens | Quarterly (90 days) | Manual | `rotate-pve-credentials.sh` |
|
|
| Database Passwords | Semi-Annual (180 days) | Manual | `rotate-paperless-password.sh` |
|
|
| JWT Secrets | Annual (365 days) | Manual | `rotate-bytestash-jwt.sh` |
|
|
| Service Credentials | Annual (365 days) | Manual | `rotate-logward-credentials.sh` |
|
|
| SSH Keys | Biennial (730 days) | Manual | TBD |
|
|
| TLS Certificates | Automatic (Let's Encrypt) | Automatic | NPM built-in |
|
|
|
|
### Rotation Workflow Example
|
|
|
|
**Paperless-ngx Database Password Rotation**:
|
|
|
|
```bash
|
|
# 1. Backup current configuration
|
|
cd /home/jramos/homelab/scripts/security
|
|
./backup-before-remediation.sh
|
|
|
|
# 2. Generate new password
|
|
NEW_PASSWORD=$(openssl rand -base64 32)
|
|
|
|
# 3. Run rotation script
|
|
./rotate-paperless-password.sh
|
|
|
|
# 4. Verify service health
|
|
docker compose -f /home/jramos/homelab/services/paperless-ngx/docker-compose.yml ps
|
|
docker compose -f /home/jramos/homelab/services/paperless-ngx/docker-compose.yml logs --tail=50
|
|
|
|
# 5. Test application login
|
|
curl -I https://atlas.apophisnetworking.net
|
|
|
|
# 6. Document rotation in logbook
|
|
echo "$(date): Rotated Paperless-ngx DB password" >> /home/jramos/homelab/security-logbook.txt
|
|
```
|
|
|
|
### Credential Storage Best Practices
|
|
|
|
1. **Never commit credentials to git**:
|
|
- Use `.env` files (gitignored)
|
|
- Use Docker secrets for production
|
|
- Use HashiCorp Vault for enterprise
|
|
|
|
2. **Separate credentials from code**:
|
|
```yaml
|
|
# BAD: Hardcoded credentials
|
|
environment:
|
|
DB_PASSWORD: "hardcoded_password"
|
|
|
|
# GOOD: Environment variable
|
|
environment:
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
|
|
# BEST: Docker secret
|
|
secrets:
|
|
- db_password
|
|
```
|
|
|
|
3. **Use strong, unique passwords**:
|
|
```bash
|
|
# Generate cryptographically secure password
|
|
openssl rand -base64 32
|
|
|
|
# Generate passphrase-style password
|
|
shuf -n 6 /usr/share/dict/words | tr '\n' '-' | sed 's/-$//'
|
|
```
|
|
|
|
---
|
|
|
|
## Secrets Migration Strategy
|
|
|
|
### Current State: Secrets in Docker Compose Files
|
|
|
|
Several services have embedded credentials in `docker-compose.yml` files tracked by git:
|
|
|
|
| Service | Secret Type | Location | Risk Level |
|
|
|---------|------------|----------|------------|
|
|
| ByteStash | JWT_SECRET | docker-compose.yml | HIGH |
|
|
| Paperless-ngx | DB_PASSWORD | docker-compose.yml | CRITICAL |
|
|
| Speedtest Tracker | APP_KEY | docker-compose.yml | MEDIUM |
|
|
| Logward | OIDC_CLIENT_SECRET | docker-compose.yml | HIGH |
|
|
|
|
**Current Risk**: Credentials visible in git history, repository access = credential access.
|
|
|
|
### Migration Path
|
|
|
|
**Phase 1: Move to .env Files** (Immediate - Low Risk)
|
|
|
|
```bash
|
|
# For each service:
|
|
cd /home/jramos/homelab/services/<service-name>
|
|
|
|
# 1. Create .env file
|
|
cat > .env << 'EOF'
|
|
# Database credentials
|
|
DB_PASSWORD=<strong-password-here>
|
|
DB_USER=paperless
|
|
|
|
# Application secrets
|
|
SECRET_KEY=<generated-secret-key>
|
|
EOF
|
|
|
|
# 2. Update docker-compose.yml
|
|
# Replace:
|
|
# environment:
|
|
# - DB_PASSWORD=hardcoded_password
|
|
# With:
|
|
# env_file:
|
|
# - .env
|
|
|
|
# 3. Verify .env is gitignored
|
|
git check-ignore .env # Should show ".env" if properly ignored
|
|
|
|
# 4. Test deployment
|
|
docker compose config # Validates .env interpolation
|
|
docker compose up -d
|
|
|
|
# 5. Remove credentials from docker-compose.yml
|
|
git add docker-compose.yml
|
|
git commit -m "fix(security): move credentials to .env file"
|
|
```
|
|
|
|
**Phase 2: Docker Secrets** (Future - Production Grade)
|
|
|
|
For services requiring enhanced security:
|
|
|
|
```yaml
|
|
# docker-compose.yml with secrets
|
|
version: '3.8'
|
|
services:
|
|
paperless:
|
|
image: ghcr.io/paperless-ngx/paperless-ngx:latest
|
|
secrets:
|
|
- db_password
|
|
- secret_key
|
|
environment:
|
|
PAPERLESS_DBPASS_FILE: /run/secrets/db_password
|
|
PAPERLESS_SECRET_KEY_FILE: /run/secrets/secret_key
|
|
|
|
secrets:
|
|
db_password:
|
|
file: ./secrets/db_password.txt
|
|
secret_key:
|
|
file: ./secrets/secret_key.txt
|
|
```
|
|
|
|
**Phase 3: External Secret Management** (Future - Enterprise)
|
|
|
|
For homelab expansion or multi-node deployments:
|
|
- HashiCorp Vault integration
|
|
- Kubernetes Secrets (if migrating to K8s)
|
|
- AWS Secrets Manager / Azure Key Vault (hybrid cloud)
|
|
|
|
### Migration Priority
|
|
|
|
1. **Immediate** (Week 1):
|
|
- ByteStash JWT_SECRET → .env
|
|
- Paperless-ngx DB_PASSWORD → .env
|
|
- Speedtest Tracker APP_KEY → .env
|
|
|
|
2. **Short-term** (Month 1):
|
|
- All remaining services migrated to .env
|
|
- Git history scrubbing (BFG Repo-Cleaner)
|
|
|
|
3. **Long-term** (Quarter 1):
|
|
- Evaluate Docker Secrets for production services
|
|
- Implement Vault for Proxmox credentials
|
|
|
|
---
|
|
|
|
## Security Audit References
|
|
|
|
### Latest Audit: 2025-12-20
|
|
|
|
**Comprehensive Security Assessment Results**:
|
|
|
|
| Severity | Count | Examples |
|
|
|----------|-------|----------|
|
|
| CRITICAL | 6 | Docker socket exposure, hardcoded credentials, database passwords |
|
|
| HIGH | 3 | Missing SSL/TLS, weak passwords, containers as root |
|
|
| MEDIUM | 2 | SSL verification disabled, missing auth |
|
|
| LOW | 20 | Documentation gaps, monitoring needs, backup encryption |
|
|
|
|
**Total Findings**: 31 security issues identified
|
|
|
|
**Detailed Report**: `/home/jramos/homelab/troubleshooting/SECURITY_AUDIT_2025-12-20.md`
|
|
|
|
### Critical Findings Summary
|
|
|
|
**CRITICAL-001: Docker Socket Exposure** (CVSS 9.8)
|
|
- **Affected**: Portainer, Nginx Proxy Manager, Speedtest Tracker
|
|
- **Impact**: Container escape to host root access
|
|
- **Remediation**: Implement docker-socket-proxy with read-only permissions
|
|
- **Timeline**: Week 1
|
|
|
|
**CRITICAL-002: Proxmox Credentials in Plaintext** (CVSS 9.1)
|
|
- **Affected**: PVE Exporter configuration files
|
|
- **Impact**: Full Proxmox infrastructure compromise
|
|
- **Remediation**: Use Proxmox API tokens, move to environment variables
|
|
- **Timeline**: Week 1
|
|
|
|
**CRITICAL-003: Database Passwords in Git** (CVSS 8.5)
|
|
- **Affected**: Paperless-ngx, ByteStash, Speedtest Tracker
|
|
- **Impact**: Credential exposure via repository access
|
|
- **Remediation**: Migrate to .env files, scrub git history
|
|
- **Timeline**: Week 1
|
|
|
|
### Remediation Progress
|
|
|
|
Track remediation status in `/home/jramos/homelab/CLAUDE_STATUS.md` under "Security Audit Initiative"
|
|
|
|
**Phase 1 - Immediate (Week 1)**:
|
|
- [ ] Backup all service configurations
|
|
- [ ] Deploy docker-socket-proxy
|
|
- [ ] Migrate Portainer to socket proxy
|
|
- [ ] Move database passwords to .env files
|
|
|
|
**Phase 2 - Low-Risk Changes (Weeks 2-3)**:
|
|
- [ ] Rotate Proxmox API credentials
|
|
- [ ] Implement SSL/TLS for internal services
|
|
- [ ] Enable container user namespacing
|
|
- [ ] Deploy fail2ban
|
|
|
|
**Phase 3 - High-Risk Changes (Month 2)**:
|
|
- [ ] Migrate NPM to socket proxy
|
|
- [ ] Remove socket mounts from all containers
|
|
- [ ] Implement network segmentation
|
|
- [ ] Enable backup encryption
|
|
|
|
**Phase 4 - Infrastructure (Quarter 1)**:
|
|
- [ ] Container vulnerability scanning pipeline
|
|
- [ ] Automated credential rotation
|
|
- [ ] Security monitoring dashboards
|
|
|
|
### Security Checklist
|
|
|
|
**Pre-Deployment Security Checklist**: `/home/jramos/homelab/templates/SECURITY_CHECKLIST.md`
|
|
|
|
Use this checklist before deploying ANY new service to ensure security best practices.
|
|
|
|
### Validation Scripts
|
|
|
|
**Security Script Validation Report**: `/home/jramos/homelab/scripts/security/VALIDATION_REPORT.md`
|
|
|
|
All security scripts have been validated by the lab-operator agent:
|
|
- **Ready for Execution**: 5/8 scripts (verify-service-status.sh, rotate-pve-credentials.sh, rotate-bytestash-jwt.sh, backup-before-remediation.sh)
|
|
- **Needs Container Name Fixes**: 3/8 scripts (see CONTAINER_NAME_FIXES.md)
|
|
|
|
---
|
|
|
|
**Last Updated**: 2025-12-21
|
|
**Maintainer**: jramos
|
|
**Repository**: http://192.168.2.102:3060/jramos/homelab
|
|
**Infrastructure**: 8 VMs, 2 Templates, 4 LXC Containers
|