Fix SSL certificate generation for HTTPS mode

- wizard/setup now generate certs when HTTPS enabled
- app.py has proper error handling for cert failures
- Add custom SSL certificate documentation to INSTALL.md
- Include SANs for hostname, localhost, and local IP

Previously HTTPS could be enabled but certs weren't generated,
causing SSL_ERROR_RX_RECORD_TOO_LONG browser errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Aaron D. Lee
2026-01-05 22:16:12 -05:00
parent 597a9c6411
commit 962c04084b
4 changed files with 145 additions and 3 deletions

View File

@@ -553,6 +553,85 @@ print(f'jpegio: {has_jpegio_support()}')
--- ---
## Custom SSL Certificates
By default, Stegasoo generates a self-signed certificate for HTTPS. To use your own certificate (e.g., from Let's Encrypt or your organization's CA):
### Replace Self-Signed Certificates
```bash
# Stop the service
sudo systemctl stop stegasoo
# Backup existing certs (optional)
mv /opt/stegasoo/frontends/web/certs /opt/stegasoo/frontends/web/certs.bak
# Create new certs directory
mkdir -p /opt/stegasoo/frontends/web/certs
# Copy your certificates (adjust paths as needed)
cp /path/to/your/certificate.crt /opt/stegasoo/frontends/web/certs/server.crt
cp /path/to/your/private.key /opt/stegasoo/frontends/web/certs/server.key
# Set permissions (key must be readable by service user)
chmod 600 /opt/stegasoo/frontends/web/certs/server.key
chown -R $(whoami):$(whoami) /opt/stegasoo/frontends/web/certs
# Start the service
sudo systemctl start stegasoo
```
### Generate New Self-Signed Certificate
If your certificate expires or you need to regenerate:
```bash
# Stop service
sudo systemctl stop stegasoo
# Generate new cert with SANs
CERT_DIR="/opt/stegasoo/frontends/web/certs"
LOCAL_IP=$(hostname -I | awk '{print $1}')
HOSTNAME=$(hostname)
openssl req -x509 -newkey rsa:2048 \
-keyout "$CERT_DIR/server.key" \
-out "$CERT_DIR/server.crt" \
-days 365 -nodes \
-subj "/O=Stegasoo/CN=$HOSTNAME" \
-addext "subjectAltName=DNS:$HOSTNAME,DNS:$HOSTNAME.local,DNS:localhost,IP:$LOCAL_IP,IP:127.0.0.1"
chmod 600 "$CERT_DIR/server.key"
# Start service
sudo systemctl start stegasoo
```
### Let's Encrypt with Certbot
For publicly accessible servers:
```bash
# Install certbot
sudo apt install certbot
# Get certificate (standalone mode)
sudo certbot certonly --standalone -d yourdomain.com
# Copy to Stegasoo
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /opt/stegasoo/frontends/web/certs/server.crt
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /opt/stegasoo/frontends/web/certs/server.key
sudo chown $(whoami):$(whoami) /opt/stegasoo/frontends/web/certs/*
sudo chmod 600 /opt/stegasoo/frontends/web/certs/server.key
# Restart
sudo systemctl restart stegasoo
```
**Note:** Set up a cron job or systemd timer to copy renewed certificates and restart Stegasoo.
---
## Verification ## Verification
### Check Installation ### Check Installation

View File

