wallarm/native/wallarm-ct-deploy.sh
Sechpoint Admin aa3d716f61 feat: add native deployment and separate docker|native structure
- Restructure repo into docker/ and native/ deployment types with a shared
  common/wallarm-lib.sh (logging, detection, validation, connectivity, env parsing)
- Move Docker scripts + artifacts (binaries/, images/) under docker/ (git mv, history preserved)
- Refactor Docker scripts to source the shared library; update artifact URLs
- Add native/ scripts for no-Docker deployment using the Wallarm all-in-one installer
  (check, deploy, reconfigure, uninstall) with version pinning via WALLARM_VERSION
- Add native/wallarm-native.sh unified node manager (Wallarm Native Node, connector
  mode) with preflight checks, parallel multi-node install, config/remove/status
- Update setup.sh to download scripts per deployment type (DEPLOYMENT_TYPE=...)
- Update README.md and changelog.md
2026-08-01 08:36:37 +01:00

673 lines
29 KiB
Bash
Executable file

#!/bin/bash
# ==============================================================================
# WALLARM DEPLOYMENT SCRIPT - V1.0 (Native deployment)
# ==============================================================================
# Purpose: Deploy Wallarm filtering node natively (NO Docker) after preflight
# Features:
# - Reads preflight check results from .env file
# - Interactive configuration (cloud region, ports, token, upstream)
# - Downloads and runs the official Wallarm all-in-one installer (meganode.wallarm.com)
# - Configures NGINX server block (proxy, wallarm_mode, trusted proxies, health)
# - Deployment verification (health endpoint, wallarm-status, node registration)
# - DAU-friendly error handling with remediation
# ==============================================================================
# Script location and shared library (colors, logging, validation, detection, connectivity)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=../common/wallarm-lib.sh
source "$SCRIPT_DIR/../common/wallarm-lib.sh"
# Strict error handling
set -euo pipefail
trap early_error_handler ERR
# Configuration
ENV_FILE=".env"
LOG_FILE="${HOME:-.}/logs/wallarm-deployment-native.log"
# Wallarm all-in-one installer (current recommended native install method)
# Override WALLARM_VERSION to pin a different version.
WALLARM_VERSION="${WALLARM_VERSION:-6.12.7}"
INSTALLER_BASE_URL="https://meganode.wallarm.com/${WALLARM_VERSION%.*}"
# Optional node labels for the installer (e.g. 'group=prod')
WALLARM_LABELS="${WALLARM_LABELS:-}"
# Deployment variables (set during execution)
CLOUD_REGION=""
API_HOST=""
INGRESS_PORT=""
UPSTREAM_IP=""
UPSTREAM_PORT=""
WALLARM_TOKEN=""
INSTANCE_NAME=""
INSTANCE_DIR=""
NGINX_CONFIG=""
# Resource reachability from check script
US_CLOUD_REACHABLE="false"
EU_CLOUD_REACHABLE="false"
INSTALLER_REACHABLE="false"
# ==============================================================================
# PREFLIGHT CHECK VERIFICATION
# ==============================================================================
verify_preflight_check() {
log_message "INFO" "Verifying preflight check results..."
if [ ! -f "$ENV_FILE" ]; then
log_message "ERROR" "Preflight check file not found: $ENV_FILE"
echo -e "\n${YELLOW}Preflight check has not been run or .env file is missing.${NC}"
echo -e "${YELLOW}Would you like to run the preflight check now?${NC}"
read -r -p "$(echo -e "${YELLOW}Run preflight check? (Y/n): ${NC}")" -n 1
echo
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
echo -e "${CYAN}Running preflight check...${NC}"
if ! "$SCRIPT_DIR/wallarm-ct-check.sh"; then
fail_with_remediation "Preflight check failed" \
"Run the preflight check manually and fix any issues:
1. $SCRIPT_DIR/wallarm-ct-check.sh
2. Review the errors in $ENV_FILE
3. Fix the issues and run this script again"
fi
else
fail_with_remediation "Preflight check required" \
"Run the preflight check before deployment:
1. $SCRIPT_DIR/wallarm-ct-check.sh
2. Review results in $ENV_FILE
3. Run this script again"
fi
fi
# Load environment variables from .env file (from shared library)
if ! load_env_file "$ENV_FILE"; then
fail_with_remediation "Cannot load preflight results" \
"The preflight check results file could not be read.
1. Run the preflight check: $SCRIPT_DIR/wallarm-ct-check.sh
2. Verify $ENV_FILE exists and is readable
3. Run this script again"
fi
if [ "${CHECK_RESULT:-}" != "pass" ]; then
log_message "ERROR" "Preflight check failed (result: $CHECK_RESULT)"
echo -e "\n${YELLOW}Preflight check found issues. Please review:${NC}"
echo -e "${YELLOW}1. Check file: $ENV_FILE${NC}"
echo -e "${YELLOW}2. Run: $SCRIPT_DIR/wallarm-ct-check.sh${NC}"
echo -e "${YELLOW}3. Fix the issues and try again${NC}"
exit 1
fi
log_message "SUCCESS" "Preflight check verified:"
log_message "SUCCESS" " OS: $OS_NAME $OS_VERSION"
log_message "SUCCESS" " Architecture: $ARCHITECTURE"
log_message "SUCCESS" " Init System: $INIT_SYSTEM"
log_message "SUCCESS" " US Cloud Reachable: $US_CLOUD_REACHABLE"
log_message "SUCCESS" " EU Cloud Reachable: $EU_CLOUD_REACHABLE"
log_message "SUCCESS" " Wallarm Installer Reachable: $INSTALLER_REACHABLE"
# Validate we have at least one cloud region reachable
if [ "$US_CLOUD_REACHABLE" = "false" ] && [ "$EU_CLOUD_REACHABLE" = "false" ]; then
fail_with_remediation "No Wallarm cloud region reachable" \
"Network connectivity issues detected:
1. Check firewall rules for Wallarm cloud endpoints
2. Verify network connectivity
3. Run preflight check again: $SCRIPT_DIR/wallarm-ct-check.sh"
fi
# The all-in-one installer must be reachable for a native deployment
if [ "$INSTALLER_REACHABLE" != "true" ]; then
fail_with_remediation "Wallarm all-in-one installer not reachable" \
"Native deployment requires access to the Wallarm all-in-one installer:
1. Verify network access to $INSTALLER_BASE_URL
2. Check the current version at https://docs.wallarm.com/updating-migrating/node-artifact-versions/
3. Pin the version with: WALLARM_VERSION=<version> sudo ./$0"
fi
}
# ==============================================================================
# CONFIGURATION COLLECTION
# ==============================================================================
# select_cloud_region, validate_ip_address and check_port_available are provided
# by the shared library (../common/wallarm-lib.sh).
collect_configuration() {
log_message "INFO" "Collecting deployment configuration..."
# Get ingress port
local default_port=80
local ingress_port=""
while [[ ! "$ingress_port" =~ ^[0-9]+$ ]] || [ "$ingress_port" -lt 1 ] || [ "$ingress_port" -gt 65535 ]; do
read -r -p "$(echo -e "${YELLOW}Enter inbound port [${default_port}]: ${NC}")" ingress_port
ingress_port="${ingress_port:-$default_port}"
if [[ ! "$ingress_port" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Port must be a number${NC}"
elif [ "$ingress_port" -lt 1 ] || [ "$ingress_port" -gt 65535 ]; then
echo -e "${RED}Port must be between 1 and 65535${NC}"
elif ! check_port_available "$ingress_port"; then
echo -e "${RED}Port $ingress_port is already in use${NC}"
ingress_port=""
fi
done
# Get application server details
local upstream_ip=""
local upstream_port=""
echo -e "\n${CYAN}${BOLD}Application Server Configuration:${NC}"
echo -e "${YELLOW}Enter the IP/hostname and port of your backend application${NC}"
while [[ -z "$upstream_ip" ]]; do
read -r -p "$(echo -e "${YELLOW}Upstream App IP/Hostname [127.0.0.1]: ${NC}")" upstream_ip
upstream_ip="${upstream_ip:-127.0.0.1}"
if ! validate_ip_address "$upstream_ip" && \
! [[ "$upstream_ip" =~ ^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$ ]]; then
echo -e "${RED}Invalid IP/hostname format${NC}"
upstream_ip=""
fi
done
while [[ ! "$upstream_port" =~ ^[0-9]+$ ]] || [ "$upstream_port" -lt 1 ] || [ "$upstream_port" -gt 65535 ]; do
read -r -p "$(echo -e "${YELLOW}Upstream App Port [8080]: ${NC}")" upstream_port
upstream_port="${upstream_port:-8080}"
if [[ ! "$upstream_port" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Port must be a number${NC}"
elif [ "$upstream_port" -lt 1 ] || [ "$upstream_port" -gt 65535 ]; then
echo -e "${RED}Port must be between 1 and 65535${NC}"
fi
done
# Verify application server reachability
log_message "INFO" "Verifying application server reachability..."
if timeout 5 bash -c "cat < /dev/null > /dev/tcp/$upstream_ip/$upstream_port" 2>/dev/null; then
log_message "SUCCESS" "Application server $upstream_ip:$upstream_port is reachable"
else
log_message "WARNING" "Application server $upstream_ip:$upstream_port is not reachable"
echo -e "${YELLOW}${BOLD}Warning:${NC} Cannot reach application server at $upstream_ip:$upstream_port"
echo -e "${YELLOW}This may cause the Wallarm node to fail. Possible reasons:${NC}"
echo -e "1. Application server is not running"
echo -e "2. Firewall blocking port $upstream_port"
echo -e "3. Wrong IP/hostname"
echo -e "4. Application server not listening on that port"
read -r -p "$(echo -e "${YELLOW}Continue anyway? (y/N): ${NC}")" -n 1
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
fail_with_remediation "Application server unreachable" \
"Ensure your application server is accessible:
1. Start your application server
2. Check it's listening: sudo ss -tlnp | grep :$upstream_port
3. Verify firewall rules allow inbound connections
4. Test connectivity: telnet $upstream_ip $upstream_port
5. If using hostname, verify DNS resolution: nslookup $upstream_ip"
fi
fi
# Get Wallarm node token
local wallarm_token=""
echo -e "\n${CYAN}${BOLD}Wallarm Node Token:${NC}"
echo -e "${YELLOW}Get your token from Wallarm Console:${NC}"
echo -e "Create a new 'Wallarm node' and copy the token (will be visible as you type)"
while [[ -z "$wallarm_token" ]]; do
read -r -p "$(echo -e "${YELLOW}Paste Wallarm Node Token: ${NC}")" wallarm_token
wallarm_token=$(echo "$wallarm_token" | tr -d '[:space:]')
if [[ -z "$wallarm_token" ]]; then
echo -e "${RED}Token cannot be empty${NC}"
elif [[ ! "$wallarm_token" =~ ^[A-Za-z0-9_+/=\-]+$ ]]; then
echo -e "${RED}Token contains invalid characters. Wallarm tokens are base64 strings (A-Z, a-z, 0-9, _, -, +, /, =)${NC}"
echo -e "${YELLOW}First 20 chars of what you entered: '${wallarm_token:0:20}...'${NC}"
wallarm_token=""
else
token_length=${#wallarm_token}
echo -e "${GREEN}Token accepted (${token_length} characters).${NC}"
echo -e "${YELLOW}First 8 chars for verification: ${wallarm_token:0:8}...${NC}"
fi
done
# Get trusted proxy IPs for real IP configuration
local trusted_proxies=""
echo -e "\n${CYAN}${BOLD}Real Client IP Configuration:${NC}"
echo -e "${YELLOW}For Wallarm to see the real client IP, specify the IP address(es) of trusted proxies"
echo -e "(e.g., load balancers, firewalls, CDNs) that forward traffic to this node.${NC}"
echo -e "${YELLOW}You can enter:${NC}"
echo -e " - Single IP: 10.0.0.10"
echo -e " - CIDR range: 10.0.0.0/24"
echo -e " - Multiple entries separated by spaces: 10.0.0.10 10.0.1.0/24 192.168.1.1"
echo -e "${YELLOW}If unsure, you can leave empty and configure later${NC}"
read -r -p "$(echo -e "${YELLOW}Trusted proxy IPs/CIDRs (space-separated): ${NC}")" trusted_proxies_input
local validated_proxies=()
if [[ -n "$trusted_proxies_input" ]]; then
IFS=' ' read -ra proxy_array <<< "$trusted_proxies_input"
for proxy in "${proxy_array[@]}"; do
proxy=$(echo "$proxy" | xargs)
if [[ -n "$proxy" ]]; then
if validate_ip_or_cidr "$proxy"; then
validated_proxies+=("$proxy")
else
echo -e "${RED}Invalid IP/CIDR format: $proxy${NC}"
echo -e "${YELLOW}Example valid formats: 10.0.0.10, 10.0.0.0/24, 192.168.1.1${NC}"
fi
fi
done
if [[ ${#validated_proxies[@]} -eq 0 ]]; then
echo -e "${YELLOW}No valid proxy IPs provided. Will skip set_real_ip_from configuration.${NC}"
echo -e "${YELLOW}You can configure it later with the reconfigure script.${NC}"
trusted_proxies=""
else
trusted_proxies="${validated_proxies[*]}"
echo -e "${GREEN}Trusted proxies configured: $trusted_proxies${NC}"
fi
else
echo -e "${YELLOW}No trusted proxies specified. The node will see the last hop IP only.${NC}"
fi
# Generate instance name and directory
local instance_name
instance_name="wallarm-$(hostname -s | tr '[:upper:]' '[:lower:]')-$(date +%Y%m%d)"
local instance_dir="/opt/wallarm/$instance_name"
sudo mkdir -p "$instance_dir"
log_message "SUCCESS" "Configuration collected:"
log_message "SUCCESS" " Ingress Port: $ingress_port"
log_message "SUCCESS" " Upstream: $upstream_ip:$upstream_port"
if [[ -n "$trusted_proxies" ]]; then
log_message "SUCCESS" " Trusted Proxies: $trusted_proxies"
else
log_message "INFO" " Trusted Proxies: Not configured (will need manual setup)"
fi
log_message "SUCCESS" " Instance: $instance_name"
log_message "SUCCESS" " Directory: $instance_dir"
INGRESS_PORT="$ingress_port"
UPSTREAM_IP="$upstream_ip"
UPSTREAM_PORT="$upstream_port"
WALLARM_TOKEN="$wallarm_token"
INSTANCE_NAME="$instance_name"
INSTANCE_DIR="$instance_dir"
TRUSTED_PROXIES="$trusted_proxies"
}
# ==============================================================================
# WALLARM NATIVE INSTALLATION (all-in-one installer)
# ==============================================================================
install_wallarm_native() {
log_message "INFO" "Installing Wallarm filtering node natively (all-in-one installer)..."
# Select the correct installer for the detected architecture
local arch_suffix
case "$ARCHITECTURE" in
"x86_64") arch_suffix="x86_64-glibc" ;;
"aarch64") arch_suffix="aarch64-glibc" ;;
*)
fail_with_remediation "Unsupported architecture for native install: $ARCHITECTURE" \
"The Wallarm all-in-one installer supports x86_64 and aarch64.
1. Check architecture: uname -m
2. If you are on a 32-bit system, consider the Docker deployment instead.
3. See https://docs.wallarm.com/installation/nginx/all-in-one/ for supported platforms."
;;
esac
local installer_name="wallarm-${WALLARM_VERSION}.${arch_suffix}.sh"
local installer_url="${INSTALLER_BASE_URL}/${installer_name}"
log_message "INFO" "Downloading Wallarm installer: $installer_name"
if ! download_from_git "$installer_url" "$installer_name" "Wallarm all-in-one installer"; then
fail_with_remediation "Failed to download Wallarm installer" \
"Could not download $installer_url
1. Verify network access to meganode.wallarm.com
2. Check the current version at https://docs.wallarm.com/updating-migrating/node-artifact-versions/
3. Pin the version with: WALLARM_VERSION=<version> sudo ./$0"
fi
chmod +x "$installer_name"
# Build installer arguments (batch mode)
local install_args="-- --batch -t $WALLARM_TOKEN"
if [ "$CLOUD_REGION" = "US" ]; then
install_args="$install_args -c US"
log_message "INFO" "Using US cloud (us1.api.wallarm.com)"
else
log_message "INFO" "Using EU cloud (api.wallarm.com)"
fi
# Run the installer (batch mode). The installer registers the node with the
# token and configures NGINX + the Wallarm module automatically.
log_message "INFO" "Running Wallarm all-in-one installer (this may take several minutes)..."
if [ -n "$WALLARM_LABELS" ]; then
log_message "INFO" "Using node labels: $WALLARM_LABELS"
if ! sudo env WALLARM_LABELS="$WALLARM_LABELS" sh "$installer_name" $install_args; then
rm -f "$installer_name"
fail_with_remediation "Wallarm installer failed" \
"The all-in-one installer exited with an error. Check:
1. The installer log output above for the exact error
2. Token validity in the Wallarm Console
3. Network access to Wallarm repositories (the installer adds them automatically)
4. Disk space and memory: df -h / && free -h
5. Retry with a higher log verbosity, or see https://docs.wallarm.com/installation/nginx/all-in-one/"
fi
else
if ! sudo sh "$installer_name" $install_args; then
rm -f "$installer_name"
fail_with_remediation "Wallarm installer failed" \
"The all-in-one installer exited with an error. Check:
1. The installer log output above for the exact error
2. Token validity in the Wallarm Console
3. Network access to Wallarm repositories (the installer adds them automatically)
4. Disk space and memory: df -h / && free -h
5. Retry with a higher log verbosity, or see https://docs.wallarm.com/installation/nginx/all-in-one/"
fi
fi
rm -f "$installer_name"
log_message "SUCCESS" "Wallarm all-in-one installer completed"
# Verify the node was registered
if [ -f "/opt/wallarm/etc/wallarm/node.yaml" ]; then
log_message "SUCCESS" "Wallarm node configuration found: /opt/wallarm/etc/wallarm/node.yaml"
else
log_message "WARNING" "Wallarm node configuration not found at /opt/wallarm/etc/wallarm/node.yaml"
echo -e "${YELLOW}The node may not have been registered. Check the installer output.${NC}"
fi
}
# ==============================================================================
# NGINX CONFIGURATION
# ==============================================================================
# Detect existing NGINX server blocks that would conflict with our ingress port
# and disable the default site if necessary.
resolve_port_conflict() {
local port="$1"
log_message "INFO" "Checking for NGINX config conflicts on port $port..."
# Only relevant for default port 80 where distro default sites listen
if [ "$port" != "80" ]; then
return 0
fi
# Look for default server blocks listening on port 80
local conflicting
conflicting=$(grep -rl "listen.*80" /etc/nginx/sites-enabled/ /etc/nginx/conf.d/ 2>/dev/null | head -1 || true)
if [ -n "$conflicting" ]; then
log_message "WARNING" "Default NGINX site found: $conflicting"
echo -e "${YELLOW}The default site listens on port 80 and may conflict with the Wallarm node.${NC}"
read -r -p "$(echo -e "${YELLOW}Disable it (backup to .bak)? (Y/n): ${NC}")" -n 1
echo
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
sudo mv "$conflicting" "${conflicting}.bak"
log_message "SUCCESS" "Disabled $conflicting (backup: ${conflicting}.bak)"
else
log_message "WARNING" "Keeping default site. The Wallarm node may not receive traffic on port 80."
fi
fi
}
create_nginx_config() {
NGINX_CONFIG="/etc/nginx/conf.d/wallarm-${INSTANCE_NAME}.conf"
log_message "INFO" "Creating NGINX configuration: $NGINX_CONFIG"
# Also keep a copy in the instance directory for reference/backup
sudo tee "$NGINX_CONFIG" > /dev/null <<EOF
# Wallarm filtering node: $INSTANCE_NAME
# Generated: $(date)
server {
listen $INGRESS_PORT;
server_name _;
EOF
# Add set_real_ip_from directives if trusted proxies are configured
if [[ -n "$TRUSTED_PROXIES" ]]; then
for proxy in $TRUSTED_PROXIES; do
sudo tee -a "$NGINX_CONFIG" > /dev/null <<EOF
set_real_ip_from $proxy;
EOF
done
sudo tee -a "$NGINX_CONFIG" > /dev/null <<EOF
real_ip_header X-Real-IP;
real_ip_recursive on;
EOF
fi
# Add the rest of the configuration
sudo tee -a "$NGINX_CONFIG" > /dev/null <<EOF
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;
proxy_set_header X-Forwarded-Server \$http_x_forwarded_server;
# Wallarm directives
wallarm_mode monitoring;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
EOF
# Keep a reference copy in the instance directory
sudo cp "$NGINX_CONFIG" "$INSTANCE_DIR/nginx.conf"
log_message "SUCCESS" "NGINX configuration created: $NGINX_CONFIG"
if [[ -n "$TRUSTED_PROXIES" ]]; then
log_message "INFO" " Configured trusted proxies: $TRUSTED_PROXIES"
else
log_message "INFO" " No trusted proxies configured - real client IP detection may be limited"
fi
}
reload_nginx() {
log_message "INFO" "Testing and reloading NGINX..."
if ! sudo nginx -t 2>&1 | tee "$INSTANCE_DIR/nginx-test.log"; then
fail_with_remediation "NGINX configuration test failed" \
"NGINX rejected the configuration. Check the test output above.
1. Review the generated config: $NGINX_CONFIG
2. Look for port conflicts or syntax errors
3. Restore the backup if the default site was disabled
4. Manual test: sudo nginx -t"
fi
# Reload according to init system
case "${INIT_SYSTEM:-systemd}" in
"systemd")
sudo systemctl reload nginx 2>/dev/null || sudo systemctl restart nginx
;;
"openrc")
sudo rc-service nginx reload 2>/dev/null || sudo rc-service nginx restart
;;
"sysvinit")
sudo service nginx reload 2>/dev/null || sudo service nginx restart
;;
*)
sudo nginx -s reload 2>/dev/null || true
;;
esac
log_message "SUCCESS" "NGINX reloaded with Wallarm configuration"
}
# ==============================================================================
# DEPLOYMENT VERIFICATION
# ==============================================================================
verify_deployment() {
log_message "INFO" "Verifying native Wallarm deployment..."
# Test ingress port
log_message "INFO" "Testing ingress port $INGRESS_PORT..."
if ! check_port_available "$INGRESS_PORT"; then
log_message "SUCCESS" "Ingress port $INGRESS_PORT is in use (as expected)"
else
log_message "WARNING" "Ingress port $INGRESS_PORT appears available (NGINX may not be listening)"
fi
# Test health check endpoint
log_message "INFO" "Testing health check endpoint..."
local health_check_url="http://localhost:$INGRESS_PORT/health"
if curl -sf --connect-timeout 5 "$health_check_url" >/dev/null 2>&1; then
log_message "SUCCESS" "Health check endpoint responsive"
else
log_message "WARNING" "Health check endpoint not responsive (may need time to start)"
sleep 5
if curl -sf --connect-timeout 5 "$health_check_url" >/dev/null 2>&1; then
log_message "SUCCESS" "Health check endpoint now responsive"
else
log_message "WARNING" "Health check endpoint still not responsive (check nginx config)"
fi
fi
# Test handshake through filtering node
log_message "INFO" "Testing handshake through filtering node to upstream..."
local test_url="http://localhost:$INGRESS_PORT/"
if curl -sfI --connect-timeout 10 "$test_url" >/dev/null 2>&1; then
log_message "SUCCESS" "Handshake successful: filtering node can reach upstream"
else
log_message "WARNING" "Handshake failed (upstream may not be responding)"
log_message "INFO" "Checking if upstream is directly reachable..."
if timeout 5 bash -c "cat < /dev/null > /dev/tcp/$UPSTREAM_IP/$UPSTREAM_PORT" 2>/dev/null; then
log_message "ERROR" "Upstream is reachable but filtering node cannot proxy"
echo -e "${YELLOW}Possible NGINX configuration issue. Check:${NC}"
echo -e "1. NGINX error log: sudo tail -50 /var/log/nginx/error.log"
echo -e "2. NGINX config: $NGINX_CONFIG"
else
log_message "WARNING" "Upstream server is not reachable (as previously warned)"
fi
fi
# Check Wallarm module status endpoint
log_message "INFO" "Checking Wallarm module status..."
if curl -sf --connect-timeout 5 "http://127.0.0.8/wallarm-status" >/dev/null 2>&1; then
log_message "SUCCESS" "Wallarm module is active (wallarm-status responsive)"
else
log_message "WARNING" "wallarm-status not responsive (module may need more time or a restart)"
fi
# Check node registration file
if [ -f "/opt/wallarm/etc/wallarm/node.yaml" ]; then
log_message "SUCCESS" "Node is registered (node.yaml present)"
else
log_message "WARNING" "node.yaml not found - node may not be registered with the cloud"
fi
log_message "SUCCESS" "Deployment verification completed"
echo -e "\n${GREEN}${BOLD}Verification Summary:${NC}"
echo -e " ${GREEN}${NC} NGINX + Wallarm module installed"
echo -e " ${GREEN}${NC} Ingress port: $INGRESS_PORT"
echo -e " ${GREEN}${NC} Upstream: $UPSTREAM_IP:$UPSTREAM_PORT"
echo -e " ${GREEN}${NC} Cloud region: $CLOUD_REGION ($API_HOST)"
}
# ==============================================================================
# MAIN FUNCTION
# ==============================================================================
main() {
clear
echo -e "${BLUE}${BOLD}"
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ WALLARM DEPLOYMENT SCRIPT (Native) - V1.0 ║"
echo "║ Filtering Node Deployment Without Docker ║"
echo "╚══════════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}Starting deployment at: $(date)${NC}"
# Initialize logging
local log_dir="${HOME:-.}/logs"
if [ ! -d "$log_dir" ]; then
if ! mkdir -p "$log_dir"; then
echo -e "${YELLOW}Cannot create log directory $log_dir, falling back to current directory...${NC}"
log_dir="."
fi
fi
LOG_FILE="$log_dir/wallarm-deployment-native.log"
if ! : > "$LOG_FILE"; then
echo -e "${RED}Cannot create log file at $LOG_FILE${NC}"
echo -e "${YELLOW}Falling back to current directory...${NC}"
LOG_FILE="./wallarm-deployment-native.log"
: > "$LOG_FILE" 2>/dev/null || true
fi
if ! chmod 644 "$LOG_FILE" 2>/dev/null; then
echo -e "${YELLOW}Warning: Could not set permissions on log file${NC}"
fi
log_message "INFO" "=== Wallarm Native Deployment Started ==="
if [ "$INSECURE_SSL" = "1" ]; then
log_message "WARNING" "SSL certificate validation is DISABLED (insecure). Set WALLARM_INSECURE_SSL=0 to enable validation."
fi
# Phase 1: Verify preflight check
log_message "INFO" "=== PHASE 1: PREFLIGHT CHECK VERIFICATION ==="
verify_preflight_check
# Phase 2: Configuration collection
log_message "INFO" "=== PHASE 2: CONFIGURATION COLLECTION ==="
select_cloud_region
collect_configuration
# Phase 3: Native installation (all-in-one installer)
log_message "INFO" "=== PHASE 3: WALLARM NATIVE INSTALLATION ==="
install_wallarm_native
# Phase 4: NGINX configuration
log_message "INFO" "=== PHASE 4: NGINX CONFIGURATION ==="
resolve_port_conflict "$INGRESS_PORT"
create_nginx_config
reload_nginx
# Phase 5: Verification
log_message "INFO" "=== PHASE 5: VERIFICATION ==="
verify_deployment
# Success message
log_message "SUCCESS" "=== WALLARM NATIVE DEPLOYMENT COMPLETED SUCCESSFULLY ==="
echo -e "\n${GREEN}${BOLD}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${BOLD}║ WALLARM FILTERING NODE DEPLOYMENT SUCCESSFUL ║${NC}"
echo -e "${GREEN}${BOLD}╚══════════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${CYAN}The Wallarm filtering node is now active and protecting your application.${NC}"
echo -e "${YELLOW}Full deployment log: $LOG_FILE${NC}"
echo -e "${YELLOW}Instance directory: $INSTANCE_DIR${NC}"
echo -e "\n${GREEN}To stop the node:${NC} sudo systemctl stop nginx"
echo -e "${GREEN}To restart:${NC} sudo systemctl restart nginx"
echo -e "${GREEN}To view logs:${NC} sudo tail -f /var/log/nginx/error.log"
echo -e "${GREEN}Node status:${NC} curl http://127.0.0.8/wallarm-status"
echo -e "\n${MAGENTA}${BOLD}Deployment completed successfully!${NC}"
echo -e "\n${YELLOW}Important next steps:${NC}"
echo -e "1. Monitor sync status in Wallarm Console"
echo -e "2. Test attack detection with safe test: curl http://localhost:$INGRESS_PORT/?wallarm_test=1"
echo -e "3. Review logs periodically: sudo tail -50 /var/log/nginx/error.log"
echo -e "4. Switch to block mode after validation: sudo ./native/wallarm-ct-reconfigure.sh"
}
# ==============================================================================
# SCRIPT EXECUTION
# ==============================================================================
# Ensure we're in bash
if [ -z "$BASH_VERSION" ]; then
echo "Error: This script must be run with bash" >&2
exit 1
fi
# Run main function
main "$@"