Files
sslh-multiplex-lab/scripts/fix_deployment.sh
2026-01-29 00:03:02 +00:00

415 lines
13 KiB
Bash
Executable File

#!/bin/bash
# Fix script for current deployment issues
# Run this on the VPS to fix nginx configs, SSLH, and Let's Encrypt
set -e
# Don't exit on errors for some commands - we want to continue fixing
set +e
echo "=========================================="
echo "Fixing Deployment Issues"
echo "=========================================="
echo ""
echo "=== Step 1: Ensuring Demo Page Exists ==="
mkdir -p /var/www/demo
chown -R www-data:www-data /var/www/demo 2>/dev/null || chown -R nginx:nginx /var/www/demo 2>/dev/null || true
if [ ! -f /var/www/demo/index.html ]; then
cat > /var/www/demo/index.html <<'HTML'
<!DOCTYPE html>
<html>
<head>
<title>Demo App Page</title>
<meta charset="utf-8">
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.container {
text-align: center;
padding: 2rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
backdrop-filter: blur(10px);
}
h1 {
margin: 0;
font-size: 3rem;
}
</style>
</head>
<body>
<div class="container">
<h1>Demo app page</h1>
</div>
</body>
</html>
HTML
echo "Created demo page"
else
echo "Demo page already exists"
fi
echo ""
echo "=== Step 2: Creating Nginx Configuration Files ==="
mkdir -p /etc/nginx/sites-available
# Create sslh-proxy config
cat > /tmp/sslh-proxy.conf <<'EOF'
# Default server for root domain (HTTPS on port 443 via SSLH)
server {
listen 127.0.0.1:8444 ssl http2 default_server;
server_name _;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/demo;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
EOF
mv /tmp/sslh-proxy.conf /etc/nginx/sites-available/sslh-proxy
chmod 644 /etc/nginx/sites-available/sslh-proxy
echo "Created /etc/nginx/sites-available/sslh-proxy"
# Create acme-challenge config
cat > /tmp/acme-challenge.conf <<'EOF'
# HTTP server for Let's Encrypt ACME challenge
server {
listen 0.0.0.0:80 default_server;
listen [::]:80 default_server;
server_name _;
# Serve ACME challenge for Let's Encrypt
location /.well-known/acme-challenge/ {
root /var/www/html;
default_type text/plain;
access_log off;
}
# For root domain, serve demo page on HTTP
location / {
root /var/www/demo;
try_files $uri $uri/ /index.html;
}
}
EOF
mv /tmp/acme-challenge.conf /etc/nginx/sites-available/acme-challenge
chmod 644 /etc/nginx/sites-available/acme-challenge
echo "Created /etc/nginx/sites-available/acme-challenge"
echo ""
echo "=== Step 3: Stopping Nginx and Removing Default Configs ==="
systemctl stop nginx 2>/dev/null || true
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/sites-enabled/default.conf
rm -f /etc/nginx/sites-enabled/000-default
rm -f /etc/nginx/sites-enabled/000-default.conf
rm -f /etc/nginx/conf.d/default.conf 2>/dev/null || true
rm -f /usr/share/nginx/html/index.html /var/www/html/index.html 2>/dev/null || true
echo "Removed default nginx configs and HTML files"
echo ""
echo "=== Step 4: Enabling Nginx Sites ==="
ln -sf /etc/nginx/sites-available/acme-challenge /etc/nginx/sites-enabled/acme-challenge
ln -sf /etc/nginx/sites-available/sslh-proxy /etc/nginx/sites-enabled/sslh-proxy
echo "Enabled nginx sites"
echo ""
echo "=== Step 5: Testing Nginx Configuration ==="
nginx -t || { echo "ERROR: Nginx configuration test failed!"; exit 1; }
echo ""
echo "=== Step 6: Fixing SSLH Configuration ==="
# Remove the problematic /etc/default/sslh
rm -f /etc/default/sslh
echo "Removed /etc/default/sslh"
# Create systemd override
mkdir -p /etc/systemd/system/sslh.service.d
cat > /tmp/sslh-override.conf <<'EOF'
[Service]
EnvironmentFile=
ExecStart=
ExecStart=/usr/sbin/sslh --foreground -F /etc/sslh.cfg
EOF
mv /tmp/sslh-override.conf /etc/systemd/system/sslh.service.d/override.conf
chmod 644 /etc/systemd/system/sslh.service.d/override.conf
echo "Created SSLH systemd override"
# Reload systemd
systemctl daemon-reload
echo "Reloaded systemd"
echo ""
echo "=== Step 7: Restarting Services ==="
systemctl restart nginx
sleep 2
# Verify nginx is listening on 8444
for i in 1 2 3 4 5; do
if ss -tlnp | grep -q ':8444 '; then
echo "Nginx is listening on port 8444"
break
fi
echo "Waiting for nginx to listen on 8444... (attempt $i/5)"
sleep 2
if [ $i -eq 5 ]; then
echo "ERROR: Nginx failed to listen on port 8444!"
systemctl status nginx --no-pager || true
exit 1
fi
done
# Restart SSLH
systemctl stop sslh 2>/dev/null || true
pkill -9 sslh sslh-select 2>/dev/null || true
ss -tlnp | grep -q ':443 ' && fuser -k 443/tcp 2>/dev/null || true
sleep 2
systemctl enable sslh
systemctl restart sslh
sleep 3
if systemctl is-active --quiet sslh; then
echo "SSLH service is running"
if ss -tlnp | grep -q ':443 '; then
echo "SSLH is listening on port 443"
else
echo "WARNING: SSLH is running but not listening on port 443"
fi
else
echo "ERROR: SSLH service failed to start!"
systemctl status sslh --no-pager || true
journalctl -u sslh -n 20 --no-pager || true
exit 1
fi
echo ""
echo "=== Step 8: Verifying Services ==="
echo "Listening ports:"
ss -tlnp | grep -E ':(22|80|443|8444|445) ' || true
echo ""
echo "=== Step 9: Testing Connectivity ==="
if timeout 2 bash -c '</dev/tcp/127.0.0.1/8444' 2>/dev/null; then
echo "SUCCESS: Nginx is accessible on port 8444"
else
echo "ERROR: Nginx is not accessible on port 8444"
fi
if ss -tlnp | grep -q ':443 '; then
echo "SUCCESS: SSLH is listening on port 443"
else
echo "ERROR: SSLH is not listening on port 443"
fi
echo ""
echo "=== Step 10: Testing HTTP and HTTPS ==="
echo "Testing HTTP (port 80):"
HTTP_CONTENT=$(timeout 3 curl -s http://127.0.0.1:80/ 2>&1)
if echo "$HTTP_CONTENT" | grep -q "Demo app page"; then
echo "SUCCESS: HTTP serves demo page"
elif echo "$HTTP_CONTENT" | grep -qi "Welcome to nginx"; then
echo "ERROR: HTTP still serving default nginx page!"
echo "HTTP content preview:"
echo "$HTTP_CONTENT" | head -5
echo "Checking enabled sites..."
ls -la /etc/nginx/sites-enabled/
else
echo "WARNING: HTTP may not be serving demo page correctly"
echo "$HTTP_CONTENT" | head -5
fi
echo "Testing HTTPS (port 8444):"
HTTPS_CONTENT=$(timeout 3 curl -k -s https://127.0.0.1:8444/ 2>&1)
if echo "$HTTPS_CONTENT" | grep -q "Demo app page"; then
echo "SUCCESS: HTTPS serves demo page"
elif echo "$HTTPS_CONTENT" | grep -qi "Welcome to nginx"; then
echo "ERROR: HTTPS still serving default nginx page!"
echo "HTTPS content preview:"
echo "$HTTPS_CONTENT" | head -5
else
echo "WARNING: HTTPS may not be serving demo page correctly"
echo "$HTTPS_CONTENT" | head -5
fi
echo ""
echo "=== Step 11: Final Verification ==="
echo "Nginx enabled sites:"
ls -la /etc/nginx/sites-enabled/ || true
echo ""
echo "Nginx listening ports:"
ss -tlnp | grep nginx || true
echo ""
echo "SSLH status:"
systemctl is-active sslh && echo "SSLH: RUNNING" || echo "SSLH: NOT RUNNING"
echo ""
echo "=== Step 11: DNS Verification ==="
if [ -n "$DOMAIN" ]; then
echo "Verifying DNS resolution for $DOMAIN..."
if nslookup $DOMAIN >/dev/null 2>&1; then
RESOLVED_IP=$(nslookup $DOMAIN | grep -A 1 "Name:" | grep "Address:" | tail -1 | awk '{print $2}' || echo "")
if [ -n "$RESOLVED_IP" ]; then
echo "$DOMAIN resolves to $RESOLVED_IP"
else
echo "$DOMAIN resolves (IP not extracted)"
fi
else
echo "$DOMAIN does not resolve"
echo " This may indicate DNS records are not properly configured"
fi
# Test common subdomains
for subdomain in ssh smb; do
FQDN="$subdomain.$DOMAIN"
if nslookup $FQDN >/dev/null 2>&1; then
RESOLVED_IP=$(nslookup $FQDN | grep -A 1 "Name:" | grep "Address:" | tail -1 | awk '{print $2}' || echo "")
if [ -n "$RESOLVED_IP" ]; then
echo "$FQDN resolves to $RESOLVED_IP"
else
echo "$FQDN resolves"
fi
fi
done
else
echo "Skipping DNS verification (DOMAIN not set)"
fi
echo ""
echo "=== Step 12: Let's Encrypt Certificate Generation ==="
if [ -n "$LETSENCRYPT_EMAIL" ] && [ -n "$DOMAIN" ]; then
echo "Domain: $DOMAIN"
echo "Email: $LETSENCRYPT_EMAIL"
echo "Checking for existing DNS records to determine subdomains..."
# Build domain list - start with root domain
DOMAINS="$DOMAIN"
# Check which subdomains have DNS records (indicating they're configured)
for subdomain in ssh smb ldap ldaps rdp mysql postgres redis mongo vnc ftp ftps smtp smtps imap imaps pop3 pop3s; do
if nslookup $subdomain.$DOMAIN >/dev/null 2>&1; then
DOMAINS="$DOMAINS $subdomain.$DOMAIN"
echo " Found: $subdomain.$DOMAIN"
fi
done
echo "Domains to include in certificate: $DOMAINS"
# Build certbot command with all domains
CERTBOT_CMD="certbot certonly --webroot -n --agree-tos -m '$LETSENCRYPT_EMAIL'"
for domain in $DOMAINS; do
CERTBOT_CMD="$CERTBOT_CMD -d $domain"
done
CERTBOT_CMD="$CERTBOT_CMD -w /var/www/html --keep-until-expiring"
echo "Running certbot..."
echo "Command: $CERTBOT_CMD"
sudo $CERTBOT_CMD 2>&1 | tee /tmp/certbot-output.log
CERTBOT_EXIT=$?
if [ $CERTBOT_EXIT -eq 0 ]; then
# Find certificate directory
CERT_DIR=$(sudo certbot certificates 2>/dev/null | grep -A 5 'Certificate Name:' | grep 'Certificate Path:' | head -1 | awk '{print $3}' | xargs dirname 2>/dev/null || echo '')
if [ -z "$CERT_DIR" ]; then
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"
fi
if [ -f "$CERT_DIR/fullchain.pem" ] || [ -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then
CERT_PATH="$CERT_DIR/fullchain.pem"
KEY_PATH="$CERT_DIR/privkey.pem"
if [ ! -f "$CERT_PATH" ]; then
CERT_PATH="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
KEY_PATH="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
fi
echo "Certificate found: $CERT_PATH"
echo "Updating nginx to use Let's Encrypt certificate..."
cat > /tmp/sslh-proxy-letsencrypt.conf <<EOF
server {
listen 127.0.0.1:8444 ssl http2 default_server;
server_name _;
ssl_certificate $CERT_PATH;
ssl_certificate_key $KEY_PATH;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/demo;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
EOF
mv /tmp/sslh-proxy-letsencrypt.conf /etc/nginx/sites-available/sslh-proxy
chmod 644 /etc/nginx/sites-available/sslh-proxy
chmod 644 "$CERT_PATH" 2>/dev/null || true
chmod 640 "$KEY_PATH" 2>/dev/null || true
chown root:root "$CERT_PATH" "$KEY_PATH" 2>/dev/null || true
nginx -t && systemctl reload nginx && echo "SUCCESS: Nginx updated to use Let's Encrypt certificate" || systemctl restart nginx
echo "Certificate Subject Alternative Names:"
openssl x509 -in "$CERT_PATH" -noout -text 2>/dev/null | grep -A 1 'Subject Alternative Name' || true
else
echo "ERROR: Certificate file not found after certbot success"
echo "Checking certbot certificates:"
sudo certbot certificates 2>&1 | head -20
fi
else
echo "WARNING: Certbot failed (exit code: $CERTBOT_EXIT)"
echo "Certbot output (last 20 lines):"
cat /tmp/certbot-output.log 2>/dev/null | tail -20
echo "Continuing with self-signed certificate..."
fi
else
echo "Skipping Let's Encrypt (DOMAIN or LETSENCRYPT_EMAIL not set)"
echo "To enable: Run './sslh-lab fix --letsencrypt-email your@email.com' or set up during initial deployment"
fi
echo ""
echo "Certificate in use:"
grep -E 'ssl_certificate|ssl_certificate_key' /etc/nginx/sites-available/sslh-proxy 2>/dev/null || echo "No SSL directives found"
echo ""
echo "=== Step 13: Final Verification ==="
echo "Nginx enabled sites:"
ls -la /etc/nginx/sites-enabled/ || true
echo ""
echo "Nginx listening ports:"
ss -tlnp | grep nginx || true
echo ""
echo "SSLH status:"
systemctl is-active sslh && echo "SSLH: RUNNING" || echo "SSLH: NOT RUNNING"
echo ""
echo "=========================================="
echo "Fix Complete"
echo "=========================================="
echo ""
echo "If HTTPS still doesn't work externally, check:"
echo "1. DNS is pointing to this server"
echo "2. Firewall allows port 443"
echo "3. SSLH is listening on port 443 (check above)"
echo ""