@@ -2324,9 +2324,21 @@ if __name__ == "__main__":
ssl_context = None ssl_context = None
if app.config.get("HTTPS_ENABLED", False): if app.config.get("HTTPS_ENABLED", False):
hostname = os.environ.get("STEGASOO_HOSTNAME", "localhost") hostname = os.environ.get("STEGASOO_HOSTNAME", "localhost")
try:
cert_path, key_path = ensure_certs(base_dir, hostname) cert_path, key_path = ensure_certs(base_dir, hostname)
if cert_path.exists() and key_path.exists():
ssl_context = (str(cert_path), str(key_path)) ssl_context = (str(cert_path), str(key_path))
print(f"HTTPS enabled with self-signed certificate for {hostname}") print(f"HTTPS enabled with self-signed certificate for {hostname}")
else:
print("ERROR: SSL certificates not found after generation attempt")
print(f" Expected: {cert_path}, {key_path}")
print(" Falling back to HTTP (INSECURE)")
except Exception as e:
print(f"ERROR: Failed to generate SSL certificates: {e}")
print(" Falling back to HTTP (INSECURE)")
print(" To fix: mkdir -p certs && openssl req -x509 -newkey rsa:2048 \\")
print(" -keyout certs/server.key -out certs/server.crt -days 365 -nodes \\")
print(" -subj '/CN=localhost'")
# Auth status # Auth status
if app.config.get("AUTH_ENABLED", True): if app.config.get("AUTH_ENABLED", True):

View File

@@ -279,6 +279,32 @@ EOF
" "
gum style --foreground 82 "✓ Service configured" gum style --foreground 82 "✓ Service configured"
# Generate SSL certificates if HTTPS enabled
if [ "$ENABLE_HTTPS" = "true" ]; then
gum spin --spinner dot --title "Generating SSL certificates..." -- bash -c "
CERT_DIR='$INSTALL_DIR/frontends/web/certs'
mkdir -p \"\$CERT_DIR\"
# Get local IP for SAN
LOCAL_IP=\$(hostname -I | awk '{print \$1}')
HOSTNAME=\$(hostname)
# Generate cert with SANs for IP, hostname, and localhost
openssl req -x509 -newkey rsa:2048 \
-keyout \"\$CERT_DIR/server.key\" \
-out \"\$CERT_DIR/server.crt\" \
-days 365 -nodes \
-subj \"/O=Stegasoo/CN=\$HOSTNAME\" \
-addext \"subjectAltName=DNS:\$HOSTNAME,DNS:\$HOSTNAME.local,DNS:localhost,IP:\$LOCAL_IP,IP:127.0.0.1\" \
2>/dev/null
# Fix permissions
chmod 600 \"\$CERT_DIR/server.key\"
chown -R $STEGASOO_USER:\$(id -gn $STEGASOO_USER) \"\$CERT_DIR\"
"
gum style --foreground 82 "✓ SSL certificates generated"
fi
# Setup port 443 if requested # Setup port 443 if requested
if [ "$USE_PORT_443" = "true" ]; then if [ "$USE_PORT_443" = "true" ]; then
gum spin --spinner dot --title "Setting up port 443 redirect..." -- bash -c " gum spin --spinner dot --title "Setting up port 443 redirect..." -- bash -c "

View File

@@ -465,6 +465,31 @@ RestartSec=5
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
# Generate SSL certificates if HTTPS enabled
if [ "$ENABLE_HTTPS" = "true" ]; then
echo " Generating SSL certificates..."
CERT_DIR="$INSTALL_DIR/frontends/web/certs"
mkdir -p "$CERT_DIR"
# Get local IP for SAN
LOCAL_IP=$(hostname -I | awk '{print $1}')
PI_HOSTNAME=$(hostname)
# Generate cert with SANs for IP, hostname, and localhost
openssl req -x509 -newkey rsa:2048 \
-keyout "$CERT_DIR/server.key" \
-out "$CERT_DIR/server.crt" \
-days 365 -nodes \
-subj "/O=Stegasoo/CN=$PI_HOSTNAME" \
-addext "subjectAltName=DNS:$PI_HOSTNAME,DNS:$PI_HOSTNAME.local,DNS:localhost,IP:$LOCAL_IP,IP:127.0.0.1" \
2>/dev/null
# Fix permissions
chmod 600 "$CERT_DIR/server.key"
chown -R "$USER:$USER" "$CERT_DIR"
echo -e " ${GREEN}${NC} SSL certificates generated"
fi
# Setup port 443 redirect if requested # Setup port 443 redirect if requested
if [ "$USE_PORT_443" = "true" ]; then if [ "$USE_PORT_443" = "true" ]; then
echo " Setting up port 443 redirect..." echo " Setting up port 443 redirect..."