Index: /branches/amp_4_0/platform/tools/README.md
===================================================================
--- /branches/amp_4_0/platform/tools/README.md	(revision 2603)
+++ /branches/amp_4_0/platform/tools/README.md	(working copy)
@@ -14,6 +14,7 @@
 * InfluxDB -> 2.7.11-1
 * InfluxDB-CLI -> 2.7.5-1
 * Telegraf -> 1.34.1-1
+* Nginx -> 1.20.1
 
 ### Installation order
 
@@ -32,11 +33,10 @@
 
 #### InfluxDB
 
-By default, influxdb GUI is not exposed to the outside network, we can allow the 8086 to access the InfluxDB GUI using
-the following firewall rules - its strictly for the debugging purpose.
+By default, influxdb GUI is not exposed to the outside network; we can allow the 8086 to access the InfluxDB GUI using
+the following firewall rules—it's strictly for the debugging purpose.
 
 sudo firewall-cmd --permanent --add-port=8086/tcp
-
 sudo firewall-cmd --permanent --add-port=8086/udp
 
 sudo firewall-cmd --reload
Index: /branches/amp_4_0/platform/tools/install_nginx.sh
===================================================================
--- /branches/amp_4_0/platform/tools/install_nginx.sh	(nonexistent)
+++ /branches/amp_4_0/platform/tools/install_nginx.sh	(working copy)
@@ -0,0 +1,335 @@
+#!/bin/bash
+
+# Script to configure Nginx on Rocky Linux 9.5 as a reverse proxy for:
+# - Custom app (backend at http://127.0.0.1:3000 or static page) on HTTPS (port 443) at root (e.g., /, /login)
+# - Kibana (backend at http://127.0.0.1:5601) accessible via /visualization on HTTPS (port 443)
+# Uses self-signed certificates and the server's IP address instead of a domain name.
+# Kibana paths are scoped under /visualization/ to avoid conflicts with custom app paths (e.g., /login).
+# Fixes duplicate server.host and handles Kibana redirects to stay under /visualization/.
+
+# --- Variables ---
+INSTALL_LOG_FILE="/var/log/nginx_installation.log"
+NGINX_CONF_D_DIR="/etc/nginx/conf.d"
+NGINX_DEFAULT_CONF="${NGINX_CONF_D_DIR}/default.conf"
+NGINX_APP_CONF="${NGINX_CONF_D_DIR}/app.conf"
+SSL_DIR="/etc/nginx/ssl"
+SSL_KEY="${SSL_DIR}/server.key"
+SSL_CRT="${SSL_DIR}/server.crt"
+SSL_COMMON_NAME="${SERVER_IP:-$(ip addr show | grep -oE 'inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}' | grep -v '127.0.0.1' | head -1)}"
+SSL_DAYS=365
+BACKEND_URL="http://127.0.0.1:3000" # Backend for custom app
+STATIC_FILES_PATH="/var/www/your_app/static" # Static files path (commented out by default)
+KIBANA_BACKEND_URL="http://127.0.0.1:5601" # Kibana backend
+
+# --- Functions ---
+log_info() {
+    echo -e "\e[32m[INFO] $1\e[0m" | tee -a "${INSTALL_LOG_FILE}"
+}
+
+log_warning() {
+    echo -e "\e[33m[WARN] $1\e[0m" | tee -a "${INSTALL_LOG_FILE}"
+}
+
+log_error() {
+    echo -e "\e[31m[ERROR] $1\e[0m" | tee -a "${INSTALL_LOG_FILE}"
+    exit 1
+}
+
+check_service() {
+    local url=$1
+    local name=$2
+    log_info "Checking if ${name} is running at ${url}..."
+    if ! curl -s --connect-timeout 5 "${url}" &>/dev/null; then
+        log_error "${name} is not running at ${url}. Start the service or update the configuration."
+    fi
+    log_info "${name} is accessible at ${url}."
+}
+
+# --- Pre-installation Setup ---
+> "${INSTALL_LOG_FILE}"
+sudo chmod 640 "${INSTALL_LOG_FILE}"
+sudo chown root:adm "${INSTALL_LOG_FILE}"
+log_info "Starting Nginx installation script. Logs are saved to ${INSTALL_LOG_FILE}"
+
+if [[ $EUID -ne 0 ]]; then
+    log_error "This script must be run as root. Please use sudo."
+fi
+
+if ! grep -q "Rocky Linux 9" /etc/os-release; then
+    log_error "This script is intended for Rocky Linux 9.x. Exiting."
+fi
+
+if [ -z "${SSL_COMMON_NAME}" ]; then
+    log_error "Could not determine server IP address. Set SERVER_IP environment variable."
+fi
+log_info "Using server IP: ${SSL_COMMON_NAME}"
+
+if rpm -q nginx &>/dev/null; then
+    log_info "Nginx is already installed. Proceeding with configuration."
+else
+    # --- Remove or Disable nginx-stable Repository ---
+    if [ -f "/etc/yum.repos.d/nginx.repo" ]; then
+        log_info "Removing existing nginx-stable repository to avoid conflicts..."
+        sudo rm /etc/yum.repos.d/nginx.repo &>> "${INSTALL_LOG_FILE}"
+        if [ $? -ne 0 ]; then
+            log_error "Failed to remove nginx-stable repository. Check ${INSTALL_LOG_FILE}."
+        fi
+    fi
+
+    # --- Install Nginx from AppStream ---
+    log_info "Installing Nginx from Rocky Linux AppStream repository..."
+    sudo dnf install -y nginx policycoreutils-python-utils &>> "${INSTALL_LOG_FILE}"
+    if [ $? -ne 0 ]; then
+        log_error "Failed to install Nginx. Check ${INSTALL_LOG_FILE}."
+    fi
+    log_info "Nginx installed successfully."
+fi
+
+# --- Check Backend Services ---
+check_service "${KIBANA_BACKEND_URL}" "Kibana"
+if curl -s --connect-timeout 5 "${BACKEND_URL}" &>/dev/null; then
+    log_info "Main application is accessible at ${BACKEND_URL}."
+else
+    log_warning "Main application is not running at ${BACKEND_URL}. Using static page instead."
+    USE_STATIC_PAGE=true
+    if [ ! -f "/usr/share/nginx/html/index.html" ]; then
+        log_warning "Static index.html not found. Creating a default page."
+        echo "<html><body><h1>Welcome to Your Application</h1></body></html>" | sudo tee /usr/share/nginx/html/index.html &>> "${INSTALL_LOG_FILE}"
+    fi
+fi
+
+# --- Create SSL Directory and Self-Signed Certificate ---
+log_info "Creating SSL directory: ${SSL_DIR}"
+sudo mkdir -p "${SSL_DIR}" &>> "${INSTALL_LOG_FILE}"
+sudo chmod 700 "${SSL_DIR}" &>> "${INSTALL_LOG_FILE}"
+
+if [ ! -f "${SSL_CRT}" ] || [ ! -f "${SSL_KEY}" ]; then
+    log_info "Generating self-signed SSL certificate for ${SSL_COMMON_NAME}..."
+    if ! command -v openssl &>/dev/null; then
+        log_warning "openssl not found. Installing openssl..."
+        sudo dnf install -y openssl &>> "${INSTALL_LOG_FILE}"
+        if [ $? -ne 0 ]; then
+            log_error "Failed to install openssl. Cannot generate certificate."
+        fi
+    fi
+
+    sudo openssl req -x509 -nodes -days "${SSL_DAYS}" -newkey rsa:2048 \
+      -keyout "${SSL_KEY}" \
+      -out "${SSL_CRT}" \
+      -subj "/C=IN/ST=Tamil Nadu/L=Erode/O=ArrayNetworks/OU=AMP/CN=${SSL_COMMON_NAME}" &>> "${INSTALL_LOG_FILE}"
+    if [ $? -ne 0 ]; then
+        log_error "Failed to generate self-signed certificate. Check ${INSTALL_LOG_FILE}."
+    fi
+    sudo chmod 600 "${SSL_KEY}"
+    log_info "Self-signed certificate generated: ${SSL_CRT} and ${SSL_KEY}"
+else
+    log_info "Using existing SSL certificate: ${SSL_CRT} and ${SSL_KEY}"
+fi
+
+# --- Configure SELinux ---
+log_info "Configuring SELinux for Nginx..."
+if command -v semanage &>/dev/null; then
+    sudo semanage fcontext -a -t httpd_config_t "${SSL_DIR}(/.*)?" &>> "${INSTALL_LOG_FILE}"
+    sudo restorecon -R -v "${SSL_DIR}" &>> "${INSTALL_LOG_FILE}"
+    sudo setsebool -P httpd_can_network_connect 1 &>> "${INSTALL_LOG_FILE}"
+    sudo semanage port -a -t http_port_t -p tcp 3000 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 3000 &>> "${INSTALL_LOG_FILE}"
+    sudo semanage port -a -t http_port_t -p tcp 5601 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 5601 &>> "${INSTALL_LOG_FILE}"
+else
+    log_warning "SELinux tools not found. Skipping SELinux configuration. Set SELinux to permissive mode or manually configure."
+    log_info "To set SELinux to permissive: sudo setenforce 0"
+fi
+
+# --- Configure FirewallD ---
+log_info "Configuring FirewallD for HTTP (80) and HTTPS (443)..."
+if ! systemctl is-active --quiet firewalld; then
+    log_warning "FirewallD is not running. Starting and enabling it."
+    sudo systemctl start firewalld &>> "${INSTALL_LOG_FILE}"
+    sudo systemctl enable firewalld &>> "${INSTALL_LOG_FILE}"
+    if [ $? -ne 0 ]; then
+        log_error "Failed to start or enable FirewallD. Check ${INSTALL_LOG_FILE}."
+    fi
+fi
+
+sudo firewall-cmd --permanent --add-service=http &>> "${INSTALL_LOG_FILE}"
+sudo firewall-cmd --permanent --add-service=https &>> "${INSTALL_LOG_FILE}"
+sudo firewall-cmd --reload &>> "${INSTALL_LOG_FILE}"
+if [ $? -ne 0 ]; then
+    log_error "Failed to configure FirewallD. Check ${INSTALL_LOG_FILE}."
+fi
+log_info "FirewallD configured to allow HTTP and HTTPS traffic."
+
+# --- Configure Kibana Base Path ---
+log_info "Configuring Kibana with base path /visualization..."
+KIBANA_CONF="/etc/kibana/kibana.yml"
+if [ -f "${KIBANA_CONF}" ]; then
+    # Remove existing server.host, server.port, server.basePath, server.rewriteBasePath to avoid duplicates
+    sudo sed -i '/^server\.host:/d' "${KIBANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    sudo sed -i '/^server\.port:/d' "${KIBANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    sudo sed -i '/^server\.basePath:/d' "${KIBANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    sudo sed -i '/^server\.rewriteBasePath:/d' "${KIBANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    # Add correct settings
+    cat <<EOK >> "${KIBANA_CONF}"
+server.host: "127.0.0.1"
+server.port: 5601
+server.basePath: "/visualization"
+server.rewriteBasePath: true
+EOK
+    log_info "Restarting Kibana to apply configuration..."
+    sudo systemctl restart kibana &>> "${INSTALL_LOG_FILE}"
+    if [ $? -ne 0 ]; then
+        log_error "Failed to restart Kibana. Check 'sudo systemctl status kibana' or ${INSTALL_LOG_FILE}."
+    fi
+    log_info "Kibana configured with base path /visualization."
+else
+    log_error "Kibana configuration file not found at ${KIBANA_CONF}. Ensure Kibana is installed and configured."
+fi
+
+# --- Configure Nginx ---
+log_info "Configuring Nginx for custom app and Kibana."
+if [ -f "${NGINX_DEFAULT_CONF}" ]; then
+    log_info "Removing default Nginx configuration file: ${NGINX_DEFAULT_CONF}"
+    sudo rm "${NGINX_DEFAULT_CONF}" &>> "${INSTALL_LOG_FILE}"
+fi
+
+if [ -f "${NGINX_APP_CONF}" ]; then
+    log_info "Backing up existing Nginx configuration: ${NGINX_APP_CONF}"
+    sudo mv "${NGINX_APP_CONF}" "${NGINX_APP_CONF}.backup-$(date +%F_%T)" &>> "${INSTALL_LOG_FILE}"
+fi
+
+log_info "Creating Nginx configuration file: ${NGINX_APP_CONF}"
+cat <<EOF | sudo tee "${NGINX_APP_CONF}" &>> "${INSTALL_LOG_FILE}"
+# /etc/nginx/conf.d/app.conf
+
+# --- HTTP Server Block (Redirects to HTTPS) ---
+server {
+    listen 80;
+    listen [::]:80;
+    server_name ${SSL_COMMON_NAME};
+
+    return 301 https://\$host\$request_uri;
+}
+
+# --- HTTPS Server Block ---
+server {
+    listen 443 ssl;
+    listen [::]:443 ssl;
+    server_name ${SSL_COMMON_NAME};
+
+    ssl_certificate ${SSL_CRT};
+    ssl_certificate_key ${SSL_KEY};
+
+    ssl_session_cache shared:SSL:10m;
+    ssl_session_timeout 10m;
+    ssl_protocols TLSv1.2 TLSv1.3;
+    ssl_prefer_server_ciphers on;
+    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
+
+    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
+
+    # Enable access logging for debugging
+    access_log /var/log/nginx/access.log;
+
+    # Kibana at /visualization/
+    location /visualization/ {
+      proxy_pass http://127.0.0.1:5601;  # No trailing slash!
+      proxy_http_version 1.1;
+      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 Upgrade \$http_upgrade;
+      proxy_set_header Connection \"upgrade";
+      proxy_cache_bypass \$http_upgrade;
+    }
+
+    # Main application
+    $(if [ "$USE_STATIC_PAGE" = true ]; then
+        echo "location / {
+            root /usr/share/nginx/html;
+            index index.html;
+        }"
+    else
+        echo "location / {
+            proxy_pass ${BACKEND_URL};
+            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-Port \$server_port;
+            proxy_connect_timeout 75s;
+            proxy_send_timeout 75s;
+            proxy_read_timeout 75s;
+            proxy_buffering off;
+        }"
+    fi)
+
+    location ~ /\. {
+        deny all;
+    }
+
+    error_page 404 /404.html;
+    location = /404.html {
+        root /usr/share/nginx/html;
+        internal;
+    }
+
+    error_page 500 502 503 504 /50x.html;
+    location = /50x.html {
+        root /usr/share/nginx/html;
+        internal;
+    }
+}
+EOF
+
+if [ $? -ne 0 ]; then
+    log_error "Failed to create Nginx configuration file. Check ${INSTALL_LOG_FILE}."
+fi
+log_info "Nginx configuration created: ${NGINX_APP_CONF}"
+
+# --- Test Nginx configuration ---
+log_info "Testing Nginx configuration syntax..."
+sudo nginx -t &>> "${INSTALL_LOG_FILE}"
+if [ $? -ne 0 ]; then
+    log_error "Nginx configuration test failed! Check ${INSTALL_LOG_FILE} for syntax errors."
+fi
+log_info "Nginx configuration syntax is OK."
+
+# --- Start and Enable Nginx Service ---
+log_info "Starting and enabling Nginx service..."
+sudo systemctl start nginx &>> "${INSTALL_LOG_FILE}"
+sudo systemctl enable nginx &>> "${INSTALL_LOG_FILE}"
+if [ $? -ne 0 ]; then
+    log_error "Failed to start or enable Nginx. Check 'sudo systemctl status nginx' or ${INSTALL_LOG_FILE}."
+fi
+log_info "Nginx service started and enabled successfully."
+
+# --- Verify Kibana Accessibility ---
+log_info "Verifying Kibana accessibility at https://${SSL_COMMON_NAME}/visualization..."
+if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/visualization" &>/dev/null; then
+    log_warning "Kibana is not accessible at https://${SSL_COMMON_NAME}/visualization. Checking backend directly..."
+    if ! curl -s --connect-timeout 5 "${KIBANA_BACKEND_URL}" &>/dev/null; then
+        log_error "Kibana backend (${KIBANA_BACKEND_URL}) is not responding. Check 'sudo systemctl status kibana' or ${INSTALL_LOG_FILE}."
+    fi
+    log_warning "Kibana backend is responding, but proxying failed. Check Nginx logs: /var/log/nginx/error.log and /var/log/nginx/access.log"
+fi
+log_info "Kibana is accessible at https://${SSL_COMMON_NAME}/visualization."
+
+# --- Verify Kibana and App Path Accessibility ---
+log_info "Verifying path accessibility for Kibana and custom app..."
+if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/visualization/login" &>/dev/null; then
+    log_warning "Kibana login page not accessible at https://${SSL_COMMON_NAME}/visualization/login. Check Kibana status."
+fi
+if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/login" &>/dev/null; then
+    log_warning "Custom app login page not accessible at https://${SSL_COMMON_NAME}/login. Check app backend or Nginx configuration."
+fi
+log_info "Path accessibility check completed."
+
+log_info "Nginx configuration complete. Serving custom app and Kibana on port 443."
+log_info "Ensure your firewall allows inbound traffic to ports 80 and 443."
+log_info "************************************************************************************************"
+log_info "** IMPORTANT ACCESS INFORMATION **"
+log_info "************************************************************************************************"
+log_info "- Custom application: https://${SSL_COMMON_NAME} (e.g., /, /login)"
+log_info "- Kibana: https://${SSL_COMMON_NAME}/visualization (e.g., /visualization/login)"
+log_warning "Browsers will show security warnings for the self-signed certificate. For production, obtain a trusted certificate from Let's Encrypt: https://letsencrypt.org/"
+log_info "Full installation log: ${INSTALL_LOG_FILE}"
