Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 0d81001

Browse files
committed
docs: [#21] update documentation to reflect SSL automation completion
- Mark Phase 2 SSL Certificate Automation as ✅ COMPLETED in issue #21 - Update implementation status table: 11/12 components complete (92% progress) - Add comprehensive SSL automation validation results to SSL Testing Guide - Document successful self-signed certificate automation implementation - Update component status: SSL scripts, HTTPS templates, deploy integration all complete - SSL automation now fully working end-to-end with no manual intervention required Key achievements documented: ✅ ssl-generate-test-certs.sh: 275-line production-ready script ✅ nginx-https-selfsigned.conf.tpl: Complete HTTPS configuration ✅ Automated SSL generation in deploy-app.sh release stage ✅ All Docker containers running with HTTPS (no more nginx restarts) ✅ Self-signed certificates with 365-day validity for local testing SSL automation is production-ready for local testing environments!
1 parent 8d8cbd9 commit 0d81001

File tree

10 files changed

+632
-87
lines changed

10 files changed

+632
-87
lines changed

application/docs/deployment.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ reusing certificates. This approach provides several advantages:
6363
#### Why Generate Certificates Per Deployment?
6464

6565
1. **Production Flexibility**: Different environments use different domains:
66+
6667
- Local testing: `test.local`
6768
- Staging: `staging.example.com`
6869
- Production: `tracker.torrust-demo.com`
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
# Application-specific shell utilities for Torrust Tracker Demo
3+
# Common logging functions for application scripts
4+
#
5+
# Usage:
6+
# # Source this file in your script:
7+
# source "$(dirname "${BASH_SOURCE[0]}")/shell-utils.sh"
8+
#
9+
# # Use logging functions:
10+
# log_info "This is an info message"
11+
# log_success "Operation completed successfully"
12+
# log_warning "This is a warning"
13+
# log_error "This is an error"
14+
# log_section "Major Section Title"
15+
16+
# Application shell utilities - can be sourced multiple times safely
17+
export APP_SHELL_UTILS_LOADED=1
18+
19+
# Colors for output
20+
export RED='\033[0;31m'
21+
export GREEN='\033[0;32m'
22+
export YELLOW='\033[1;33m'
23+
export BLUE='\033[0;34m'
24+
export CYAN='\033[0;36m'
25+
export MAGENTA='\033[0;35m'
26+
export WHITE='\033[1;37m'
27+
export NC='\033[0m' # No Color
28+
29+
# Core logging function
30+
log() {
31+
local message="$1"
32+
echo -e "${message}"
33+
}
34+
35+
# Logging functions with standardized prefixes and colors
36+
log_info() {
37+
log "${BLUE}[INFO]${NC} $1"
38+
}
39+
40+
log_success() {
41+
log "${GREEN}[SUCCESS]${NC} $1"
42+
}
43+
44+
log_warning() {
45+
log "${YELLOW}[WARNING]${NC} $1"
46+
}
47+
48+
log_error() {
49+
log "${RED}[ERROR]${NC} $1"
50+
}
51+
52+
log_debug() {
53+
if [[ "${DEBUG:-false}" == "true" ]]; then
54+
log "${CYAN}[DEBUG]${NC} $1"
55+
fi
56+
}
57+
58+
# Section header logging - displays a prominent section separator
59+
log_section() {
60+
log ""
61+
log "${BLUE}===============================================${NC}"
62+
log "${BLUE}$1${NC}"
63+
log "${BLUE}===============================================${NC}"
64+
}
65+
66+
# Check if command exists
67+
command_exists() {
68+
command -v "$1" >/dev/null 2>&1
69+
}
Lines changed: 267 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,275 @@
11
#!/bin/bash
22
# Generate Self-Signed SSL Certificates for Torrust Tracker Demo
3+
#
4+
# This script generates self-signed SSL certificates on the host filesystem
5+
# for local development and testing. These certificates provide HTTPS security
6+
# but will show browser warnings as they are not issued by a trusted CA.
7+
#
8+
# Usage: ./ssl-generate-test-certs.sh DOMAIN
9+
#
10+
# Arguments:
11+
# DOMAIN The domain name for which to generate certificates
12+
#
13+
# Examples:
14+
# ./ssl-generate-test-certs.sh test.local
15+
# ./ssl-generate-test-certs.sh example.com
16+
317
set -euo pipefail
418

5-
# Import common functions
6-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7-
source "${SCRIPT_DIR}/../dev/shell-utils.sh"
19+
# Source application-specific shell utilities
20+
source "$(dirname "${BASH_SOURCE[0]}")/shell-utils.sh"
821

922
# Configuration
10-
DOMAIN="${1:-}"
23+
DOMAIN=""
24+
CERT_VALIDITY_DAYS=365
25+
KEY_SIZE=2048
26+
27+
# Parse command line arguments
28+
parse_arguments() {
29+
if [[ $# -ne 1 ]]; then
30+
log_error "Invalid number of arguments"
31+
show_usage
32+
exit 1
33+
fi
34+
35+
DOMAIN="$1"
36+
}
37+
38+
# Show usage information
39+
show_usage() {
40+
cat << 'EOF'
41+
Generate Self-Signed SSL Certificates for Torrust Tracker Demo
42+
43+
This script generates self-signed SSL certificates on the host filesystem
44+
for local development and testing. The certificates are valid for HTTPS but
45+
will show security warnings in browsers as they are not issued by a trusted
46+
Certificate Authority.
47+
48+
USAGE:
49+
$0 DOMAIN
50+
51+
ARGUMENTS:
52+
DOMAIN Domain name for SSL certificates (e.g., test.local)
53+
54+
EXAMPLES:
55+
# Generate certificates for local testing
56+
$0 test.local
57+
58+
# Generate certificates for a custom domain
59+
$0 example.com
60+
61+
GENERATED CERTIFICATES:
62+
The script generates certificates for:
63+
- tracker.DOMAIN (Torrust Tracker API and web interface)
64+
- grafana.DOMAIN (Grafana monitoring dashboard)
65+
66+
CERTIFICATE LOCATIONS:
67+
Certificates are generated on the host filesystem at:
68+
- /var/lib/torrust/proxy/certs/tracker.DOMAIN.crt
69+
- /var/lib/torrust/proxy/private/tracker.DOMAIN.key
70+
- /var/lib/torrust/proxy/certs/grafana.DOMAIN.crt
71+
- /var/lib/torrust/proxy/private/grafana.DOMAIN.key
72+
73+
PREREQUISITES:
74+
1. OpenSSL must be available on the host system
75+
2. Write access to /var/lib/torrust/proxy/ directory
76+
3. Running from the application directory (where compose.yaml is located)
77+
78+
SECURITY NOTE:
79+
Self-signed certificates provide encryption but not identity verification.
80+
They are suitable for development and testing but should be replaced with
81+
trusted certificates (Let's Encrypt) for production use.
82+
EOF
83+
}
84+
85+
# Validate arguments
86+
validate_arguments() {
87+
if [[ -z "${DOMAIN}" ]]; then
88+
log_error "Domain name is required"
89+
show_usage
90+
exit 1
91+
fi
92+
93+
# Validate domain format (basic check)
94+
if [[ ! "${DOMAIN}" =~ ^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$ ]]; then
95+
log_error "Invalid domain format: ${DOMAIN}"
96+
exit 1
97+
fi
98+
}
99+
100+
# Check prerequisites
101+
check_prerequisites() {
102+
log_info "Checking prerequisites..."
103+
104+
# Check if we're in the application directory
105+
if [[ ! -f "compose.yaml" ]]; then
106+
log_error "This script must be run from the application directory"
107+
log_error "Expected to find compose.yaml in current directory"
108+
exit 1
109+
fi
110+
111+
# Check if OpenSSL is available on the host
112+
if ! command -v openssl >/dev/null 2>&1; then
113+
log_error "OpenSSL is not available on the system"
114+
log_error "Please install OpenSSL: sudo apt update && sudo apt install openssl"
115+
exit 1
116+
fi
117+
118+
log_success "Prerequisites check passed"
119+
}
120+
121+
# Generate self-signed certificate for a subdomain
122+
generate_certificate() {
123+
local subdomain="$1"
124+
local cert_path="/var/lib/torrust/proxy/certs/${subdomain}.crt"
125+
local key_path="/var/lib/torrust/proxy/private/${subdomain}.key"
126+
local config_path="/tmp/cert_config_${subdomain}.conf"
127+
128+
log_info "Generating self-signed certificate for ${subdomain}..."
129+
130+
# Generate private key
131+
log_info " - Generating private key..."
132+
if ! openssl genrsa -out "${key_path}" "${KEY_SIZE}"; then
133+
log_error "Failed to generate private key for ${subdomain}"
134+
return 1
135+
fi
136+
137+
# Set secure permissions on private key
138+
chmod 600 "${key_path}"
139+
140+
# Generate certificate configuration
141+
log_info " - Creating certificate configuration..."
142+
cat > "${config_path}" << EOF
143+
[req]
144+
distinguished_name = req_distinguished_name
145+
req_extensions = v3_req
146+
prompt = no
147+
148+
[req_distinguished_name]
149+
C=US
150+
ST=Test
151+
L=Test
152+
O=Torrust Tracker Demo
153+
OU=Testing
154+
CN=${subdomain}
155+
156+
[v3_req]
157+
keyUsage = keyEncipherment, dataEncipherment
158+
extendedKeyUsage = serverAuth
159+
subjectAltName = @alt_names
160+
161+
[alt_names]
162+
DNS.1 = ${subdomain}
163+
DNS.2 = localhost
164+
IP.1 = 127.0.0.1
165+
EOF
166+
167+
# Generate self-signed certificate
168+
log_info " - Generating self-signed certificate..."
169+
if ! openssl req -new -x509 \
170+
-key "${key_path}" \
171+
-out "${cert_path}" \
172+
-days "${CERT_VALIDITY_DAYS}" \
173+
-config "${config_path}" \
174+
-extensions v3_req; then
175+
log_error "Failed to generate certificate for ${subdomain}"
176+
rm -f "${config_path}"
177+
return 1
178+
fi
179+
180+
# Clean up temporary config file
181+
rm -f "${config_path}"
182+
183+
# Set appropriate permissions on certificate
184+
chmod 644 "${cert_path}"
185+
186+
log_success " ✅ Certificate generated for ${subdomain}"
187+
log_info " Private key: ${key_path}"
188+
log_info " Certificate: ${cert_path}"
189+
return 0
190+
}
191+
192+
# Show certificate information
193+
show_certificate_info() {
194+
local subdomain="$1"
195+
local cert_path="/var/lib/torrust/proxy/certs/${subdomain}.crt"
196+
197+
log_info "Certificate information for ${subdomain}:"
198+
log_info " Location: ${cert_path}"
199+
log_info " Type: Self-signed certificate"
200+
log_info " Validity: ${CERT_VALIDITY_DAYS} days"
201+
202+
# Try to show certificate details
203+
if [[ -f "${cert_path}" ]]; then
204+
local subject
205+
local expiry
206+
subject=$(openssl x509 -in "${cert_path}" -noout -subject 2>/dev/null | cut -d= -f2- || echo "Unable to determine")
207+
expiry=$(openssl x509 -in "${cert_path}" -noout -enddate 2>/dev/null | cut -d= -f2 || echo "Unable to determine")
208+
log_info " Subject: ${subject}"
209+
log_info " Expires: ${expiry}"
210+
fi
211+
}
212+
213+
# Main certificate generation function
214+
main() {
215+
log_info "Starting self-signed SSL certificate generation"
216+
log_info "Domain: ${DOMAIN}"
217+
log_info "Validity: ${CERT_VALIDITY_DAYS} days"
218+
219+
check_prerequisites
220+
221+
# Create SSL certificate directories if they don't exist
222+
local cert_dir="/var/lib/torrust/proxy/certs"
223+
local private_dir="/var/lib/torrust/proxy/private"
224+
if [[ ! -d "${cert_dir}" ]] || [[ ! -d "${private_dir}" ]]; then
225+
log_info "Creating SSL certificate directories..."
226+
sudo mkdir -p "${cert_dir}" "${private_dir}"
227+
sudo chown -R torrust:torrust /var/lib/torrust/proxy/
228+
sudo chmod 755 "${cert_dir}"
229+
sudo chmod 700 "${private_dir}"
230+
fi
231+
232+
# Generate certificates for required subdomains
233+
local subdomains=("tracker.${DOMAIN}" "grafana.${DOMAIN}")
234+
local generation_failed=false
235+
236+
for subdomain in "${subdomains[@]}"; do
237+
if ! generate_certificate "${subdomain}"; then
238+
generation_failed=true
239+
fi
240+
done
241+
242+
# Check if any certificate generation failed
243+
if [[ "${generation_failed}" == "true" ]]; then
244+
log_error "Certificate generation failed for one or more subdomains"
245+
log_error "Please check the error messages above and resolve any issues"
246+
exit 1
247+
fi
248+
249+
# Show certificate information
250+
log_info ""
251+
log_info "Certificate generation completed successfully!"
252+
for subdomain in "${subdomains[@]}"; do
253+
show_certificate_info "${subdomain}"
254+
done
255+
256+
# Show next steps
257+
log_info ""
258+
log_info "Next steps:"
259+
log_info "1. Start Docker services that will use these certificates"
260+
log_info "2. Test HTTPS endpoints (expect certificate warnings in browsers)"
261+
log_info "3. To upgrade to trusted certificates later, use Let's Encrypt SSL setup"
262+
log_info ""
263+
log_warning "⚠️ Self-signed certificate security notes:"
264+
log_warning " - Browsers will show security warnings"
265+
log_warning " - These certificates provide encryption but not identity verification"
266+
log_warning " - Suitable for development/testing, not production use"
267+
log_warning " - For production, use Let's Encrypt certificates instead"
11268

12-
if [[ -z "${DOMAIN}" ]]; then
13-
echo "Usage: $0 DOMAIN"
14-
exit 1
15-
fi
269+
log_success "✅ Self-signed SSL certificate generation completed successfully!"
270+
}
16271

17-
log_info "Generating self-signed certificates for ${DOMAIN}"
18-
log_success "✅ Certificate generation completed"
272+
# Parse arguments and run main function
273+
parse_arguments "$@"
274+
validate_arguments
275+
main

0 commit comments

Comments
 (0)