diff --git a/ct-deployment.sh b/ct-deployment.sh index f16b2c3..8a42e55 100644 --- a/ct-deployment.sh +++ b/ct-deployment.sh @@ -1,98 +1,102 @@ #!/bin/bash # ============================================================================== -# Wallarm PoC: Multi-Instance Safe Deployer (Podman/Docker) +# Wallarm PoC: Interactive "KISS" Deployer (Keystone Bank Edition) # ============================================================================== -# --- Instance Configuration --- -NODE_NAME="wallarm-01" -TRAFFIC_PORT="8000" -MONITOR_PORT="9000" - -# --- UPSTREAM SETTINGS --- -UPSTREAM_IP="10.0.0.14" # Internal Application IP -UPSTREAM_PORT="6042" # Internal Application Port - -# --- CLOUD SETTINGS --- -TOKEN="YOUR_NODE_TOKEN_HERE" -REGION="EU" # US or EU - -# --- Colors --- YELLOW='\033[1;33m' GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' -echo -e "${YELLOW}🔍 PHASE 0: Pre-Flight Connectivity Checks...${NC}" +clear +echo -e "${YELLOW}====================================================${NC}" +echo -e "${YELLOW} Wallarm Guided Instance Deployer (US Cloud) ${NC}" +echo -e "${YELLOW}====================================================${NC}\n" -# 1. Root Check -[[ $EUID -ne 0 ]] && { echo -e "${RED}❌ ERROR: Run as root.${NC}"; exit 1; } +# --- 1. THE ID (The "Magic Number") --- +echo -e "Existing Instances in /opt/wallarm/:" +ls /opt/wallarm/ 2>/dev/null || echo "None" +echo "" -# 2. Specific Upstream Port Check -echo -n "Verifying connectivity to $UPSTREAM_IP on port $UPSTREAM_PORT... " -if ! timeout 3 bash -c "cat < /dev/null > /dev/tcp/$UPSTREAM_IP/$UPSTREAM_PORT" 2>/dev/null; then +read -p "Enter Instance ID number (e.g., 1, 2, 3): " INSTANCE_ID + +# Auto-generate naming and ports +NODE_NAME=$(printf "wallarm-%02d" $INSTANCE_ID) +TRAFFIC_PORT=$((8000 + INSTANCE_ID)) +MONITOR_PORT=$((9000 + INSTANCE_ID)) + +# --- 2. CONFIGURATION --- +read -p "Enter Upstream IP (App Server): " UPSTREAM_IP +read -p "Enter Upstream Port [default 80]: " UPSTREAM_PORT +UPSTREAM_PORT=${UPSTREAM_PORT:-80} + +# Hardcoded to US based on your tip +REGION="US" +API_HOST="us1.api.wallarm.com" + +read -p "Paste Wallarm Token (US Cloud): " TOKEN + +# --- 3. PRE-FLIGHT VALIDATION --- +echo -e "\n${YELLOW}🔍 Starting Pre-Flight Connectivity Checks...${NC}" + +# A. Internal Check (Upstream) +echo -n "Checking App Server ($UPSTREAM_IP:$UPSTREAM_PORT)... " +if ! timeout 2 bash -c "cat < /dev/null > /dev/tcp/$UPSTREAM_IP/$UPSTREAM_PORT" 2>/dev/null; then echo -e "${RED}FAILED${NC}" - echo -e "${RED}❌ ERROR: The VM cannot reach the application on port $UPSTREAM_PORT.${NC}" - echo -e "${YELLOW}Action: Ask the bank's Network Team to open egress to $UPSTREAM_IP:$UPSTREAM_PORT.${NC}" - exit 1 + echo -e "${RED}❌ ERROR: VM cannot reach internal app server.${NC}"; exit 1 else echo -e "${GREEN}OK${NC}" fi -# 3. Wallarm Cloud Check -API_HOST=$( [[ "$REGION" == "US" ]] && echo "us1.api.wallarm.com" || echo "api.wallarm.com" ) +# B. External Check (Wallarm Cloud) +echo -n "Checking Wallarm US Cloud ($API_HOST)... " if ! curl -s --connect-timeout 5 "https://$API_HOST" > /dev/null; then - echo -e "${RED}❌ ERROR: Cannot reach Wallarm Cloud ($API_HOST). Check Proxy settings.${NC}" - exit 1 + echo -e "${RED}FAILED${NC}" + echo -e "${RED}❌ ERROR: VM cannot talk to Wallarm US Cloud.${NC}" + echo -e "${YELLOW}Action: Check Bank Proxy or Firewall egress for port 443.${NC}"; exit 1 +else + echo -e "${GREEN}OK${NC}" fi -# --- PHASE 1: Engine Setup --- +# --- 4. ENGINE SETUP --- +echo -e "\n${YELLOW}🛠️ Ensuring Engine (Podman/Docker) is ready...${NC}" if [ -f /etc/redhat-release ]; then ENGINE="podman" - dnf install -y epel-release - dnf install -y podman podman-docker podman-compose wget curl - systemctl enable --now podman.socket - # Open OS Firewalld for incoming traffic - firewall-cmd --permanent --add-port=$TRAFFIC_PORT/tcp - firewall-cmd --permanent --add-port=$MONITOR_PORT/tcp - firewall-cmd --reload -elif [ -f /etc/debian_version ]; then - ENGINE="docker" - apt update && apt install -y docker.io docker-compose wget curl - systemctl enable --now docker + dnf install -y epel-release podman podman-docker podman-compose wget curl &>/dev/null + systemctl enable --now podman.socket &>/dev/null + firewall-cmd --permanent --add-port=$TRAFFIC_PORT/tcp --add-port=$MONITOR_PORT/tcp &>/dev/null + firewall-cmd --reload &>/dev/null else - echo -e "${RED}❌ Unsupported OS${NC}"; exit 1 + ENGINE="docker" + apt update && apt install -y docker.io docker-compose wget curl &>/dev/null + systemctl enable --now docker &>/dev/null fi - COMPOSE_CMD=$([[ "$ENGINE" == "podman" ]] && echo "podman-compose" || echo "docker-compose") -# --- PHASE 2: Instance Workspace --- +# --- 5. WORKSPACE & CONFIG --- INSTANCE_DIR="/opt/wallarm/$NODE_NAME" mkdir -p "$INSTANCE_DIR" -# Generate Nginx Config using the specific Upstream Port cat < "$INSTANCE_DIR/nginx.conf" server { listen 80; - wallarm_mode monitoring; - + wallarm_mode monitoring; # Set to monitoring for PoC safety location / { proxy_pass http://$UPSTREAM_IP:$UPSTREAM_PORT; 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; } } -server { - listen 90; - location /wallarm-status { - wallarm_status on; - allow all; - } +server { + listen 90; + location /wallarm-status { + wallarm_status on; + allow all; + } } EOF -# Compose File with SELinux ( :Z ) flag cat < "$INSTANCE_DIR/conf.yml" version: '3.8' services: @@ -100,21 +104,32 @@ services: image: docker.io/wallarm/node:4.10-latest container_name: $NODE_NAME restart: always - ports: - - "$TRAFFIC_PORT:80" - - "$MONITOR_PORT:90" + ports: ["$TRAFFIC_PORT:80", "$MONITOR_PORT:90"] environment: - WALLARM_API_TOKEN=$TOKEN - WALLARM_API_HOST=$API_HOST - volumes: - - ./nginx.conf:/etc/nginx/http.d/default.conf:ro,Z + volumes: ["./nginx.conf:/etc/nginx/http.d/default.conf:ro,Z"] EOF -# --- PHASE 3: Launch --- -echo -e "${YELLOW}🚀 Launching Wallarm Instance...${NC}" +# --- 6. LAUNCH --- +echo -e "${YELLOW}🚀 Launching $NODE_NAME...${NC}" cd "$INSTANCE_DIR" $COMPOSE_CMD -f conf.yml up -d -echo -e "\n${GREEN}✅ DEPLOYMENT COMPLETE${NC}" -echo -e "External Port: $TRAFFIC_PORT -> Internal: $UPSTREAM_IP:$UPSTREAM_PORT" -echo -e "View real-time logs: $ENGINE logs -f $NODE_NAME" \ No newline at end of file +# --- 7. POST-DEPLOY VERIFICATION --- +echo -e "\n${YELLOW}⏳ Waiting 5s for handshake...${NC}" +sleep 5 +echo -en "Checking instance status page... " +if curl -s "http://localhost:$MONITOR_PORT/wallarm-status" | grep -q "requests"; then + echo -e "${GREEN}SUCCESS${NC}" +else + echo -e "${RED}WARNING: Status page not responding yet.${NC}" +fi + +echo -e "\n${GREEN}✅ DEPLOYMENT FINISHED${NC}" +echo -e "--------------------------------------------------" +echo -e "Instance Name: $NODE_NAME" +echo -e "Traffic Port: $TRAFFIC_PORT" +echo -e "Monitor Port: $MONITOR_PORT" +echo -e "Logs Command: $ENGINE logs -f $NODE_NAME" +echo -e "--------------------------------------------------" \ No newline at end of file diff --git a/wallarm-deploy-ct.sh b/wallarm-deploy-ct.sh new file mode 100644 index 0000000..99d45b3 --- /dev/null +++ b/wallarm-deploy-ct.sh @@ -0,0 +1,224 @@ +#!/bin/bash +# ============================================================================== +# Sechpoint Wallarm Smart Deployer - Container Edition (PoC Optimized) +# ============================================================================== + +# --- Styling --- +YELLOW='\033[1;33m' +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' + +LOG_FILE="/var/log/wallarm-deploy.log" +EU_DATA_NODES=("api.wallarm.com" "node-data0.eu1.wallarm.com" "node-data1.eu1.wallarm.com") +US_DATA_NODES=("us1.api.wallarm.com" "node-data0.us1.wallarm.com" "node-data1.us1.wallarm.com") + +# --- Initialization --- +sudo touch "$LOG_FILE" && sudo chmod 644 "$LOG_FILE" +exec > >(tee -a "$LOG_FILE") 2>&1 # Log everything to file while showing on screen + +clear +echo -e "${YELLOW}====================================================${NC}" +echo -e "${YELLOW} Wallarm Automated Container Deployer ${NC}" +echo -e "${YELLOW}====================================================${NC}" + +# --- 1. PRE-FLIGHT FUNCTIONS --- + +check_sudo() { + echo -e "\n${YELLOW}[1/4] Checking Sudo...${NC}" + if sudo -v; then + echo -e "${GREEN}[PASS]${NC} Sudo access confirmed." + return 0 + else + echo -e "${RED}[FAIL]${NC} Sudo access denied."; return 1 + fi +} + +check_wallarm_cloud() { + echo -e "\n${YELLOW}[2/4] Testing Wallarm Cloud Connectivity (Port 443)...${NC}" + local fail=0 + + # We ask for cloud preference early to avoid testing everything unnecessarily + read -p "Wallarm Cloud (US/EU) [US]: " CLOUD_SEL + CLOUD_SEL=${CLOUD_SEL^^} + CLOUD_SEL=${CLOUD_SEL:-US} + + local nodes_to_test=("${US_DATA_NODES[@]}") + if [[ "$CLOUD_SEL" == "EU" ]]; then + nodes_to_test=("${EU_DATA_NODES[@]}") + fi + + echo "Testing $CLOUD_SEL Cloud Endpoints..." + for node in "${nodes_to_test[@]}"; do + if ! curl -skI --connect-timeout 5 "https://$node" > /dev/null 2>&1; then + echo -e "${RED}[FAIL]${NC} Cannot reach $node"; fail=1 + else + echo -e "${GREEN}[PASS]${NC} Reached $node" + fi + done + + API_HOST=$([[ "$CLOUD_SEL" == "EU" ]] && echo "api.wallarm.com" || echo "us1.api.wallarm.com") + return $fail +} + +# --- 2. INPUT & CONFIGURATION --- + +get_user_input() { + echo -e "\n${YELLOW}[3/4] Configuration & Workspace Setup...${NC}" + + # Instance ID Logic - Simplified to numeric directory structure + echo -e "Existing Deployments in /opt/wallarm/:" + if [ -d /opt/wallarm ]; then + ls -F /opt/wallarm/ | grep '/' | sed 's/\///' || echo "None" + else + echo "None" + fi + echo "" + + read -p "Enter Instance Number (e.g., 1, 2, 3): " INSTANCE_NUM + # Validate it's a number + if ! [[ "$INSTANCE_NUM" =~ ^[0-9]+$ ]]; then + echo -e "${RED}ERROR: Please enter a valid number.${NC}"; exit 1 + fi + + NODE_NAME="wallarm-node-$INSTANCE_NUM" + INSTANCE_DIR="/opt/wallarm/$INSTANCE_NUM" + TRAFFIC_PORT=$((8000 + INSTANCE_NUM)) + MONITOR_PORT=$((9000 + INSTANCE_NUM)) + + # App Server Logic + read -p "Enter Upstream IP (App Server) [127.0.0.1]: " UPSTREAM_IP + UPSTREAM_IP=${UPSTREAM_IP:-127.0.0.1} + read -p "Enter Upstream Port [80]: " UPSTREAM_PORT + UPSTREAM_PORT=${UPSTREAM_PORT:-80} + + read -p "Paste Wallarm Token ($CLOUD_SEL Cloud): " TOKEN + + # Internal Connectivity Test (The Gatekeeper) + echo -n "Verifying connection to App Server ($UPSTREAM_IP:$UPSTREAM_PORT)... " + # Port check using /dev/tcp for speed and reliability in shell + if ! timeout 2 bash -c "cat < /dev/null > /dev/tcp/$UPSTREAM_IP/$UPSTREAM_PORT" 2>/dev/null; then + echo -e "${RED}FAILED${NC}" + echo -e "${RED}❌ ERROR: VM cannot reach internal app server at $UPSTREAM_IP:$UPSTREAM_PORT.${NC}"; exit 1 + else + echo -e "${GREEN}OK${NC}" + fi +} + +# --- 3. ENGINE SETUP --- + +setup_engine() { + echo -e "\n${YELLOW}[4/4] 🛠️ Ensuring Engine (Podman/Docker) is ready...${NC}" + if [ -f /etc/redhat-release ]; then + ENGINE="podman" + echo "Detected RHEL/CentOS. Setting up Podman..." + sudo dnf install -y epel-release podman podman-docker wget curl &>/dev/null + sudo systemctl enable --now podman.socket &>/dev/null + # Firewall adjustments for Bank DMZs + sudo firewall-cmd --permanent --add-port=$TRAFFIC_PORT/tcp --add-port=$MONITOR_PORT/tcp &>/dev/null + sudo firewall-cmd --reload &>/dev/null + else + ENGINE="docker" + echo "Detected Ubuntu/Debian. Setting up Docker..." + sudo apt update && sudo apt install -y docker.io wget curl &>/dev/null + sudo systemctl enable --now docker &>/dev/null + fi + + # Check for compose utility + if ! command -v docker-compose &> /dev/null && ! command -v podman-compose &> /dev/null; then + echo "Installing Compose utility..." + if [ "$ENGINE" == "docker" ]; then sudo apt install -y docker-compose &>/dev/null; fi + if [ "$ENGINE" == "podman" ]; then sudo dnf install -y podman-compose &>/dev/null; fi + fi +} + +# --- 4. DEPLOYMENT --- + +execute_deployment() { + echo -e "\n${YELLOW}🚀 Preparing Workspace: $INSTANCE_DIR${NC}" + sudo mkdir -p "$INSTANCE_DIR" + + # Navigate to directory to ensure relative volume paths work correctly + cd "$INSTANCE_DIR" + + echo "Generating Nginx Configuration..." + sudo tee "$INSTANCE_DIR/nginx.conf" > /dev/null < /dev/null </dev/null + + if command -v podman-compose &> /dev/null; then + sudo podman-compose -f conf.yml up -d + else + sudo docker-compose -f conf.yml up -d + fi +} + +# --- 5. VERIFICATION --- + +verify_health() { + echo -e "\n${YELLOW}⏳ Waiting 5s for handshake...${NC}" + sleep 5 + echo -en "Checking instance status page (port $MONITOR_PORT)... " + if curl -s "http://localhost:$MONITOR_PORT/wallarm-status" | grep -q "requests"; then + echo -e "${GREEN}SUCCESS${NC}" + else + echo -e "${RED}WARNING: Status page not responding yet. Check logs with 'sudo $ENGINE logs $NODE_NAME'${NC}" + fi + + echo -e "\n${GREEN}✅ DEPLOYMENT FINISHED${NC}" + echo -e "--------------------------------------------------" + echo -e "Instance ID: $INSTANCE_NUM" + echo -e "Directory: $INSTANCE_DIR" + echo -e "Container Name: $NODE_NAME" + echo -e "Traffic Port: $TRAFFIC_PORT (Forwarded to $UPSTREAM_IP:$UPSTREAM_PORT)" + echo -e "Monitor Port: $MONITOR_PORT" + echo -e "Log File: $LOG_FILE" + echo -e "--------------------------------------------------" +} + +# --- MAIN FLOW --- +check_sudo || exit 1 +check_wallarm_cloud || { echo -e "${RED}Cloud connectivity failed. Cannot continue.${NC}"; exit 1; } +get_user_input +setup_engine +execute_deployment +verify_health \ No newline at end of file