#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}==========================================${NC}"
echo -e "${BLUE}  Elasticsearch Security Check${NC}"
echo -e "${BLUE}==========================================${NC}\n"

# Check if Elasticsearch is running
if ! systemctl is-active --quiet elasticsearch; then
    echo -e "${YELLOW}⚠ Elasticsearch is not running${NC}"
    exit 0
fi

echo -e "${GREEN}✓ Elasticsearch is running${NC}\n"

# Check listening interfaces
echo -e "${BLUE}Checking network bindings...${NC}"
LISTEN_OUTPUT=$(ss -tlnp 2>/dev/null | grep 9200)

if [ -z "$LISTEN_OUTPUT" ]; then
    echo -e "${RED}✗ Elasticsearch not found listening on port 9200${NC}\n"
    exit 1
fi

echo "$LISTEN_OUTPUT"
echo ""

# Check if bound to localhost only
# Accept: 127.0.0.1, ::1, and ::ffff:127.0.0.1 (IPv6-mapped IPv4)
if echo "$LISTEN_OUTPUT" | grep -qE "127.0.0.1:9200|::1\]:9200|::ffff:127.0.0.1\]:9200"; then
    if echo "$LISTEN_OUTPUT" | grep -qE "0.0.0.0:9200|\*:9200"; then
        echo -e "${RED}✗ DANGER: Elasticsearch is bound to ALL interfaces (0.0.0.0)${NC}"
        echo -e "${RED}  This means it's accessible from the network/internet!${NC}\n"
        EXPOSED=true
    else
        echo -e "${GREEN}✓ SAFE: Elasticsearch is bound to localhost only${NC}"
        if echo "$LISTEN_OUTPUT" | grep -q "::ffff:127.0.0.1"; then
            echo -e "${GREEN}  (Including IPv6-mapped IPv4 localhost)${NC}\n"
        else
            echo ""
        fi
        EXPOSED=false
    fi
else
    if echo "$LISTEN_OUTPUT" | grep -qE "0.0.0.0:9200|\*:9200"; then
        echo -e "${RED}✗ DANGER: Elasticsearch is bound to ALL interfaces (0.0.0.0)${NC}"
        echo -e "${RED}  This means it's accessible from the network/internet!${NC}\n"
        EXPOSED=true
    else
        echo -e "${YELLOW}⚠ WARNING: Elasticsearch might be bound to a specific network interface${NC}\n"
        EXPOSED=true
    fi
fi

# Check configuration file
echo -e "${BLUE}Checking configuration file...${NC}"
if [ -f /etc/elasticsearch/elasticsearch.yml ]; then
    NETWORK_HOST=$(grep "^network.host:" /etc/elasticsearch/elasticsearch.yml 2>/dev/null | awk '{print $2}')
    SECURITY_ENABLED=$(grep "^xpack.security.enabled:" /etc/elasticsearch/elasticsearch.yml 2>/dev/null | awk '{print $2}')

    if [ -n "$NETWORK_HOST" ]; then
        echo -e "network.host: ${YELLOW}$NETWORK_HOST${NC}"
        if [ "$NETWORK_HOST" = "127.0.0.1" ] || [ "$NETWORK_HOST" = "localhost" ]; then
            echo -e "${GREEN}✓ Configuration: Bound to localhost${NC}"
        elif [ "$NETWORK_HOST" = "0.0.0.0" ]; then
            echo -e "${RED}✗ Configuration: Bound to ALL interfaces - INSECURE!${NC}"
        else
            echo -e "${YELLOW}⚠ Configuration: Bound to specific interface${NC}"
        fi
    else
        echo -e "${YELLOW}⚠ network.host not explicitly set (using default)${NC}"
    fi

    if [ -n "$SECURITY_ENABLED" ]; then
        echo -e "xpack.security.enabled: ${YELLOW}$SECURITY_ENABLED${NC}"
        if [ "$SECURITY_ENABLED" = "true" ]; then
            echo -e "${GREEN}✓ Security: Authentication enabled${NC}"
        else
            echo -e "${YELLOW}⚠ Security: Authentication disabled${NC}"
            if [ "$NETWORK_HOST" = "127.0.0.1" ] || [ "$NETWORK_HOST" = "localhost" ]; then
                echo -e "${GREEN}  (OK for localhost-only setup)${NC}"
            else
                echo -e "${RED}  (DANGEROUS if accessible from network!)${NC}"
            fi
        fi
    else
        echo -e "${YELLOW}⚠ xpack.security.enabled not set (default: false)${NC}"
    fi
    echo ""
