153 lines
6.2 KiB
Bash
Executable File
153 lines
6.2 KiB
Bash
Executable File
#!/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
|