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:
79
INSTALL.md
79
INSTALL.md
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
cert_path, key_path = ensure_certs(base_dir, hostname)
|
try:
|
||||||
ssl_context = (str(cert_path), str(key_path))
|
cert_path, key_path = ensure_certs(base_dir, hostname)
|
||||||
print(f"HTTPS enabled with self-signed certificate for {hostname}")
|
if cert_path.exists() and key_path.exists():
|
||||||
|
ssl_context = (str(cert_path), str(key_path))
|
||||||
|
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):
|
||||||
|
|||||||
@@ -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 "
|
||||||
|
|||||||
25
rpi/setup.sh
25
rpi/setup.sh
@@ -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..."
|
||||||
|
|||||||
Reference in New Issue
Block a user