LinuxParty
Si llevas años utilizando geoiplookup para identificar el país o la procedencia de una dirección IP, quizá haya llegado el momento de revisar de dónde salen sus datos. En LinuxParty hemos preparado geoipshscript.sh: una alternativa en Bash que consulta un servicio en línea y conserva la presentación tradicional para facilitar su integración en nuestros scripts.
Hay herramientas que terminan formando parte del paisaje de cualquier terminal Linux. geoiplookup es una de ellas: una dirección IP, una orden y una respuesta sencilla que podemos leer directamente o procesar con otras utilidades.
El problema aparece cuando seguimos consultando bases de datos antiguas. El programa puede ejecutarse perfectamente y, aun así, ofrecer información desfasada.
MaxMind retiró sus bases de datos GeoIP Legacy en mayo de 2022 y recomienda migrar a GeoIP2 y libmaxminddb. Por tanto, conviene comprobar qué base de datos utiliza nuestra instalación antes de confiar en sus resultados.
Nuestra alternativa: Bash, curl y jq
Para nuestras consultas habituales hemos desarrollado geoipshscript.sh, un script Bash que obtiene los datos de geolocalización mediante una petición HTTPS a ipwho.is y transforma su respuesta JSON en una salida familiar.
Su funcionamiento es sencillo:
- Recibe una dirección IPv4 o IPv6.
- Consulta el servicio mediante
curl. - Comprueba que la respuesta sea válida y que la consulta haya tenido éxito.
- Extrae los campos con
jq. - Presenta país, ubicación y sistema autónomo con las etiquetas tradicionales.
Si lo ejecutamos sin argumentos, consulta la IP pública de salida de nuestra conexión.
No necesita mantener una base de datos local: la información procede del proveedor en el momento de la consulta. Esto evita depender del fichero antiguo que tengamos instalado, aunque la exactitud sigue dependiendo de los datos del servicio.
Hemos conservado la presentación de geoiplookup
Una de nuestras prioridades era mantener una salida reconocible. Muchos administradores ya tienen pequeñas automatizaciones que buscan determinadas líneas o extraen sus campos.
Por eso conservamos estas tres etiquetas:
GeoIP Country Edition: GeoIP City Edition, Rev 1: GeoIP ASNum Edition:
La estructura de salida es la siguiente:
GeoIP Country Edition: código de país, país GeoIP City Edition, Rev 1: país, código de región, región, ciudad, código postal, latitud, longitud, 0, 0 GeoIP ASNum Edition: ASnúmero organización
Cuando falta información, el script utiliza N/A. Si no recibe un ASN válido, muestra:
GeoIP ASNum Edition: IP Address not found
El objetivo es preservar los posibles scripts que utilizaban esta forma de presentación y reducir los cambios necesarios para adaptarlos.
Hay un detalle que debemos tener en cuenta: mantenemos las etiquetas y una estructura similar, pero no se trata de una compatibilidad completa con todas las opciones y campos de geoiplookup. Los dos ceros finales de la línea de ciudad son valores de relleno; no representan información obtenida del proveedor. También conviene revisar las automatizaciones que interpreten posiciones concretas, códigos de región o nombres de ubicación.
Qué necesitamos para utilizarlo
El script requiere Bash, curl y jq.
En Debian, Ubuntu y distribuciones derivadas podemos instalar las dependencias con:
sudo apt install curl jq
En Fedora:
sudo dnf install curl jq
Una vez guardado el código en ~/bin/geoipshscript.sh, le damos permisos de ejecución:
chmod +x ~/bin/geoipshscript.sh
Y ya podemos consultar una dirección:
~/bin/geoipshscript.sh 8.8.8.8
También admite IPv6:
~/bin/geoipshscript.sh 2001:4860:4860::8888
Para consultar nuestra propia IP pública:
~/bin/geoipshscript.sh
La ayuda está disponible mediante:
~/bin/geoipshscript.sh --help
Cómo adaptarlo a nuestras automatizaciones
Si antes teníamos una consulta como esta:
geoiplookup "$ip"
Podemos sustituirla por:
"$HOME/bin/geoipshscript.sh" "$ip"
Los filtros basados en las etiquetas conservadas pueden seguir resultando útiles. Por ejemplo, para seleccionar únicamente la línea del país:
"$HOME/bin/geoipshscript.sh" "$ip" | awk '/^GeoIP Country Edition:/'
Antes de incorporarlo a una tarea programada, debemos comprobar que los campos que consume nuestro script mantienen el significado esperado y gestionar los posibles errores de consulta.
Controles para evitar respuestas engañosas
El script comprueba que las dependencias estén instaladas, limita los caracteres admitidos en la dirección y establece tiempos máximos de conexión y respuesta.
Además, verifica que el proveedor devuelva un objeto JSON y confirme el éxito de la consulta. Los errores se escriben en la salida de error y el programa termina con un código distinto de cero.
También limpia caracteres de control y comas dentro de los campos de texto para mantener una línea por registro y unos separadores estables.
Qué cambia al utilizar un servicio en línea
Frente a una consulta sobre una base de datos local, esta alternativa necesita conexión a Internet y envía la dirección consultada al proveedor.
Está sujeta a la disponibilidad, las condiciones de uso y los límites de consultas de ipwho.is. Antes de utilizarla para procesar grandes registros o realizar consultas masivas, conviene revisar la documentación del servicio.
La ubicación obtenida debe interpretarse como una estimación: no identifica el domicilio de una persona ni garantiza que el equipo esté físicamente en la ciudad indicada.
Para consultas puntuales desde la terminal y automatizaciones sencillas que acepten esa dependencia de red, geoipshscript.sh es una alternativa práctica al viejo geoiplookup: renovamos la fuente de información y conservamos su presentación clásica para facilitar la transición.
#!/usr/bin/env bash # Script: geoipshscript.sh set -euo pipefail # Uso: # ./geoipshscript.sh 8.8.8.8 # ./geoipshscript.sh # # Sin argumento consulta la IP púlica de salida. # La IP consultada se envía ipwho.is mediante HTTPS. error() { printf 'Error: %s\n' "$*" >&2 exit 1 } ayuda() { printf 'Uso: %s [IPv4|IPv6]\n' "${0##*/}" printf 'Sin argumento consulta tu IP púlica.\n' } if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then ayuda exit 0 fi (( $# <= 1 )) || { ayuda >&2 exit 1 } for programa in curl jq; do command -v "$programa" >/dev/null 2>&1 || error "falta $programa. Instálalo para continuar." done ip="${1:-}" # Evitar que el argumento introduzca rutas o parámetros en la URL. # La validación definitiva de la dirección corresponde al proveedor. if [[ -n "$ip" && ! "$ip" =~ ^[0-9A-Fa-f:.]+$ ]]; then error "indica una dirección IPv4 o IPv6 válida." fi if ! respuesta="$( curl \ --silent \ --show-error \ --fail \ --proto '=https' \ --connect-timeout 5 \ --max-time 20 \ --get \ --data-urlencode 'lang=en' \ "https://ipwho.is/${ip}" )"; then error "No se ha podido consultar el servicio. Comprueba la conexión o el límite de consultas." fi if ! jq -e 'type == "object"' >/dev/null 2>&1 <<< "$respuesta"; then error "El proveedor no ha devuelto un objeto JSON válido." fi if ! jq -e '.success == true' >/dev/null <<< "$respuesta"; then mensaje="$( jq -r ' (.message // "Consulta rechazada o IP sin datos") | tostring | gsub("[[:cntrl:]]"; " ") ' <<< "$respuesta" )" error "$mensaje" fi jq -r ' # Mantener una línea por registro y separadores estables. def campo: if . == null or . == "" then "N/A" else tostring | gsub("[[:cntrl:]]"; " ") | gsub(","; " ") end; def coordenada: if type == "number" then tostring else "N/A" end; (.connection | if type == "object" then . else {} end) as $conexion | "GeoIP Country Edition: \(.country_code | campo), \(.country | campo)", ( "GeoIP City Edition, Rev 1: " + ([ (.country_code | campo), (.region_code | campo), (.region | campo), (.city | campo), (.postal | campo), (.latitude | coordenada), (.longitude | coordenada), "0", "0" ] | join(", ")) ), ( "GeoIP ASNum Edition: " + ( if $conexion.asn == null or $conexion.asn == "" or $conexion.asn == 0 then "IP Address not found" else "AS" + ($conexion.asn | campo | sub("^AS"; "")) + " " + ( ( $conexion.org | if . == null or . == "" then $conexion.isp else . end ) | campo ) end ) ) ' <<< "$respuesta"
-
Scripting
- ¿Tu geoiplookup se ha quedado obsoleto? Sustitúyelo por este script Bash sin renunciar a su formato clásico
- Cómo convertir imágenes WebP y PNG a JPG en Linux con un script Bash
- Script en Bash para pausas interactivas con timeout y confirmación
- Monitoriza el uso de CPU y memoria en Linux con el script queprocesos.sh
- Cómo hacer operaciones matemáticas en Bash: cálculos con enteros, decimales, `bc` y `awk`
- Script para realizar copias de seguridad en un servidor en Producción con Dominios en Plesk
- Script para escuchar la Radio en Linux
- 🧠 Cómo forzar evitar distracciones con tus propios scripts en Linux
- Script copiacompleta2, un Script para hacer copias de seguridad completa de tu usuario.
- Iniciar una aplicación o un programa automáticamente desde el Cron en Linux
- Cómo instalar y habilitar el completado automático de Bash Linux
- Operaciones matemáticas en Shell Scripts



