#!/bin/bash # C Nostr Relay - Nginx SSL Proxy Setup Script # Sets up nginx as a reverse proxy with Let's Encrypt SSL set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration DOMAIN="" EMAIL="" RELAY_PORT="8888" NGINX_CONF_DIR="/etc/nginx" SITES_AVAILABLE="/etc/nginx/sites-available" SITES_ENABLED="/etc/nginx/sites-enabled" # Functions print_step() { echo -e "${BLUE}[STEP]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } show_help() { echo "Usage: $0 -d DOMAIN -e EMAIL [OPTIONS]" echo echo "Required options:" echo " -d, --domain DOMAIN Domain name for the relay (e.g., relay.example.com)" echo " -e, --email EMAIL Email address for Let's Encrypt" echo echo "Optional options:" echo " -p, --port PORT Relay port (default: 8888)" echo " -h, --help Show this help message" echo echo "Example:" echo " $0 -d relay.example.com -e admin@example.com" } parse_args() { while [[ $# -gt 0 ]]; do case $1 in -d|--domain) DOMAIN="$2" shift 2 ;; -e|--email) EMAIL="$2" shift 2 ;; -p|--port) RELAY_PORT="$2" shift 2 ;; -h|--help) show_help exit 0 ;; *) print_error "Unknown option: $1" show_help exit 1 ;; esac done if [[ -z "$DOMAIN" || -z "$EMAIL" ]]; then print_error "Domain and email are required" show_help exit 1 fi } check_root() { if [[ $EUID -ne 0 ]]; then print_error "This script must be run as root (use sudo)" exit 1 fi } check_relay_running() { print_step "Checking if C Nostr Relay is running..." if ! pgrep -f "c_relay_x86" > /dev/null; then print_error "C Nostr Relay is not running" print_error "Please start the relay first with: sudo systemctl start c-relay" exit 1 fi if ! netstat -tln | grep -q ":$RELAY_PORT"; then print_error "Relay is not listening on port $RELAY_PORT" exit 1 fi print_success "Relay is running on port $RELAY_PORT" } install_nginx() { print_step "Installing nginx..." if command -v nginx &> /dev/null; then print_warning "Nginx is already installed" else apt update apt install -y nginx systemctl enable nginx print_success "Nginx installed" fi } install_certbot() { print_step "Installing certbot for Let's Encrypt..." if command -v certbot &> /dev/null; then print_warning "Certbot is already installed" else apt install -y certbot python3-certbot-nginx print_success "Certbot installed" fi } create_nginx_config() { print_step "Creating nginx configuration..." # Backup existing default config if [[ -f "$SITES_ENABLED/default" ]]; then mv "$SITES_ENABLED/default" "$SITES_ENABLED/default.backup" print_warning "Backed up default nginx config" fi # Create site configuration cat > "$SITES_AVAILABLE/$DOMAIN" << EOF # HTTP Server (will be modified by certbot for HTTPS) server { listen 80; server_name $DOMAIN; # Rate limiting limit_req_zone \$remote_addr zone=relay:10m rate=10r/s; limit_req zone=relay burst=20 nodelay; # Map WebSocket upgrade map \$http_upgrade \$connection_upgrade { default upgrade; '' close; } location / { # Proxy settings proxy_pass http://127.0.0.1:$RELAY_PORT; proxy_http_version 1.1; proxy_cache_bypass \$http_upgrade; # Headers proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; # WebSocket support proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection \$connection_upgrade; # Timeouts for WebSocket connections proxy_read_timeout 86400s; proxy_send_timeout 86400s; # Buffer settings proxy_buffering off; } # Health check location /health { proxy_pass http://127.0.0.1:$RELAY_PORT/health; access_log off; } } EOF # Enable the site ln -sf "$SITES_AVAILABLE/$DOMAIN" "$SITES_ENABLED/" print_success "Nginx configuration created for $DOMAIN" } test_nginx_config() { print_step "Testing nginx configuration..." if nginx -t; then print_success "Nginx configuration is valid" else print_error "Nginx configuration is invalid" exit 1 fi } restart_nginx() { print_step "Restarting nginx..." systemctl restart nginx systemctl enable nginx if systemctl is-active --quiet nginx; then print_success "Nginx restarted successfully" else print_error "Failed to restart nginx" exit 1 fi } setup_ssl() { print_step "Setting up SSL certificate with Let's Encrypt..." # Obtain certificate if certbot --nginx -d "$DOMAIN" --email "$EMAIL" --agree-tos --non-interactive; then print_success "SSL certificate obtained and configured" else print_error "Failed to obtain SSL certificate" exit 1 fi } setup_auto_renewal() { print_step "Setting up SSL certificate auto-renewal..." # Create renewal cron job cat > /etc/cron.d/certbot-renew << EOF # Renew Let's Encrypt certificates 0 12 * * * root /usr/bin/certbot renew --quiet && /usr/bin/systemctl reload nginx EOF print_success "Auto-renewal configured" } configure_firewall() { print_step "Configuring firewall..." if command -v ufw &> /dev/null; then ufw allow 'Nginx Full' ufw delete allow 'Nginx HTTP' 2>/dev/null || true print_success "UFW configured for nginx" elif command -v firewall-cmd &> /dev/null; then firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload print_success "Firewalld configured" else print_warning "No recognized firewall found" print_warning "Please ensure ports 80 and 443 are open" fi } test_setup() { print_step "Testing the setup..." sleep 5 # Test HTTP redirect if curl -s -o /dev/null -w "%{http_code}" "http://$DOMAIN" | grep -q "301\|302"; then print_success "HTTP to HTTPS redirect working" else print_warning "HTTP redirect test failed" fi # Test HTTPS if curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN" | grep -q "200"; then print_success "HTTPS connection working" else print_warning "HTTPS test failed" fi # Test WebSocket (if relay supports it) if command -v wscat &> /dev/null; then print_step "Testing WebSocket connection..." timeout 5 wscat -c "wss://$DOMAIN" --execute "exit" &>/dev/null && \ print_success "WebSocket connection working" || \ print_warning "WebSocket test inconclusive (install wscat for better testing)" fi } show_final_status() { echo echo "🎉 SSL Proxy Setup Complete!" echo echo "Configuration Summary:" echo " Domain: $DOMAIN" echo " SSL: Let's Encrypt" echo " Backend: 127.0.0.1:$RELAY_PORT" echo " Config: $SITES_AVAILABLE/$DOMAIN" echo echo "Your Nostr relay is now accessible at:" echo " HTTPS URL: https://$DOMAIN" echo " WebSocket: wss://$DOMAIN" echo echo "Management Commands:" echo " Test config: sudo nginx -t" echo " Reload nginx: sudo systemctl reload nginx" echo " Check SSL: sudo certbot certificates" echo " Renew SSL: sudo certbot renew" echo echo "SSL certificate will auto-renew via cron." echo } # Main execution main() { echo echo "============================================" echo "🔒 C Nostr Relay - SSL Proxy Setup" echo "============================================" echo parse_args "$@" check_root check_relay_running install_nginx install_certbot create_nginx_config test_nginx_config restart_nginx setup_ssl setup_auto_renewal configure_firewall test_setup show_final_status print_success "SSL proxy setup completed successfully!" } # Run main function main "$@"