mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 18:45:53 +00:00
docs: improve password recovery documentation with secure methods
- Removed overly convenient password reset script (security concern) - Documented existing secure recovery token system - Added proper security warnings and considerations - Three-tier recovery approach: tokens (secure), recovery mode (localhost), manual (last resort) - Emphasizes security best practices and password manager usage - Addresses GitHub discussion #413 with security-conscious approach
This commit is contained in:
+106
-82
@@ -4,76 +4,130 @@
|
||||
|
||||
### Authentication Problems
|
||||
|
||||
#### Forgot Password / Password Reset
|
||||
#### Forgot Password / Lost Access
|
||||
|
||||
**⚠️ SECURITY WARNING**: Password reset requires server-level access. If someone can reset your Pulse password, they already have root/admin access to your server. **Secure your server access first!**
|
||||
|
||||
**Problem**: Can't remember the password and are locked out of the Pulse interface.
|
||||
|
||||
**Solutions**:
|
||||
**Important Security Considerations**:
|
||||
- These methods require server access (SSH/console)
|
||||
- If an attacker can perform these steps, they already have server control
|
||||
- Use a password manager to avoid needing password resets
|
||||
- **Re-enable authentication immediately after regaining access**
|
||||
|
||||
**Option 1: Use the password reset script (Native Install)**
|
||||
## Secure Recovery Methods
|
||||
|
||||
### Method 1: Recovery Token (Most Secure)
|
||||
|
||||
Pulse includes a secure recovery token system for emergency access:
|
||||
|
||||
**Step 1: Generate Recovery Token (from server)**
|
||||
```bash
|
||||
# Run the password reset script
|
||||
sudo /opt/pulse/scripts/reset-password.sh
|
||||
# SSH into your server and generate a time-limited recovery token
|
||||
curl -X POST http://localhost:7655/api/security/recovery \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"action": "generate_token", "duration": 30}'
|
||||
|
||||
# Choose option 1 to reset password (keeps username)
|
||||
# Choose option 2 to set new username and password
|
||||
# Choose option 3 to disable authentication temporarily
|
||||
# Choose option 4 to check current status
|
||||
# This returns a token valid for 30 minutes (max 60)
|
||||
# Save this token immediately - it's shown only once!
|
||||
```
|
||||
|
||||
**Option 2: Manually reset via .env file (Native Install)**
|
||||
**Step 2: Use Recovery Token (from any browser)**
|
||||
```bash
|
||||
# Edit the .env file directly
|
||||
sudo nano /opt/pulse/.env
|
||||
# Use the token to access the recovery endpoint
|
||||
curl -X POST http://your-server:7655/api/security/recovery \
|
||||
-H "X-Recovery-Token: your-token-here" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"action": "disable_auth"}'
|
||||
|
||||
# Option A: Disable authentication temporarily
|
||||
# Add or modify this line:
|
||||
DISABLE_AUTH=true
|
||||
# Then restart: sudo systemctl restart pulse
|
||||
|
||||
# Option B: Set new credentials
|
||||
# Add or modify these lines:
|
||||
PULSE_AUTH_USER=yournewusername
|
||||
PULSE_AUTH_PASS=yournewpassword
|
||||
# Then restart: sudo systemctl restart pulse
|
||||
# Now you can access the UI and reset your password
|
||||
```
|
||||
|
||||
**Option 3: Docker - Reset authentication**
|
||||
**Step 3: Re-enable Authentication**
|
||||
```bash
|
||||
# Option A: Disable auth temporarily
|
||||
docker exec pulse sh -c "echo 'DISABLE_AUTH=true' > /data/.env"
|
||||
# After setting new password in the UI
|
||||
curl -X POST http://localhost:7655/api/security/recovery \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"action": "enable_auth"}'
|
||||
```
|
||||
|
||||
**Security Features:**
|
||||
- Tokens are single-use only
|
||||
- Time-limited (30-60 minutes)
|
||||
- Cryptographically secure (32 bytes of entropy)
|
||||
- Logged for audit purposes
|
||||
- Constant-time validation to prevent timing attacks
|
||||
|
||||
### Method 2: Emergency Recovery Mode (Localhost Only)
|
||||
|
||||
If you have direct server access but can't use tokens:
|
||||
|
||||
**Native Install:**
|
||||
```bash
|
||||
# Enable recovery mode (localhost access only)
|
||||
echo "Recovery mode enabled at $(date)" | sudo tee /etc/pulse/.auth_recovery
|
||||
|
||||
# Access Pulse from the server itself (localhost)
|
||||
curl http://localhost:7655 # or use local browser/port forward
|
||||
|
||||
# Set new credentials through the UI
|
||||
|
||||
# Disable recovery mode
|
||||
sudo rm /etc/pulse/.auth_recovery
|
||||
sudo systemctl restart pulse
|
||||
```
|
||||
|
||||
**Docker:**
|
||||
```bash
|
||||
# Enable recovery mode
|
||||
docker exec pulse sh -c "echo 'Recovery mode' > /data/.auth_recovery"
|
||||
|
||||
# Access from localhost (port forward if needed)
|
||||
# Set new credentials
|
||||
|
||||
# Disable recovery mode
|
||||
docker exec pulse rm /data/.auth_recovery
|
||||
docker restart pulse
|
||||
|
||||
# Option B: Set new credentials
|
||||
docker exec pulse sh -c "cat > /data/.env << 'EOF'
|
||||
PULSE_AUTH_USER=yournewusername
|
||||
PULSE_AUTH_PASS=yournewpassword
|
||||
EOF"
|
||||
docker restart pulse
|
||||
|
||||
# Option C: Remove auth completely and use Quick Setup
|
||||
docker exec pulse rm -f /data/.env
|
||||
docker restart pulse
|
||||
# Then access the UI and use Quick Security Setup
|
||||
```
|
||||
|
||||
**Option 4: ProxmoxVE LXC - Reset from console**
|
||||
### Method 3: Manual Override (Last Resort)
|
||||
|
||||
⚠️ **Only use if other methods fail:**
|
||||
|
||||
```bash
|
||||
# Access the container console in Proxmox
|
||||
# Then run:
|
||||
/opt/pulse/scripts/reset-password.sh
|
||||
# Temporarily bypass auth (native install)
|
||||
echo "DISABLE_AUTH=true" | sudo tee -a /opt/pulse/.env
|
||||
sudo systemctl restart pulse
|
||||
|
||||
# Or manually edit:
|
||||
nano /opt/pulse/.env
|
||||
# Add: DISABLE_AUTH=true
|
||||
# Then: systemctl restart pulse
|
||||
# IMMEDIATELY set new credentials in UI
|
||||
# Then remove the DISABLE_AUTH line and restart
|
||||
|
||||
# For Docker:
|
||||
docker exec pulse sh -c "echo 'DISABLE_AUTH=true' >> /data/.env"
|
||||
docker restart pulse
|
||||
# Set credentials, then remove the line
|
||||
```
|
||||
|
||||
**Important Notes:**
|
||||
- Passwords are hashed with bcrypt when Pulse starts (you'll see a 60-character hash starting with $2)
|
||||
- Minimum password length is 8 characters
|
||||
- The .env file is located at `/opt/pulse/.env` (native) or `/data/.env` (Docker)
|
||||
- After resetting, you can re-enable authentication through the UI's security settings
|
||||
**Best Practices to Avoid This Situation**:
|
||||
1. **Use a password manager** - Store credentials securely
|
||||
2. **Document credentials** - Keep in a secure location
|
||||
3. **Set up API tokens** - Alternative authentication method
|
||||
4. **Regular backups** - Include .env file in backups
|
||||
5. **Secure server access** - Use SSH keys, disable root login, use fail2ban
|
||||
|
||||
**Alternative: API Token Access**:
|
||||
If you have an API token configured, you can still access the API:
|
||||
```bash
|
||||
curl -H "X-API-Token: your-token-here" http://localhost:7655/api/config/system
|
||||
```
|
||||
|
||||
**Security Reminder**:
|
||||
After regaining access:
|
||||
1. Set a strong password (use a password generator)
|
||||
2. Save credentials in a password manager
|
||||
3. Review server access logs for unauthorized access
|
||||
4. Consider implementing additional server security measures
|
||||
|
||||
#### Cannot login after setting up security
|
||||
**Symptoms**: "Invalid username or password" error despite correct credentials
|
||||
@@ -216,39 +270,9 @@ systemctl status pulse 2>/dev/null || systemctl status pulse-backend
|
||||
### Data Recovery
|
||||
|
||||
#### Lost authentication
|
||||
If you've lost access and need to reset:
|
||||
See [Forgot Password / Lost Access](#forgot-password--lost-access) section above for detailed recovery instructions.
|
||||
|
||||
**Native Install (Recommended)**:
|
||||
```bash
|
||||
# Use the password reset script
|
||||
sudo /opt/pulse/scripts/reset-password.sh
|
||||
# Follow the prompts to reset or disable auth
|
||||
```
|
||||
|
||||
**Docker**:
|
||||
```bash
|
||||
# Option 1: Reset credentials
|
||||
docker exec pulse sh -c "echo 'DISABLE_AUTH=true' > /data/.env"
|
||||
docker restart pulse
|
||||
# Access UI and set new credentials
|
||||
|
||||
# Option 2: Remove auth completely
|
||||
docker exec pulse rm /data/.env
|
||||
docker restart pulse
|
||||
# Access UI and use Quick Security Setup
|
||||
```
|
||||
|
||||
**Manual Reset**:
|
||||
```bash
|
||||
# Native install
|
||||
sudo nano /opt/pulse/.env
|
||||
# Add: DISABLE_AUTH=true
|
||||
sudo systemctl restart pulse # or pulse-backend
|
||||
|
||||
# Docker
|
||||
docker exec pulse sh -c "echo 'DISABLE_AUTH=true' > /data/.env"
|
||||
docker restart pulse
|
||||
```
|
||||
**⚠️ Security Note**: Password recovery requires root access. If someone can reset your password, they already have full control of your server. Focus on securing server access (SSH keys, firewall rules, etc.) rather than worrying about Pulse password resets.
|
||||
|
||||
#### Corrupt configuration
|
||||
Restore from backup or delete config files to start fresh:
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Pulse Password Reset Tool
|
||||
# This script helps reset the Pulse UI password
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check if running as root or with sudo
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Please run this script as root or with sudo${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pulse configuration location
|
||||
ENV_FILE="/opt/pulse/.env"
|
||||
BACKUP_FILE="/opt/pulse/.env.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
echo -e "${GREEN}=== Pulse Password Reset Tool ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo -e "${YELLOW}No .env file found. Creating new configuration...${NC}"
|
||||
touch "$ENV_FILE"
|
||||
chown pulse:pulse "$ENV_FILE" 2>/dev/null || true
|
||||
chmod 600 "$ENV_FILE"
|
||||
fi
|
||||
|
||||
# Backup existing configuration
|
||||
if [ -s "$ENV_FILE" ]; then
|
||||
echo -e "${GREEN}Creating backup: $BACKUP_FILE${NC}"
|
||||
cp "$ENV_FILE" "$BACKUP_FILE"
|
||||
fi
|
||||
|
||||
# Function to update or add a line in .env
|
||||
update_env_var() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
|
||||
if grep -q "^${key}=" "$ENV_FILE"; then
|
||||
# Update existing line
|
||||
sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
|
||||
else
|
||||
# Add new line
|
||||
echo "${key}=${value}" >> "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Ask what the user wants to do
|
||||
echo "What would you like to do?"
|
||||
echo "1) Reset password (keep existing username)"
|
||||
echo "2) Set new username and password"
|
||||
echo "3) Disable authentication completely"
|
||||
echo "4) Show current authentication status"
|
||||
echo ""
|
||||
read -p "Enter choice (1-4): " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
# Reset password only
|
||||
echo ""
|
||||
# Check if there's an existing username
|
||||
if grep -q "^PULSE_AUTH_USER=" "$ENV_FILE"; then
|
||||
current_user=$(grep "^PULSE_AUTH_USER=" "$ENV_FILE" | cut -d'=' -f2)
|
||||
echo -e "${GREEN}Current username: $current_user${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}No username found. Please use option 2 to set both username and password.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -s -p "Enter new password (minimum 8 characters): " password
|
||||
echo ""
|
||||
read -s -p "Confirm new password: " password2
|
||||
echo ""
|
||||
|
||||
if [ "$password" != "$password2" ]; then
|
||||
echo -e "${RED}Passwords do not match!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#password} -lt 8 ]; then
|
||||
echo -e "${RED}Password must be at least 8 characters!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update password
|
||||
update_env_var "PULSE_AUTH_PASS" "$password"
|
||||
# Ensure auth is enabled
|
||||
sed -i '/^DISABLE_AUTH=/d' "$ENV_FILE"
|
||||
|
||||
echo -e "${GREEN}✓ Password reset successfully${NC}"
|
||||
;;
|
||||
|
||||
2)
|
||||
# Set new username and password
|
||||
echo ""
|
||||
read -p "Enter new username: " username
|
||||
|
||||
if [ -z "$username" ]; then
|
||||
echo -e "${RED}Username cannot be empty!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -s -p "Enter new password (minimum 8 characters): " password
|
||||
echo ""
|
||||
read -s -p "Confirm new password: " password2
|
||||
echo ""
|
||||
|
||||
if [ "$password" != "$password2" ]; then
|
||||
echo -e "${RED}Passwords do not match!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#password} -lt 8 ]; then
|
||||
echo -e "${RED}Password must be at least 8 characters!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update username and password
|
||||
update_env_var "PULSE_AUTH_USER" "$username"
|
||||
update_env_var "PULSE_AUTH_PASS" "$password"
|
||||
# Ensure auth is enabled
|
||||
sed -i '/^DISABLE_AUTH=/d' "$ENV_FILE"
|
||||
|
||||
echo -e "${GREEN}✓ Username and password set successfully${NC}"
|
||||
;;
|
||||
|
||||
3)
|
||||
# Disable authentication
|
||||
echo ""
|
||||
echo -e "${YELLOW}WARNING: This will disable all authentication for Pulse!${NC}"
|
||||
echo -e "${YELLOW}Anyone with network access will be able to view and modify your configuration.${NC}"
|
||||
echo ""
|
||||
read -p "Are you sure you want to disable authentication? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" = "yes" ]; then
|
||||
# Remove auth credentials and set DISABLE_AUTH=true
|
||||
sed -i '/^PULSE_AUTH_USER=/d' "$ENV_FILE"
|
||||
sed -i '/^PULSE_AUTH_PASS=/d' "$ENV_FILE"
|
||||
update_env_var "DISABLE_AUTH" "true"
|
||||
|
||||
echo -e "${GREEN}✓ Authentication disabled${NC}"
|
||||
else
|
||||
echo "Cancelled"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
|
||||
4)
|
||||
# Show current status
|
||||
echo ""
|
||||
echo -e "${GREEN}Current Authentication Status:${NC}"
|
||||
echo ""
|
||||
|
||||
if grep -q "^DISABLE_AUTH=true" "$ENV_FILE"; then
|
||||
echo -e "${YELLOW}Authentication is DISABLED${NC}"
|
||||
elif grep -q "^PULSE_AUTH_USER=" "$ENV_FILE"; then
|
||||
current_user=$(grep "^PULSE_AUTH_USER=" "$ENV_FILE" | cut -d'=' -f2)
|
||||
echo -e "${GREEN}Authentication is ENABLED${NC}"
|
||||
echo "Username: $current_user"
|
||||
|
||||
if grep -q "^PULSE_AUTH_PASS=" "$ENV_FILE"; then
|
||||
pass_value=$(grep "^PULSE_AUTH_PASS=" "$ENV_FILE" | cut -d'=' -f2)
|
||||
# Check if it's a bcrypt hash (starts with $2 and is ~60 chars)
|
||||
if [[ $pass_value == \$2* ]] && [ ${#pass_value} -ge 55 ]; then
|
||||
echo "Password: [HASHED - Secure]"
|
||||
else
|
||||
echo "Password: [SET - Plain text, will be hashed on restart]"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Password: [NOT SET]${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}No authentication configured${NC}"
|
||||
echo "Use option 2 to set up authentication"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo -e "${RED}Invalid choice${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set proper permissions
|
||||
chown pulse:pulse "$ENV_FILE" 2>/dev/null || true
|
||||
chmod 600 "$ENV_FILE"
|
||||
|
||||
# Ask if user wants to restart Pulse
|
||||
echo ""
|
||||
echo -e "${YELLOW}Changes have been saved to $ENV_FILE${NC}"
|
||||
echo ""
|
||||
read -p "Would you like to restart Pulse now to apply changes? (y/n): " restart
|
||||
|
||||
if [ "$restart" = "y" ] || [ "$restart" = "Y" ]; then
|
||||
# Check which service is running
|
||||
if systemctl is-active --quiet pulse-backend; then
|
||||
echo "Restarting pulse-backend service..."
|
||||
systemctl restart pulse-backend
|
||||
echo -e "${GREEN}✓ Service restarted${NC}"
|
||||
elif systemctl is-active --quiet pulse; then
|
||||
echo "Restarting pulse service..."
|
||||
systemctl restart pulse
|
||||
echo -e "${GREEN}✓ Service restarted${NC}"
|
||||
elif systemctl is-active --quiet pulse-dev; then
|
||||
echo "Restarting pulse-dev service..."
|
||||
systemctl restart pulse-dev
|
||||
echo -e "${GREEN}✓ Service restarted${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}No Pulse service found running. Please restart manually if needed.${NC}"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo "To apply changes, restart Pulse manually with:"
|
||||
echo " sudo systemctl restart pulse"
|
||||
echo " or"
|
||||
echo " sudo systemctl restart pulse-backend"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Done!${NC}"
|
||||
Reference in New Issue
Block a user