7c3f01c9eb
12 funciones Bash del dominio cybersecurity: auditoria de red y servicios (analyze_dns, audit_http_headers, inspect_ssl_cert, list_active_connections, enumerate_subdomains, geolocate_ip), auditoria de sistema (audit_ssh_config, check_firewall, detect_suspicious_users), y utilidades crypto (encrypt_file, generate_password, verify_file_hash). Dominio nuevo en bash/functions/.
151 lines
5.3 KiB
Bash
151 lines
5.3 KiB
Bash
#!/usr/bin/env bash
|
|
# geolocate_ip
|
|
# ------------
|
|
# Geolocaliza una IP o dominio usando la API pública de ip-api.com.
|
|
# Muestra país, ciudad, ISP, ASN y detecta VPN/Proxy/Hosting.
|
|
#
|
|
# USO (directo):
|
|
# geolocate_ip <ip_o_dominio>
|
|
#
|
|
# Depende de: curl, dig (para resolver dominios)
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/../shell/bash_colors.sh"
|
|
source "$SCRIPT_DIR/../shell/bash_log.sh"
|
|
bash_colors
|
|
bash_log_init
|
|
|
|
# ─── Constantes ───────────────────────────────────────────────────────────────
|
|
|
|
_GEOIP_API="http://ip-api.com/json"
|
|
_GEOIP_FIELDS="status,message,country,countryCode,regionName,city,zip,lat,lon,isp,org,as,proxy,hosting,query"
|
|
|
|
# ─── Funciones puras ──────────────────────────────────────────────────────────
|
|
|
|
_geo_is_ip() {
|
|
[[ "$1" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
|
|
}
|
|
|
|
_geo_build_api_url() {
|
|
local target="$1"
|
|
echo "${_GEOIP_API}/${target}?fields=${_GEOIP_FIELDS}"
|
|
}
|
|
|
|
_geo_extract_field() {
|
|
local json="$1"
|
|
local key="$2"
|
|
echo "$json" | grep -o "\"${key}\":[^,}]*" | cut -d: -f2- | tr -d '"' | xargs
|
|
}
|
|
|
|
# ─── Funciones de efecto ──────────────────────────────────────────────────────
|
|
|
|
_geo_resolve_domain() {
|
|
local domain="$1"
|
|
dig +short A "$domain" 2>/dev/null | head -1 || true
|
|
}
|
|
|
|
_geo_fetch() {
|
|
local target="$1"
|
|
local url
|
|
url="$(_geo_build_api_url "$target")"
|
|
curl -s --max-time 10 "$url" 2>/dev/null
|
|
}
|
|
|
|
_geo_display_result() {
|
|
local json="$1"
|
|
|
|
local status
|
|
status="$(_geo_extract_field "$json" "status")"
|
|
if [[ "$status" != "success" ]]; then
|
|
local msg
|
|
msg="$(_geo_extract_field "$json" "message")"
|
|
error "La API devolvió error: ${msg:-respuesta inesperada}" >&2
|
|
return 1
|
|
fi
|
|
|
|
local ip_queried country country_code region city zip lat lon isp org asn proxy hosting
|
|
ip_queried="$(_geo_extract_field "$json" "query")"
|
|
country="$(_geo_extract_field "$json" "country")"
|
|
country_code="$(_geo_extract_field "$json" "countryCode")"
|
|
region="$(_geo_extract_field "$json" "regionName")"
|
|
city="$(_geo_extract_field "$json" "city")"
|
|
zip="$(_geo_extract_field "$json" "zip")"
|
|
lat="$(_geo_extract_field "$json" "lat")"
|
|
lon="$(_geo_extract_field "$json" "lon")"
|
|
isp="$(_geo_extract_field "$json" "isp")"
|
|
org="$(_geo_extract_field "$json" "org")"
|
|
asn="$(_geo_extract_field "$json" "as")"
|
|
proxy="$(_geo_extract_field "$json" "proxy")"
|
|
hosting="$(_geo_extract_field "$json" "hosting")"
|
|
|
|
echo ""
|
|
echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
|
|
echo -e " ${CYAN}IP consultada:${NC} ${ip_queried}"
|
|
echo -e " ${CYAN}País:${NC} ${country} (${country_code})"
|
|
echo -e " ${CYAN}Región:${NC} ${region}"
|
|
echo -e " ${CYAN}Ciudad:${NC} ${city} ${zip}"
|
|
echo -e " ${CYAN}Coordenadas:${NC} ${lat}, ${lon}"
|
|
echo -e " ${CYAN}ISP:${NC} ${isp}"
|
|
echo -e " ${CYAN}Organización:${NC} ${org}"
|
|
echo -e " ${CYAN}ASN:${NC} ${asn}"
|
|
echo ""
|
|
|
|
if [[ "$proxy" == "true" ]]; then
|
|
echo -e " ${RED}[!] VPN / Proxy detectado${NC}"
|
|
fi
|
|
if [[ "$hosting" == "true" ]]; then
|
|
echo -e " ${YELLOW}[i] Hosting / datacenter detectado${NC}"
|
|
fi
|
|
if [[ "$proxy" != "true" && "$hosting" != "true" ]]; then
|
|
echo -e " ${GREEN}[ok] Sin indicios de VPN, Proxy o Tor${NC}"
|
|
fi
|
|
|
|
echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
|
|
}
|
|
|
|
# ─── Punto de entrada ─────────────────────────────────────────────────────────
|
|
|
|
geolocate_ip() {
|
|
local target="$1"
|
|
|
|
if [[ -z "$target" ]]; then
|
|
error "geolocate_ip: se requiere una IP o dominio como argumento" >&2
|
|
return 1
|
|
fi
|
|
|
|
if ! command -v curl &>/dev/null; then
|
|
error "geolocate_ip: 'curl' no está instalado (sudo apt install curl)" >&2
|
|
return 1
|
|
fi
|
|
|
|
local query_target="$target"
|
|
|
|
if ! _geo_is_ip "$target"; then
|
|
info "Resolviendo dominio a IP..."
|
|
local resolved
|
|
resolved="$(_geo_resolve_domain "$target")"
|
|
if [[ -z "$resolved" ]]; then
|
|
error "geolocate_ip: no se pudo resolver '$target'" >&2
|
|
return 1
|
|
fi
|
|
info "Resuelto: ${target} -> ${resolved}"
|
|
query_target="$resolved"
|
|
fi
|
|
|
|
info "Consultando geolocalización de ${query_target}..."
|
|
local json
|
|
json="$(_geo_fetch "$query_target")"
|
|
|
|
if [[ -z "$json" ]]; then
|
|
error "geolocate_ip: no se obtuvo respuesta de la API" >&2
|
|
return 1
|
|
fi
|
|
|
|
_geo_display_result "$json"
|
|
}
|
|
|
|
# Ejecutar si se llama directamente
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
geolocate_ip "$@"
|
|
fi
|