else
    echo -e "${RED}✗ Cannot access /etc/elasticsearch/elasticsearch.yml${NC}"
    echo -e "${YELLOW}  (Run with sudo to read config file)${NC}\n"
fi

# Test local access
echo -e "${BLUE}Testing local access...${NC}"
LOCAL_RESPONSE=$(curl -s http://localhost:9200 2>&1)
if echo "$LOCAL_RESPONSE" | grep -q "\"cluster_name\""; then
    echo -e "${GREEN}✓ Accessible locally on localhost:9200${NC}\n"
else
    echo -e "${RED}✗ Cannot access locally${NC}\n"
fi

# Get network interfaces
echo -e "${BLUE}Network interfaces:${NC}"
ip addr show | grep "inet " | grep -v "127.0.0.1" | awk '{print "  " $2}'
echo ""

# Try to test external access (if we have an external IP)
EXTERNAL_IP=$(ip addr show | grep "inet " | grep -v "127.0.0.1" | head -1 | awk '{print $2}' | cut -d'/' -f1)
if [ -n "$EXTERNAL_IP" ]; then
    echo -e "${BLUE}Testing external access from $EXTERNAL_IP...${NC}"
    EXTERNAL_RESPONSE=$(curl -s --connect-timeout 2 "http://$EXTERNAL_IP:9200" 2>&1)
    if echo "$EXTERNAL_RESPONSE" | grep -q "\"cluster_name\""; then
        echo -e "${RED}✗✗✗ DANGER: Elasticsearch IS ACCESSIBLE from $EXTERNAL_IP ✗✗✗${NC}"
        echo -e "${RED}     Anyone on your network can access your database!${NC}\n"
        EXPOSED=true
    elif echo "$EXTERNAL_RESPONSE" | grep -q "Connection refused"; then
        echo -e "${GREEN}✓ SAFE: Not accessible from $EXTERNAL_IP${NC}\n"
    else
        echo -e "${YELLOW}⚠ Unable to test (got: $EXTERNAL_RESPONSE)${NC}\n"
    fi
fi

# Final verdict
echo -e "${BLUE}==========================================${NC}"
if [ "$EXPOSED" = true ]; then
    echo -e "${RED}     SECURITY RISK DETECTED!${NC}"
    echo -e "${BLUE}==========================================${NC}\n"
    echo -e "${RED}Action Required:${NC}"
    echo -e "1. Stop Elasticsearch: ${YELLOW}sudo systemctl stop elasticsearch${NC}"
    echo -e "2. Edit config: ${YELLOW}sudo nano /etc/elasticsearch/elasticsearch.yml${NC}"
    echo -e "3. Set: ${YELLOW}network.host: 127.0.0.1${NC}"
    echo -e "4. Set: ${YELLOW}xpack.security.enabled: true${NC}"
    echo -e "5. Restart: ${YELLOW}sudo systemctl start elasticsearch${NC}"
    echo -e "\nSee ${BLUE}references/ELASTICSEARCH_SETUP.md${NC} for detailed security guide\n"
    exit 1
else
    echo -e "${GREEN}     System appears secure${NC}"
    echo -e "${BLUE}==========================================${NC}\n"
    if [ "$SECURITY_ENABLED" != "true" ]; then
        echo -e "${YELLOW}Recommendation: Enable authentication for additional security${NC}"
        echo -e "See ${BLUE}references/ELASTICSEARCH_SETUP.md${NC} for instructions\n"
    fi
    exit 0
fi
