Fix container SSH detection and improve troubleshooting for issue #617

Related to #617

This fixes a misconfiguration scenario where Docker containers could
attempt direct SSH connections (producing [preauth] log spam) instead
of using the sensor proxy.

Changes:
- Fix container detection to check PULSE_DOCKER=true in addition to
  system.InContainer() heuristics (both temperature.go and config_handlers.go)
- Upgrade temperature collection log from Error to Warn with actionable
  guidance about mounting the proxy socket
- Add Info log when dev mode override is active so operators understand
  the security posture
- Add troubleshooting section to docs for SSH [preauth] logs from containers

The container detection was inconsistent - monitor.go checked both flags
but temperature.go and config_handlers.go only checked InContainer().
Now all locations consistently check PULSE_DOCKER || InContainer().
This commit is contained in:
rcourtman
2025-11-06 09:57:53 +00:00
parent 12dc8693c4
commit dfe960deb4
3 changed files with 38 additions and 5 deletions

View File

@@ -359,6 +359,28 @@ You should see JSON output with temperature data.
## Troubleshooting
### SSH Connection Attempts from Container ([preauth] Logs)
**Symptom:** Proxmox host logs (`/var/log/auth.log`) show repeated SSH connection attempts from your Pulse container:
```
Connection closed by authenticating user root <container-ip> port <port> [preauth]
```
**This indicates a misconfiguration.** Containerized Pulse should communicate via the sensor proxy, not direct SSH.
**Common causes:**
- Dev mode enabled (`PULSE_DEV_ALLOW_CONTAINER_SSH=true` environment variable)
- Sensor proxy not installed or socket not accessible
- Legacy SSH keys from pre-v4.24.0 installations
**Fix:**
- **Docker:** Follow [Quick Start for Docker Deployments](#quick-start-for-docker-deployments) to install the proxy and add the bind mount
- **LXC:** Run the setup script on your Proxmox host (see [Setup (Automatic)](#setup-automatic))
- **Dev mode:** Remove `PULSE_DEV_ALLOW_CONTAINER_SSH=true` from your environment/docker-compose
- **Verify:** Check Pulse logs for `Temperature proxy detected - using secure host-side bridge`
Once the proxy is properly configured, these log entries will stop immediately. See [Container Security Considerations](#container-security-considerations) for why direct container SSH is blocked.
### No Temperature Data Shown
**Check SSH access**:

View File

@@ -5878,7 +5878,9 @@ func (h *ConfigHandlers) getOrGenerateSSHKeys() SSHKeyPair {
// CRITICAL SECURITY CHECK: Never generate SSH keys in containers (unless dev mode)
// Container compromise = SSH key compromise = root access to Proxmox
devModeAllowSSH := os.Getenv("PULSE_DEV_ALLOW_CONTAINER_SSH") == "true"
if system.InContainer() && !devModeAllowSSH {
isContainer := os.Getenv("PULSE_DOCKER") == "true" || system.InContainer()
if isContainer && !devModeAllowSSH {
log.Error().Msg("SECURITY BLOCK: SSH key generation disabled in containerized deployments")
log.Error().Msg("For temperature monitoring in containers, deploy pulse-sensor-proxy on the Proxmox host")
log.Error().Msg("See: https://github.com/rcourtman/Pulse/blob/main/SECURITY.md#critical-security-notice-for-container-deployments")
@@ -5886,7 +5888,7 @@ func (h *ConfigHandlers) getOrGenerateSSHKeys() SSHKeyPair {
return SSHKeyPair{}
}
if devModeAllowSSH && system.InContainer() {
if devModeAllowSSH && isContainer {
log.Warn().Msg("⚠️ DEV MODE: SSH key generation ENABLED in container - FOR TESTING ONLY")
log.Warn().Msg("⚠️ This grants root SSH access from container - NEVER use in production!")
}

View File

@@ -114,10 +114,19 @@ func (tc *TemperatureCollector) CollectTemperature(ctx context.Context, nodeHost
// SECURITY: Block SSH fallback when running in containers (unless dev mode)
// Container compromise = SSH key compromise = root access to infrastructure
devModeAllowSSH := os.Getenv("PULSE_DEV_ALLOW_CONTAINER_SSH") == "true"
if system.InContainer() && !devModeAllowSSH {
log.Error().
isContainer := os.Getenv("PULSE_DOCKER") == "true" || system.InContainer()
if isContainer && devModeAllowSSH {
// Log when dev override is active so operators understand the security posture
log.Info().
Str("node", nodeName).
Msg("SECURITY BLOCK: SSH temperature collection disabled in containers - deploy pulse-sensor-proxy")
Msg("Temperature collection using direct SSH (dev mode override active - not for production)")
}
if isContainer && !devModeAllowSSH {
log.Warn().
Str("node", nodeName).
Msg("Temperature collection disabled: containerized Pulse requires pulse-sensor-proxy. Mount /run/pulse-sensor-proxy or set PULSE_DEV_ALLOW_CONTAINER_SSH=true for development only")
return &models.Temperature{Available: false}, nil
}