219 lines
6.4 KiB
Bash
Executable File
219 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Initialize Let's Encrypt SSL certificates with Certbot
|
|
# This improved version handles the chicken-and-egg problem with SSL files
|
|
|
|
set -e
|
|
|
|
# Bold text function
|
|
bold() {
|
|
echo -e "\033[1m$1\033[0m"
|
|
}
|
|
|
|
# Print section header
|
|
header() {
|
|
echo
|
|
bold "=== $1 ==="
|
|
}
|
|
|
|
# Check requirements
|
|
header "Checking requirements"
|
|
|
|
if ! [ -x "$(command -v docker-compose)" ]; then
|
|
echo 'Error: docker-compose is not installed.' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Default domain and email settings
|
|
domains=${DOMAIN:-}
|
|
email=${EMAIL:-}
|
|
staging=${STAGING:-0} # Set to 1 if you're testing your setup
|
|
|
|
# Ask for domain if not provided
|
|
if [ -z "$domains" ]; then
|
|
read -p "Enter your domain name (e.g., gametracker.example.com): " domains
|
|
fi
|
|
|
|
# Ask for email if not provided
|
|
if [ -z "$email" ]; then
|
|
read -p "Enter your email (for Let's Encrypt notifications): " email
|
|
fi
|
|
|
|
header "Setting up SSL for domain: $domains"
|
|
|
|
# Create required directories
|
|
mkdir -p ./data/certbot/conf
|
|
mkdir -p ./data/certbot/www
|
|
mkdir -p ./nginx
|
|
|
|
# Create dummy certificates to bootstrap nginx
|
|
echo "Creating dummy certificates..."
|
|
|
|
rsa_key_size=4096
|
|
dummy_cert_path="./data/certbot/conf/live/$domains"
|
|
|
|
# Make sure the directory is empty and exists
|
|
rm -rf "$dummy_cert_path"
|
|
mkdir -p "$dummy_cert_path"
|
|
|
|
# Generate dummy certificates
|
|
openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1 \
|
|
-keyout "$dummy_cert_path/privkey.pem" \
|
|
-out "$dummy_cert_path/fullchain.pem" \
|
|
-subj "/CN=localhost"
|
|
|
|
# Create required files for Nginx
|
|
echo "Creating required SSL configurations..."
|
|
|
|
# Create options-ssl-nginx.conf
|
|
cat > ./data/certbot/conf/options-ssl-nginx.conf << EOF
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
|
ssl_session_timeout 1d;
|
|
ssl_session_cache shared:SSL:10m;
|
|
ssl_session_tickets off;
|
|
ssl_stapling on;
|
|
ssl_stapling_verify on;
|
|
EOF
|
|
|
|
# Create ssl-dhparams.pem
|
|
cat > ./data/certbot/conf/ssl-dhparams.pem << EOF
|
|
-----BEGIN DH PARAMETERS-----
|
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
|
-----END DH PARAMETERS-----
|
|
EOF
|
|
|
|
# Generate Nginx config using template
|
|
header "Configuring Nginx"
|
|
echo "Generating Nginx configuration..."
|
|
|
|
# Use sed instead of envsubst to only replace DOMAIN_NAME without affecting nginx variables
|
|
cp ./nginx/app.conf.template ./nginx/app.conf
|
|
sed -i "s/\${DOMAIN_NAME}/$domains/g" ./nginx/app.conf
|
|
|
|
echo "Generated nginx configuration for domain: $domains"
|
|
|
|
# Stop any existing services
|
|
echo "Stopping any existing services..."
|
|
docker-compose down
|
|
|
|
header "Starting services with dummy certificates"
|
|
|
|
# Start services with dummy certificates
|
|
echo "Starting Nginx and web containers..."
|
|
docker-compose up --force-recreate -d
|
|
|
|
# Give Nginx time to start
|
|
echo "Waiting for Nginx to start..."
|
|
sleep 5
|
|
|
|
# Check if Nginx is running
|
|
docker-compose ps nginx | grep Up
|
|
if [ $? -ne 0 ]; then
|
|
echo "Nginx failed to start! Checking logs:"
|
|
docker-compose logs nginx
|
|
exit 1
|
|
fi
|
|
|
|
header "Obtaining real certificates from Let's Encrypt"
|
|
|
|
# Prepare staging argument for Certbot
|
|
staging_arg=""
|
|
if [ "$staging" = 1 ]; then
|
|
staging_arg="--staging"
|
|
echo "Running in staging mode (test certificates)"
|
|
fi
|
|
|
|
# Get real certificates
|
|
domain_args="-d $domains"
|
|
echo "Requesting certificates for: $domains"
|
|
|
|
# First check DNS resolution
|
|
echo "Checking DNS for $domains..."
|
|
host $domains
|
|
if [ $? -ne 0 ]; then
|
|
echo "WARNING: DNS resolution failed for $domains. This may cause certificate issuance to fail."
|
|
echo "Make sure your domain is correctly pointed to this server's IP address."
|
|
read -p "Continue anyway? (y/n): " continue_dns
|
|
if [[ "$continue_dns" != [Yy]* ]]; then
|
|
echo "Aborting certificate request."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Check if port 80 is publicly accessible
|
|
echo "Checking if port 80 is accessible..."
|
|
nc -z -w 5 $domains 80
|
|
if [ $? -ne 0 ]; then
|
|
echo "WARNING: Port 80 doesn't seem to be accessible on $domains."
|
|
echo "Let's Encrypt needs port 80 accessible for domain validation."
|
|
read -p "Continue anyway? (y/n): " continue_port
|
|
if [[ "$continue_port" != [Yy]* ]]; then
|
|
echo "Aborting certificate request."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Clean up any existing certificates for this domain first
|
|
echo "Cleaning up any existing certificates..."
|
|
docker-compose run --rm --entrypoint "\
|
|
rm -rf /etc/letsencrypt/live/$domains && \
|
|
rm -rf /etc/letsencrypt/archive/$domains && \
|
|
rm -rf /etc/letsencrypt/renewal/$domains.conf" certbot || true
|
|
|
|
# Run certbot with verbose output
|
|
echo "Running certbot with verbose output..."
|
|
docker-compose run --rm --entrypoint "\
|
|
certbot certonly --webroot -w /var/www/certbot \
|
|
$staging_arg \
|
|
--email $email \
|
|
--agree-tos \
|
|
--no-eff-email \
|
|
--verbose \
|
|
$domain_args" certbot
|
|
|
|
certbot_exit=$?
|
|
|
|
# Show logs if there was an error
|
|
if [ $certbot_exit -ne 0 ]; then
|
|
echo "Certificate issuance failed with exit code: $certbot_exit"
|
|
echo "Showing certbot logs:"
|
|
docker-compose run --rm --entrypoint "cat /var/log/letsencrypt/letsencrypt.log" certbot
|
|
|
|
echo "
|
|
Troubleshooting tips:"
|
|
echo "1. Make sure your domain ($domains) points to this server's IP"
|
|
echo "2. Check if port 80 is open in your firewall"
|
|
echo "3. If using a cloud provider, ensure port 80 is allowed in security groups"
|
|
echo "4. Try running in staging mode for testing: STAGING=1 ./init-letsencrypt.sh"
|
|
|
|
read -p "Would you like to continue with the deployment anyway? (y/n): " continue_deploy
|
|
if [[ "$continue_deploy" != [Yy]* ]]; then
|
|
echo "Aborting deployment."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Check if certificates were obtained successfully
|
|
if [ ! -d "./data/certbot/conf/live/$domains" ]; then
|
|
echo "Certificate directory not found after certbot run."
|
|
exit 1
|
|
fi
|
|
|
|
# Reload Nginx to use the new certificates
|
|
echo "Reloading Nginx to use new certificates..."
|
|
docker-compose exec nginx nginx -s reload
|
|
|
|
header "HTTPS Setup Completed Successfully!"
|
|
echo "Your app is now available at: https://$domains"
|
|
echo ""
|
|
echo "The certificates will auto-renew every 90 days."
|
|
echo "To view logs: docker-compose logs -f"
|
|
echo "To stop the server: docker-compose down"
|