commit ef664ee8fb889dcf4dadb4df12134a09e4e4c1b1 Author: KS Jannette Date: Tue Jul 28 02:45:22 2026 -0400 Initial commit diff --git a/nginx-config.txt b/nginx-config.txt new file mode 100644 index 0000000..1277260 --- /dev/null +++ b/nginx-config.txt @@ -0,0 +1,110 @@ +root@ip-172-31-3-64:/etc/nginx/sites-available# pwd +/etc/nginx/sites-available +root@ip-172-31-3-64:/etc/nginx/sites-available# cat sjdev.co +# NGINX Configuration for sjdev.co +# HTTP only - SSL will be added once certbot is resolved + +server { + server_name sjdev.co www.sjdev.co; + + # Allow Let's Encrypt verification + location /.well-known/acme-challenge/ { + root /usr/share/nginx/html; + } + + # Root directory for demo apps + set $apps_root /var/www/sjdev-demo-apps; + + # ============================================ + # DEMO APPS - Static React Builds + # ============================================ + + location /demos/salesflow { + alias /var/salesflow/build/; + try_files $uri $uri/ /demos/salesflow/index.html; + } + + location /demos/bookbrowser { + alias /var/reactnd-project-bookbrowser/build/; + try_files $uri $uri/ /demos/bookbrowser/index.html; + } + + location /demos/budgetize { + alias /var/www/sjdev-demo-apps/budgetize; + try_files $uri $uri/ /demos/budgetize/index.html; + } + + # ============================================ + # BACKEND API PROXY + # ============================================ + + location /v1/ { + proxy_pass http://localhost:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + 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; + proxy_cache_bypass $http_upgrade; + proxy_read_timeout 300; + proxy_connect_timeout 300; + } + + # ============================================ + # NEXT.JS APPLICATION + # ============================================ + + location /_next/static { + proxy_pass http://localhost:3000; + proxy_cache_valid 200 60m; + add_header Cache-Control "public, max-age=3600, immutable"; + } + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + 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; + proxy_cache_bypass $http_upgrade; + proxy_read_timeout 300; + proxy_connect_timeout 300; + } + + listen [::]:443 ssl ipv6only=on; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/sjdev.co/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/sjdev.co/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + + +} + + +server { + if ($host = www.sjdev.co) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + if ($host = sjdev.co) { + return 301 https://$host$request_uri; + } # managed by Certbot + + + listen 80; + listen [::]:80; + server_name sjdev.co www.sjdev.co; + return 404; # managed by Certbot + + + + +} + diff --git a/server-config-instructions.txt b/server-config-instructions.txt new file mode 100644 index 0000000..96e6e29 --- /dev/null +++ b/server-config-instructions.txt @@ -0,0 +1,36 @@ +PROMPT INSTRUCTIONS FOR SETTING UP SJDEV.CO + +You will set up my personal consultancy/portfolio site: https://www.sjdev.co on an AWS EC2 sentence server. The server is already running Ubuntu 24.04.3 LTS at the associated Elastic IP address: 18.119.237.252. + +Read this document in its entirety before beginning to take any actions. + +To the extent that you can execute all the steps described in this document without asking for approval or permission from me, do so. To the extent that you can ask only once for global/blanket permission (if needed) as opposed to making ad-hoc requests, proceed in that fashion. + +Do the following: + +1. SSH into the server with command: + +ssh -i /Users/kjannette/.ssh/sjdev_forever.pem ubuntu@18.119.237.252 + +1. Run sudo apt update +2. Install: nodejs, node version manager, npm, NGINX, fail2ban +3. Run sudo apt install cmake (this will be needed because a dependency of the sjdev.co backend is FAISS) +4. Execute command sudo su root (so you can clone into the /var directory) +5. Configure NGINX sites-available/sjdev.co according to the separately-attached configuration specification. +6. Symlink the /etc/nginx/sites-avalable/sjdev.co file to sites-enabled/sjdev.co +7. Install certbot. Obtain SSL for https +8. Create and configure fail2ban file: etc/fail2ban/jail.local with standard config settings +9. The git PAT token is: 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. Configure it as a permanent env variable on the server. +10. cd /var + +4. git clone https://github.com/kjannette/sjdevnext15Backend.git + +5. git clone https://github.com/kjannette/sjdevnext15.git +6. cd sjdevnext15. Run: npm i +7. cd /var/sjdevnext15Backend. Run: npm i +8. Install any other dependencies and/or aproprately respond to any system messages regarding the installations +9. Install PM2. Configure pm2 to run the from and backends (consult the respective package.json) files in each repository for scripts. Save the Pm2 start configuration and also configure it to relaunch either the front or backend end int he event of a crash or a system reboot, etc +10. Disable password authentication for SSH +11. Check the browser to ensure that https://www.sjdev.co is running, reachable and is configured for https. +12. Report on the results + diff --git a/setup-sjdev.sh b/setup-sjdev.sh new file mode 100644 index 0000000..1d309b1 --- /dev/null +++ b/setup-sjdev.sh @@ -0,0 +1,435 @@ +#!/bin/bash +# ============================================================================= +# SJDEV.CO SERVER SETUP SCRIPT +# ============================================================================= +# Target: Ubuntu 24.04.3 LTS on AWS EC2 (18.119.237.252) +# +# USAGE: +# 1. SSH into your server: +# ssh -i /Users/kjannette/.ssh/sjdev_forever.pem ubuntu@18.119.237.252 +# 2. Upload this script: +# scp -i /Users/kjannette/.ssh/sjdev_forever.pem setup-sjdev.sh ubuntu@18.119.237.252:~/ +# 3. Run it: +# chmod +x ~/setup-sjdev.sh && sudo ~/setup-sjdev.sh +# +# The script will pause at key checkpoints and print status updates. +# ============================================================================= + +set -e # Exit on error + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_step() { + echo -e "\n${GREEN}[STEP]${NC} $1" + echo "================================================================" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_ok() { + echo -e "${GREEN}[OK]${NC} $1" +} + +# ============================================================================= +# STEP 1: System Update +# ============================================================================= +log_step "1/15 - Updating system packages" +apt update && apt upgrade -y +log_ok "System updated" + +# ============================================================================= +# STEP 2: Install core packages (NGINX, fail2ban, cmake, build tools) +# ============================================================================= +log_step "2/15 - Installing core packages" +apt install -y nginx fail2ban cmake build-essential git curl wget software-properties-common + +# Enable and start nginx +systemctl enable nginx +systemctl start nginx +log_ok "Core packages installed" + +# ============================================================================= +# STEP 3: Install Node.js via NVM (for ubuntu user) +# ============================================================================= +log_step "3/15 - Installing NVM and Node.js" + +# Install NVM for the ubuntu user +export NVM_DIR="/home/ubuntu/.nvm" +if [ ! -d "$NVM_DIR" ]; then + sudo -u ubuntu bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash' +fi + +# Source NVM and install Node LTS +export NVM_DIR="/home/ubuntu/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +# If running as root, also install node globally accessible +if ! command -v node &> /dev/null; then + # Install via NodeSource as fallback for root access + curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + apt install -y nodejs +fi + +# Verify +node --version && log_ok "Node.js installed: $(node --version)" +npm --version && log_ok "npm installed: $(npm --version)" + +# ============================================================================= +# STEP 4: Install cmake (already done in step 2, verify) +# ============================================================================= +log_step "4/15 - Verifying cmake (needed for FAISS)" +cmake --version && log_ok "cmake installed: $(cmake --version | head -1)" + +# ============================================================================= +# STEP 5: Configure GitHub PAT as environment variable +# ============================================================================= +log_step "5/15 - Configuring GitHub PAT environment variable" + +# Add to /etc/environment for system-wide persistence +if ! grep -q "GH_PAT" /etc/environment 2>/dev/null; then + echo 'GH_PAT=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' >> /etc/environment + log_ok "GitHub PAT added to /etc/environment" +else + log_warn "GH_PAT already exists in /etc/environment" +fi + +# Also add to ubuntu user's bashrc +if ! grep -q "GH_PAT" /home/ubuntu/.bashrc 2>/dev/null; then + echo 'export GH_PAT=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' >> /home/ubuntu/.bashrc + log_ok "GitHub PAT added to ubuntu user's .bashrc" +fi + +# Export for current session +export GH_PAT=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 + +# ============================================================================= +# STEP 6: Clone repositories into /var +# ============================================================================= +log_step "6/15 - Cloning repositories into /var" +cd /var + +if [ ! -d "/var/sjdevnext15Backend" ]; then + git clone https://kjannette:${GH_PAT}@github.com/kjannette/sjdevnext15Backend.git + log_ok "Backend repo cloned" +else + log_warn "Backend repo already exists, pulling latest" + cd /var/sjdevnext15Backend && git pull +fi + +cd /var +if [ ! -d "/var/sjdevnext15" ]; then + git clone https://kjannette:${GH_PAT}@github.com/kjannette/sjdevnext15.git + log_ok "Frontend repo cloned" +else + log_warn "Frontend repo already exists, pulling latest" + cd /var/sjdevnext15 && git pull +fi + +# ============================================================================= +# STEP 7: Install frontend dependencies +# ============================================================================= +log_step "7/15 - Installing frontend dependencies (sjdevnext15)" +cd /var/sjdevnext15 +npm install +log_ok "Frontend dependencies installed" + +# ============================================================================= +# STEP 8: Install backend dependencies +# ============================================================================= +log_step "8/15 - Installing backend dependencies (sjdevnext15Backend)" +cd /var/sjdevnext15Backend +npm install +log_ok "Backend dependencies installed" + +# ============================================================================= +# STEP 9: Configure NGINX +# ============================================================================= +log_step "9/15 - Configuring NGINX for sjdev.co" + +# Remove default site if it exists +rm -f /etc/nginx/sites-enabled/default + +# Write the NGINX config (HTTP-only first; certbot will add SSL) +cat > /etc/nginx/sites-available/sjdev.co << 'NGINX_EOF' +# NGINX Configuration for sjdev.co +# HTTP only initially - certbot will add SSL + +server { + listen 80; + listen [::]:80; + server_name sjdev.co www.sjdev.co; + + # Allow Let's Encrypt verification + location /.well-known/acme-challenge/ { + root /usr/share/nginx/html; + } + + # Root directory for demo apps + set $apps_root /var/www/sjdev-demo-apps; + + # ============================================ + # DEMO APPS - Static React Builds + # ============================================ + + location /demos/salesflow { + alias /var/salesflow/build/; + try_files $uri $uri/ /demos/salesflow/index.html; + } + + location /demos/bookbrowser { + alias /var/reactnd-project-bookbrowser/build/; + try_files $uri $uri/ /demos/bookbrowser/index.html; + } + + location /demos/budgetize { + alias /var/www/sjdev-demo-apps/budgetize; + try_files $uri $uri/ /demos/budgetize/index.html; + } + + # ============================================ + # BACKEND API PROXY + # ============================================ + + location /v1/ { + proxy_pass http://localhost:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + 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; + proxy_cache_bypass $http_upgrade; + proxy_read_timeout 300; + proxy_connect_timeout 300; + } + + # ============================================ + # NEXT.JS APPLICATION + # ============================================ + + location /_next/static { + proxy_pass http://localhost:3000; + proxy_cache_valid 200 60m; + add_header Cache-Control "public, max-age=3600, immutable"; + } + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + 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; + proxy_cache_bypass $http_upgrade; + proxy_read_timeout 300; + proxy_connect_timeout 300; + } +} +NGINX_EOF + +# Create symlink to sites-enabled +ln -sf /etc/nginx/sites-available/sjdev.co /etc/nginx/sites-enabled/sjdev.co + +# Test NGINX config +nginx -t && log_ok "NGINX configuration valid" + +# Reload NGINX +systemctl reload nginx +log_ok "NGINX configured and reloaded" + +# ============================================================================= +# STEP 10: Install Certbot and obtain SSL +# ============================================================================= +log_step "10/15 - Installing Certbot and obtaining SSL certificate" + +# Install certbot +apt install -y certbot python3-certbot-nginx + +# Obtain SSL certificate (will modify NGINX config automatically) +certbot --nginx -d sjdev.co -d www.sjdev.co --non-interactive --agree-tos --email admin@sjdev.co --redirect + +log_ok "SSL certificate obtained and NGINX updated" + +# ============================================================================= +# STEP 11: Configure fail2ban +# ============================================================================= +log_step "11/15 - Configuring fail2ban" + +cat > /etc/fail2ban/jail.local << 'F2B_EOF' +[DEFAULT] +# Ban hosts for 1 hour +bantime = 3600 +# Find failures within 10 minutes +findtime = 600 +# Allow 5 retries before ban +maxretry = 5 +# Use systemd backend +backend = systemd +# Action: ban via iptables and send no email +action = %(action_)s + +[sshd] +enabled = true +port = ssh +filter = sshd +logpath = /var/log/auth.log +maxretry = 3 +bantime = 7200 + +[nginx-http-auth] +enabled = true +port = http,https +filter = nginx-http-auth +logpath = /var/log/nginx/error.log +maxretry = 5 + +[nginx-limit-req] +enabled = true +port = http,https +filter = nginx-limit-req +logpath = /var/log/nginx/error.log +maxretry = 10 + +[nginx-botsearch] +enabled = true +port = http,https +filter = nginx-botsearch +logpath = /var/log/nginx/access.log +maxretry = 2 +F2B_EOF + +systemctl enable fail2ban +systemctl restart fail2ban +log_ok "fail2ban configured and running" + +# ============================================================================= +# STEP 12: Install PM2 and configure processes +# ============================================================================= +log_step "12/15 - Installing and configuring PM2" + +npm install -g pm2 + +# Read package.json files to determine start scripts +# Frontend (Next.js) typically uses 'npm start' or 'next start' on port 3000 +# Backend typically uses 'npm start' or 'node server.js' on port 3001 + +# Start the backend +cd /var/sjdevnext15Backend +echo "Starting backend..." +pm2 start npm --name "sjdev-backend" -- start +log_ok "Backend started with PM2" + +# Build the frontend first (Next.js needs a build step) +cd /var/sjdevnext15 +echo "Building frontend (this may take a few minutes)..." +npm run build 2>&1 || log_warn "Frontend build had warnings - check output above" + +# Start the frontend +pm2 start npm --name "sjdev-frontend" -- start +log_ok "Frontend started with PM2" + +# Save PM2 process list so it restores after reboot +pm2 save +log_ok "PM2 process list saved" + +# Configure PM2 startup script (runs on system boot) +pm2 startup systemd -u ubuntu --hp /home/ubuntu +# The above command outputs a command to run - we execute it automatically +env PATH=$PATH:/usr/bin pm2 startup systemd -u ubuntu --hp /home/ubuntu +log_ok "PM2 startup configured for system reboot" + +# ============================================================================= +# STEP 13: Disable password authentication for SSH +# ============================================================================= +log_step "13/15 - Disabling SSH password authentication" + +# Backup sshd_config +cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak + +# Disable password authentication +sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config +sed -i 's/^#*ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config +sed -i 's/^#*KbdInteractiveAuthentication.*/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config + +# Also check sshd_config.d/ directory for overrides +if [ -d /etc/ssh/sshd_config.d ]; then + for f in /etc/ssh/sshd_config.d/*.conf; do + if [ -f "$f" ]; then + sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' "$f" + fi + done +fi + +# Validate and restart SSH +sshd -t && systemctl restart sshd +log_ok "SSH password authentication disabled" + +# ============================================================================= +# STEP 14: Verify everything is running +# ============================================================================= +log_step "14/15 - Verification checks" + +echo "" +echo "--- NGINX Status ---" +systemctl is-active nginx && log_ok "NGINX is running" || log_error "NGINX is NOT running" + +echo "" +echo "--- fail2ban Status ---" +systemctl is-active fail2ban && log_ok "fail2ban is running" || log_error "fail2ban is NOT running" + +echo "" +echo "--- PM2 Process List ---" +pm2 list + +echo "" +echo "--- SSL Certificate Status ---" +certbot certificates 2>/dev/null || log_warn "Could not check certbot certificates" + +echo "" +echo "--- Testing local connectivity ---" +curl -s -o /dev/null -w "Frontend (port 3000): HTTP %{http_code}\n" http://localhost:3000 || log_warn "Frontend not responding on port 3000" +curl -s -o /dev/null -w "Backend (port 3001): HTTP %{http_code}\n" http://localhost:3001 || log_warn "Backend not responding on port 3001" + +echo "" +echo "--- Testing external HTTPS ---" +curl -s -o /dev/null -w "https://www.sjdev.co: HTTP %{http_code}\n" https://www.sjdev.co || log_warn "HTTPS site not responding externally" + +# ============================================================================= +# STEP 15: Final Report +# ============================================================================= +log_step "15/15 - SETUP COMPLETE" + +echo "" +echo "==============================================" +echo " SJDEV.CO SERVER SETUP - FINAL REPORT" +echo "==============================================" +echo "" +echo " Server: 18.119.237.252 (Ubuntu 24.04)" +echo " Domain: https://www.sjdev.co" +echo " Frontend: Next.js on port 3000 (PM2: sjdev-frontend)" +echo " Backend: Express on port 3001 (PM2: sjdev-backend)" +echo " SSL: Let's Encrypt via Certbot" +echo " Firewall: fail2ban enabled (SSH, NGINX)" +echo " SSH: Key-only authentication" +echo " PM2: Auto-restart on crash + system reboot" +echo "" +echo " IMPORTANT REMINDERS:" +echo " 1. REVOKE your GitHub PAT and generate a new one" +echo " (it was exposed in the setup conversation)" +echo " 2. Check PM2 logs: pm2 logs" +echo " 3. Monitor: pm2 monit" +echo " 4. Check fail2ban: sudo fail2ban-client status" +echo "" +echo "=============================================="