feat: add bash cybersecurity audit and hardening functions
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/.
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user